--- /dev/null
+### System information
+
+- **SolveSpace version:** <!--e.g. 3.0~3dd2fc00; go to Help → About...-->
+- **Operating system:** <!--e.g. Debian testing-->
+
+### Expected behavior
+
+<!--What should have happened?-->
+
+### Actual behavior
+
+<!--What actually happened?-->
+
+### Additional information
+
+<!--For bugs, please attach a savefile that shows the problematic behavior.
+You can attach `.slvs` files by archiving them into a `.zip` first.-->
--- /dev/null
+#!/bin/sh -xe
+
+ENABLE_SANITIZERS="OFF"
+if [ "$1" = "release" ]; then
+ BUILD_TYPE="RelWithDebInfo"
+ ENABLE_LTO="ON"
+else
+ BUILD_TYPE="Debug"
+ ENABLE_LTO="OFF"
+fi
+
+# this is an option for our Github CI only, since it doesn't have a macos arm64 image yet
+CMAKE_GENERATOR="Unix Makefiles"
+CMAKE_PREFIX_PATH=""
+if [ "$2" = "arm64" ]; then
+ OSX_ARCHITECTURE="arm64"
+ CMAKE_PREFIX_PATH=$(find /tmp/libomp-arm64/libomp -depth 1)
+ git apply cmake/libpng-macos-arm64.patch || echo "Could not apply patch, probably already patched..."
+ mkdir build-arm64 || true
+ cd build-arm64
+elif [ "$2" = "x86_64" ]; then
+ OSX_ARCHITECTURE="x86_64"
+ CMAKE_PREFIX_PATH=$(find /tmp/libomp-x86_64/libomp -depth 1)
+ mkdir build || true
+ cd build
+else
+ mkdir build || true
+ cd build
+fi
+
+if [ "$3" = "xcode" ]; then
+ CMAKE_GENERATOR="Xcode"
+fi
+
+cmake \
+ -G "${CMAKE_GENERATOR}" \
+ -D CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \
+ -D CMAKE_OSX_ARCHITECTURES="${OSX_ARCHITECTURE}" \
+ -D CMAKE_BUILD_TYPE="${BUILD_TYPE}" \
+ -D ENABLE_OPENMP="ON" \
+ -D ENABLE_SANITIZERS="${ENABLE_SANITIZERS}" \
+ -D ENABLE_LTO="${ENABLE_LTO}" \
+ ..
+
+if [ "$3" = "xcode" ]; then
+ open solvespace.xcodeproj
+else
+ cmake --build . --config "${BUILD_TYPE}" -j$(sysctl -n hw.logicalcpu)
+ if [ $(uname -m) = "$2" ]; then
+ make -j$(sysctl -n hw.logicalcpu) test_solvespace
+ fi
+fi
\ No newline at end of file
--- /dev/null
+#!/bin/sh -xe
+
+./pkg/snap/build.sh --use-lxd
--- /dev/null
+#!/bin/sh -xe
+
+mkdir build
+cd build
+cmake \
+ -DCMAKE_BUILD_TYPE="Debug" \
+ -DENABLE_OPENMP="ON" \
+ -DENABLE_SANITIZERS="ON" \
+ ..
+make -j$(nproc) VERBOSE=1
+make test_solvespace
--- /dev/null
+#!/bin/sh -xe
+
+mkdir build
+cd build
+
+if [ "$1" = "release" ]; then
+ if [ "$2" = "openmp" ]; then
+ ENABLE_OPENMP="ON"
+ else
+ ENABLE_OPENMP="OFF"
+ fi
+ BUILD_TYPE=RelWithDebInfo
+ cmake \
+ -G "Visual Studio 16 2019" \
+ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
+ -DENABLE_OPENMP="${ENABLE_OPENMP}" \
+ -DENABLE_LTO=ON \
+ -DCMAKE_GENERATOR_PLATFORM="Win32" \
+ ..
+else
+ BUILD_TYPE=Debug
+ cmake \
+ -G "Visual Studio 16 2019" \
+ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
+ -DENABLE_OPENMP="ON" \
+ -DCMAKE_GENERATOR_PLATFORM="Win32" \
+ ..
+fi
+
+cmake --build . --config "${BUILD_TYPE}" -- -maxcpucount
+
+bin/$BUILD_TYPE/solvespace-testsuite.exe
+
+if [ "$2" = "openmp" ]; then
+ mv bin/$BUILD_TYPE/solvespace.exe bin/$BUILD_TYPE/solvespace-openmp.exe
+fi
--- /dev/null
+#!/bin/sh -xe
+
+if [ "$1" = "ci" ]; then
+ armloc=$(brew fetch --bottle-tag=arm64_big_sur libomp | grep -i downloaded | grep tar.gz | cut -f2 -d:)
+ x64loc=$(brew fetch --bottle-tag=big_sur libomp | grep -i downloaded | grep tar.gz | cut -f2 -d:)
+ cp $armloc /tmp/libomp-arm64.tar.gz
+ mkdir /tmp/libomp-arm64 || true
+ tar -xzvf /tmp/libomp-arm64.tar.gz -C /tmp/libomp-arm64
+ cp $x64loc /tmp/libomp-x86_64.tar.gz
+ mkdir /tmp/libomp-x86_64 || true
+ tar -xzvf /tmp/libomp-x86_64.tar.gz -C /tmp/libomp-x86_64
+else
+ brew install libomp
+fi
+
+git submodule update --init extlib/cairo extlib/freetype extlib/libdxfrw extlib/libpng extlib/mimalloc extlib/pixman extlib/zlib extlib/eigen
--- /dev/null
+#!/bin/sh -xe
+
+sudo /snap/bin/lxd waitready
+sudo /snap/bin/lxd init --auto
+sudo chgrp travis /var/snap/lxd/common/lxd/unix.socket
+mkdir -p "$TRAVIS_BUILD_DIR/snaps-cache"
--- /dev/null
+#!/bin/sh -xe
+
+sudo apt-get update -qq
+
+sudo apt-get install -q -y \
+ zlib1g-dev libpng-dev libcairo2-dev libfreetype6-dev libjson-c-dev \
+ libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev libgl-dev \
+ libgl-dev libglu-dev libspnav-dev
+
+git submodule update --init extlib/libdxfrw extlib/mimalloc extlib/eigen
--- /dev/null
+#!/bin/sh -xe
+
+git submodule update --init
--- /dev/null
+#!/bin/bash -xe
+
+lipo \
+ -create \
+ build/bin/SolveSpace.app/Contents/Resources/libomp.dylib \
+ build-arm64/bin/SolveSpace.app/Contents/Resources/libomp.dylib \
+ -output \
+ build/bin/SolveSpace.app/Contents/Resources/libomp.dylib
+
+lipo \
+ -create \
+ build/bin/SolveSpace.app/Contents/MacOS/SolveSpace \
+ build-arm64/bin/SolveSpace.app/Contents/MacOS/SolveSpace \
+ -output \
+ build/bin/SolveSpace.app/Contents/MacOS/SolveSpace
+
+lipo \
+ -create \
+ build/bin/SolveSpace.app/Contents/MacOS/solvespace-cli \
+ build-arm64/bin/SolveSpace.app/Contents/MacOS/solvespace-cli \
+ -output \
+ build/bin/SolveSpace.app/Contents/MacOS/solvespace-cli
+
+cd build
+
+openmp="bin/SolveSpace.app/Contents/Resources/libomp.dylib"
+app="bin/SolveSpace.app"
+dmg="bin/SolveSpace.dmg"
+bundle_id="com.solvespace.solvespace"
+
+if [ "$CI" = "true" ]; then
+ # get the signing certificate (this is the Developer ID:Application: Your Name, exported to a p12 file, then converted to base64, e.g.: cat ~/Desktop/certificate.p12 | base64 | pbcopy)
+ echo $MACOS_CERTIFICATE_P12 | base64 --decode > certificate.p12
+
+ # create a keychain
+ security create-keychain -p secret build.keychain
+ security default-keychain -s build.keychain
+ security unlock-keychain -p secret build.keychain
+
+ # import the key
+ security import certificate.p12 -k build.keychain -P "${MACOS_CERTIFICATE_PASSWORD}" -T /usr/bin/codesign
+
+ security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychain
+
+ # check if all is good
+ security find-identity -v
+fi
+
+# sign openmp
+codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${openmp}"
+
+# sign the .app
+codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${app}"
+
+# create the .dmg from the signed .app
+hdiutil create -srcfolder "${app}" "${dmg}"
+
+# sign the .dmg
+codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${dmg}"
+
+# notarize and store request uuid in variable
+notarize_uuid=$(xcrun altool --notarize-app --primary-bundle-id "${bundle_id}" --username "${MACOS_APPSTORE_USERNAME}" --password "${MACOS_APPSTORE_APP_PASSWORD}" --file "${dmg}" 2>&1 | grep RequestUUID | awk '{print $3'})
+
+echo $notarize_uuid
+
+# wait a bit so we don't get errors during checking
+sleep 10
+
+success=0
+for (( ; ; ))
+do
+ echo "Checking progress..."
+ progress=$(xcrun altool --notarization-info "${notarize_uuid}" -u "${MACOS_APPSTORE_USERNAME}" -p "${MACOS_APPSTORE_APP_PASSWORD}" 2>&1)
+ # echo "${progress}"
+
+ if [ $? -ne 0 ] || [[ "${progress}" =~ "Invalid" ]] ; then
+ echo "Error with notarization. Exiting"
+ break
+ fi
+
+ if [[ "${progress}" =~ "success" ]]; then
+ success=1
+ break
+ else
+ echo "Not completed yet. Sleeping for 10 seconds"
+ fi
+ sleep 10
+done
+
+# staple
+xcrun stapler staple "${dmg}"
\ No newline at end of file
--- /dev/null
+name: CD
+
+on:
+ push:
+ branches:
+ - master
+ release:
+ types:
+ - created
+
+jobs:
+ cancel_previous_runs:
+ runs-on: ubuntu-latest
+ name: Cancel Previous Runs
+ steps:
+ - uses: styfle/cancel-workflow-action@0.8.0
+ with:
+ access_token: ${{ github.token }}
+
+ test_ubuntu:
+ needs: [cancel_previous_runs]
+ runs-on: ubuntu-18.04
+ name: Test Ubuntu
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-ubuntu.sh
+ - name: Build & Test
+ run: .github/scripts/build-ubuntu.sh
+
+ test_windows:
+ needs: [cancel_previous_runs]
+ runs-on: windows-2019
+ name: Test Windows
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-windows.sh
+ shell: bash
+ - name: Build & Test
+ run: .github/scripts/build-windows.sh
+ shell: bash
+
+ test_macos:
+ needs: [cancel_previous_runs]
+ runs-on: macos-10.15
+ name: Test macOS
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-macos.sh ci
+ - name: Build & Test
+ run: .github/scripts/build-macos.sh debug arm64 && .github/scripts/build-macos.sh debug x86_64
+
+ build_release_windows:
+ needs: [test_ubuntu, test_windows, test_macos]
+ name: Build Release Windows
+ runs-on: windows-2019
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-windows.sh
+ shell: bash
+ - name: Build & Test
+ run: .github/scripts/build-windows.sh release
+ shell: bash
+ - name: Upload artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: windows
+ path: build/bin/RelWithDebInfo/solvespace.exe
+
+ build_release_windows_openmp:
+ needs: [test_ubuntu, test_windows, test_macos]
+ name: Build Release Windows (OpenMP)
+ runs-on: windows-2019
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-windows.sh
+ shell: bash
+ - name: Build & Test
+ run: .github/scripts/build-windows.sh release openmp
+ shell: bash
+ - name: Upload artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: windows-openmp
+ path: build/bin/RelWithDebInfo/solvespace-openmp.exe
+
+ build_release_macos:
+ needs: [test_ubuntu, test_windows, test_macos]
+ name: Build Release macOS
+ runs-on: macos-10.15
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-macos.sh ci
+ - name: Build & Test
+ run: .github/scripts/build-macos.sh release arm64 && .github/scripts/build-macos.sh release x86_64
+ - name: Sign Build
+ run: .github/scripts/sign-macos.sh
+ env:
+ MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
+ MACOS_CERTIFICATE_P12: ${{ secrets.MACOS_CERTIFICATE_P12 }}
+ MACOS_APPSTORE_APP_PASSWORD: ${{ secrets.MACOS_APPSTORE_APP_PASSWORD }}
+ MACOS_APPSTORE_USERNAME: ${{ secrets.MACOS_APPSTORE_USERNAME }}
+ MACOS_DEVELOPER_ID: ${{ secrets.MACOS_DEVELOPER_ID }}
+ - name: Upload artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: macos
+ path: build/bin/SolveSpace.dmg
+
+ deploy_snap_amd64:
+ needs: [test_ubuntu, test_windows, test_macos]
+ name: Deploy AMD64 Snap
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Fetch Tags
+ run: git fetch --force --tags
+ - name: Set Up Source
+ run: rsync --filter=":- .gitignore" -r ./ pkg/snap/solvespace-snap-src
+ - name: Build Snap
+ uses: snapcore/action-build@v1
+ id: build
+ with:
+ path: pkg/snap
+ - name: Upload & Release to Edge
+ if: github.event_name == 'push'
+ uses: snapcore/action-publish@v1
+ with:
+ store_login: ${{ secrets.SNAPSTORE_LOGIN }}
+ snap: ${{ steps.build.outputs.snap }}
+ release: edge
+ - name: Upload & Release to Beta + Edge
+ if: github.event_name == 'release'
+ uses: snapcore/action-publish@v1
+ with:
+ store_login: ${{ secrets.SNAPSTORE_LOGIN }}
+ snap: ${{ steps.build.outputs.snap }}
+ release: edge,beta
+
+ upload_release_assets:
+ name: Upload Release Assets
+ needs: [build_release_windows, build_release_windows_openmp, build_release_macos]
+ if: "!cancelled() && github.event_name == 'release'"
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download All Workflow Artifacts
+ uses: actions/download-artifact@v2
+ - name: Get Release Upload URL
+ id: get_upload_url
+ env:
+ event: ${{ toJson(github.event) }}
+ run: |
+ upload_url=$(echo "$event" | jq -r ".release.upload_url")
+ echo "::set-output name=upload_url::$upload_url"
+ echo "Upload URL: $upload_url"
+ - name: Upload solvespace.exe
+ uses: actions/upload-release-asset@v1
+ continue-on-error: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.get_upload_url.outputs.upload_url }}
+ asset_path: windows/solvespace.exe
+ asset_name: solvespace.exe
+ asset_content_type: binary/octet-stream
+ - name: Upload solvespace-openmp.exe
+ uses: actions/upload-release-asset@v1
+ continue-on-error: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.get_upload_url.outputs.upload_url }}
+ asset_path: windows-openmp/solvespace-openmp.exe
+ asset_name: solvespace-openmp.exe
+ asset_content_type: binary/octet-stream
+ - name: Upload SolveSpace.dmg
+ uses: actions/upload-release-asset@v1
+ continue-on-error: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.get_upload_url.outputs.upload_url }}
+ asset_path: macos/SolveSpace.dmg
+ asset_name: SolveSpace.dmg
+ asset_content_type: binary/octet-stream
--- /dev/null
+name: Source Tarball
+
+on:
+ release:
+ types:
+ - created
+
+jobs:
+ create_tarball:
+ name: Create & Upload Tarball
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: true
+ fetch-depth: 0
+ - name: Pack Tarball
+ id: pack_tarball
+ run: |
+ version="${GITHUB_REF#refs/tags/v}"
+ dir_name="solvespace-${version}"
+ archive_name="${dir_name}.tar.xz"
+ archive_path="${HOME}/${archive_name}"
+
+ echo "::set-output name=archive_name::${archive_name}"
+ echo "::set-output name=archive_path::${archive_path}"
+
+ cd ..
+ tar \
+ --exclude-vcs \
+ --transform "s:^solvespace:${dir_name}:" \
+ -cvaf \
+ ${archive_path} \
+ solvespace
+ - name: Get Release Upload URL
+ id: get_upload_url
+ env:
+ event: ${{ toJson(github.event) }}
+ run: |
+ upload_url=$(echo "$event" | jq -r ".release.upload_url")
+ echo "::set-output name=upload_url::$upload_url"
+ echo "Upload URL: $upload_url"
+ - name: Upload Tarball
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.get_upload_url.outputs.upload_url }}
+ asset_path: ${{ steps.pack_tarball.outputs.archive_path }}
+ asset_name: ${{ steps.pack_tarball.outputs.archive_name }}
+ asset_content_type: binary/octet-stream
--- /dev/null
+name: Test
+
+on:
+ pull_request:
+ branches:
+ - master
+ push:
+ branches-ignore:
+ - master
+ tags-ignore:
+ - v*
+
+jobs:
+ test_ubuntu:
+ runs-on: ubuntu-18.04
+ name: Test Ubuntu
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-ubuntu.sh
+ - name: Build & Test
+ run: .github/scripts/build-ubuntu.sh
+
+ test_windows:
+ runs-on: windows-2019
+ name: Test Windows
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-windows.sh
+ shell: bash
+ - name: Build & Test
+ run: .github/scripts/build-windows.sh
+ shell: bash
+
+ test_macos:
+ runs-on: macos-10.15
+ name: Test macOS
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install Dependencies
+ run: .github/scripts/install-macos.sh ci
+ - name: Build & Test
+ run: .github/scripts/build-macos.sh debug arm64 && .github/scripts/build-macos.sh debug x86_64
Changelog
=========
+3.x - since the 3.0 release, only available in edge builds
+---
+
+Constraints:
+
+* Arcs length ratio and difference.
+* Arc & Line length ratio and difference.
+* Allow comments to be associated with point entities.
+
+Sketching:
+
+* Support for pan, zoom and rotate trackpad gestures on macOS
+* Add "exploded view" to sketches via "\\" key. Shows sketch elements separated
+ by a configurable distance perpendicular to the sketch plane.
+* Added Feet-Inches as a unit of measure. Inputs are still in inches.
+ But the display shows feet, inches, and fraction of an inch.
+* Added an optional "pitch" parameter to helix extrusions (in the text window)
+* Allow use of Point & Normal to define "sketch-in-new-workplane".
+* Update "Property Browser" live while dragging the sketch.
+
+MISC:
+
+* Add a link to the GitHub commit from which SolveSpace was built in the Help
+ menu.
+* Make all points, vectors and normals shown in the Property Browser into
+ active links. This makes them explorable and selectable.
+* Load 16bit PNG images correctly by re-scaling to 8bit.
+* Fixed hang when trying to display characters missing from the embedded font.
+* The main window vertical size can be as small as the toolbar.
+* Configurable "SafeHeight" parameter instead of the fixed 5mm for G-code export.
+* Add Spanish / Argentina translation.
+* Move "perspective factor", "lighting direction" and "explode distance" from
+ the "configuration" screen to the "view" screen.
+* Add a "∆" suffix to groups which have "force to triangle mesh" ticked
+* Gray the group name in the text window for groups with suppressed solid model.
+* Added the ability to Link STL files.
+* When linking circuit boards (IDF .emn files) show keepout regions as construction entities.
+
+Performance:
+
+* Speed up sketches with many constraints by roughly 8x by using the Eigen
+ library in the solver. The maximum unknowns increased from 1024 to 2048.
+* Add a "suppress dof calculation" setting to groups - increases performance for
+ complex sketches.
+* More changes to the ID list implementation.
+
3.0
---
New sketch features:
- * New intersection boolean operation for solid models.
- * New groups, revolution and helical extrusion.
- * Extrude, lathe, translate and rotate groups can use the "assembly"
- boolean operation, to increase performance.
- * The solid model of extrude and lathe groups can be suppressed,
- for splitting a single model in multiple parts to export,
- or if only the generated entities are desired, without the mesh.
- * Translate and rotate groups can create n-dimensional arrays using
- the "difference" and "assembly" boolean operations.
- * A new sketch in workplane group can be created based on existing workplane.
- * TTF text request has two additional points on the right side, which allow
- constraining the width of text.
- * Image requests can now be created, similar to TTF text requests.
- This replaces the "style → background image" feature.
- * Irrelevant points (e.g. arc center point) are not counted when estimating
- the bounding box used to compute chord tolerance.
- * When adding a constraint which has a label and is redundant with another
- constraint, the constraint is added as a reference, avoiding an error.
- * Datum points can be copied and pasted.
- * "Split Curves at Intersection" can now split curves at point lying on curve,
- not just at intersection of two curves.
- * Property browser now shows amount of degrees of freedom in group list.
- It also shows a yellow "err" if the sketch has problems (e.g. self
- intersecting) that would propagate in subsequent groups.
+
+* New intersection boolean operation for solid models.
+* New groups, revolution and helical extrusion.
+* Extrude, lathe, translate and rotate groups can use the "assembly"
+ boolean operation, to increase performance.
+* The solid model of extrude and lathe groups can be suppressed,
+ for splitting a single model in multiple parts to export,
+ or if only the generated entities are desired, without the mesh.
+* Translate and rotate groups can create n-dimensional arrays using
+ the "difference" and "assembly" boolean operations.
+* A new sketch in workplane group can be created based on existing workplane.
+* TTF text request has two additional points on the right side, which allow
+ constraining the width of text.
+* Image requests can now be created, similar to TTF text requests.
+ This replaces the "style → background image" feature.
+* Irrelevant points (e.g. arc center point) are not counted when estimating
+ the bounding box used to compute chord tolerance.
+* When adding a constraint which has a label and is redundant with another
+ constraint, the constraint is added as a reference, avoiding an error.
+* Datum points can be copied and pasted.
+* "Split Curves at Intersection" can now split curves at point lying on curve,
+ not just at intersection of two curves.
+* Property browser now shows amount of degrees of freedom in group list.
+ It also shows a yellow "err" if the sketch has problems (e.g. self
+ intersecting) that would propagate in subsequent groups.
+* It is now possible to press "g" to toggle construction on new objects while
+ they are still being drawn.
+* Allow right click to end sketching of all entities.
New constraint features:
- * When dragging an arc or rectangle point, it will be automatically
- constrained to other points with a click.
- * When selecting a constraint, the requests it constraints can be selected
- in the text window.
- * When selecting an entity, the constraints applied to it can be selected
- in the text window.
- * Distance constraint labels can now be formatted to use SI prefixes.
- Values are edited in the configured unit regardless of label format.
- * When creating a constraint, if an exactly identical constraint already
- exists, it is now selected instead of adding a redundant constraint.
- * It is now possible to turn off automatic creation of horizontal/vertical
- constraints on line segments.
- * Automatic creation of constraints no longer happens if the constraint
- would have been redundant with other ones.
- * New option to open the constraint editor for newly created constraints
- with a value.
+
+* When dragging an arc or rectangle point, it will be automatically
+ constrained to other points with a click.
+* When selecting a constraint, the requests it constraints can be selected
+ in the text window.
+* When selecting an entity, the constraints applied to it can be selected
+ in the text window.
+* Distance constraint labels can now be formatted to use SI prefixes.
+ Values are edited in the configured unit regardless of label format.
+* When creating a constraint, if an exactly identical constraint already
+ exists, it is now selected instead of adding a redundant constraint.
+* It is now possible to turn off automatic creation of horizontal/vertical
+ constraints on line segments.
+* Automatic creation of constraints no longer happens if the constraint
+ would have been redundant with other ones.
+* New option to open the constraint editor for newly created constraints
+ with a value.
+* New "redundant constraint timeout (in ms)" option to prevent UI freeze
+ when looking for redundant constraints.
+* Swap vertical and horizontal constraints when pasting rotated by 90/270
+ degrees.
New export/import features:
- * Link IDF circuit boards in an assembly (.emn files)
- * Three.js: allow configuring projection for exported model, and initially
- use the current viewport projection.
- * Wavefront OBJ: a material file is exported alongside the model, containing
- mesh color information.
- * DXF/DWG: 3D DXF files are imported as construction entities, in 3d.
- * [ADDED 2019-02-25](https://github.com/solvespace/solvespace/pull/384) and [REMOVED 2020-11-13](https://github.com/solvespace/solvespace/issues/795):
- Q3D: [Q3D](https://github.com/q3k/q3d/) triangle meshes can now be
- exported. This format allows to easily hack on triangle mesh data created
- in SolveSpace, supports colour information and is more space efficient than
- most other formats.
- * VRML (WRL) triangle meshes can now be exported, useful for e.g. [KiCAD](http://kicad.org).
- * Export 2d section: custom styled entities that lie in the same
- plane as the exported section are included.
+
+* Link IDF circuit boards in an assembly (.emn files)
+* Three.js: allow configuring projection for exported model, and initially
+ use the current viewport projection.
+* Wavefront OBJ: a material file is exported alongside the model, containing
+ mesh color information.
+* DXF/DWG: 3D DXF files are imported as construction entities, in 3d.
+* VRML (WRL) triangle meshes can now be exported, useful for e.g. [KiCAD](http://kicad.org).
+* Export 2d section: custom styled entities that lie in the same
+ plane as the exported section are included.
+* Added ExportBackgroundColor in configuration for EPS, PDF, and SVG files.
+* STEP export includes object colors and transparency.
+* Default "line styles" have a new "export these objects" option.
New rendering features:
- * The "Show/hide hidden lines" button is now a tri-state button that allows
- showing all lines (on top of shaded mesh), stippling occluded lines
- or not drawing them at all.
- * The "Show/hide outlines" button is now independent from "Show/hide edges".
+
+* The "Show/hide hidden lines" button is now a tri-state button that allows
+ showing all lines (on top of shaded mesh), stippling occluded lines
+ or not drawing them at all.
+* The "Show/hide outlines" button is now independent from "Show/hide edges".
+* "View | Darken Inactive Solids" added. When turned off and a "sketch in plane"
+ group is active solids form previous groups will not be "darkened" (have the
+ s000d-#def-dim-solid style applied to them).
New measurement/analysis features:
- * New choice for base unit, meters.
- * New command for measuring total length of selected entities,
- "Analyze → Measure Perimeter".
- * New command for measuring center of mass, with live updates as the sketch
- changes, "Analyze → Center of Mass".
- * New option for displaying areas of closed contours.
- * When calculating volume of the mesh, volume of the solid from the current
- group is now shown alongside total volume of all solids.
- * When calculating area, and faces are selected, calculate area of those faces
- instead of the closed contour in the sketch.
- * When selecting a point and a line, projected distance to current
- workplane is displayed.
+
+* New choice for base unit, meters.
+* New command for measuring total length of selected entities,
+ "Analyze → Measure Perimeter".
+* New command for measuring center of mass, with live updates as the sketch
+ changes, "Analyze → Center of Mass".
+* New option for displaying areas of closed contours.
+* When calculating volume of the mesh, volume of the solid from the current
+ group is now shown alongside total volume of all solids.
+* When calculating area, and faces are selected, calculate area of those faces
+ instead of the closed contour in the sketch.
+* When selecting a point and a line, projected distance to current
+ workplane is displayed.
Other new features:
- * Added ExportBackgroundColor in configuration for EPS, PDF, and SVG files.
- * Improvements to the text window for selected entities and constraints.
- * Ambient light source added in text window to allow flat shaded renderings.
- * New command-line interface, for batch exporting and more.
- * The graphical interface now supports HiDPI screens on every OS.
- * New option to lock Z axis to be always vertical, like in SketchUp.
- * New button to hide all construction entities.
- * New link to match the on-screen size of the sketch with its actual size,
- "view → set to full scale".
- * When zooming to fit, constraints are also considered.
- * Ctrl-clicking entities now deselects them, as the inverse of clicking.
- * When clicking on an entity that shares a place with other entities,
- the entity from the current group is selected.
- * When dragging an entity that shares a place with other entities,
- the entity from a request is selected. For example, dragging a point on
- a face of an extrusion coincident with the source sketch plane will
- drag the point from the source sketch.
- * The default font for TTF text is now Bitstream Vera Sans, which is
- included in the resources such that it is available on any OS.
- * In expressions, numbers can contain the digit group separator, "_".
- * The "=" key is bound to "Zoom In", like "+" key.
- * The numpad decimal separator key is bound to "." regardless of locale.
- * On Windows, full-screen mode is implemented.
- * On Linux, native file chooser dialog can be used.
- * New edit menu items "Line Styles", "View Projection" and "Configuration"
- that are shortcuts to the respective configuration screens.
- * New cmake build options using -DENABLE_OPENMP=yes and -DENABLE_LTO=yes
- to enable support for multi-threading and link-time optimization.
- * "Shift+Scroll" for ten times finer zoom.
+
+* Improvements to the text window for selected entities and constraints.
+* Ambient light source added in text window to allow flat shaded renderings.
+* New command-line interface, for batch exporting and more.
+* The graphical interface now supports HiDPI screens on every OS.
+* New option to lock Z axis to be always vertical when rotating the view,
+ a.k.a. "turntable navigation".
+* New button to hide all construction entities.
+* New link to match the on-screen size of the sketch with its actual size,
+ "view → set to full scale".
+* When zooming to fit, constraints are also considered.
+* Ctrl-clicking entities now deselects them, as the inverse of clicking.
+* When clicking on an entity that shares a place with other entities,
+ the entity from the current group is selected.
+* When dragging an entity that shares a place with other entities,
+ the entity from a request is selected. For example, dragging a point on
+ a face of an extrusion coincident with the source sketch plane will
+ drag the point from the source sketch.
+* The default font for TTF text is now Bitstream Vera Sans, which is
+ included in the resources such that it is available on any OS.
+* In expressions, numbers can contain the digit group separator, "_".
+* The "=" key is bound to "Zoom In", like "+" key.
+* The numpad decimal separator key is bound to "." regardless of locale.
+* On Windows, full-screen mode is implemented.
+* On Linux, native file chooser dialog can be used.
+* New edit menu items "Line Styles", "View Projection" and "Configuration"
+ that are shortcuts to the respective configuration screens.
+* New cmake build options using -DENABLE_OPENMP=yes and -DENABLE_LTO=yes
+ to enable support for multi-threading and link-time optimization.
+* "Shift+Scroll" for ten times finer zoom.
+* Translations: Chinese, French, German, Russian, Turkish, Ukrainian.
Bugs fixed:
- * Fixed broken --view options for command line thumbnail image creation.
- * Some errors in Triangulation of surfaces.
- * Some NURNS boolean operations that failed particularly on surfaces
- created with Lathe, Revolve, or Helix.
- * Segfault in Remove Spline Point context menu.
- * A point in 3d constrained to any line whose length is free no longer
- causes the line length to collapse.
- * Curve-line constraints (in 3d), parallel constraints (in 3d), and
- same orientation constraints are more robust.
- * Adding some constraints (vertical, midpoint, etc) twice errors out
- immediately, instead of later and in a confusing way.
- * Constraining a newly placed point to a hovered entity does not cause
- spurious changes in the sketch.
- * Points highlighted with "Analyze → Show Degrees of Freedom" are drawn
- on top of all other geometry.
- * A step rotate/translate group using a group forced to triangle mesh
- as a source group also gets forced to triangle mesh.
- * Paste Transformed with a negative scale does not invert arcs.
- * The tangent arc now modifies the original entities instead of deleting
- them, such that their constraints are retained.
- * When linking a sketch file, missing custom styles are now imported from
- the linked file.
- * 3Dconnexion SpaceMouse should now work (on Windows and macOS X).
- * Improved NURBS boolean operations on curved surfaces in some cases.
- * Show only usable fonts in the font selector.
+
+* Fixed broken --view options for command line thumbnail image creation.
+* Some errors in Triangulation of surfaces.
+* Some NURNS boolean operations that failed particularly on surfaces
+ created with Lathe, Revolve, or Helix.
+* Segfault in Remove Spline Point context menu.
+* A point in 3d constrained to any line whose length is free no longer
+ causes the line length to collapse.
+* Curve-line constraints (in 3d), parallel constraints (in 3d), and
+ same orientation constraints are more robust.
+* Adding some constraints (vertical, midpoint, etc) twice errors out
+ immediately, instead of later and in a confusing way.
+* Constraining a newly placed point to a hovered entity does not cause
+ spurious changes in the sketch.
+* Points highlighted with "Analyze → Show Degrees of Freedom" are drawn
+ on top of all other geometry.
+* A step rotate/translate group using a group forced to triangle mesh
+ as a source group also gets forced to triangle mesh.
+* Paste Transformed with a negative scale does not invert arcs.
+* The tangent arc now modifies the original entities instead of deleting
+ them, such that their constraints are retained.
+* When linking a sketch file, missing custom styles are now imported from
+ the linked file.
+* 3Dconnexion SpaceMouse should now work (on Windows and macOS X).
+* Improved NURBS boolean operations on curved surfaces in some cases.
+* Show only usable fonts in the font selector.
2.x
---
Bug fixes:
- * Do not crash when changing an unconstrained lathe group between
- union and difference modes.
+
+* Do not crash when changing an unconstrained lathe group between
+ union and difference modes.
2.3
---
Bug fixes:
- * Do not crash when applying a symmetry constraint to two points.
- * Fix TTF font metrics again (properly this time).
- * Fix the "draw back faces in red" option.
- * Fix export of wireframe as 3D DXF.
- * Various minor crashes.
+
+* Do not crash when applying a symmetry constraint to two points.
+* Fix TTF font metrics again (properly this time).
+* Fix the "draw back faces in red" option.
+* Fix export of wireframe as 3D DXF.
+* Various minor crashes.
2.2
---
Other new features:
- * OS X: support 3Dconnexion devices (SpaceMouse, SpaceNavigator, etc).
- * GTK: files with uppercase extensions can be opened.
+
+* OS X: support 3Dconnexion devices (SpaceMouse, SpaceNavigator, etc).
+* GTK: files with uppercase extensions can be opened.
Bug fixes:
- * Do not remove autosaves after successfully opening a file, preventing
- data loss in case of two abnormal terminations in a row.
- * Do not crash when changing autosave interval.
- * Unbreak the "Show degrees of freedom" command.
- * Three.js: correctly respond to controls when browser zoom is used.
- * OS X: do not completely hide main window when defocused.
- * GTK: unbreak 3Dconnexion support.
- * When pasting transformed entities, multiply constraint values by scale.
- * Fix TTF font metrics (restore the behavior from version 2.0).
- * Forcibly show the current group once we start a drawing operation.
- * DXF export: always declare layers before using them.
- * Do not truncate operations on selections to first 32 selected entities.
- * Translate and rotate groups inherit the "suppress solid model" setting.
- * DXF: files with paths containing non-ASCII or spaces can be exported
- or imported.
- * Significantly improved performance when dragging an entity.
- * Various crashes and minor glitches.
+
+* Do not remove autosaves after successfully opening a file, preventing
+ data loss in case of two abnormal terminations in a row.
+* Do not crash when changing autosave interval.
+* Unbreak the "Show degrees of freedom" command.
+* Three.js: correctly respond to controls when browser zoom is used.
+* OS X: do not completely hide main window when defocused.
+* GTK: unbreak 3Dconnexion support.
+* When pasting transformed entities, multiply constraint values by scale.
+* Fix TTF font metrics (restore the behavior from version 2.0).
+* Forcibly show the current group once we start a drawing operation.
+* DXF export: always declare layers before using them.
+* Do not truncate operations on selections to first 32 selected entities.
+* Translate and rotate groups inherit the "suppress solid model" setting.
+* DXF: files with paths containing non-ASCII or spaces can be exported
+ or imported.
+* Significantly improved performance when dragging an entity.
+* Various crashes and minor glitches.
2.1
---
New sketch features:
- * Lathe groups create circle and face entities.
- * New toolbar button for creating lathe groups.
- * Chord tolerance is separated into two: display chord tolerance (specified
- in percents, relative to model bounding box), and export chord tolerance
- (specified in millimeters as absolute value).
- * Bezier spline points can be added and removed after the spline is created.
- * When an unconstrained extrusion is switched between "union" and
- "difference", its normal is flipped.
- * Groups can be added in the middle of the stack. Note that this results
- in files incompatible with version 2.0.
- * Active group can be removed.
- * Removing an imported group does not cause all subsequent groups to also
- be removed.
- * When a new group with a solid is created, the color is taken from
- a previous group with a solid, if any.
- * Entities in a newly active group do not become visible.
- * When entities are selected, "Zoom to fit" zooms to fit only these
- entities and not the entire sketch.
- * Zero-length edges are reported with a "zero-length error", not
- "points not all coplanar".
+
+* Lathe groups create circle and face entities.
+* New toolbar button for creating lathe groups.
+* Chord tolerance is separated into two: display chord tolerance (specified
+ in percents, relative to model bounding box), and export chord tolerance
+ (specified in millimeters as absolute value).
+* Bezier spline points can be added and removed after the spline is created.
+* When an unconstrained extrusion is switched between "union" and
+ "difference", its normal is flipped.
+* Groups can be added in the middle of the stack. Note that this results
+ in files incompatible with version 2.0.
+* Active group can be removed.
+* Removing an imported group does not cause all subsequent groups to also
+ be removed.
+* When a new group with a solid is created, the color is taken from
+ a previous group with a solid, if any.
+* Entities in a newly active group do not become visible.
+* When entities are selected, "Zoom to fit" zooms to fit only these
+ entities and not the entire sketch.
+* Zero-length edges are reported with a "zero-length error", not
+ "points not all coplanar".
New constraint features:
- * Height of the font used for drawing constraint labels can be changed.
- * New constraint, length difference, placed with J.
- (Patch by Peter Ruevski)
- * Horizontal/vertical constraints are automatically added if a line segment
- is close enough to being horizontal/vertical. This can be disabled by
- holding Ctrl.
- * Reference dimensions and angles can be placed with Shift+D and Shift+N.
- * Copying and pasting entities duplicates any constraints that only involve
- entities in the clipboard, as well as selected comments.
- * Diameter constraints can be shown as radius.
- * The "pi" identifier can be used in expressions.
- * Constraint labels can be snapped to grid.
- * Integer angles are displayed without trailing zeroes.
- * Angle constraints have proper reference lines and arrowheads.
- * Extension lines are drawn for point-line distance constraints.
+
+* Height of the font used for drawing constraint labels can be changed.
+* New constraint, length difference, placed with J.
+ (Patch by Peter Ruevski)
+* Horizontal/vertical constraints are automatically added if a line segment
+ is close enough to being horizontal/vertical. This can be disabled by
+ holding Ctrl.
+* Reference dimensions and angles can be placed with Shift+D and Shift+N.
+* Copying and pasting entities duplicates any constraints that only involve
+ entities in the clipboard, as well as selected comments.
+* Diameter constraints can be shown as radius.
+* The "pi" identifier can be used in expressions.
+* Constraint labels can be snapped to grid.
+* Integer angles are displayed without trailing zeroes.
+* Angle constraints have proper reference lines and arrowheads.
+* Extension lines are drawn for point-line distance constraints.
New solver features:
- * Sketches with redundant and unsolvable constraints are distinguished.
- * New group setting, "allow redundant constraints". Note that it makes
- the solver less stable.
+
+* Sketches with redundant and unsolvable constraints are distinguished.
+* New group setting, "allow redundant constraints". Note that it makes
+ the solver less stable.
New rendering and styling features:
- * New line style parameter: stippling, based on ISO 128.
- * Outlines of solids can be drawn in a particular style (by default, thick
- lines) controlled by the "Show outline of solid model" button.
- * Occluded edges can be drawn in a particular style (by default, stippled
- with short dashes) controlled by the "Show hidden lines" button.
- * Solids can be made transparent.
+
+* New line style parameter: stippling, based on ISO 128.
+* Outlines of solids can be drawn in a particular style (by default, thick
+ lines) controlled by the "Show outline of solid model" button.
+* Occluded edges can be drawn in a particular style (by default, stippled
+ with short dashes) controlled by the "Show hidden lines" button.
+* Solids can be made transparent.
New export/import features:
- * The old "import" command (for .slvs files) is renamed to "link".
- * If a linked .slvs file is not found, first the relative path recorded
- in the .slvs file is checked and then the absolute path; this is
- an inversion of the previously used order. If it is still not found,
- a dialog appears offering to locate it.
- * DXF and DWG files can be imported, with point-coincident, horizontal and
- vertical constraints automatically inferred from geometry, and distance
- and angle constraints created when a dimension placed against geometry
- exists.
- * Triangle mesh can be exported for viewing in the browser through WebGL.
- * Export dialogs remember the last file format used, and preselect it.
- * Exported DXF files have exact circles, arcs and splines instead of
- a piecewise linear approximation (unless hidden line removal was needed).
- * Exported DXF files preserve color and line thickness.
- * In exported DXF files, constraints are represented as DXF dimensions,
- instead of piecewise linear geometry.
- * When exporting 2d views, overlapping lines are removed.
+
+* The old "import" command (for .slvs files) is renamed to "link".
+* If a linked .slvs file is not found, first the relative path recorded
+ in the .slvs file is checked and then the absolute path; this is
+ an inversion of the previously used order. If it is still not found,
+ a dialog appears offering to locate it.
+* DXF and DWG files can be imported, with point-coincident, horizontal and
+ vertical constraints automatically inferred from geometry, and distance
+ and angle constraints created when a dimension placed against geometry
+ exists.
+* Triangle mesh can be exported for viewing in the browser through WebGL.
+* Export dialogs remember the last file format used, and preselect it.
+* Exported DXF files have exact circles, arcs and splines instead of
+ a piecewise linear approximation (unless hidden line removal was needed).
+* Exported DXF files preserve color and line thickness.
+* In exported DXF files, constraints are represented as DXF dimensions,
+ instead of piecewise linear geometry.
+* When exporting 2d views, overlapping lines are removed.
Other new features:
- * Native Linux (GTK 2 and GTK 3) and Mac OS X ports.
- * Automatically save and then restore sketches if SolveSpace crashes.
- (Patch by Marc Britten)
- * Unicode is supported everywhere (filenames, group names, TTF text,
- comments), although RTL scripts and scripts making heavy use of ligatures
- are not rendered correctly.
- * The vector font is grid-fitted when rendered on screen to make it easier
- to read regardless of its size.
+
+* Native Linux (GTK 2 and GTK 3) and Mac OS X ports.
+* Automatically save and then restore sketches if SolveSpace crashes.
+ (Patch by Marc Britten)
+* Unicode is supported everywhere (filenames, group names, TTF text,
+ comments), although RTL scripts and scripts making heavy use of ligatures
+ are not rendered correctly.
+* The vector font is grid-fitted when rendered on screen to make it easier
+ to read regardless of its size.
2.0
---
# cmake configuration
+cmake_minimum_required(VERSION 3.9...3.19)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR
" mkdir build && cd build && cmake ..")
endif()
-cmake_minimum_required(VERSION 3.7.2 FATAL_ERROR)
-if(NOT CMAKE_VERSION VERSION_LESS 3.11.0)
- cmake_policy(VERSION 3.11.0)
-endif()
-if(NOT CMAKE_VERSION VERSION_LESS 3.9)
- # LTO/IPO with non-Intel compilers on Linux requires policy CMP0069 to be set to NEW.
- # Set it explicitly until cmake_minimum_required is raised to >= 3.9.
- cmake_policy(SET CMP0069 NEW)
-endif()
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+list(APPEND CMAKE_MODULE_PATH
"${CMAKE_SOURCE_DIR}/cmake/")
+
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX
"${CMAKE_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake")
-if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
+if (APPLE)
+ # Docs say this must be set before the first project() call
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "macOS minimum supported version")
+endif()
+
# project
# NOTE TO PACKAGERS: The embedded git commit hash is critical for rapid bug triage when the builds
# and instead uncomment the following, adding the complete git hash of the checkout you are using:
# set(GIT_COMMIT_HASH 0000000000000000000000000000000000000000)
-project(solvespace)
-set(solvespace_VERSION_MAJOR 3)
-set(solvespace_VERSION_MINOR 0)
string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
+project(solvespace
+ VERSION 3.1
+ LANGUAGES C CXX ASM)
set(ENABLE_GUI ON CACHE BOOL
"Whether the graphical interface is enabled")
"Whether to enable Clang's AddressSanitizer and UndefinedBehaviorSanitizer")
set(ENABLE_OPENMP OFF CACHE BOOL
"Whether geometric operations will be parallelized using OpenMP")
-set(ENABLE_LTO OFF CACHE BOOL
+set(ENABLE_LTO OFF CACHE BOOL
"Whether interprocedural (global) optimizations are enabled")
+option(FORCE_VENDORED_Eigen3
+ "Whether we should use our bundled Eigen even in the presence of a system copy"
+ OFF)
set(OPENGL 3 CACHE STRING "OpenGL version to use (one of: 1 3)")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/bin>)
endif()
-if(NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID)
- message(FATAL_ERROR "C and C++ compilers should be supplied by the same vendor")
-endif()
-
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
# GCC 4.8/4.9 ship with broken but present <regex>. meh.
# common compiler flags
include(CheckCXXCompilerFlag)
-set(FILE_PREFIX_MAP "-ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.")
-check_cxx_compiler_flag("${FILE_PREFIX_MAP}" HAS_FILE_PREFIX_MAP)
-if(HAS_FILE_PREFIX_MAP)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FILE_PREFIX_MAP}")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FILE_PREFIX_MAP}")
+if (NOT APPLE)
+ set(FILE_PREFIX_MAP "-ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.")
+ check_cxx_compiler_flag("${FILE_PREFIX_MAP}" HAS_FILE_PREFIX_MAP)
+ if(HAS_FILE_PREFIX_MAP)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FILE_PREFIX_MAP}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FILE_PREFIX_MAP}")
+ endif()
endif()
if(MINGW)
if(ENABLE_OPENMP)
find_package( OpenMP REQUIRED )
if(OPENMP_FOUND)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+ add_library(slvs_openmp INTERFACE)
+ target_compile_options(slvs_openmp INTERFACE ${OpenMP_CXX_FLAGS})
+ target_link_libraries(slvs_openmp INTERFACE
+ ${OpenMP_CXX_LIBRARIES})
+ target_include_directories(slvs_openmp INTERFACE SYSTEM
+ ${OpenMP_CXX_INCLUDE_DIRS})
message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} )
endif()
endif()
message(STATUS "Using in-tree libdxfrw")
add_subdirectory(extlib/libdxfrw)
+message(STATUS "Using in-tree eigen")
+include_directories(extlib/eigen)
+
message(STATUS "Using in-tree mimalloc")
set(MI_OVERRIDE OFF CACHE BOOL "")
set(MI_BUILD_SHARED OFF CACHE BOOL "")
add_subdirectory(extlib/mimalloc EXCLUDE_FROM_ALL)
set(MIMALLOC_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/mimalloc/include)
+if(NOT FORCE_VENDORED_Eigen3)
+ find_package(Eigen3 CONFIG)
+endif()
+if(FORCE_VENDORED_Eigen3 OR NOT EIGEN3_FOUND)
+ message(STATUS "Using in-tree Eigen")
+ set(EIGEN3_FOUND YES)
+ set(EIGEN3_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/eigen)
+else()
+ message(STATUS "Using system Eigen: ${EIGEN3_INCLUDE_DIRS}")
+endif()
+
+
if(WIN32 OR APPLE)
# On Win32 and macOS we use vendored packages, since there is little to no benefit
# to trying to find system versions. In particular, trying to link to libraries from
find_vendored_package(PNG libpng
SKIP_INSTALL_ALL ON
PNG_LIBRARY png_static
+ PNG_ARM_NEON "off"
+ PNG_SHARED OFF
+ PNG_STATIC ON
+ PNG_EXECUTABLES OFF
+ PNG_TESTS OFF
+ PNG_FRAMEWORK OFF
PNG_PNG_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/libpng)
list(APPEND PNG_PNG_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/libpng)
FREETYPE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/freetype/include)
message(STATUS "Using in-tree pixman")
- add_vendored_subdirectory(extlib/pixman)
set(PIXMAN_FOUND YES)
set(PIXMAN_LIBRARY pixman)
+ set(PIXMAN_BUILD_TESTS OFF CACHE BOOL "")
+ set(PIXMAN_BUILD_DEMOS OFF CACHE BOOL "")
+
set(PIXMAN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/pixman/pixman)
list(APPEND PIXMAN_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/extlib/pixman/pixman)
+ add_vendored_subdirectory(extlib/pixman)
message(STATUS "Using in-tree cairo")
add_vendored_subdirectory(extlib/cairo)
Licensing
---------------
-SolveSpace is licensed under the GPLv3 and any contributions must be made available
-under the terms of that license.
+SolveSpace is licensed under the GPLv3 or later and any contributions
+must be made available under the terms of that license.
Contributing translations
-------------------------
+# SolveSpace
+
<img src="res/freedesktop/solvespace-scalable.svg" width="70" height="70" alt="SolveSpace Logo" align="left">
-SolveSpace
-==========
[](https://github.com/solvespace/solvespace/actions)
[](https://snapcraft.io/solvespace)
[](https://snapcraft.io/solvespace)
This repository contains the source code of [SolveSpace][], a parametric
2d/3d CAD.
-[solvespace]: http://solvespace.com
+[solvespace]: https://solvespace.com
-Community
----------
+## Community
The official SolveSpace [website][sswebsite] has [tutorials][sstutorial],
[reference manual][ssref] and a [forum][ssforum]; there is also an official
-IRC channel [#solvespace at irc.freenode.net][ssirc].
+IRC channel [#solvespace at web.libera.chat][ssirc].
[sswebsite]: http://solvespace.com/
[ssref]: http://solvespace.com/ref.pl
[sstutorial]: http://solvespace.com/tutorial.pl
[ssforum]: http://solvespace.com/forum.pl
-[ssirc]: https://webchat.freenode.net/?channels=solvespace
+[ssirc]: https://web.libera.chat/#solvespace
-Installation
-------------
+## Installation
-### Via official binary packages
+### Via Official Packages
-_Official_ release binary packages for macOS (>=10.6 64-bit) and Windows (>=Vista 32-bit) are
-available via [GitHub releases][rel]. These packages are automatically built by
-the SolveSpace maintainers for each stable release.
+_Official_ release packages for macOS (>=10.6 64-bit) and Windows
+(>=Vista 32-bit) are available via [GitHub releases][rel]. These packages are
+automatically built by the SolveSpace maintainers for each stable release.
[rel]: https://github.com/solvespace/solvespace/releases
### Via Snap Store
-Builds from master are automatically released to the `edge` channel in the Snap Store. Those packages contain the latest improvements, but receive less testing than release builds.
+Official releases can be installed from the `stable` channel.
-Future official releases will appear in the `stable` channel.
+Builds from master are automatically released to the `edge` channel in the Snap
+Store. Those packages contain the latest improvements, but receive less testing
+than release builds.
[](https://snapcraft.io/solvespace)
Or install from a terminal:
+```sh
+# for the latest stable release:
+snap install solvespace
+
+# for the bleeding edge builds from master:
+snap install solvespace --edge
```
-snap install --edge solvespace
-```
-### Via third-party binary packages
+### Via automated edge builds
+
+> :warning: **Edge builds might be unstable or contain severe bugs!**
+> They are intended for experienced users to test new features or verify bugfixes.
-_Third-party_ nightly binary packages for Debian and Ubuntu are available
-via [notesalexp.org][notesalexp]. These packages are automatically built from non-released
-source code. The SolveSpace maintainers do not control the contents of these packages
-and cannot guarantee their functionality.
+Cutting edge builds from the latest master commit are available as zip archives
+from the following links:
-[notesalexp]: https://notesalexp.org/packages/en/source/solvespace/
+- [macOS](https://nightly.link/solvespace/solvespace/workflows/cd/master/macos.zip)
+- [Windows](https://nightly.link/solvespace/solvespace/workflows/cd/master/windows.zip)
+- [Windows with OpenMP enabled](https://nightly.link/solvespace/solvespace/workflows/cd/master/windows-openmp.zip)
+
+Extract the downloaded archive and install or execute the contained file as is
+appropriate for your platform.
### Via source code
See below.
-Building on Linux
------------------
+## Building on Linux
### Building for Linux
-You will need the usual build tools, CMake, zlib, libpng, cairo, freetype.
-To build the GUI, you will need fontconfig, gtkmm 3.0 (version 3.16 or later), pangomm 1.4,
-OpenGL and OpenGL GLU, and optionally, the Space Navigator client library.
-On a Debian derivative (e.g. Ubuntu) these can be installed with:
+You will need the usual build tools, CMake, zlib, libpng, cairo, freetype. To
+build the GUI, you will need fontconfig, gtkmm 3.0 (version 3.16 or later),
+pangomm 1.4, OpenGL and OpenGL GLU, and optionally, the Space Navigator client
+library. On a Debian derivative (e.g. Ubuntu) these can be installed with:
- sudo apt install git build-essential cmake zlib1g-dev libpng-dev \
- libcairo2-dev libfreetype6-dev libjson-c-dev \
- libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev \
- libgl-dev libglu-dev libspnav-dev
+```sh
+sudo apt install git build-essential cmake zlib1g-dev libpng-dev \
+ libcairo2-dev libfreetype6-dev libjson-c-dev \
+ libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev \
+ libgl-dev libglu-dev libspnav-dev
+```
-On a Redhat derivative (e.g. Fedora) the dependencies can be installed with:
+On a RedHat derivative (e.g. Fedora) the dependencies can be installed with:
- sudo dnf install git gcc-c++ cmake zlib-devel libpng-devel \
- cairo-devel freetype-devel json-c-devel \
- fontconfig-devel gtkmm30-devel pangomm-devel \
- mesa-libGL-devel mesa-libGLU-devel libspnav-devel
+```sh
+sudo dnf install git gcc-c++ cmake zlib-devel libpng-devel \
+ cairo-devel freetype-devel json-c-devel \
+ fontconfig-devel gtkmm30-devel pangomm-devel \
+ mesa-libGL-devel mesa-libGLU-devel libspnav-devel
+```
Before building, check out the project and the necessary submodules:
- git clone https://github.com/solvespace/solvespace
- cd solvespace
- git submodule update --init extlib/libdxfrw extlib/mimalloc
+```sh
+git clone https://github.com/solvespace/solvespace
+cd solvespace
+git submodule update --init extlib/libdxfrw extlib/mimalloc extlib/eigen
+```
After that, build SolveSpace as following:
- mkdir build
- cd build
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make
- sudo make install
+```sh
+mkdir build
+cd build
+cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_OPENMP=ON
+make
-The graphical interface is built as `build/bin/solvespace`, and the command-line interface
-is built as `build/bin/solvespace-cli`. It is possible to build only the command-line interface
-by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation.
+# Optionally
+sudo make install
+```
+
+Link Time Optimization is supported by adding `-DENABLE_LTO=ON` to cmake at the
+expense of longer build time.
+
+The graphical interface is built as `build/bin/solvespace`, and the command-line
+interface is built as `build/bin/solvespace-cli`. It is possible to build only
+the command-line interface by passing the `-DENABLE_GUI=OFF` flag to the cmake
+invocation.
### Building for Windows
-Ubuntu will require 20.04 or above. Cross-compiling with WSL is also confirmed to work.
+Ubuntu will require 20.04 or above. Cross-compiling with WSL is also confirmed
+to work.
-You will need the usual build tools, CMake, a Windows cross-compiler, and flatc. On a Debian derivative (e.g. Ubuntu) these can be installed with:
+You will need the usual build tools, CMake, and a Windows cross-compiler. On a
+Debian derivative (e.g. Ubuntu) these can be installed with:
- apt-get install git build-essential cmake mingw-w64
+```sh
+apt-get install git build-essential cmake mingw-w64
+```
Before building, check out the project and the necessary submodules:
- git clone https://github.com/solvespace/solvespace
- cd solvespace
- git submodule update --init
+```sh
+git clone https://github.com/solvespace/solvespace
+cd solvespace
+git submodule update --init
+```
Build 64-bit SolveSpace with the following:
- mkdir build
- cd build
- cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake \
- -DCMAKE_BUILD_TYPE=Release \
- -DFLATC=$(which flatc)
- make
+```sh
+mkdir build
+cd build
+cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake \
+ -DCMAKE_BUILD_TYPE=Release
+make
+```
-The graphical interface is built as `build/bin/solvespace.exe`, and the command-line interface
-is built as `build/bin/solvespace-cli.exe`.
+The graphical interface is built as `build/bin/solvespace.exe`, and the
+command-line interface is built as `build/bin/solvespace-cli.exe`.
Space Navigator support will not be available.
-If using Ubuntu to cross-compile, Ubuntu 17.10 or newer (or, alternatively, MinGW from the Ubuntu
-17.10 repositories) is required.
+## Building on macOS
-Building on macOS
------------------
-
-You will need git, XCode tools and CMake. Git and CMake can be installed
+You will need git, XCode tools, CMake and libomp. Git, CMake and libomp can be installed
via [Homebrew][]:
- brew install git cmake
+```sh
+brew install git cmake libomp
+```
XCode has to be installed via AppStore or [the Apple website][appledeveloper];
it requires a free Apple ID.
Before building, check out the project and the necessary submodules:
- git clone https://github.com/solvespace/solvespace
- cd solvespace
- git submodule update --init
+```sh
+git clone https://github.com/solvespace/solvespace
+cd solvespace
+git submodule update --init
+```
After that, build SolveSpace as following:
- mkdir build
- cd build
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make
+```sh
+mkdir build
+cd build
+cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_OPENMP=ON
+make
+```
+
+Link Time Optimization is supported by adding `-DENABLE_LTO=ON` to cmake at the
+expense of longer build time.
Alternatively, generate an XCode project, open it, and build the "Release" scheme:
- mkdir build
- cd build
- cmake .. -G Xcode
+```sh
+mkdir build
+cd build
+cmake .. -G Xcode
+```
The application is built in `build/bin/SolveSpace.app`, the graphical interface executable
is `build/bin/SolveSpace.app/Contents/MacOS/SolveSpace`, and the command-line interface executable
[homebrew]: https://brew.sh/
[appledeveloper]: https://developer.apple.com/download/
-Building on OpenBSD
--------------------
+## Building on OpenBSD
You will need git, cmake, libexecinfo, libpng, gtk3mm and pangomm.
These can be installed from the ports tree:
- pkg_add -U git cmake libexecinfo png json-c gtk3mm pangomm
+```sh
+pkg_add -U git cmake libexecinfo png json-c gtk3mm pangomm
+```
Before building, check out the project and the necessary submodules:
- git clone https://github.com/solvespace/solvespace
- cd solvespace
- git submodule update --init extlib/libdxfrw extlib/mimalloc
+```sh
+git clone https://github.com/solvespace/solvespace
+cd solvespace
+git submodule update --init extlib/libdxfrw extlib/mimalloc extlib/eigen
+```
After that, build SolveSpace as following:
- mkdir build
- cd build
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make
+```sh
+mkdir build
+cd build
+cmake .. -DCMAKE_BUILD_TYPE=Release
+make
+sudo make install
+```
Unfortunately, on OpenBSD, the produced executables are not filesystem location independent
and must be installed before use. By default, the graphical interface is installed to
`/usr/local/bin/solvespace-cli`. It is possible to build only the command-line interface
by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation.
-Building on Windows
--------------------
+## Building on Windows
You will need [git][gitwin], [cmake][cmakewin] and a C++ compiler
(either Visual C++ or MinGW). If using Visual C++, Visual Studio 2015
or later is required.
+If gawk is in your path be sure it is a proper Windows port that can handle CL LF line endings.
+If not CMake may fail in libpng due to some awk scripts - issue #1228.
### Building with Visual Studio IDE
### Building with Visual Studio in a command prompt
-First, ensure that git and cl (the Visual C++ compiler driver) are in your
+First, ensure that `git` and `cl` (the Visual C++ compiler driver) are in your
`%PATH%`; the latter is usually done by invoking `vcvarsall.bat` from your
Visual Studio install. Then, run the following in cmd or PowerShell:
- git clone https://github.com/solvespace/solvespace
- cd solvespace
- git submodule update --init
- mkdir build
- cd build
- cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
- nmake
+```bat
+git clone https://github.com/solvespace/solvespace
+cd solvespace
+git submodule update --init
+mkdir build
+cd build
+cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
+nmake
+```
### Building with MinGW
First, ensure that git and gcc are in your `$PATH`. Then, run the following
in bash:
- git clone https://github.com/solvespace/solvespace
- cd solvespace
- git submodule update --init
- mkdir build
- cd build
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make
+```sh
+git clone https://github.com/solvespace/solvespace
+cd solvespace
+git submodule update --init
+mkdir build
+cd build
+cmake .. -DCMAKE_BUILD_TYPE=Release
+make
+```
[gitwin]: https://git-scm.com/download/win
[cmakewin]: http://www.cmake.org/download/#latest
[mingw]: http://www.mingw.org/
-Contributing
-------------
+## Contributing
See the [guide for contributors](CONTRIBUTING.md) for the best way to file issues, contribute code,
and debug SolveSpace.
-License
--------
+## License
-SolveSpace is distributed under the terms of the [GPL v3 license](COPYING.txt).
+SolveSpace is distributed under the terms of the [GPL v3](COPYING.txt) or later.
# Support the REQUIRED and QUIET arguments, and set SPACEWARE_FOUND if found.
include(FindPackageHandleStandardArgs)
- FIND_PACKAGE_HANDLE_STANDARD_ARGS(SPACEWARE DEFAULT_MSG
+ find_package_handle_standard_args(SpaceWare DEFAULT_MSG
SPACEWARE_LIBRARY SPACEWARE_INCLUDE_DIR)
if(SPACEWARE_FOUND)
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleVersion</key>
- <string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}</string>
+ <string>${PROJECT_VERSION}~${solvespace_GIT_HASH}</string>
<key>CFBundleShortVersionString</key>
- <string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}</string>
+ <string>${PROJECT_VERSION}</string>
<key>NSHumanReadableCopyright</key>
- <string>© 2008-2016 Jonathan Westhues and other authors</string>
+ <string>© 2008-2022 Jonathan Westhues and other authors</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSMainNibFile</key>
--- /dev/null
+diff --git a/extlib/libpng/CMakeLists.txt b/extlib/libpng/CMakeLists.txt
+index 42ff0f9025..6834ea332e 100644
+--- a/extlib/libpng/CMakeLists.txt
++++ b/extlib/libpng/CMakeLists.txt
+@@ -65,11 +65,22 @@ option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON)
+ set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
+ set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
+
++# CMake currently sets CMAKE_SYSTEM_PROCESSOR to one of x86_64 or arm64 on macOS,
++# based upon the OS architecture, not the target architecture. As such, we need
++# to check CMAKE_OSX_ARCHITECTURES to identify which hardware-specific flags to
++# enable. Note that this will fail if you attempt to build a universal binary in
++# a single cmake invocation.
++if (APPLE AND CMAKE_OSX_ARCHITECTURES)
++ set(TARGET_ARCH ${CMAKE_OSX_ARCHITECTURES})
++else()
++ set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
++endif()
++
+ if(PNG_HARDWARE_OPTIMIZATIONS)
+
+ # Set definitions and sources for ARM.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
++if(TARGET_ARCH MATCHES "^arm" OR
++ TARGET_ARCH MATCHES "^aarch64")
+ set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
+ set(PNG_ARM_NEON "check"
+ CACHE STRING "Enable ARM NEON optimizations: check|on|off; check is default")
+@@ -95,8 +106,8 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
+ endif()
+
+ # Set definitions and sources for PowerPC.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
++if(TARGET_ARCH MATCHES "^powerpc*" OR
++ TARGET_ARCH MATCHES "^ppc64*")
+ set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
+ set(PNG_POWERPC_VSX "on"
+ CACHE STRING "Enable POWERPC VSX optimizations: on|off; on is default")
+@@ -118,8 +129,8 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
+ endif()
+
+ # Set definitions and sources for Intel.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
++if(TARGET_ARCH MATCHES "^i?86" OR
++ TARGET_ARCH MATCHES "^x86_64*")
+ set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
+ set(PNG_INTEL_SSE "on"
+ CACHE STRING "Enable INTEL_SSE optimizations: on|off; on is default")
+@@ -141,8 +152,8 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
+ endif()
+
+ # Set definitions and sources for MIPS.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
++if(TARGET_ARCH MATCHES "mipsel*" OR
++ TARGET_ARCH MATCHES "mips64el*")
+ set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
+ set(PNG_MIPS_MSA "on"
+ CACHE STRING "Enable MIPS_MSA optimizations: on|off; on is default")
+@@ -166,26 +177,26 @@ endif()
+ else(PNG_HARDWARE_OPTIMIZATIONS)
+
+ # Set definitions and sources for ARM.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
++if(TARGET_ARCH MATCHES "^arm" OR
++ TARGET_ARCH MATCHES "^aarch64")
+ add_definitions(-DPNG_ARM_NEON_OPT=0)
+ endif()
+
+ # Set definitions and sources for PowerPC.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
++if(TARGET_ARCH MATCHES "^powerpc*" OR
++ TARGET_ARCH MATCHES "^ppc64*")
+ add_definitions(-DPNG_POWERPC_VSX_OPT=0)
+ endif()
+
+ # Set definitions and sources for Intel.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
++if(TARGET_ARCH MATCHES "^i?86" OR
++ TARGET_ARCH MATCHES "^x86_64*")
+ add_definitions(-DPNG_INTEL_SSE_OPT=0)
+ endif()
+
+ # Set definitions and sources for MIPS.
+-if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
+- CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
++if(TARGET_ARCH MATCHES "mipsel*" OR
++ TARGET_ARCH MATCHES "mips64el*")
+ add_definitions(-DPNG_MIPS_MSA_OPT=0)
+ endif()
+
+@@ -412,19 +412,11 @@ else()
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
+
+- add_custom_target(symbol-check
+- DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
+-
+ generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
+ generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
+
+- add_custom_target(genvers
+- DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
+- add_custom_target(gensym
+- DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
+-
+ add_custom_target("genprebuilt"
+ COMMAND "${CMAKE_COMMAND}"
+ "-DOUTPUT=scripts/pnglibconf.h.prebuilt"
--- /dev/null
+Some notes about Entities, Entity IDs and the IdList structure
+==============================================================
+Sketch entities in SolveSpace are all of the same type without use of language
+support for polymorphism. The entity class is defined in sketch.h. That class
+contains an enum for each entity to define its type (line, arc, etc...) and some
+other members that can be used to store different things depending on the entity
+type. This means all entities are the same size, so some data may be reference
+by pointers from the entity (font, extra points, etc...)
+
+Entities in a sketch are kept in a global array (IdList) referenced by a unique
+Id (handle) and can be looked up by Id in log(n) time via binary search. In
+order to use binary search the array must be kept in order sorted by Id. One
+problem is that insertion takes O(n) time because half the list (on average)
+must be shifted to make room for a new item.
+
+The IdList class is a template and is used for more than entities.
+
+EntityMap:
+==========
+Another important structure is the EntityMap and EntityKey defined in sketch.h
+This is what allows SovleSpace to update groups when earlier groups in the
+sketch are changed. If a rectangle is extruded to a box and items are
+constrained to entities on that box, the user can go back to the sketch and
+modify it. Entities can be added, modified an even deleted. So long as the
+entities that are later used to build upon are kept the later extrude group will
+pick up the changes from the 2D sketch and anything build on it will remain.
+
+The way this works is that each group has a member called remap, which is one of
+these maps. This is where my understanding is fuzzy. At the end of Group.cpp is
+a function called Group::CopyEntity() which is used to make new sketch entities
+when a group is created. These are generally copies of entities in the previous
+group, but there are exceptions. A point will be used to generate a line when
+extruding a 2D sketch. A point will also be "copied" to a circle for a Lathe
+group. For this reason, the entity key is derived by combining its previous key
+with something often called the CopyNumber or just remap (unfortunate).
+
+When a group is regenerated (the first time, or after a previous one is
+modified) entities are copied from the old group to the new one. For Step
+Translating and Rotating there may be many copies, and the copy number is
+literally N for the Nth copy except for the last one which gets an enum - it is
+common to constrain the last item, so it gets a large unique number so that
+constraints still refer to it if the number of copies changes. When an entity is
+copied like this a new handle is created unless there is already an entity in
+Remap that was created the same way. This is how constructions are preserved
+across underlying changes.
+
+There are some hard limits used in the hash table for the remap mechanism which
+limit the number of entities in a group (but not the global sketch).
+
POINT_N_COPY: A non-transformed copy of a point - numeric copy?
-POINT_N_ROT_AA: A point rotated arount point param[0],param[1],param[2] Where the
+POINT_N_ROT_AA: A point rotated around point param[0],param[1],param[2] Where the
angle is given by param[3]*timesApplied (times 2?) and the axis
of rotation defined by param[4],param[5],param[6]
The ForceTo() functions are shortcuts for using the solver. They are passed the
desired location of a point (or orientation of a normal...) and have the opportunity
to back-calculate what the group parameters should be to place it there. This is
-used for mouse dragging of copied entites. It is notable that the constraints will
+used for mouse dragging of copied entities. It is notable that the constraints will
still be applied afterward, but this is a good shortcut.
When creating a new entity transformation, the first thing to do is define the
+++ /dev/null
-# default behavior is to always use unix style line endings
-* text eol=lf
-*.png binary
-*.pdn binary
-*.sln binary
-*.suo binary
-*.vcproj binary
-*.patch binary
-*.dll binary
-*.lib binary
+++ /dev/null
-ide/vs20??/*.db
-ide/vs20??/*.opendb
-ide/vs20??/*.user
-ide/vs20??/*.vcxproj.filters
-ide/vs20??/.vs
-out/
-docs/
-*.zip
option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF)
option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF)
option(MI_SEE_ASM "Generate assembly files" OFF)
-option(MI_INTERPOSE "Use interpose to override standard malloc on macOS" ON)
-option(MI_OSX_ZONE "Use malloc zone to override standard malloc on macOS" OFF) # enables interpose as well
+option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON)
+option(MI_OSX_ZONE "Use malloc zone to override standard malloc on macOS" ON)
option(MI_LOCAL_DYNAMIC_TLS "Use slightly slower, dlopen-compatible TLS mechanism (Unix)" OFF)
option(MI_BUILD_SHARED "Build shared library" ON)
option(MI_BUILD_STATIC "Build static library" ON)
option(MI_BUILD_TESTS "Build test executables" ON)
option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF)
option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clang++)" OFF)
+option(MI_SKIP_COLLECT_ON_EXIT, "Skip collecting memory on program exit" OFF)
+
+# deprecated options
option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode (deprecated, use MI_DEBUG_FULL instead)" OFF)
+option(MI_INSTALL_TOPLEVEL "Install directly into $CMAKE_INSTALL_PREFIX instead of PREFIX/lib/mimalloc-version (deprecated)" OFF)
+option(MI_USE_LIBATOMIC "Explicitly link with -latomic (on older systems) (deprecated and detected automatically)" OFF)
+include(GNUInstallDirs)
include("cmake/mimalloc-config-version.cmake")
set(mi_sources
src/stats.c
src/random.c
src/os.c
+ src/bitmap.c
src/arena.c
- src/region.c
+ src/segment-cache.c
src/segment.c
src/page.c
src/alloc.c
src/options.c
src/init.c)
+
# -----------------------------------------------------------------------------
-# Converience: set default build type depending on the build directory
+# Convenience: set default build type depending on the build directory
# -----------------------------------------------------------------------------
+message(STATUS "")
if (NOT CMAKE_BUILD_TYPE)
- if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$" OR MI_DEBUG_FULL MATCHES "ON")
+ if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$" OR MI_DEBUG_FULL)
message(STATUS "No build type selected, default to: Debug")
set(CMAKE_BUILD_TYPE "Debug")
else()
set(MI_SECURE "ON")
endif()
+
# -----------------------------------------------------------------------------
# Process options
# -----------------------------------------------------------------------------
set(MI_USE_CXX "ON")
endif()
-if(MI_OVERRIDE MATCHES "ON")
+if(MI_OVERRIDE)
message(STATUS "Override standard malloc (MI_OVERRIDE=ON)")
if(APPLE)
- if(MI_OSX_ZONE MATCHES "ON")
+ if(MI_OSX_ZONE)
# use zone's on macOS
message(STATUS " Use malloc zone to override malloc (MI_OSX_ZONE=ON)")
list(APPEND mi_sources src/alloc-override-osx.c)
- list(APPEND mi_defines MI_OSX_ZONE=1)
- if(NOT MI_INTERPOSE MATCHES "ON")
- message(STATUS " (enabling INTERPOSE as well since zone's require this)")
- set(MI_INTERPOSE "ON")
+ list(APPEND mi_defines MI_OSX_ZONE=1)
+ if (NOT MI_OSX_INTERPOSE)
+ message(STATUS " WARNING: zone overriding usually also needs interpose (use -DMI_OSX_INTERPOSE=ON)")
endif()
endif()
- if(MI_INTERPOSE MATCHES "ON")
+ if(MI_OSX_INTERPOSE)
# use interpose on macOS
- message(STATUS " Use interpose to override malloc (MI_INTERPOSE=ON)")
- list(APPEND mi_defines MI_INTERPOSE)
+ message(STATUS " Use interpose to override malloc (MI_OSX_INTERPOSE=ON)")
+ list(APPEND mi_defines MI_OSX_INTERPOSE=1)
+ if (NOT MI_OSX_ZONE)
+ message(STATUS " WARNING: interpose usually also needs zone overriding (use -DMI_OSX_INTERPOSE=ON)")
+ endif()
+ endif()
+ if(MI_USE_CXX AND MI_OSX_INTERPOSE)
+ message(STATUS " WARNING: if dynamically overriding malloc/free, it is more reliable to build mimalloc as C code (use -DMI_USE_CXX=OFF)")
endif()
endif()
endif()
-if(MI_SECURE MATCHES "ON")
+if(MI_SECURE)
message(STATUS "Set full secure build (MI_SECURE=ON)")
list(APPEND mi_defines MI_SECURE=4)
endif()
-if(MI_SEE_ASM MATCHES "ON")
+if(MI_SEE_ASM)
message(STATUS "Generate assembly listings (MI_SEE_ASM=ON)")
list(APPEND mi_cflags -save-temps)
endif()
-if(MI_CHECK_FULL MATCHES "ON")
+if(MI_CHECK_FULL)
message(STATUS "The MI_CHECK_FULL option is deprecated, use MI_DEBUG_FULL instead")
set(MI_DEBUG_FULL "ON")
endif()
-if(MI_DEBUG_FULL MATCHES "ON")
+if (MI_SKIP_COLLECT_ON_EXIT)
+ message(STATUS "Skip collecting memory on program exit (MI_SKIP_COLLECT_ON_EXIT=ON)")
+ list(APPEND mi_defines MI_SKIP_COLLECT_ON_EXIT=1)
+endif()
+
+if(MI_DEBUG_FULL)
message(STATUS "Set debug level to full internal invariant checking (MI_DEBUG_FULL=ON)")
list(APPEND mi_defines MI_DEBUG=3) # full invariant checking
endif()
-if(MI_PADDING MATCHES "OFF")
+if(NOT MI_PADDING)
message(STATUS "Disable padding of heap blocks in debug mode (MI_PADDING=OFF)")
list(APPEND mi_defines MI_PADDING=0)
endif()
-if(MI_XMALLOC MATCHES "ON")
+if(MI_XMALLOC)
message(STATUS "Enable abort() calls on memory allocation failure (MI_XMALLOC=ON)")
list(APPEND mi_defines MI_XMALLOC=1)
endif()
-if(MI_SHOW_ERRORS MATCHES "ON")
+if(MI_SHOW_ERRORS)
message(STATUS "Enable printing of error and warning messages by default (MI_SHOW_ERRORS=ON)")
list(APPEND mi_defines MI_SHOW_ERRORS=1)
endif()
-if(MI_DEBUG_TSAN MATCHES "ON")
+if(MI_DEBUG_TSAN)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
message(STATUS "Build with thread sanitizer (MI_DEBUG_TSAN=ON)")
+ list(APPEND mi_defines MI_TSAN=1)
list(APPEND mi_cflags -fsanitize=thread -g -O1)
list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=thread)
else()
endif()
endif()
-if(MI_DEBUG_UBSAN MATCHES "ON")
+if(MI_DEBUG_UBSAN)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Build with undefined-behavior sanitizer (MI_DEBUG_UBSAN=ON)")
- list(APPEND mi_cflags -fsanitize=undefined -g)
+ list(APPEND mi_cflags -fsanitize=undefined -g -fno-sanitize-recover=undefined)
list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined)
- if (MI_USE_CXX MATCHES "OFF")
+ if (NOT MI_USE_CXX)
message(STATUS "(switch to use C++ due to MI_DEBUG_UBSAN)")
set(MI_USE_CXX "ON")
endif()
endif()
endif()
-if(MI_USE_CXX MATCHES "ON")
+if(MI_USE_CXX)
message(STATUS "Use the C++ compiler to compile (MI_USE_CXX=ON)")
set_source_files_properties(${mi_sources} PROPERTIES LANGUAGE CXX )
- set_source_files_properties(src/static.c test/test-api.c test/test-stress PROPERTIES LANGUAGE CXX )
+ set_source_files_properties(src/static.c test/test-api.c test/test-api-fill test/test-stress PROPERTIES LANGUAGE CXX )
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang")
list(APPEND mi_cflags -Wno-deprecated)
endif()
# Compiler flags
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU")
list(APPEND mi_cflags -Wall -Wextra -Wno-unknown-pragmas -fvisibility=hidden)
- if(CMAKE_C_COMPILER_ID MATCHES "GNU")
- list(APPEND mi_cflags -Wno-invalid-memory-model)
+ if(NOT MI_USE_CXX)
+ list(APPEND mi_cflags -Wstrict-prototypes)
+ endif()
+ if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang")
+ list(APPEND mi_cflags -Wpedantic -Wno-static-in-inline)
endif()
endif()
endif()
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku")
- if(MI_LOCAL_DYNAMIC_TLS MATCHES "ON")
+ if(MI_LOCAL_DYNAMIC_TLS)
list(APPEND mi_cflags -ftls-model=local-dynamic)
else()
list(APPEND mi_cflags -ftls-model=initial-exec)
endif()
+ if(MI_OVERRIDE)
+ list(APPEND mi_cflags -fno-builtin-malloc)
+ endif()
endif()
-# Architecture flags
-if(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm")
- list(APPEND mi_cflags -march=native)
+if (MSVC AND MSVC_VERSION GREATER_EQUAL 1914)
+ list(APPEND mi_cflags /Zc:__cplusplus)
endif()
# extra needed libraries
if(WIN32)
- list(APPEND mi_libraries psapi shell32 user32 bcrypt)
+ list(APPEND mi_libraries psapi shell32 user32 advapi32 bcrypt)
else()
- if(NOT ${CMAKE_C_COMPILER} MATCHES "android")
- list(APPEND mi_libraries pthread)
- find_library(LIBRT rt)
- if(LIBRT)
- list(APPEND mi_libraries ${LIBRT})
- endif()
+ find_library(MI_LIBPTHREAD pthread)
+ if (MI_LIBPTHREAD)
+ list(APPEND mi_libraries ${MI_LIBPTHREAD})
+ endif()
+ find_library(MI_LIBRT rt)
+ if(MI_LIBRT)
+ list(APPEND mi_libraries ${MI_LIBRT})
+ endif()
+ find_library(MI_LIBATOMIC atomic)
+ if (MI_LIBATOMIC OR MI_USE_LIBATOMIC)
+ list(APPEND mi_libraries atomic)
endif()
endif()
# Install and output names
# -----------------------------------------------------------------------------
-set(mi_install_dir "${CMAKE_INSTALL_PREFIX}/lib/mimalloc-${mi_version}")
-if(MI_SECURE MATCHES "ON")
+# dynamic/shared library and symlinks always go to /usr/local/lib equivalent
+set(mi_install_libdir "${CMAKE_INSTALL_LIBDIR}")
+
+# static libraries and object files, includes, and cmake config files
+# are either installed at top level, or use versioned directories for side-by-side installation (default)
+if (MI_INSTALL_TOPLEVEL)
+ set(mi_install_objdir "${CMAKE_INSTALL_LIBDIR}")
+ set(mi_install_incdir "${CMAKE_INSTALL_INCLUDEDIR}")
+ set(mi_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/mimalloc")
+else()
+ set(mi_install_objdir "${CMAKE_INSTALL_LIBDIR}/mimalloc-${mi_version}") # for static library and object files
+ set(mi_install_incdir "${CMAKE_INSTALL_INCLUDEDIR}/mimalloc-${mi_version}") # for includes
+ set(mi_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/mimalloc-${mi_version}") # for cmake package info
+endif()
+
+if(MI_SECURE)
set(mi_basename "mimalloc-secure")
else()
set(mi_basename "mimalloc")
endif()
+
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LC)
-if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel)$"))
+if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel|none)$"))
set(mi_basename "${mi_basename}-${CMAKE_BUILD_TYPE_LC}") #append build type (e.g. -debug) if not a release version
endif()
if(MI_BUILD_SHARED)
if(MI_BUILD_TESTS)
list(APPEND mi_build_targets "tests")
endif()
+
message(STATUS "")
message(STATUS "Library base name: ${mi_basename}")
+message(STATUS "Version : ${mi_version}")
message(STATUS "Build type : ${CMAKE_BUILD_TYPE_LC}")
-message(STATUS "Install directory: ${mi_install_dir}")
+if(MI_USE_CXX)
+ message(STATUS "C++ Compiler : ${CMAKE_CXX_COMPILER}")
+else()
+ message(STATUS "C Compiler : ${CMAKE_C_COMPILER}")
+endif()
+message(STATUS "Compiler flags : ${mi_cflags}")
+message(STATUS "Compiler defines : ${mi_defines}")
+message(STATUS "Link libraries : ${mi_libraries}")
message(STATUS "Build targets : ${mi_build_targets}")
message(STATUS "")
# shared library
if(MI_BUILD_SHARED)
add_library(mimalloc SHARED ${mi_sources})
- set_target_properties(mimalloc PROPERTIES VERSION ${mi_version} OUTPUT_NAME ${mi_basename} )
+ set_target_properties(mimalloc PROPERTIES VERSION ${mi_version} SOVERSION ${mi_version_major} OUTPUT_NAME ${mi_basename} )
target_compile_definitions(mimalloc PRIVATE ${mi_defines} MI_SHARED_LIB MI_SHARED_LIB_EXPORT)
target_compile_options(mimalloc PRIVATE ${mi_cflags})
target_link_libraries(mimalloc PUBLIC ${mi_libraries})
target_include_directories(mimalloc PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
- $<INSTALL_INTERFACE:${mi_install_dir}/include>
+ $<INSTALL_INTERFACE:${mi_install_incdir}>
)
if(WIN32)
# On windows copy the mimalloc redirection dll too.
- target_link_libraries(mimalloc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect.lib)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set(MIMALLOC_REDIRECT_SUFFIX "32")
+ else()
+ set(MIMALLOC_REDIRECT_SUFFIX "")
+ endif()
+
+ target_link_libraries(mimalloc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.lib)
add_custom_command(TARGET mimalloc POST_BUILD
- COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect.dll" $<TARGET_FILE_DIR:mimalloc>
- COMMENT "Copy mimalloc-redirect.dll to output directory")
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.dll" $<TARGET_FILE_DIR:mimalloc>
+ COMMENT "Copy mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.dll to output directory")
+ install(FILES "$<TARGET_FILE_DIR:mimalloc>/mimalloc-redirect${MIMALLOC_REDIRECT_SUFFIX}.dll" DESTINATION ${mi_install_libdir})
endif()
- install(TARGETS mimalloc EXPORT mimalloc DESTINATION ${mi_install_dir} LIBRARY)
- install(EXPORT mimalloc DESTINATION ${mi_install_dir}/cmake)
+ install(TARGETS mimalloc EXPORT mimalloc DESTINATION ${mi_install_libdir} LIBRARY)
+ install(EXPORT mimalloc DESTINATION ${mi_install_cmakedir})
endif()
# static library
target_link_libraries(mimalloc-static PUBLIC ${mi_libraries})
target_include_directories(mimalloc-static PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
- $<INSTALL_INTERFACE:${mi_install_dir}/include>
+ $<INSTALL_INTERFACE:${mi_install_incdir}>
)
if(WIN32)
# When building both static and shared libraries on Windows, a static library should use a
set_target_properties(mimalloc-static PROPERTIES OUTPUT_NAME ${mi_basename})
endif()
- install(TARGETS mimalloc-static EXPORT mimalloc DESTINATION ${mi_install_dir})
+ install(TARGETS mimalloc-static EXPORT mimalloc DESTINATION ${mi_install_objdir} LIBRARY)
+ install(EXPORT mimalloc DESTINATION ${mi_install_cmakedir})
endif()
# install include files
-install(FILES include/mimalloc.h DESTINATION ${mi_install_dir}/include)
-install(FILES include/mimalloc-override.h DESTINATION ${mi_install_dir}/include)
-install(FILES include/mimalloc-new-delete.h DESTINATION ${mi_install_dir}/include)
-install(FILES cmake/mimalloc-config.cmake DESTINATION ${mi_install_dir}/cmake)
-install(FILES cmake/mimalloc-config-version.cmake DESTINATION ${mi_install_dir}/cmake)
+install(FILES include/mimalloc.h DESTINATION ${mi_install_incdir})
+install(FILES include/mimalloc-override.h DESTINATION ${mi_install_incdir})
+install(FILES include/mimalloc-new-delete.h DESTINATION ${mi_install_incdir})
+install(FILES cmake/mimalloc-config.cmake DESTINATION ${mi_install_cmakedir})
+install(FILES cmake/mimalloc-config-version.cmake DESTINATION ${mi_install_cmakedir})
-if(NOT WIN32 AND MI_BUILD_SHARED)
- # install a symlink in the /usr/local/lib to the versioned library
- set(mi_symlink "${CMAKE_SHARED_MODULE_PREFIX}${mi_basename}${CMAKE_SHARED_LIBRARY_SUFFIX}")
- set(mi_soname "mimalloc-${mi_version}/${mi_symlink}.${mi_version}")
- install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${mi_soname} ${mi_symlink} WORKING_DIRECTORY ${mi_install_dir}/..)")
- install(CODE "MESSAGE(\"-- Symbolic link: ${CMAKE_INSTALL_PREFIX}/lib/${mi_symlink} -> ${mi_soname}\")")
-endif()
# single object file for more predictable static overriding
if (MI_BUILD_OBJECT)
target_compile_options(mimalloc-obj PRIVATE ${mi_cflags})
target_include_directories(mimalloc-obj PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
- $<INSTALL_INTERFACE:${mi_install_dir}/include>
+ $<INSTALL_INTERFACE:${mi_install_incdir}>
)
# the following seems to lead to cmake warnings/errors on some systems, disable for now :-(
- # install(TARGETS mimalloc-obj EXPORT mimalloc DESTINATION ${mi_install_dir})
+ # install(TARGETS mimalloc-obj EXPORT mimalloc DESTINATION ${mi_install_objdir})
# the FILES expression can also be: $<TARGET_OBJECTS:mimalloc-obj>
# but that fails cmake versions less than 3.10 so we leave it as is for now
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/mimalloc-obj.dir/src/static.c${CMAKE_C_OUTPUT_EXTENSION}
- DESTINATION ${mi_install_dir}
+ DESTINATION ${mi_install_objdir}
RENAME ${mi_basename}${CMAKE_C_OUTPUT_EXTENSION} )
endif()
# API surface testing
# -----------------------------------------------------------------------------
-if (MI_BUILD_TESTS MATCHES "ON")
- add_executable(mimalloc-test-api test/test-api.c)
- target_compile_definitions(mimalloc-test-api PRIVATE ${mi_defines})
- target_compile_options(mimalloc-test-api PRIVATE ${mi_cflags})
- target_include_directories(mimalloc-test-api PRIVATE include)
- target_link_libraries(mimalloc-test-api PRIVATE mimalloc-static ${mi_libraries})
+if (MI_BUILD_TESTS)
+ enable_testing()
- add_executable(mimalloc-test-stress test/test-stress.c)
- target_compile_definitions(mimalloc-test-stress PRIVATE ${mi_defines})
- target_compile_options(mimalloc-test-stress PRIVATE ${mi_cflags})
- target_include_directories(mimalloc-test-stress PRIVATE include)
- target_link_libraries(mimalloc-test-stress PRIVATE mimalloc ${mi_libraries})
+ foreach(TEST_NAME api api-fill stress)
+ add_executable(mimalloc-test-${TEST_NAME} test/test-${TEST_NAME}.c)
+ target_compile_definitions(mimalloc-test-${TEST_NAME} PRIVATE ${mi_defines})
+ target_compile_options(mimalloc-test-${TEST_NAME} PRIVATE ${mi_cflags})
+ target_include_directories(mimalloc-test-${TEST_NAME} PRIVATE include)
+ target_link_libraries(mimalloc-test-${TEST_NAME} PRIVATE mimalloc ${mi_libraries})
- enable_testing()
- add_test(test_api, mimalloc-test-api)
- add_test(test_stress, mimalloc-test-stress)
+ add_test(NAME test-${TEST_NAME} COMMAND mimalloc-test-${TEST_NAME})
+ endforeach()
endif()
# -----------------------------------------------------------------------------
# Set override properties
# -----------------------------------------------------------------------------
-if (MI_OVERRIDE MATCHES "ON")
+if (MI_OVERRIDE)
if (MI_BUILD_SHARED)
target_compile_definitions(mimalloc PRIVATE MI_MALLOC_OVERRIDE)
endif()
MIT License
-Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
# https://aka.ms/yaml
trigger:
-- master
-- dev
+ branches:
+ include:
+ - master
+ - dev
+ - dev-slice
+ tags:
+ include:
+ - v*
-jobs:
+jobs:
- job:
displayName: Windows
pool:
vmImage:
- windows-2019
+ windows-2019
strategy:
matrix:
Debug:
inputs:
solution: $(BuildType)/libmimalloc.sln
configuration: '$(MSBuildConfiguration)'
- - script: |
- cd $(BuildType)
- ctest
+ msbuildArguments: -m
+ - script: ctest --verbose --timeout 120 -C $(MSBuildConfiguration)
+ workingDirectory: $(BuildType)
displayName: CTest
-# - upload: $(Build.SourcesDirectory)/$(BuildType)
-# artifact: mimalloc-windows-$(BuildType)
+ #- script: $(BuildType)\$(BuildType)\mimalloc-test-stress
+ # displayName: TestStress
+ #- upload: $(Build.SourcesDirectory)/$(BuildType)
+ # artifact: mimalloc-windows-$(BuildType)
- job:
displayName: Linux
pool:
vmImage:
- ubuntu-16.04
+ ubuntu-18.04
strategy:
matrix:
Debug:
cmakeArgs: .. $(cmakeExtraArgs)
- script: make -j$(nproc) -C $(BuildType)
displayName: Make
- - script: make test -C $(BuildType)
+ - script: ctest --verbose --timeout 120
+ workingDirectory: $(BuildType)
displayName: CTest
# - upload: $(Build.SourcesDirectory)/$(BuildType)
# artifact: mimalloc-ubuntu-$(BuildType)
displayName: macOS
pool:
vmImage:
- macOS-10.14
+ macOS-latest
strategy:
matrix:
Debug:
cmakeArgs: .. $(cmakeExtraArgs)
- script: make -j$(sysctl -n hw.ncpu) -C $(BuildType)
displayName: Make
- - script: make test -C $(BuildType)
+ # - script: MIMALLOC_VERBOSE=1 ./mimalloc-test-api
+ # workingDirectory: $(BuildType)
+ # displayName: TestAPI
+ # - script: MIMALLOC_VERBOSE=1 ./mimalloc-test-stress
+ # workingDirectory: $(BuildType)
+ # displayName: TestStress
+ - script: ctest --verbose --timeout 120
+ workingDirectory: $(BuildType)
displayName: CTest
+
# - upload: $(Build.SourcesDirectory)/$(BuildType)
# artifact: mimalloc-macos-$(BuildType)
+
+# - job:
+# displayName: Windows-2017
+# pool:
+# vmImage:
+# vs2017-win2016
+# strategy:
+# matrix:
+# Debug:
+# BuildType: debug
+# cmakeExtraArgs: -A x64 -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON
+# MSBuildConfiguration: Debug
+# Release:
+# BuildType: release
+# cmakeExtraArgs: -A x64 -DCMAKE_BUILD_TYPE=Release
+# MSBuildConfiguration: Release
+# Secure:
+# BuildType: secure
+# cmakeExtraArgs: -A x64 -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON
+# MSBuildConfiguration: Release
+# steps:
+# - task: CMake@1
+# inputs:
+# workingDirectory: $(BuildType)
+# cmakeArgs: .. $(cmakeExtraArgs)
+# - task: MSBuild@1
+# inputs:
+# solution: $(BuildType)/libmimalloc.sln
+# configuration: '$(MSBuildConfiguration)'
+# - script: |
+# cd $(BuildType)
+# ctest --verbose --timeout 120
+# displayName: CTest
-set(mi_version_major 1)
-set(mi_version_minor 6)
+set(mi_version_major 2)
+set(mi_version_minor 0)
+set(mi_version_patch 6)
set(mi_version ${mi_version_major}.${mi_version_minor})
set(PACKAGE_VERSION ${mi_version})
-if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "${mi_version_major}")
- if ("${PACKAGE_FIND_VERSION_MINOR}" EQUAL "${mi_version_minor}")
- set(PACKAGE_VERSION_EXACT TRUE)
- elseif("${PACKAGE_FIND_VERSION_MINOR}" LESS "${mi_version_minor}")
- set(PACKAGE_VERSION_COMPATIBLE TRUE)
+if(PACKAGE_FIND_VERSION_MAJOR)
+ if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "${mi_version_major}")
+ if ("${PACKAGE_FIND_VERSION_MINOR}" EQUAL "${mi_version_minor}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ elseif("${PACKAGE_FIND_VERSION_MINOR}" LESS "${mi_version_minor}")
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ else()
+ set(PACKAGE_VERSION_UNSUITABLE TRUE)
+ endif()
else()
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
-else()
- set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
include(${CMAKE_CURRENT_LIST_DIR}/mimalloc.cmake)
-get_filename_component(MIMALLOC_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}" PATH)
+get_filename_component(MIMALLOC_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}" PATH) # one up from the cmake dir, e.g. /usr/local/lib/cmake/mimalloc-2.0
+get_filename_component(MIMALLOC_VERSION_DIR "${CMAKE_CURRENT_LIST_DIR}" NAME)
+string(REPLACE "/lib/cmake" "/lib" MIMALLOC_LIBRARY_DIR "${MIMALLOC_CMAKE_DIR}")
+if("${MIMALLOC_VERSION_DIR}" EQUAL "mimalloc")
+ # top level install
+ string(REPLACE "/lib/cmake" "/include" MIMALLOC_INCLUDE_DIR "${MIMALLOC_CMAKE_DIR}")
+ set(MIMALLOC_OBJECT_DIR "${MIMALLOC_LIBRARY_DIR}")
+else()
+ # versioned
+ string(REPLACE "/lib/cmake/" "/include/" MIMALLOC_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}")
+ string(REPLACE "/lib/cmake/" "/lib/" MIMALLOC_OBJECT_DIR "${CMAKE_CURRENT_LIST_DIR}")
+endif()
+set(MIMALLOC_TARGET_DIR "${MIMALLOC_LIBRARY_DIR}") # legacy
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='167.731pt' version='1.1' viewBox='52.938 54.996 381.624 167.731' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip1'>
+<path d='M82.148 206.586H434.164V81.34H82.148Z'/>
+</clipPath>
+<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/>
+<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/>
+<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/>
+<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/>
+<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/>
+<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/>
+<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/>
+<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/>
+<use id='g3-102' transform='scale(1.143)' xlink:href='#g0-102'/>
+<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/>
+<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/>
+<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/>
+<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/>
+<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/>
+<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/>
+<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/>
+<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/>
+<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/>
+<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/>
+<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/>
+<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/>
+<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/>
+<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/>
+<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/>
+<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/>
+<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/>
+<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/>
+<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/>
+<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/>
+<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/>
+<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/>
+<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/>
+<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/>
+<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/>
+<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/>
+<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/>
+<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/>
+<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/>
+<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/>
+<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/>
+<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/>
+<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/>
+<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/>
+<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/>
+<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/>
+<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/>
+<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/>
+<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/>
+<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/>
+<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/>
+<path d='M1.325 -2.657H2.12V-3.096H1.304V-3.898C1.304 -4.38 1.743 -4.449 1.974 -4.449C2.12 -4.449 2.308 -4.428 2.566 -4.331V-4.84C2.385 -4.882 2.169 -4.91 1.981 -4.91C1.262 -4.91 0.739 -4.394 0.739 -3.703V-3.096H0.202V-2.657H0.739V0H1.325V-2.657Z' id='g0-102'/>
+<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/>
+<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/>
+<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/>
+<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/>
+<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/>
+<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/>
+<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/>
+<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/>
+<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/>
+<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/>
+</defs>
+<g id='page1'>
+<path d='M140.82 215.441V206.586M199.488 215.441V206.586M258.156 215.441V206.586M316.824 215.441V206.586M375.496 215.441V206.586M140.82 72.48V81.34M199.488 72.48V81.34M258.156 72.48V81.34M316.824 72.48V81.34M375.496 72.48V81.34' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 210.836V206.586M170.152 210.836V206.586M228.824 210.836V206.586M287.492 210.836V206.586M346.16 210.836V206.586M404.828 210.836V206.586M111.484 77.086V81.34M170.152 77.086V81.34M228.824 77.086V81.34M287.492 77.086V81.34M346.16 77.086V81.34M404.828 77.086V81.34' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 206.586H86.402M82.148 175.273H86.402M82.148 143.961H86.402M82.148 112.648H86.402M82.148 81.34H86.402M434.164 206.586H429.91M434.164 175.273H429.91M434.164 143.961H429.91M434.164 112.648H429.91M434.164 81.34H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 206.586V81.34H434.164V206.586H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 34.954)'>
+<use x='114.487' xlink:href='#g3-99' y='186.027'/>
+<use x='118.25' xlink:href='#g3-102' y='186.027'/>
+<use x='120.838' xlink:href='#g3-114' y='186.027'/>
+<use x='123.73' xlink:href='#g3-97' y='186.027'/>
+<use x='127.798' xlink:href='#g3-99' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 45.565 34.954)'>
+<use x='114.487' xlink:href='#g3-108' y='186.027'/>
+<use x='116.507' xlink:href='#g3-101' y='186.027'/>
+<use x='120.271' xlink:href='#g3-97' y='186.027'/>
+<use x='124.339' xlink:href='#g3-110' y='186.027'/>
+<use x='128.711' xlink:href='#g3-78' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 106.188 34.954)'>
+<use x='114.487' xlink:href='#g3-114' y='186.027'/>
+<use x='117.379' xlink:href='#g3-101' y='186.027'/>
+<use x='121.142' xlink:href='#g3-100' y='186.027'/>
+<use x='125.515' xlink:href='#g3-105' y='186.027'/>
+<use x='127.535' xlink:href='#g3-115' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 159.716 34.954)'>
+<use x='114.487' xlink:href='#g3-108' y='186.027'/>
+<use x='116.507' xlink:href='#g3-97' y='186.027'/>
+<use x='120.34' xlink:href='#g3-114' y='186.027'/>
+<use x='123.232' xlink:href='#g3-115' y='186.027'/>
+<use x='126.478' xlink:href='#g3-111' y='186.027'/>
+<use x='130.712' xlink:href='#g3-110' y='186.027'/>
+<use x='135.085' xlink:href='#g3-78' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 215.596 34.954)'>
+<use x='114.487' xlink:href='#g3-109' y='186.027'/>
+<use x='121.211' xlink:href='#g3-115' y='186.027'/>
+<use x='124.458' xlink:href='#g3-116' y='186.027'/>
+<use x='127.516' xlink:href='#g3-114' y='186.027'/>
+<use x='130.408' xlink:href='#g3-101' y='186.027'/>
+<use x='134.171' xlink:href='#g3-115' y='186.027'/>
+<use x='137.418' xlink:href='#g3-115' y='186.027'/>
+<use x='140.664' xlink:href='#g3-78' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 277.158 34.954)'>
+<use x='114.487' xlink:href='#g3-114' y='186.027'/>
+<use x='117.379' xlink:href='#g3-112' y='186.027'/>
+<use x='121.751' xlink:href='#g3-116' y='186.027'/>
+<use x='124.809' xlink:href='#g3-101' y='186.027'/>
+<use x='128.573' xlink:href='#g3-115' y='186.027'/>
+<use x='131.819' xlink:href='#g3-116' y='186.027'/>
+<use x='134.877' xlink:href='#g3-78' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 22.192)'>
+<use x='114.487' xlink:href='#g2-48' y='186.027'/>
+<use x='117.133' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.12)'>
+<use x='114.487' xlink:href='#g2-48' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-53' y='186.027'/>
+<use x='121.25' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.431)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.743)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-53' y='186.027'/>
+<use x='121.25' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.054)'>
+<use x='114.487' xlink:href='#g2-50' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-120' y='186.027'/>
+</g>
+<path clip-path='url(#clip1)' d='M82.148 143.961H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M88.945 206.586H92.18V143.961H88.945ZM147.613 206.586H150.852V143.961H147.613ZM206.281 206.586H209.52V143.961H206.281ZM264.949 206.586H268.188V143.961H264.949ZM323.621 206.586H326.859V143.961H323.621ZM382.289 206.586H385.527V143.961H382.289Z' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M88.945 206.586H92.18V143.961H88.945ZM147.613 206.586H150.852V143.961H147.613ZM206.281 206.586H209.52V143.961H206.281ZM264.949 206.586H268.188V143.961H264.949ZM323.621 206.586H326.859V143.961H323.621ZM382.289 206.586H385.527V143.961H382.289Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M90.563 143.961V143.898' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M90.563 143.961V143.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M88.57 143.898H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M90.563 143.961V144.023' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M90.563 143.961V144.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M92.555 144.024H88.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M149.231 143.961V143.523' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M149.231 143.961V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M147.238 143.524H151.226' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M149.231 143.961V144.398' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M149.231 143.961V144.398' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M151.223 144.398H147.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M207.902 143.961V142.207' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M207.902 143.961V142.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M205.91 142.207H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M207.902 143.961V145.715' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M207.902 143.961V145.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M209.891 145.715H205.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M266.57 143.961V143.336' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M266.57 143.961V143.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M264.578 143.336H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M266.57 143.961V144.586' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M266.57 143.961V144.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M268.563 144.586H264.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M325.238 143.961V143.586' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M325.238 143.961V143.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M323.246 143.586H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M325.238 143.961V144.336' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M325.238 143.961V144.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M327.231 144.336H323.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M383.906 143.961V143.523' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M383.906 143.961V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M381.914 143.524H385.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M383.906 143.961V144.398' fill='#993333'/>
+<path clip-path='url(#clip1)' d='M383.906 143.961V144.398' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M385.898 144.398H381.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M94.176 206.586H97.41V142.519H94.176ZM152.844 206.586H156.082V140.203H152.844ZM211.512 206.586H214.75V148.344H211.512ZM270.18 206.586H273.418V121.418H270.18ZM328.852 206.586H332.09V135.07H328.852ZM387.52 206.586H390.758V81.34H387.52Z' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M94.176 206.586H97.41V142.519H94.176ZM152.844 206.586H156.082V140.203H152.844ZM211.512 206.586H214.75V148.344H211.512ZM270.18 206.586H273.418V121.418H270.18ZM328.852 206.586H332.09V135.07H328.852ZM387.52 206.586H390.758V81.34H387.52Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M95.793 142.519V142.519' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M93.801 142.52H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M95.793 142.519V142.519' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M93.801 142.52H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M154.461 140.203V139.203' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M154.461 140.203V139.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M152.469 139.203H156.457' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M154.461 140.203V141.207' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M154.461 140.203V141.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M156.453 141.207H152.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M213.133 148.344V148.031' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M213.133 148.344V148.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M211.141 148.032H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M213.133 148.344V148.656' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M213.133 148.344V148.656' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M215.121 148.656H211.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M271.801 121.418V121.23' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M271.801 121.418V121.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M269.809 121.23H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M271.801 121.418V121.605' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M271.801 121.418V121.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M273.793 121.606H269.808' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M330.469 135.07V134.254' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M330.469 135.07V134.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M328.477 134.254H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M330.469 135.07V135.883' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M330.469 135.07V135.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M332.461 135.883H328.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M389.137 81.34V81.34' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M387.145 81.34H391.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M389.137 81.34V81.34' fill='#8080bf'/>
+<path clip-path='url(#clip1)' d='M387.145 81.34H391.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M99.406 206.586H102.641V140.266H99.406ZM158.074 206.586H161.313V142.898H158.074ZM216.742 206.586H219.981V134.754H216.742ZM275.41 206.586H278.649V99.25H275.41ZM334.082 206.586H337.32V81.34H334.082ZM392.75 206.586H395.988V81.34H392.75Z' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M99.406 206.586H102.641V140.266H99.406ZM158.074 206.586H161.313V142.898H158.074ZM216.742 206.586H219.981V134.754H216.742ZM275.41 206.586H278.649V99.25H275.41ZM334.082 206.586H337.32V81.34H334.082ZM392.75 206.586H395.988V81.34H392.75Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M101.024 140.266V140.203' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M101.024 140.266V140.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M99.031 140.203H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M101.024 140.266V140.328' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M101.024 140.266V140.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M103.016 140.328H99.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M159.691 142.898V142.269' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M159.691 142.898V142.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M157.699 142.269H161.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M159.691 142.898V143.523' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M159.691 142.898V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M161.684 143.524H157.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M218.363 134.754V134.066' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M218.363 134.754V134.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M216.371 134.067H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M218.363 134.754V135.445' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M218.363 134.754V135.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M220.352 135.445H216.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M277.031 99.25V91.168' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M277.031 99.25V91.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M275.039 91.172H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M277.031 99.25V107.328' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M277.031 99.25V107.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M279.024 107.328H275.039' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M335.699 81.34V81.34' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M333.707 81.34H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M335.699 81.34V81.34' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M333.707 81.34H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M394.367 81.34V81.34' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M392.375 81.34H396.363' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M394.367 81.34V81.34' fill='#ffb733'/>
+<path clip-path='url(#clip1)' d='M392.375 81.34H396.363' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M104.637 206.586H107.871V124.859H104.637ZM163.305 206.586H166.543V141.207H163.305ZM221.973 206.586H225.211V118.035H221.973ZM280.641 206.586H283.879V121.043H280.641ZM339.313 206.586H342.551V133.066H339.313ZM397.981 206.586H401.219V89.039H397.981Z' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M104.637 206.586H107.871V124.859H104.637ZM163.305 206.586H166.543V141.207H163.305ZM221.973 206.586H225.211V118.035H221.973ZM280.641 206.586H283.879V121.043H280.641ZM339.313 206.586H342.551V133.066H339.313ZM397.981 206.586H401.219V89.039H397.981Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M106.254 124.859V124.797' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M106.254 124.859V124.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M104.261 124.796H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M106.254 124.859V124.922' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M106.254 124.859V124.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M108.246 124.922H104.261' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M164.922 141.207V140.894' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M164.922 141.207V140.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M162.929 140.895H166.917' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M164.922 141.207V141.519' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M164.922 141.207V141.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M166.914 141.52H162.929' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M223.594 118.035V117.973' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M223.594 118.035V117.973' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M221.601 117.973H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M223.594 118.035V118.098' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M223.594 118.035V118.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M225.582 118.098H221.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M282.262 121.043V120.539' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M282.262 121.043V120.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M280.269 120.539H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M282.262 121.043V121.543' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M282.262 121.043V121.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M284.254 121.543H280.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M340.93 133.066V132.812' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M340.93 133.066V132.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M338.937 132.812H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M340.93 133.066V133.316' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M340.93 133.066V133.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M342.922 133.316H338.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M399.598 89.039V88.539' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M399.598 89.039V88.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M397.605 88.539H401.593' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M399.598 89.039V89.543' fill='#bf80bf'/>
+<path clip-path='url(#clip1)' d='M399.598 89.039V89.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M401.59 89.543H397.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M109.867 206.586H113.102V142.332H109.867ZM168.535 206.586H171.774V143.086H168.535ZM227.203 206.586H230.442V132.125H227.203ZM285.871 206.586H289.109V139.641H285.871ZM344.543 206.586H347.781V81.34H344.543ZM403.211 206.586H406.449V100.187H403.211Z' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M109.867 206.586H113.102V142.332H109.867ZM168.535 206.586H171.774V143.086H168.535ZM227.203 206.586H230.442V132.125H227.203ZM285.871 206.586H289.109V139.641H285.871ZM344.543 206.586H347.781V81.34H344.543ZM403.211 206.586H406.449V100.187H403.211Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M111.484 142.332V142.269' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M111.484 142.332V142.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M109.492 142.269H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M111.484 142.332V142.394' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M111.484 142.332V142.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M113.477 142.395H109.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M170.152 143.086V142.644' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M170.152 143.086V142.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M168.16 142.644H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M170.152 143.086V143.523' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M170.152 143.086V143.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M172.145 143.524H168.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M228.824 132.125V131.312' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M228.824 132.125V131.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M226.832 131.312H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M228.824 132.125V132.941' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M228.824 132.125V132.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M230.813 132.941H226.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M287.492 139.641V138.387' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M287.492 139.641V138.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M285.5 138.387H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M287.492 139.641V140.894' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M287.492 139.641V140.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M289.485 140.895H285.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M346.16 81.34V81.34' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M344.168 81.34H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M346.16 81.34V81.34' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M344.168 81.34H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M404.828 100.187V99.562' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M404.828 100.187V99.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M402.836 99.562H406.824' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M404.828 100.187V100.812' fill='#dfbf9f'/>
+<path clip-path='url(#clip1)' d='M404.828 100.187V100.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M406.821 100.813H402.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M115.098 206.586H118.332V135.57H115.098ZM173.766 206.586H177.004V136.07H173.766ZM232.434 206.586H235.672V114.965H232.434ZM291.102 206.586H294.34V113.84H291.102ZM349.774 206.586H353.012V81.34H349.774ZM408.442 206.586H411.68V81.34H408.442Z' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M115.098 206.586H118.332V135.57H115.098ZM173.766 206.586H177.004V136.07H173.766ZM232.434 206.586H235.672V114.965H232.434ZM291.102 206.586H294.34V113.84H291.102ZM349.774 206.586H353.012V81.34H349.774ZM408.442 206.586H411.68V81.34H408.442Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M116.715 135.57V135.508' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M116.715 135.57V135.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M114.722 135.508H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M116.715 135.57V135.633' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M116.715 135.57V135.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M118.707 135.633H114.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M175.383 136.07V135.258' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M175.383 136.07V135.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M173.39 135.258H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M175.383 136.07V136.883' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M175.383 136.07V136.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M177.375 136.883H173.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M234.055 114.965V114.09' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M234.055 114.965V114.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M232.062 114.09H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M234.055 114.965V115.844' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M234.055 114.965V115.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M236.043 115.843H232.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M292.723 113.84V113.215' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M292.723 113.84V113.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M290.73 113.215H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M292.723 113.84V114.465' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M292.723 113.84V114.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M294.715 114.465H290.73' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M351.391 81.34V81.34' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M349.398 81.34H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M351.391 81.34V81.34' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M349.398 81.34H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M410.059 81.34V81.34' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M408.066 81.34H412.054' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M410.059 81.34V81.34' fill='#80bf80'/>
+<path clip-path='url(#clip1)' d='M408.066 81.34H412.054' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M120.328 206.586H123.563V135.633H120.328ZM178.996 206.586H182.234V81.34H178.996ZM237.664 206.586H240.902V138.387H237.664ZM296.332 206.586H299.57V81.34H296.332ZM355.004 206.586H358.238V81.34H355.004ZM413.672 206.586H416.91V81.34H413.672Z' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M120.328 206.586H123.563V135.633H120.328ZM178.996 206.586H182.234V81.34H178.996ZM237.664 206.586H240.902V138.387H237.664ZM296.332 206.586H299.57V81.34H296.332ZM355.004 206.586H358.238V81.34H355.004ZM413.672 206.586H416.91V81.34H413.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M121.945 135.633V135.57' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M121.945 135.633V135.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M119.953 135.571H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M121.945 135.633V135.695' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M121.945 135.633V135.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M123.938 135.695H119.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M180.613 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M178.621 81.34H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M180.613 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M178.621 81.34H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M239.285 138.387V136.195' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M239.285 138.387V136.195' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M237.293 136.195H241.278' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M239.285 138.387V140.578' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M239.285 138.387V140.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M241.274 140.578H237.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M297.953 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M295.961 81.34H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M297.953 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M295.961 81.34H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M356.621 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M354.629 81.34H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M356.621 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M354.629 81.34H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M415.289 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M413.297 81.34H417.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M415.289 81.34V81.34' fill='#bfbf80'/>
+<path clip-path='url(#clip1)' d='M413.297 81.34H417.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M125.559 206.586H128.793V139.266H125.559ZM184.227 206.586H187.465V135.695H184.227ZM242.895 206.586H246.133V137.824H242.895ZM301.563 206.586H304.801V97.433H301.563ZM360.234 206.586H363.469V81.34H360.234ZM418.902 206.586H422.141V81.34H418.902Z' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M125.559 206.586H128.793V139.266H125.559ZM184.227 206.586H187.465V135.695H184.227ZM242.895 206.586H246.133V137.824H242.895ZM301.563 206.586H304.801V97.433H301.563ZM360.234 206.586H363.469V81.34H360.234ZM418.902 206.586H422.141V81.34H418.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M127.176 139.266V139.203' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M127.176 139.266V139.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M125.183 139.203H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M127.176 139.266V139.328' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M127.176 139.266V139.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M129.168 139.328H125.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M185.844 135.695V135.258' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M185.844 135.695V135.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M183.851 135.258H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M185.844 135.695V136.133' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M185.844 135.695V136.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M187.836 136.133H183.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M244.516 137.824V137.012' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M244.516 137.824V137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M242.523 137.012H246.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M244.516 137.824V138.637' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M244.516 137.824V138.637' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M246.504 138.637H242.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M303.184 97.433V95.617' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M303.184 97.433V95.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M301.191 95.617H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M303.184 97.433V99.25' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M303.184 97.433V99.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M305.176 99.25H301.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M361.852 81.34V81.34' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M359.859 81.34H363.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M361.852 81.34V81.34' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M359.859 81.34H363.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M420.52 81.34V81.34' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M418.527 81.34H422.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M420.52 81.34V81.34' fill='#339999'/>
+<path clip-path='url(#clip1)' d='M418.527 81.34H422.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M130.789 206.586H134.024V136.508H130.789ZM189.457 206.586H192.695V143.023H189.457ZM248.125 206.586H251.363V139.391H248.125ZM306.793 206.586H310.031V134.191H306.793ZM365.465 206.586H368.699V81.34H365.465ZM424.133 206.586H427.371V85.348H424.133Z' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M130.789 206.586H134.024V136.508H130.789ZM189.457 206.586H192.695V143.023H189.457ZM248.125 206.586H251.363V139.391H248.125ZM306.793 206.586H310.031V134.191H306.793ZM365.465 206.586H368.699V81.34H365.465ZM424.133 206.586H427.371V85.348H424.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M132.406 136.508V136.445' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M132.406 136.508V136.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M130.414 136.445H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M132.406 136.508V136.57' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M132.406 136.508V136.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M134.399 136.571H130.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M191.074 143.023V142.582' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M191.074 143.023V142.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M189.082 142.582H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M191.074 143.023V143.461' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M191.074 143.023V143.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M193.067 143.461H189.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M249.746 139.391V136.383' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M249.746 139.391V136.383' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M247.754 136.383H251.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M249.746 139.391V142.394' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M249.746 139.391V142.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M251.735 142.395H247.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M308.414 134.191V131.875' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M308.414 134.191V131.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M306.422 131.875H310.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M308.414 134.191V136.508' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M308.414 134.191V136.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M310.407 136.508H306.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M367.082 81.34V81.34' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M365.09 81.34H369.075' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M367.082 81.34V81.34' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M365.09 81.34H369.075' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M425.75 85.348V72.633' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M425.75 85.348V72.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M423.758 72.633H427.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M425.75 85.348V98.058' fill='#bf8080'/>
+<path clip-path='url(#clip1)' d='M425.75 85.348V98.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M427.743 98.059H423.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -93.83 252.423)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.161 252.423)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.508 252.423)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.177 252.423)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.846 252.423)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.515 252.423)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -88.6 250.983)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-50' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.93 248.666)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-54' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.739 256.807)'>
+<use x='114.487' xlink:href='#g2-48' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-57' y='186.027'/>
+<use x='121.25' xlink:href='#g2-51' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.408 229.879)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-51' y='186.027'/>
+<use x='121.25' xlink:href='#g2-54' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.077 243.531)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-52' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.746 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-53' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-56' y='186.027'/>
+<use x='126.877' xlink:href='#g2-50' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.369 248.729)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-54' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.7 251.359)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-50' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.969 243.218)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-53' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.638 207.711)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-55' y='186.027'/>
+<use x='121.25' xlink:href='#g2-49' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.307 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-50' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-51' y='186.027'/>
+<use x='126.877' xlink:href='#g2-54' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.976 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-50' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-57' y='186.027'/>
+<use x='126.877' xlink:href='#g2-49' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.139 233.323)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-51' y='186.027'/>
+<use x='121.25' xlink:href='#g2-49' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.47 249.668)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-52' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.199 226.497)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-52' y='186.027'/>
+<use x='121.25' xlink:href='#g2-49' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.868 229.503)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-51' y='186.027'/>
+<use x='121.25' xlink:href='#g2-55' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.537 241.527)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-55' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.206 197.503)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-56' y='186.027'/>
+<use x='121.25' xlink:href='#g2-56' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -72.908 250.795)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-51' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.239 251.547)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-49' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.43 240.588)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-57' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.099 248.102)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-55' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.768 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-50' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-49' y='186.027'/>
+<use x='126.877' xlink:href='#g2-54' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.437 208.65)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-55' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -67.678 244.032)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-51' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.009 244.533)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-51' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.66 223.429)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-52' y='186.027'/>
+<use x='121.25' xlink:href='#g2-54' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.329 222.302)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-52' y='186.027'/>
+<use x='121.25' xlink:href='#g2-56' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.998 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-56' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-52' y='186.027'/>
+<use x='126.877' xlink:href='#g2-50' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.667 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-57' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-57' y='186.027'/>
+<use x='126.877' xlink:href='#g2-51' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.447 244.095)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-51' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.778 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-51' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-54' y='186.027'/>
+<use x='126.877' xlink:href='#g2-51' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.891 246.85)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-57' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.56 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-50' y='186.027'/>
+<use x='122.76' xlink:href='#g2-51' y='186.027'/>
+<use x='125.406' xlink:href='#g2-46' y='186.027'/>
+<use x='126.877' xlink:href='#g2-57' y='186.027'/>
+<use x='129.523' xlink:href='#g2-57' y='186.027'/>
+<use x='132.169' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.229 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-49' y='186.027'/>
+<use x='122.76' xlink:href='#g2-56' y='186.027'/>
+<use x='125.406' xlink:href='#g2-46' y='186.027'/>
+<use x='126.877' xlink:href='#g2-53' y='186.027'/>
+<use x='129.523' xlink:href='#g2-52' y='186.027'/>
+<use x='132.169' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.898 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-51' y='186.027'/>
+<use x='122.76' xlink:href='#g2-52' y='186.027'/>
+<use x='125.406' xlink:href='#g2-46' y='186.027'/>
+<use x='126.877' xlink:href='#g2-52' y='186.027'/>
+<use x='129.523' xlink:href='#g2-53' y='186.027'/>
+<use x='132.169' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.217 247.727)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-56' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 1.452 244.157)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-51' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 60.121 246.286)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-48' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.79 205.895)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-55' y='186.027'/>
+<use x='121.25' xlink:href='#g2-52' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 177.459 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-52' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-51' y='186.027'/>
+<use x='126.877' xlink:href='#g2-51' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 236.128 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-50' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-49' y='186.027'/>
+<use x='126.877' xlink:href='#g2-50' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -51.986 244.971)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-50' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.683 251.484)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-50' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 65.352 247.852)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-48' y='186.027'/>
+<use x='121.25' xlink:href='#g2-55' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 124.021 242.654)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-49' y='186.027'/>
+<use x='121.25' xlink:href='#g2-54' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.69 189.8)'>
+<use x='109.598' xlink:href='#g4-1' y='186.027'/>
+<use x='113.103' xlink:href='#g4-1' y='186.027'/>
+<use x='116.608' xlink:href='#g4-1' y='186.027'/>
+<use x='120.114' xlink:href='#g2-50' y='186.027'/>
+<use x='122.76' xlink:href='#g2-46' y='186.027'/>
+<use x='124.23' xlink:href='#g2-50' y='186.027'/>
+<use x='126.877' xlink:href='#g2-55' y='186.027'/>
+<use x='129.523' xlink:href='#g2-120' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 241.359 193.808)'>
+<use x='114.487' xlink:href='#g2-49' y='186.027'/>
+<use x='117.133' xlink:href='#g2-46' y='186.027'/>
+<use x='118.603' xlink:href='#g2-57' y='186.027'/>
+<use x='121.25' xlink:href='#g2-52' y='186.027'/>
+</g>
+<g transform='matrix(0 -1 1 0 -126.667 313.708)'>
+<use x='114.487' xlink:href='#g1-82' y='186.027'/>
+<use x='120.457' xlink:href='#g1-101' y='186.027'/>
+<use x='124.553' xlink:href='#g1-108' y='186.027'/>
+<use x='126.753' xlink:href='#g1-97' y='186.027'/>
+<use x='131.181' xlink:href='#g1-116' y='186.027'/>
+<use x='134.509' xlink:href='#g1-105' y='186.027'/>
+<use x='136.709' xlink:href='#g1-118' y='186.027'/>
+<use x='140.957' xlink:href='#g1-101' y='186.027'/>
+<use x='148.124' xlink:href='#g1-116' y='186.027'/>
+<use x='151.452' xlink:href='#g1-105' y='186.027'/>
+<use x='153.652' xlink:href='#g1-109' y='186.027'/>
+<use x='160.972' xlink:href='#g1-101' y='186.027'/>
+<use x='168.139' xlink:href='#g3-40' y='186.027'/>
+<use x='171.432' xlink:href='#g3-108' y='186.027'/>
+<use x='173.453' xlink:href='#g3-111' y='186.027'/>
+<use x='177.452' xlink:href='#g3-119' y='186.027'/>
+<use x='183' xlink:href='#g3-101' y='186.027'/>
+<use x='186.764' xlink:href='#g3-114' y='186.027'/>
+<use x='192.479' xlink:href='#g3-105' y='186.027'/>
+<use x='194.499' xlink:href='#g3-115' y='186.027'/>
+<use x='200.568' xlink:href='#g3-98' y='186.027'/>
+<use x='205.176' xlink:href='#g3-101' y='186.027'/>
+<use x='208.94' xlink:href='#g3-116' y='186.027'/>
+<use x='211.998' xlink:href='#g3-116' y='186.027'/>
+<use x='215.056' xlink:href='#g3-101' y='186.027'/>
+<use x='218.819' xlink:href='#g3-114' y='186.027'/>
+<use x='221.711' xlink:href='#g3-41' y='186.027'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='258.383pt' version='1.1' viewBox='106.736 54.996 381.623 258.383' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip2'>
+<path d='M135.949 251.93H487.961V84.164H135.949Z'/>
+</clipPath>
+<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/>
+<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/>
+<use id='g3-45' transform='scale(1.143)' xlink:href='#g0-45'/>
+<use id='g3-49' transform='scale(1.143)' xlink:href='#g0-49'/>
+<use id='g3-54' transform='scale(1.143)' xlink:href='#g0-54'/>
+<use id='g3-56' transform='scale(1.143)' xlink:href='#g0-56'/>
+<use id='g3-58' transform='scale(1.143)' xlink:href='#g0-58'/>
+<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/>
+<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/>
+<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/>
+<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/>
+<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/>
+<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/>
+<use id='g3-103' transform='scale(1.143)' xlink:href='#g0-103'/>
+<use id='g3-104' transform='scale(1.143)' xlink:href='#g0-104'/>
+<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/>
+<use id='g3-106' transform='scale(1.143)' xlink:href='#g0-106'/>
+<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/>
+<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/>
+<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/>
+<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/>
+<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/>
+<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/>
+<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/>
+<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/>
+<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/>
+<use id='g3-120' transform='scale(1.143)' xlink:href='#g0-120'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/>
+<use id='g2-44' transform='scale(0.714)' xlink:href='#g0-44'/>
+<use id='g2-45' transform='scale(0.714)' xlink:href='#g0-45'/>
+<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/>
+<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/>
+<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/>
+<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/>
+<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/>
+<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/>
+<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/>
+<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/>
+<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/>
+<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/>
+<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/>
+<use id='g2-64' transform='scale(0.714)' xlink:href='#g0-64'/>
+<use id='g2-67' transform='scale(0.714)' xlink:href='#g0-67'/>
+<use id='g2-71' transform='scale(0.714)' xlink:href='#g0-71'/>
+<use id='g2-73' transform='scale(0.714)' xlink:href='#g0-73'/>
+<use id='g2-85' transform='scale(0.714)' xlink:href='#g0-85'/>
+<use id='g2-88' transform='scale(0.714)' xlink:href='#g0-88'/>
+<use id='g2-97' transform='scale(0.714)' xlink:href='#g0-97'/>
+<use id='g2-98' transform='scale(0.714)' xlink:href='#g0-98'/>
+<use id='g2-99' transform='scale(0.714)' xlink:href='#g0-99'/>
+<use id='g2-100' transform='scale(0.714)' xlink:href='#g0-100'/>
+<use id='g2-101' transform='scale(0.714)' xlink:href='#g0-101'/>
+<use id='g2-103' transform='scale(0.714)' xlink:href='#g0-103'/>
+<use id='g2-104' transform='scale(0.714)' xlink:href='#g0-104'/>
+<use id='g2-108' transform='scale(0.714)' xlink:href='#g0-108'/>
+<use id='g2-109' transform='scale(0.714)' xlink:href='#g0-109'/>
+<use id='g2-110' transform='scale(0.714)' xlink:href='#g0-110'/>
+<use id='g2-111' transform='scale(0.714)' xlink:href='#g0-111'/>
+<use id='g2-112' transform='scale(0.714)' xlink:href='#g0-112'/>
+<use id='g2-114' transform='scale(0.714)' xlink:href='#g0-114'/>
+<use id='g2-115' transform='scale(0.714)' xlink:href='#g0-115'/>
+<use id='g2-116' transform='scale(0.714)' xlink:href='#g0-116'/>
+<use id='g2-117' transform='scale(0.714)' xlink:href='#g0-117'/>
+<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/>
+<use id='g2-122' transform='scale(0.714)' xlink:href='#g0-122'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/>
+<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/>
+<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/>
+<path d='M1.339 -0.007V-0.628H0.711V0H0.907L0.704 0.893H1.018L1.339 -0.007Z' id='g0-44'/>
+<path d='M2.05 -1.332V-1.771H0.084V-1.332H2.05Z' id='g0-45'/>
+<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/>
+<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/>
+<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/>
+<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/>
+<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/>
+<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/>
+<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/>
+<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/>
+<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/>
+<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/>
+<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/>
+<path d='M1.339 -3.096H0.711V-2.469H1.339V-3.096ZM0.711 -0.628V0H1.339V-0.628H0.711Z' id='g0-58'/>
+<path d='M4.142 -0.614C4.038 -0.614 4.024 -0.614 3.968 -0.586C3.626 -0.467 3.271 -0.391 2.901 -0.391C1.778 -0.391 0.976 -1.339 0.976 -2.42C0.976 -3.592 1.883 -4.449 2.859 -4.449C3.055 -4.449 3.515 -4.4 3.745 -3.843C3.55 -3.954 3.333 -4.003 3.152 -4.003C2.406 -4.003 1.778 -3.306 1.778 -2.42C1.778 -1.513 2.427 -0.837 3.145 -0.837C3.689 -0.837 4.519 -1.276 4.519 -2.518C4.519 -3.222 4.47 -4.91 2.866 -4.91C1.541 -4.91 0.411 -3.815 0.411 -2.42C0.411 -1.039 1.527 0.07 2.873 0.07C3.515 0.07 4.115 -0.195 4.519 -0.614H4.142ZM3.152 -1.297C2.72 -1.297 2.343 -1.778 2.343 -2.42C2.343 -3.082 2.734 -3.543 3.145 -3.543C3.578 -3.543 3.954 -3.062 3.954 -2.42C3.954 -1.757 3.564 -1.297 3.152 -1.297Z' id='g0-64'/>
+<path d='M4.317 -0.851C3.829 -0.551 3.605 -0.418 2.908 -0.418C1.827 -0.418 1.172 -1.43 1.172 -2.434C1.172 -3.466 1.89 -4.435 2.908 -4.435C3.368 -4.435 3.843 -4.289 4.163 -4.045L4.275 -4.679C3.787 -4.861 3.396 -4.917 2.887 -4.917C1.506 -4.917 0.474 -3.773 0.474 -2.427C0.474 -0.99 1.569 0.07 2.929 0.07C3.612 0.07 3.898 -0.07 4.359 -0.321L4.317 -0.851Z' id='g0-67'/>
+<path d='M4.442 -2.085H2.88V-1.625H3.829V-0.558C3.522 -0.481 3.222 -0.418 2.908 -0.418C1.834 -0.418 1.172 -1.43 1.172 -2.427C1.172 -3.382 1.82 -4.435 2.873 -4.435C3.515 -4.435 3.919 -4.24 4.268 -3.947L4.38 -4.582C3.898 -4.812 3.473 -4.924 2.943 -4.924C1.534 -4.924 0.474 -3.822 0.474 -2.427C0.474 -1.067 1.527 0.07 2.901 0.07C3.403 0.07 3.996 -0.042 4.442 -0.272V-2.085Z' id='g0-71'/>
+<path d='M1.381 -4.84H0.676V0H1.381V-4.84Z' id='g0-73'/>
+<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/>
+<path d='M4.4 -4.84H3.794V-1.625C3.794 -0.69 3.166 -0.265 2.566 -0.265S1.381 -0.697 1.381 -1.618V-4.84H0.676V-1.632C0.676 -0.607 1.555 0.146 2.559 0.146C3.557 0.146 4.4 -0.614 4.4 -1.632V-4.84Z' id='g0-85'/>
+<path d='M2.755 -2.552L4.519 -4.84H3.759L2.413 -3.055L1.039 -4.84H0.209L2.071 -2.552L0.105 0H0.865L2.413 -2.099L3.996 0H4.826L2.755 -2.552Z' id='g0-88'/>
+<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/>
+<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/>
+<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/>
+<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/>
+<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/>
+<path d='M3.508 -3.166C3.354 -3.166 2.887 -3.159 2.357 -2.957L2.343 -2.95C2.092 -3.117 1.848 -3.166 1.646 -3.166C0.962 -3.166 0.453 -2.629 0.453 -2.029C0.453 -1.785 0.537 -1.534 0.697 -1.339C0.6 -1.22 0.495 -1.025 0.495 -0.76C0.495 -0.488 0.607 -0.314 0.669 -0.23C0.286 -0.007 0.209 0.314 0.209 0.481C0.209 1.011 0.941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 0.481C3.487 -0.502 2.267 -0.502 1.967 -0.502H1.318C1.206 -0.502 0.907 -0.502 0.907 -0.865C0.907 -1.004 0.955 -1.074 0.962 -1.088C1.206 -0.934 1.451 -0.886 1.639 -0.886C2.322 -0.886 2.831 -1.423 2.831 -2.022C2.831 -2.246 2.769 -2.448 2.643 -2.636C2.615 -2.678 2.615 -2.685 2.615 -2.692C2.615 -2.72 3.034 -2.72 3.068 -2.72C3.075 -2.72 3.34 -2.72 3.592 -2.692L3.508 -3.166ZM1.646 -1.318C1.269 -1.318 0.99 -1.555 0.99 -2.022C0.99 -2.566 1.339 -2.734 1.639 -2.734C2.015 -2.734 2.294 -2.497 2.294 -2.029C2.294 -1.485 1.946 -1.318 1.646 -1.318ZM1.974 0.042C2.134 0.042 2.957 0.042 2.957 0.488C2.957 0.788 2.434 0.997 1.848 0.997S0.739 0.788 0.739 0.488C0.739 0.453 0.739 0.042 1.304 0.042H1.974Z' id='g0-103'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.625 -3.166 1.304 -2.817 1.165 -2.671V-4.84H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-104'/>
+<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/>
+<path d='M1.381 -4.784H0.676V-4.08H1.381V-4.784ZM-0.453 1.186C-0.133 1.36 0.181 1.423 0.446 1.423C0.928 1.423 1.381 1.053 1.381 0.411V-3.096H0.795V0.46C0.795 0.586 0.795 0.697 0.649 0.816C0.488 0.934 0.293 0.934 0.23 0.934C-0.063 0.934 -0.244 0.802 -0.328 0.725L-0.453 1.186Z' id='g0-106'/>
+<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/>
+<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/>
+<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/>
+<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/>
+<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/>
+<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/>
+<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/>
+<path d='M3.243 -3.096H2.636V-1.074C2.636 -0.516 2.162 -0.342 1.757 -0.342C1.241 -0.342 1.186 -0.481 1.186 -0.802V-3.096H0.579V-0.76C0.579 -0.139 0.851 0.07 1.339 0.07C1.625 0.07 2.239 0.014 2.657 -0.321V0H3.243V-3.096Z' id='g0-117'/>
+<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/>
+<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/>
+<path d='M2.957 -2.803V-3.096H0.307V-2.65H1.332C1.416 -2.65 1.499 -2.657 1.583 -2.657H2.127L0.209 -0.307V0H2.978V-0.467H1.897C1.813 -0.467 1.73 -0.46 1.646 -0.46H1.039L2.957 -2.803Z' id='g0-122'/>
+</defs>
+<g id='page2'>
+<path d='M194.617 260.785V251.93M253.285 260.785V251.93M311.953 260.785V251.93M370.625 260.785V251.93M429.293 260.785V251.93M194.617 75.308V84.164M253.285 75.308V84.164M311.953 75.308V84.164M370.625 75.308V84.164M429.293 75.308V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 256.18V251.93M223.953 256.18V251.93M282.621 256.18V251.93M341.289 256.18V251.93M399.957 256.18V251.93M458.629 256.18V251.93M165.281 79.91V84.164M223.953 79.91V84.164M282.621 79.91V84.164M341.289 79.91V84.164M399.957 79.91V84.164M458.629 79.91V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 251.93H140.199M135.949 218.375H140.199M135.949 184.824H140.199M135.949 151.269H140.199M135.949 117.719H140.199M135.949 84.164H140.199M487.961 251.93H483.711M487.961 218.375H483.711M487.961 184.824H483.711M487.961 151.269H483.711M487.961 117.719H483.711M487.961 84.164H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 251.93V84.164H487.961V251.93H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 74.992)'>
+<use x='168.285' xlink:href='#g3-97' y='191.334'/>
+<use x='172.353' xlink:href='#g3-108' y='191.334'/>
+<use x='174.373' xlink:href='#g3-108' y='191.334'/>
+<use x='176.393' xlink:href='#g3-111' y='191.334'/>
+<use x='180.863' xlink:href='#g3-99' y='191.334'/>
+<use x='184.627' xlink:href='#g3-45' y='191.334'/>
+<use x='187.449' xlink:href='#g3-116' y='191.334'/>
+<use x='190.507' xlink:href='#g3-101' y='191.334'/>
+<use x='194.271' xlink:href='#g3-115' y='191.334'/>
+<use x='197.517' xlink:href='#g3-116' y='191.334'/>
+<use x='200.575' xlink:href='#g3-49' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 74.992)'>
+<use x='168.285' xlink:href='#g3-97' y='191.334'/>
+<use x='172.353' xlink:href='#g3-108' y='191.334'/>
+<use x='174.373' xlink:href='#g3-108' y='191.334'/>
+<use x='176.393' xlink:href='#g3-111' y='191.334'/>
+<use x='180.863' xlink:href='#g3-99' y='191.334'/>
+<use x='184.627' xlink:href='#g3-45' y='191.334'/>
+<use x='187.449' xlink:href='#g3-116' y='191.334'/>
+<use x='190.507' xlink:href='#g3-101' y='191.334'/>
+<use x='194.271' xlink:href='#g3-115' y='191.334'/>
+<use x='197.517' xlink:href='#g3-116' y='191.334'/>
+<use x='200.575' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 74.992)'>
+<use x='168.285' xlink:href='#g3-115' y='191.334'/>
+<use x='171.531' xlink:href='#g3-104' y='191.334'/>
+<use x='175.904' xlink:href='#g3-54' y='191.334'/>
+<use x='180.138' xlink:href='#g3-98' y='191.334'/>
+<use x='184.746' xlink:href='#g3-101' y='191.334'/>
+<use x='188.509' xlink:href='#g3-110' y='191.334'/>
+<use x='192.882' xlink:href='#g3-99' y='191.334'/>
+<use x='196.646' xlink:href='#g3-104' y='191.334'/>
+<use x='201.018' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 74.992)'>
+<use x='168.285' xlink:href='#g3-115' y='191.334'/>
+<use x='171.531' xlink:href='#g3-104' y='191.334'/>
+<use x='175.904' xlink:href='#g3-56' y='191.334'/>
+<use x='180.138' xlink:href='#g3-98' y='191.334'/>
+<use x='184.746' xlink:href='#g3-101' y='191.334'/>
+<use x='188.509' xlink:href='#g3-110' y='191.334'/>
+<use x='192.882' xlink:href='#g3-99' y='191.334'/>
+<use x='196.646' xlink:href='#g3-104' y='191.334'/>
+<use x='201.018' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 74.992)'>
+<use x='168.285' xlink:href='#g3-120' y='191.334'/>
+<use x='172.187' xlink:href='#g3-109' y='191.334'/>
+<use x='178.912' xlink:href='#g3-97' y='191.334'/>
+<use x='182.98' xlink:href='#g3-108' y='191.334'/>
+<use x='185' xlink:href='#g3-108' y='191.334'/>
+<use x='187.02' xlink:href='#g3-111' y='191.334'/>
+<use x='191.49' xlink:href='#g3-99' y='191.334'/>
+<use x='195.254' xlink:href='#g3-45' y='191.334'/>
+<use x='198.076' xlink:href='#g3-116' y='191.334'/>
+<use x='201.134' xlink:href='#g3-101' y='191.334'/>
+<use x='204.898' xlink:href='#g3-115' y='191.334'/>
+<use x='208.144' xlink:href='#g3-116' y='191.334'/>
+<use x='211.202' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 74.992)'>
+<use x='168.285' xlink:href='#g3-99' y='191.334'/>
+<use x='172.049' xlink:href='#g3-97' y='191.334'/>
+<use x='176.117' xlink:href='#g3-99' y='191.334'/>
+<use x='179.88' xlink:href='#g3-104' y='191.334'/>
+<use x='184.253' xlink:href='#g3-101' y='191.334'/>
+<use x='188.017' xlink:href='#g3-45' y='191.334'/>
+<use x='190.839' xlink:href='#g3-115' y='191.334'/>
+<use x='194.086' xlink:href='#g3-99' y='191.334'/>
+<use x='197.849' xlink:href='#g3-114' y='191.334'/>
+<use x='200.741' xlink:href='#g3-97' y='191.334'/>
+<use x='204.81' xlink:href='#g3-116' y='191.334'/>
+<use x='207.868' xlink:href='#g3-99' y='191.334'/>
+<use x='211.631' xlink:href='#g3-104' y='191.334'/>
+<use x='216.004' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 62.23)'>
+<use x='168.285' xlink:href='#g2-48' y='191.334'/>
+<use x='170.931' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.677)'>
+<use x='168.285' xlink:href='#g2-48' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -4.876)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -38.43)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.983)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -105.536)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<path clip-path='url(#clip2)' d='M135.949 184.824H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M144.359 184.824V184.758' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M144.359 184.824V184.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M142.367 184.758H146.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M144.359 184.824V184.891' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M144.359 184.824V184.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M146.352 184.891H142.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M203.031 184.824V184.621' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M203.031 184.824V184.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M201.039 184.621H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M203.031 184.824V185.023' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M203.031 184.824V185.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M205.023 185.023H201.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M261.699 184.824V179.855' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M261.699 184.824V179.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M259.707 179.855H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M261.699 184.824V189.789' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M261.699 184.824V189.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M263.691 189.789H259.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M320.367 184.824V184.824' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M318.375 184.824H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M320.367 184.824V184.824' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M318.375 184.824H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M379.035 184.824V184.152' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M379.035 184.824V184.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M377.043 184.152H381.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M379.035 184.824V185.492' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M379.035 184.824V185.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M381.027 185.492H377.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M437.707 184.824V179.254' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M437.707 184.824V179.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M435.715 179.254H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M437.707 184.824V190.394' fill='#993333'/>
+<path clip-path='url(#clip2)' d='M437.707 184.824V190.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M439.699 190.395H435.711' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M147.973 251.93H151.211V184.621H147.973ZM206.641 251.93H209.879V163.75H206.641ZM265.309 251.93H268.547V84.164H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M147.973 251.93H151.211V184.621H147.973ZM206.641 251.93H209.879V163.75H206.641ZM265.309 251.93H268.547V84.164H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M149.59 184.621V184.555' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M149.59 184.621V184.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M147.598 184.555H151.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M149.59 184.621V184.687' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M149.59 184.621V184.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M151.582 184.688H147.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M208.262 163.75V162.41' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M208.262 163.75V162.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M206.27 162.411H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M208.262 163.75V165.094' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M208.262 163.75V165.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M210.253 165.094H206.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M266.93 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M264.938 84.164H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M266.93 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M264.938 84.164H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M325.598 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M325.598 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M384.266 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M384.266 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M442.938 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M442.938 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip2)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M153.203 251.93H156.442V178.312H153.203ZM211.871 251.93H215.11V178.984H211.871ZM270.539 251.93H273.777V131.875H270.539ZM329.211 251.93H332.449V124.832H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M153.203 251.93H156.442V178.312H153.203ZM211.871 251.93H215.11V178.984H211.871ZM270.539 251.93H273.777V131.875H270.539ZM329.211 251.93H332.449V124.832H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M154.82 178.312V178.312' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M152.828 178.313H156.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M154.82 178.312V178.312' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M152.828 178.313H156.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M213.492 178.984V178.918' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M213.492 178.984V178.918' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M211.5 178.918H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M213.492 178.984V179.051' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M213.492 178.984V179.051' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M215.484 179.051H211.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M272.16 131.875V126.91' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M272.16 131.875V126.91' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M270.168 126.91H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M272.16 131.875V136.844' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M272.16 131.875V136.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M274.152 136.844H270.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M330.828 124.832V121.945' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M330.828 124.832V121.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M328.836 121.946H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M330.828 124.832V127.715' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M330.828 124.832V127.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M332.82 127.715H328.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M389.496 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M389.496 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M448.168 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M448.168 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip2)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M158.434 251.93H161.672V164.422H158.434ZM217.102 251.93H220.34V166.57H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V97.383H334.442ZM393.109 251.93H396.348V130.535H393.109ZM451.777 251.93H455.016V184.824H451.777Z' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M158.434 251.93H161.672V164.422H158.434ZM217.102 251.93H220.34V166.57H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V97.383H334.442ZM393.109 251.93H396.348V130.535H393.109ZM451.777 251.93H455.016V184.824H451.777Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M160.051 164.422V164.355' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M160.051 164.422V164.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M158.058 164.356H162.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M160.051 164.422V164.488' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M160.051 164.422V164.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M162.043 164.488H158.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M218.723 166.57V166.57' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M216.73 166.57H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M218.723 166.57V166.57' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M216.73 166.57H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M277.391 84.164V84.164' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M277.391 84.164V84.164' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M336.059 97.383V93.558' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M336.059 97.383V93.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M334.066 93.559H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M336.059 97.383V101.207' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M336.059 97.383V101.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M338.05 101.207H334.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M394.727 130.535V129.996' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M394.727 130.535V129.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M392.734 129.996H396.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M394.727 130.535V131.07' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M394.727 130.535V131.07' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M396.718 131.07H392.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M453.399 184.824V179.254' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M453.399 184.824V179.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M451.406 179.254H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M453.399 184.824V190.394' fill='#bf80bf'/>
+<path clip-path='url(#clip2)' d='M453.399 184.824V190.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M455.39 190.395H451.402' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M163.664 251.93H166.903V178.449H163.664ZM222.332 251.93H225.57V182.34H222.332ZM281 251.93H284.238V160.129H281ZM339.672 251.93H342.91V179.723H339.672ZM398.34 251.93H401.578V183.211H398.34ZM457.008 251.93H460.246V180.863H457.008Z' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M163.664 251.93H166.903V178.449H163.664ZM222.332 251.93H225.57V182.34H222.332ZM281 251.93H284.238V160.129H281ZM339.672 251.93H342.91V179.723H339.672ZM398.34 251.93H401.578V183.211H398.34ZM457.008 251.93H460.246V180.863H457.008Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M165.281 178.449V178.379' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M165.281 178.449V178.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M163.289 178.379H167.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M165.281 178.449V178.516' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M165.281 178.449V178.516' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M167.274 178.516H163.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M223.953 182.34V182.004' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M223.953 182.34V182.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M221.961 182.004H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M223.953 182.34V182.676' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M223.953 182.34V182.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M225.945 182.676H221.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M282.621 160.129V155.164' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M282.621 160.129V155.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M280.629 155.164H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M282.621 160.129V165.094' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M282.621 160.129V165.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M284.613 165.094H280.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M341.289 179.723V178.312' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M341.289 179.723V178.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M339.297 178.313H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M341.289 179.723V181.133' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M341.289 179.723V181.133' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M343.281 181.133H339.297' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M399.957 183.211V182.207' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M399.957 183.211V182.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M397.965 182.207H401.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M399.957 183.211V184.219' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M399.957 183.211V184.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M401.949 184.219H397.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M458.629 180.863V171.199' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M458.629 180.863V171.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M456.637 171.2H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M458.629 180.863V190.527' fill='#dfbf9f'/>
+<path clip-path='url(#clip2)' d='M458.629 180.863V190.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M460.621 190.527H456.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M168.895 251.93H172.133V175.496H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M168.895 251.93H172.133V175.496H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M170.512 175.496V175.43' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M170.512 175.496V175.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M168.519 175.429H172.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M170.512 175.496V175.562' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M170.512 175.496V175.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M172.504 175.562H168.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M229.184 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M229.184 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M287.852 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M287.852 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M346.52 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M346.52 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M405.188 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M405.188 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M463.859 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M463.859 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip2)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M174.125 251.93H177.363V120.402H174.125ZM232.793 251.93H236.031V84.164H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V84.164H350.133ZM408.801 251.93H412.039V84.164H408.801ZM467.469 251.93H470.707V184.824H467.469Z' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M174.125 251.93H177.363V120.402H174.125ZM232.793 251.93H236.031V84.164H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V84.164H350.133ZM408.801 251.93H412.039V84.164H408.801ZM467.469 251.93H470.707V184.824H467.469Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M175.742 120.402V120.266' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M175.742 120.402V120.266' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M173.75 120.266H177.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M175.742 120.402V120.535' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M175.742 120.402V120.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M177.735 120.535H173.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M234.414 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M232.422 84.164H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M234.414 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M232.422 84.164H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M293.082 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M293.082 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M351.75 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M349.758 84.164H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M351.75 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M349.758 84.164H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M410.418 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M408.426 84.164H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M410.418 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M408.426 84.164H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M469.09 184.824V179.254' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M469.09 184.824V179.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M467.098 179.254H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M469.09 184.824V190.394' fill='#bfbf80'/>
+<path clip-path='url(#clip2)' d='M469.09 184.824V190.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M471.082 190.395H467.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M179.356 251.93H182.594V168.652H179.356ZM238.024 251.93H241.262V169.457H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M179.356 251.93H182.594V168.652H179.356ZM238.024 251.93H241.262V169.457H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M180.973 168.652V168.582' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M180.973 168.652V168.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M178.98 168.582H182.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M180.973 168.652V168.719' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M180.973 168.652V168.719' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M182.965 168.719H178.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M239.645 169.457V169.387' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M239.645 169.457V169.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M237.652 169.387H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M239.645 169.457V169.523' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M239.645 169.457V169.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M241.633 169.524H237.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M298.313 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M298.313 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M356.981 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M356.981 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M415.649 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M415.649 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M474.32 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M474.32 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip2)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M184.586 251.93H187.824V176.301H184.586ZM243.254 251.93H246.492V177.309H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V84.164H360.594ZM419.262 251.93H422.5V143.621H419.262ZM477.93 251.93H481.168V176.906H477.93Z' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M184.586 251.93H187.824V176.301H184.586ZM243.254 251.93H246.492V177.309H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V84.164H360.594ZM419.262 251.93H422.5V143.621H419.262ZM477.93 251.93H481.168V176.906H477.93Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M186.203 176.301V175.965' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M186.203 176.301V175.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M184.211 175.965H188.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M186.203 176.301V176.637' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M186.203 176.301V176.637' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M188.196 176.637H184.211' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M244.875 177.309V177.172' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M244.875 177.309V177.172' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M242.883 177.172H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M244.875 177.309V177.441' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M244.875 177.309V177.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M246.864 177.441H242.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M303.543 84.164V84.164' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M303.543 84.164V84.164' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M362.211 84.164V84.164' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M360.219 84.164H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M362.211 84.164V84.164' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M360.219 84.164H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M420.879 143.621V142.746' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M420.879 143.621V142.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M418.887 142.746H422.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M420.879 143.621V144.492' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M420.879 143.621V144.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M422.871 144.492H418.887' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M479.551 176.906V171.336' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M479.551 176.906V171.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M477.559 171.336H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M479.551 176.906V182.473' fill='#bf8080'/>
+<path clip-path='url(#clip2)' d='M479.551 176.906V182.473' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M481.543 182.472H477.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M420.539 312.98H487.762V278.973H420.539Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 255.575 118.327)'>
+<use x='168.285' xlink:href='#g2-99' y='167.424'/>
+<use x='170.637' xlink:href='#g2-53' y='167.424'/>
+<use x='173.284' xlink:href='#g2-45' y='167.424'/>
+<use x='175.048' xlink:href='#g2-49' y='167.424'/>
+<use x='177.694' xlink:href='#g2-56' y='167.424'/>
+<use x='180.341' xlink:href='#g2-120' y='167.424'/>
+<use x='182.779' xlink:href='#g2-108' y='167.424'/>
+<use x='184.042' xlink:href='#g2-97' y='167.424'/>
+<use x='186.438' xlink:href='#g2-114' y='167.424'/>
+<use x='188.245' xlink:href='#g2-103' y='167.424'/>
+<use x='190.891' xlink:href='#g2-101' y='167.424'/>
+<use x='193.244' xlink:href='#g2-44' y='167.424'/>
+<use x='196.478' xlink:href='#g2-49' y='167.424'/>
+<use x='199.124' xlink:href='#g2-52' y='167.424'/>
+<use x='201.771' xlink:href='#g2-52' y='167.424'/>
+<use x='204.417' xlink:href='#g2-71' y='167.424'/>
+<use x='207.946' xlink:href='#g2-98' y='167.424'/>
+<use x='168.285' xlink:href='#g2-55' y='173.401'/>
+<use x='170.931' xlink:href='#g2-50' y='173.401'/>
+<use x='175.342' xlink:href='#g2-112' y='173.401'/>
+<use x='177.928' xlink:href='#g2-114' y='173.401'/>
+<use x='179.735' xlink:href='#g2-111' y='173.401'/>
+<use x='182.529' xlink:href='#g2-99' y='173.401'/>
+<use x='186.645' xlink:href='#g2-73' y='173.401'/>
+<use x='188.115' xlink:href='#g2-110' y='173.401'/>
+<use x='190.848' xlink:href='#g2-116' y='173.401'/>
+<use x='192.759' xlink:href='#g2-101' y='173.401'/>
+<use x='195.112' xlink:href='#g2-108' y='173.401'/>
+<use x='198.139' xlink:href='#g2-88' y='173.401'/>
+<use x='201.667' xlink:href='#g2-101' y='173.401'/>
+<use x='204.019' xlink:href='#g2-111' y='173.401'/>
+<use x='206.666' xlink:href='#g2-110' y='173.401'/>
+<use x='211.163' xlink:href='#g2-64' y='173.401'/>
+<use x='214.691' xlink:href='#g2-51' y='173.401'/>
+<use x='217.338' xlink:href='#g2-71' y='173.401'/>
+<use x='220.866' xlink:href='#g2-104' y='173.401'/>
+<use x='223.599' xlink:href='#g2-122' y='173.401'/>
+<use x='168.285' xlink:href='#g2-85' y='179.379'/>
+<use x='171.917' xlink:href='#g2-98' y='179.379'/>
+<use x='174.65' xlink:href='#g2-117' y='179.379'/>
+<use x='177.383' xlink:href='#g2-110' y='179.379'/>
+<use x='180.116' xlink:href='#g2-116' y='179.379'/>
+<use x='182.027' xlink:href='#g2-117' y='179.379'/>
+<use x='186.524' xlink:href='#g2-49' y='179.379'/>
+<use x='189.17' xlink:href='#g2-56' y='179.379'/>
+<use x='191.817' xlink:href='#g2-46' y='179.379'/>
+<use x='193.287' xlink:href='#g2-48' y='179.379'/>
+<use x='195.933' xlink:href='#g2-52' y='179.379'/>
+<use x='198.58' xlink:href='#g2-46' y='179.379'/>
+<use x='200.05' xlink:href='#g2-49' y='179.379'/>
+<use x='202.696' xlink:href='#g2-44' y='179.379'/>
+<use x='205.931' xlink:href='#g2-71' y='179.379'/>
+<use x='209.459' xlink:href='#g2-67' y='179.379'/>
+<use x='212.841' xlink:href='#g2-67' y='179.379'/>
+<use x='217.986' xlink:href='#g2-55' y='179.379'/>
+<use x='220.633' xlink:href='#g2-46' y='179.379'/>
+<use x='222.103' xlink:href='#g2-52' y='179.379'/>
+<use x='224.749' xlink:href='#g2-46' y='179.379'/>
+<use x='226.219' xlink:href='#g2-48' y='179.379'/>
+<use x='168.285' xlink:href='#g2-51' y='185.357'/>
+<use x='170.931' xlink:href='#g2-54' y='185.357'/>
+<use x='175.342' xlink:href='#g2-99' y='185.357'/>
+<use x='177.694' xlink:href='#g2-111' y='185.357'/>
+<use x='180.193' xlink:href='#g2-114' y='185.357'/>
+<use x='182.001' xlink:href='#g2-101' y='185.357'/>
+<use x='184.353' xlink:href='#g2-115' y='185.357'/>
+<use x='188.146' xlink:href='#g2-111' y='185.357'/>
+<use x='190.793' xlink:href='#g2-110' y='185.357'/>
+<use x='195.29' xlink:href='#g2-50' y='185.357'/>
+<use x='199.7' xlink:href='#g2-110' y='185.357'/>
+<use x='202.433' xlink:href='#g2-117' y='185.357'/>
+<use x='205.166' xlink:href='#g2-109' y='185.357'/>
+<use x='209.369' xlink:href='#g2-97' y='185.357'/>
+<use x='213.676' xlink:href='#g2-110' y='185.357'/>
+<use x='216.409' xlink:href='#g2-111' y='185.357'/>
+<use x='219.202' xlink:href='#g2-100' y='185.357'/>
+<use x='221.935' xlink:href='#g2-101' y='185.357'/>
+<use x='224.287' xlink:href='#g2-115' y='185.357'/>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-48' y='191.334'/>
+<use x='173.578' xlink:href='#g2-50' y='191.334'/>
+<use x='176.224' xlink:href='#g2-48' y='191.334'/>
+<use x='178.87' xlink:href='#g2-45' y='191.334'/>
+<use x='180.635' xlink:href='#g2-48' y='191.334'/>
+<use x='183.281' xlink:href='#g2-49' y='191.334'/>
+<use x='185.927' xlink:href='#g2-45' y='191.334'/>
+<use x='187.692' xlink:href='#g2-49' y='191.334'/>
+<use x='190.338' xlink:href='#g2-56' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -45.339 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 13.33 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 71.999 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 130.668 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 189.337 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 248.006 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -40.108 346.703)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 18.561 325.833)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-51' y='191.334'/>
+<use x='175.048' xlink:href='#g2-49' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 77.23 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-50' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-56' y='191.334'/>
+<use x='180.675' xlink:href='#g2-52' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.899 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-49' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-51' y='191.334'/>
+<use x='183.321' xlink:href='#g2-50' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.568 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-49' y='191.334'/>
+<use x='179.205' xlink:href='#g2-51' y='191.334'/>
+<use x='181.851' xlink:href='#g2-46' y='191.334'/>
+<use x='183.321' xlink:href='#g2-55' y='191.334'/>
+<use x='185.968' xlink:href='#g2-49' y='191.334'/>
+<use x='188.614' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 253.236 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-50' y='191.334'/>
+<use x='176.558' xlink:href='#g2-56' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-55' y='191.334'/>
+<use x='183.321' xlink:href='#g2-54' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -34.878 340.395)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.791 341.066)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.46 293.957)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-55' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 141.129 286.911)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-56' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.798 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-48' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-52' y='191.334'/>
+<use x='183.321' xlink:href='#g2-52' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 258.467 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-50' y='191.334'/>
+<use x='176.558' xlink:href='#g2-56' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-53' y='191.334'/>
+<use x='183.321' xlink:href='#g2-51' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.648 326.504)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-51' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 29.021 328.651)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-50' y='191.334'/>
+<use x='175.048' xlink:href='#g2-55' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.69 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-50' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-54' y='191.334'/>
+<use x='180.675' xlink:href='#g2-56' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.359 259.465)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-51' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 205.028 292.615)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-56' y='191.334'/>
+<use x='175.048' xlink:href='#g2-49' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 263.697 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.417 340.529)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 34.252 344.421)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-52' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.921 322.209)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-51' y='191.334'/>
+<use x='175.048' xlink:href='#g2-55' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.59 341.804)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-56' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 210.259 345.293)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-50' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 268.928 342.945)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-54' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.187 337.576)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-52' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.482 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-54' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-50' y='191.334'/>
+<use x='180.675' xlink:href='#g2-56' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 98.151 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-54' y='191.334'/>
+<use x='176.558' xlink:href='#g2-48' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-48' y='191.334'/>
+<use x='183.321' xlink:href='#g2-48' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.82 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-50' y='191.334'/>
+<use x='176.558' xlink:href='#g2-49' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-55' y='191.334'/>
+<use x='183.321' xlink:href='#g2-57' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.489 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-48' y='191.334'/>
+<use x='179.205' xlink:href='#g2-55' y='191.334'/>
+<use x='181.851' xlink:href='#g2-46' y='191.334'/>
+<use x='183.321' xlink:href='#g2-48' y='191.334'/>
+<use x='185.968' xlink:href='#g2-50' y='191.334'/>
+<use x='188.614' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 274.158 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-51' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-51' y='191.334'/>
+<use x='183.321' xlink:href='#g2-53' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -13.956 282.482)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-57' y='191.334'/>
+<use x='175.048' xlink:href='#g2-54' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.713 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-52' y='191.334'/>
+<use x='176.558' xlink:href='#g2-50' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-53' y='191.334'/>
+<use x='183.321' xlink:href='#g2-56' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.382 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-50' y='191.334'/>
+<use x='176.558' xlink:href='#g2-50' y='191.334'/>
+<use x='179.205' xlink:href='#g2-57' y='191.334'/>
+<use x='181.851' xlink:href='#g2-46' y='191.334'/>
+<use x='183.321' xlink:href='#g2-53' y='191.334'/>
+<use x='185.968' xlink:href='#g2-56' y='191.334'/>
+<use x='188.614' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 162.051 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-55' y='191.334'/>
+<use x='176.558' xlink:href='#g2-51' y='191.334'/>
+<use x='179.205' xlink:href='#g2-53' y='191.334'/>
+<use x='181.851' xlink:href='#g2-46' y='191.334'/>
+<use x='183.321' xlink:href='#g2-50' y='191.334'/>
+<use x='185.968' xlink:href='#g2-55' y='191.334'/>
+<use x='188.614' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.72 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-50' y='191.334'/>
+<use x='179.205' xlink:href='#g2-52' y='191.334'/>
+<use x='181.851' xlink:href='#g2-46' y='191.334'/>
+<use x='183.321' xlink:href='#g2-54' y='191.334'/>
+<use x='185.968' xlink:href='#g2-55' y='191.334'/>
+<use x='188.614' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 279.389 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -8.726 330.731)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-50' y='191.334'/>
+<use x='175.048' xlink:href='#g2-52' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.943 331.537)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-50' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.612 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-52' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-54' y='191.334'/>
+<use x='183.321' xlink:href='#g2-56' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 167.281 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-55' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-50' y='191.334'/>
+<use x='180.675' xlink:href='#g2-57' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.95 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-52' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-49' y='191.334'/>
+<use x='180.675' xlink:href='#g2-51' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 284.619 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-49' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-52' y='191.334'/>
+<use x='183.321' xlink:href='#g2-55' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.495 338.381)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 55.174 339.388)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-49' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.843 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-52' y='191.334'/>
+<use x='180.675' xlink:href='#g2-50' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.512 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-53' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-50' y='191.334'/>
+<use x='180.675' xlink:href='#g2-55' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 231.181 305.701)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-54' y='191.334'/>
+<use x='175.048' xlink:href='#g2-49' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 289.85 338.985)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-50' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.176 391.591)'>
+<use x='168.285' xlink:href='#g1-82' y='191.334'/>
+<use x='174.255' xlink:href='#g1-101' y='191.334'/>
+<use x='178.351' xlink:href='#g1-108' y='191.334'/>
+<use x='180.551' xlink:href='#g1-97' y='191.334'/>
+<use x='184.979' xlink:href='#g1-116' y='191.334'/>
+<use x='188.307' xlink:href='#g1-105' y='191.334'/>
+<use x='190.507' xlink:href='#g1-118' y='191.334'/>
+<use x='194.755' xlink:href='#g1-101' y='191.334'/>
+<use x='201.922' xlink:href='#g1-116' y='191.334'/>
+<use x='205.25' xlink:href='#g1-105' y='191.334'/>
+<use x='207.45' xlink:href='#g1-109' y='191.334'/>
+<use x='214.77' xlink:href='#g1-101' y='191.334'/>
+<use x='221.937' xlink:href='#g3-40' y='191.334'/>
+<use x='225.231' xlink:href='#g3-108' y='191.334'/>
+<use x='227.251' xlink:href='#g3-111' y='191.334'/>
+<use x='231.25' xlink:href='#g3-119' y='191.334'/>
+<use x='236.799' xlink:href='#g3-101' y='191.334'/>
+<use x='240.562' xlink:href='#g3-114' y='191.334'/>
+<use x='246.277' xlink:href='#g3-105' y='191.334'/>
+<use x='248.297' xlink:href='#g3-115' y='191.334'/>
+<use x='254.366' xlink:href='#g3-98' y='191.334'/>
+<use x='258.974' xlink:href='#g3-101' y='191.334'/>
+<use x='262.738' xlink:href='#g3-116' y='191.334'/>
+<use x='265.796' xlink:href='#g3-116' y='191.334'/>
+<use x='268.854' xlink:href='#g3-101' y='191.334'/>
+<use x='272.618' xlink:href='#g3-114' y='191.334'/>
+<use x='275.51' xlink:href='#g3-41' y='191.334'/>
+</g>
+<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='#ffffff'/>
+<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='#993333'/>
+<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -40.354 114.479)'>
+<use x='195.372' xlink:href='#g3-120' y='178.327'/>
+<use x='199.274' xlink:href='#g3-109' y='178.327'/>
+<use x='205.999' xlink:href='#g3-105' y='178.327'/>
+<use x='208.019' xlink:href='#g3-58' y='178.327'/>
+<use x='210.371' xlink:href='#g0-57' y='178.327'/>
+<use x='214.076' xlink:href='#g0-57' y='178.327'/>
+</g>
+<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='#8080bf'/>
+<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.441 114.036)'>
+<use x='239.382' xlink:href='#g3-116' y='178.327'/>
+<use x='242.44' xlink:href='#g3-99' y='178.327'/>
+<use x='246.204' xlink:href='#g3-58' y='178.327'/>
+<use x='248.556' xlink:href='#g0-53' y='178.327'/>
+<use x='252.261' xlink:href='#g0-55' y='178.327'/>
+</g>
+<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='#ffb733'/>
+<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.04 114.479)'>
+<use x='281.863' xlink:href='#g3-106' y='178.327'/>
+<use x='284.119' xlink:href='#g3-101' y='178.327'/>
+<use x='287.882' xlink:href='#g3-58' y='178.327'/>
+<use x='290.235' xlink:href='#g0-53' y='178.327'/>
+<use x='293.94' xlink:href='#g0-56' y='178.327'/>
+</g>
+<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='#bf80bf'/>
+<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.932 114.515)'>
+<use x='321.287' xlink:href='#g3-116' y='178.327'/>
+<use x='324.345' xlink:href='#g3-98' y='178.327'/>
+<use x='328.717' xlink:href='#g3-98' y='178.327'/>
+<use x='333.09' xlink:href='#g3-58' y='178.327'/>
+<use x='335.442' xlink:href='#g0-53' y='178.327'/>
+<use x='339.147' xlink:href='#g0-56' y='178.327'/>
+</g>
+<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='#dfbf9f'/>
+<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.662 114.036)'>
+<use x='356.019' xlink:href='#g3-114' y='178.327'/>
+<use x='358.911' xlink:href='#g3-112' y='178.327'/>
+<use x='363.284' xlink:href='#g3-58' y='178.327'/>
+<use x='365.636' xlink:href='#g0-56' y='178.327'/>
+<use x='369.341' xlink:href='#g0-49' y='178.327'/>
+</g>
+<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='#80bf80'/>
+<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -43.882 114.515)'>
+<use x='195.372' xlink:href='#g3-104' y='191.334'/>
+<use x='199.744' xlink:href='#g3-111' y='191.334'/>
+<use x='203.978' xlink:href='#g3-97' y='191.334'/>
+<use x='207.811' xlink:href='#g3-114' y='191.334'/>
+<use x='210.703' xlink:href='#g3-100' y='191.334'/>
+<use x='215.076' xlink:href='#g3-58' y='191.334'/>
+<use x='217.428' xlink:href='#g0-51' y='191.334'/>
+<use x='221.133' xlink:href='#g0-51' y='191.334'/>
+</g>
+<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='#bfbf80'/>
+<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -43.084 114.515)'>
+<use x='239.382' xlink:href='#g3-109' y='191.334'/>
+<use x='246.107' xlink:href='#g3-101' y='191.334'/>
+<use x='249.871' xlink:href='#g3-115' y='191.334'/>
+<use x='253.117' xlink:href='#g3-104' y='191.334'/>
+<use x='257.489' xlink:href='#g3-58' y='191.334'/>
+<use x='259.842' xlink:href='#g0-50' y='191.334'/>
+<use x='263.547' xlink:href='#g0-56' y='191.334'/>
+</g>
+<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='#339999'/>
+<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -42.353 114.515)'>
+<use x='281.863' xlink:href='#g3-103' y='191.334'/>
+<use x='286.097' xlink:href='#g3-108' y='191.334'/>
+<use x='288.118' xlink:href='#g3-105' y='191.334'/>
+<use x='290.138' xlink:href='#g3-98' y='191.334'/>
+<use x='294.746' xlink:href='#g3-99' y='191.334'/>
+<use x='298.509' xlink:href='#g3-58' y='191.334'/>
+<use x='300.862' xlink:href='#g0-52' y='191.334'/>
+<use x='304.567' xlink:href='#g0-55' y='191.334'/>
+</g>
+<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='#bf8080'/>
+<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -40.026 114.479)'>
+<use x='321.287' xlink:href='#g3-115' y='191.334'/>
+<use x='324.533' xlink:href='#g3-109' y='191.334'/>
+<use x='331.258' xlink:href='#g3-105' y='191.334'/>
+<use x='333.278' xlink:href='#g3-58' y='191.334'/>
+<use x='335.63' xlink:href='#g0-54' y='191.334'/>
+<use x='339.335' xlink:href='#g0-55' y='191.334'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='193.064pt' version='1.1' viewBox='52.938 51.67 381.624 193.064' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip7'>
+<path d='M82.148 228.594H434.164V60.828H82.148Z'/>
+</clipPath>
+<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/>
+<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/>
+<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/>
+<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/>
+<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/>
+<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/>
+<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/>
+<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/>
+<use id='g3-102' transform='scale(1.143)' xlink:href='#g0-102'/>
+<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/>
+<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/>
+<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/>
+<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/>
+<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/>
+<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/>
+<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/>
+<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/>
+<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/>
+<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g1-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g1-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/>
+<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/>
+<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/>
+<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/>
+<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/>
+<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/>
+<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/>
+<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/>
+<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/>
+<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/>
+<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/>
+<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/>
+<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/>
+<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/>
+<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/>
+<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/>
+<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/>
+<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/>
+<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/>
+<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/>
+<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/>
+<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/>
+<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/>
+<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/>
+<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/>
+<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/>
+<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/>
+<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/>
+<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/>
+<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/>
+<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/>
+<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/>
+<path d='M1.325 -2.657H2.12V-3.096H1.304V-3.898C1.304 -4.38 1.743 -4.449 1.974 -4.449C2.12 -4.449 2.308 -4.428 2.566 -4.331V-4.84C2.385 -4.882 2.169 -4.91 1.981 -4.91C1.262 -4.91 0.739 -4.394 0.739 -3.703V-3.096H0.202V-2.657H0.739V0H1.325V-2.657Z' id='g0-102'/>
+<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/>
+<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/>
+<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/>
+<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/>
+<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/>
+<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/>
+<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/>
+<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/>
+<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/>
+<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/>
+</defs>
+<g id='page7'>
+<path d='M140.82 237.449V228.594M199.488 237.449V228.594M258.156 237.449V228.594M316.824 237.449V228.594M375.496 237.449V228.594M140.82 51.969V60.828M199.488 51.969V60.828M258.156 51.969V60.828M316.824 51.969V60.828M375.496 51.969V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 232.844V228.594M170.152 232.844V228.594M228.824 232.844V228.594M287.492 232.844V228.594M346.16 232.844V228.594M404.828 232.844V228.594M111.484 56.574V60.828M170.152 56.574V60.828M228.824 56.574V60.828M287.492 56.574V60.828M346.16 56.574V60.828M404.828 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 228.594H86.402M82.148 195.039H86.402M82.148 161.484H86.402M82.148 127.934H86.402M82.148 94.379H86.402M82.148 60.828H86.402M434.164 228.594H429.91M434.164 195.039H429.91M434.164 161.484H429.91M434.164 127.934H429.91M434.164 94.379H429.91M434.164 60.828H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 228.594V60.828H434.164V228.594H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 34.954)'>
+<use x='114.487' xlink:href='#g3-99' y='208.035'/>
+<use x='118.25' xlink:href='#g3-102' y='208.035'/>
+<use x='120.838' xlink:href='#g3-114' y='208.035'/>
+<use x='123.73' xlink:href='#g3-97' y='208.035'/>
+<use x='127.798' xlink:href='#g3-99' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 45.565 34.954)'>
+<use x='114.487' xlink:href='#g3-108' y='208.035'/>
+<use x='116.507' xlink:href='#g3-101' y='208.035'/>
+<use x='120.271' xlink:href='#g3-97' y='208.035'/>
+<use x='124.339' xlink:href='#g3-110' y='208.035'/>
+<use x='128.711' xlink:href='#g3-78' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 106.188 34.954)'>
+<use x='114.487' xlink:href='#g3-114' y='208.035'/>
+<use x='117.379' xlink:href='#g3-101' y='208.035'/>
+<use x='121.142' xlink:href='#g3-100' y='208.035'/>
+<use x='125.515' xlink:href='#g3-105' y='208.035'/>
+<use x='127.535' xlink:href='#g3-115' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 159.716 34.954)'>
+<use x='114.487' xlink:href='#g3-108' y='208.035'/>
+<use x='116.507' xlink:href='#g3-97' y='208.035'/>
+<use x='120.34' xlink:href='#g3-114' y='208.035'/>
+<use x='123.232' xlink:href='#g3-115' y='208.035'/>
+<use x='126.478' xlink:href='#g3-111' y='208.035'/>
+<use x='130.712' xlink:href='#g3-110' y='208.035'/>
+<use x='135.085' xlink:href='#g3-78' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 215.596 34.954)'>
+<use x='114.487' xlink:href='#g3-109' y='208.035'/>
+<use x='121.211' xlink:href='#g3-115' y='208.035'/>
+<use x='124.458' xlink:href='#g3-116' y='208.035'/>
+<use x='127.516' xlink:href='#g3-114' y='208.035'/>
+<use x='130.408' xlink:href='#g3-101' y='208.035'/>
+<use x='134.171' xlink:href='#g3-115' y='208.035'/>
+<use x='137.418' xlink:href='#g3-115' y='208.035'/>
+<use x='140.664' xlink:href='#g3-78' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 277.158 34.954)'>
+<use x='114.487' xlink:href='#g3-114' y='208.035'/>
+<use x='117.379' xlink:href='#g3-112' y='208.035'/>
+<use x='121.751' xlink:href='#g3-116' y='208.035'/>
+<use x='124.809' xlink:href='#g3-101' y='208.035'/>
+<use x='128.573' xlink:href='#g3-115' y='208.035'/>
+<use x='131.819' xlink:href='#g3-116' y='208.035'/>
+<use x='134.877' xlink:href='#g3-78' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 22.192)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-120' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -11.361)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-120' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -44.915)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-120' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -78.468)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-120' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -112.021)'>
+<use x='114.487' xlink:href='#g2-50' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-120' y='208.035'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -145.574)'>
+<use x='114.487' xlink:href='#g2-50' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-120' y='208.035'/>
+</g>
+<path clip-path='url(#clip7)' d='M82.148 161.484H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M88.945 228.594H92.18V161.484H88.945ZM147.613 228.594H150.852V161.484H147.613ZM206.281 228.594H209.52V161.484H206.281ZM264.949 228.594H268.188V161.484H264.949ZM323.621 228.594H326.859V161.484H323.621ZM382.289 228.594H385.527V161.484H382.289Z' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M88.945 228.594H92.18V161.484H88.945ZM147.613 228.594H150.852V161.484H147.613ZM206.281 228.594H209.52V161.484H206.281ZM264.949 228.594H268.188V161.484H264.949ZM323.621 228.594H326.859V161.484H323.621ZM382.289 228.594H385.527V161.484H382.289Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M90.563 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M88.57 161.484H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M90.563 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M88.57 161.484H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M149.231 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M147.238 161.484H151.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M149.231 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M147.238 161.484H151.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M207.902 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M205.906 161.484H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M207.902 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M205.906 161.484H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M266.57 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M264.578 161.484H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M266.57 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M264.578 161.484H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M325.238 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M323.246 161.484H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M325.238 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M323.246 161.484H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M383.906 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M381.914 161.484H385.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M383.906 161.484V161.484' fill='#ffffff'/>
+<path clip-path='url(#clip7)' d='M381.914 161.484H385.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M94.176 228.594H97.41V74.719H94.176ZM152.844 228.594H156.082V172.559H152.844ZM211.512 228.594H214.75V145.852H211.512ZM270.18 228.594H273.418V154.773H270.18ZM328.852 228.594H332.09V193.43H328.852ZM387.52 228.594H390.758V191.148H387.52Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M94.176 228.594H97.41V74.719H94.176ZM152.844 228.594H156.082V172.559H152.844ZM211.512 228.594H214.75V145.852H211.512ZM270.18 228.594H273.418V154.773H270.18ZM328.852 228.594H332.09V193.43H328.852ZM387.52 228.594H390.758V191.148H387.52Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M95.793 74.719V74.719' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M93.801 74.719H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M95.793 74.719V74.719' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M93.801 74.719H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M154.461 172.559V172.559' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M152.469 172.558H156.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M154.461 172.559V172.559' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M152.469 172.558H156.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M213.133 145.852V145.852' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M211.137 145.851H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M213.133 145.852V145.852' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M211.137 145.851H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M271.801 154.773V154.773' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M269.809 154.773H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M271.801 154.773V154.773' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M269.809 154.773H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M330.469 193.43V193.43' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M328.477 193.429H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M330.469 193.43V193.43' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M328.477 193.429H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M389.137 191.148V191.148' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M387.145 191.149H391.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M389.137 191.148V191.148' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M387.145 191.149H391.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M99.406 228.594H102.641V138.133H99.406ZM158.074 228.594H161.313V162.961H158.074ZM216.742 228.594H219.981V157.797H216.742ZM275.41 228.594H278.649V141.02H275.41ZM334.082 228.594H337.32V191.816H334.082ZM392.75 228.594H395.988V179.871H392.75Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M99.406 228.594H102.641V138.133H99.406ZM158.074 228.594H161.313V162.961H158.074ZM216.742 228.594H219.981V157.797H216.742ZM275.41 228.594H278.649V141.02H275.41ZM334.082 228.594H337.32V191.816H334.082ZM392.75 228.594H395.988V179.871H392.75Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M101.024 138.133V138.133' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M99.031 138.133H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M101.024 138.133V138.133' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M99.031 138.133H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M159.691 162.961V162.961' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M157.699 162.961H161.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M159.691 162.961V162.961' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M157.699 162.961H161.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M218.363 157.797V157.797' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M216.367 157.797H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M218.363 157.797V157.797' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M216.367 157.797H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M277.031 141.02V141.02' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M275.039 141.02H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M277.031 141.02V141.02' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M275.039 141.02H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M335.699 191.816V191.816' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M333.707 191.816H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M335.699 191.816V191.816' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M333.707 191.816H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M394.367 179.871V179.871' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M392.375 179.871H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M394.367 179.871V179.871' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M392.375 179.871H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M104.637 228.594H107.871V140.883H104.637ZM163.305 228.594H166.543V152.695H163.305ZM221.973 228.594H225.211V115.184H221.973ZM280.641 228.594H283.879V167.793H280.641ZM339.313 228.594H342.551V189.738H339.313ZM397.981 228.594H401.219V194.367H397.981Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M104.637 228.594H107.871V140.883H104.637ZM163.305 228.594H166.543V152.695H163.305ZM221.973 228.594H225.211V115.184H221.973ZM280.641 228.594H283.879V167.793H280.641ZM339.313 228.594H342.551V189.738H339.313ZM397.981 228.594H401.219V194.367H397.981Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M106.254 140.883V140.883' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M104.261 140.882H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M106.254 140.883V140.883' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M104.261 140.882H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M164.922 152.695V152.695' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M162.929 152.695H166.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M164.922 152.695V152.695' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M162.929 152.695H166.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M223.594 115.184V115.184' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M221.597 115.184H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M223.594 115.184V115.184' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M221.597 115.184H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M282.262 167.793V167.793' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M280.269 167.793H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M282.262 167.793V167.793' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M280.269 167.793H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M340.93 189.738V189.738' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M338.937 189.739H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M340.93 189.738V189.738' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M338.937 189.739H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M399.598 194.367V194.367' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M397.605 194.367H401.589' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M399.598 194.367V194.367' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M397.605 194.367H401.589' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M109.867 228.594H113.102V163.031H109.867ZM168.535 228.594H171.774V157.191H168.535ZM227.203 228.594H230.442V142.094H227.203ZM285.871 228.594H289.109V150.414H285.871ZM344.543 228.594H347.781V150.949H344.543ZM403.211 228.594H406.449V103.105H403.211Z' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M109.867 228.594H113.102V163.031H109.867ZM168.535 228.594H171.774V157.191H168.535ZM227.203 228.594H230.442V142.094H227.203ZM285.871 228.594H289.109V150.414H285.871ZM344.543 228.594H347.781V150.949H344.543ZM403.211 228.594H406.449V103.105H403.211Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M111.484 163.031V163.031' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M109.492 163.031H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M111.484 163.031V163.031' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M109.492 163.031H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M170.152 157.191V157.191' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M168.16 157.191H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M170.152 157.191V157.191' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M168.16 157.191H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M228.824 142.094V142.094' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M226.828 142.093H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M228.824 142.094V142.094' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M226.828 142.093H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M287.492 150.414V150.414' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M285.5 150.414H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M287.492 150.414V150.414' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M285.5 150.414H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M346.16 150.949V150.949' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M344.168 150.949H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M346.16 150.949V150.949' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M344.168 150.949H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M404.828 103.105V103.105' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M402.836 103.106H406.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M404.828 103.105V103.105' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M402.836 103.106H406.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M115.098 228.594H118.332V133.906H115.098ZM173.766 228.594H177.004V148.133H173.766ZM232.434 228.594H235.672V144.91H232.434ZM291.102 228.594H294.34V160.48H291.102ZM349.774 228.594H353.012V168.801H349.774ZM408.442 228.594H411.68V181.484H408.442Z' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M115.098 228.594H118.332V133.906H115.098ZM173.766 228.594H177.004V148.133H173.766ZM232.434 228.594H235.672V144.91H232.434ZM291.102 228.594H294.34V160.48H291.102ZM349.774 228.594H353.012V168.801H349.774ZM408.442 228.594H411.68V181.484H408.442Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M116.715 133.906V133.906' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M114.722 133.906H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M116.715 133.906V133.906' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M114.722 133.906H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M175.383 148.133V148.133' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M173.39 148.133H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M175.383 148.133V148.133' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M173.39 148.133H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M234.055 144.91V144.91' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M232.058 144.91H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M234.055 144.91V144.91' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M232.058 144.91H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M292.723 160.48V160.48' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M290.73 160.48H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M292.723 160.48V160.48' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M290.73 160.48H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M351.391 168.801V168.801' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M349.398 168.801H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M351.391 168.801V168.801' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M349.398 168.801H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M410.059 181.484V181.484' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M408.066 181.485H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M410.059 181.484V181.484' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M408.066 181.485H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M120.328 228.594H123.563V140.48H120.328ZM178.996 228.594H182.234V159.473H178.996ZM237.664 228.594H240.902V159.406H237.664ZM296.332 228.594H299.57V157.797H296.332ZM355.004 228.594H358.238V172.355H355.004ZM413.672 228.594H416.91V184.637H413.672Z' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M120.328 228.594H123.563V140.48H120.328ZM178.996 228.594H182.234V159.473H178.996ZM237.664 228.594H240.902V159.406H237.664ZM296.332 228.594H299.57V157.797H296.332ZM355.004 228.594H358.238V172.355H355.004ZM413.672 228.594H416.91V184.637H413.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M121.945 140.48V140.48' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M119.953 140.481H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M121.945 140.48V140.48' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M119.953 140.481H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M180.613 159.473V159.473' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M178.621 159.473H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M180.613 159.473V159.473' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M178.621 159.473H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M239.285 159.406V159.406' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M237.289 159.407H241.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M239.285 159.406V159.406' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M237.289 159.407H241.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M297.953 157.797V157.797' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M295.961 157.797H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M297.953 157.797V157.797' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M295.961 157.797H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M356.621 172.355V172.355' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M354.629 172.355H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M356.621 172.355V172.355' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M354.629 172.355H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M415.289 184.637V184.637' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M413.297 184.637H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M415.289 184.637V184.637' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M413.297 184.637H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M125.559 228.594H128.793V163.098H125.559ZM184.227 228.594H187.465V151.824H184.227ZM242.895 228.594H246.133V161.082H242.895ZM301.563 228.594H304.801V167.457H301.563ZM360.234 228.594H363.469V168.195H360.234ZM418.902 228.594H422.141V199.332H418.902Z' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M125.559 228.594H128.793V163.098H125.559ZM184.227 228.594H187.465V151.824H184.227ZM242.895 228.594H246.133V161.082H242.895ZM301.563 228.594H304.801V167.457H301.563ZM360.234 228.594H363.469V168.195H360.234ZM418.902 228.594H422.141V199.332H418.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M127.176 163.098V163.098' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M125.183 163.097H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M127.176 163.098V163.098' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M125.183 163.097H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M185.844 151.824V151.824' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M183.851 151.825H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M185.844 151.824V151.824' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M183.851 151.825H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M244.516 161.082V161.082' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M242.519 161.082H246.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M244.516 161.082V161.082' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M242.519 161.082H246.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M303.184 167.457V167.457' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M301.191 167.457H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M303.184 167.457V167.457' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M301.191 167.457H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M361.852 168.195V168.195' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M359.859 168.196H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M361.852 168.195V168.195' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M359.859 168.196H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M420.52 199.332V199.332' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M418.527 199.332H422.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M420.52 199.332V199.332' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M418.527 199.332H422.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M130.789 228.594H134.024V157.996H130.789ZM189.457 228.594H192.695V153.969H189.457ZM248.125 228.594H251.363V154.305H248.125ZM306.793 228.594H310.031V122.633H306.793ZM365.465 228.594H368.699V165.98H365.465ZM424.133 228.594H427.371V150.211H424.133Z' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M130.789 228.594H134.024V157.996H130.789ZM189.457 228.594H192.695V153.969H189.457ZM248.125 228.594H251.363V154.305H248.125ZM306.793 228.594H310.031V122.633H306.793ZM365.465 228.594H368.699V165.98H365.465ZM424.133 228.594H427.371V150.211H424.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M132.406 157.996V157.996' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M130.414 157.996H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M132.406 157.996V157.996' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M130.414 157.996H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M191.074 153.969V153.969' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M189.082 153.969H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M191.074 153.969V153.969' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M189.082 153.969H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M249.746 154.305V154.305' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M247.75 154.305H251.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M249.746 154.305V154.305' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M247.75 154.305H251.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M308.414 122.633V122.633' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M306.422 122.633H310.407' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M308.414 122.633V122.633' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M306.422 122.633H310.407' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M367.082 165.98V165.98' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M365.09 165.98H369.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M367.082 165.98V165.98' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M365.09 165.98H369.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M425.75 150.211V150.211' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M423.758 150.211H427.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M425.75 150.211V150.211' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M423.758 150.211H427.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -115.838 269.769)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.169 269.769)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 1.5 269.769)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 60.169 269.769)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.838 269.769)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 177.507 269.769)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -110.608 183.001)'>
+<use x='114.487' xlink:href='#g2-50' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-50' y='208.035'/>
+<use x='121.25' xlink:href='#g2-57' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -51.938 280.841)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-56' y='208.035'/>
+<use x='121.25' xlink:href='#g2-52' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.731 254.133)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-50' y='208.035'/>
+<use x='121.25' xlink:href='#g2-51' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 65.4 263.058)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 124.069 301.711)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-50' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.738 299.43)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-54' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -105.377 246.416)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-51' y='208.035'/>
+<use x='121.25' xlink:href='#g2-53' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -46.708 271.245)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-56' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 11.961 266.078)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-53' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 70.63 249.302)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-51' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 129.299 300.101)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-53' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 187.968 288.156)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-55' y='208.035'/>
+<use x='121.25' xlink:href='#g2-51' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -100.147 249.167)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-51' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -41.478 260.978)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-51' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 17.191 223.466)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-54' y='208.035'/>
+<use x='121.25' xlink:href='#g2-57' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 75.86 276.077)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 134.529 298.021)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-56' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 193.198 302.651)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -94.916 271.312)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-56' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -36.247 265.474)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-54' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 22.422 250.375)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-50' y='208.035'/>
+<use x='121.25' xlink:href='#g2-57' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 81.091 258.696)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-54' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 139.76 259.233)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-54' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 198.429 211.387)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-56' y='208.035'/>
+<use x='121.25' xlink:href='#g2-55' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -89.686 242.188)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-52' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -31.017 256.415)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-50' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 27.652 253.194)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-50' y='208.035'/>
+<use x='121.25' xlink:href='#g2-53' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 86.321 268.762)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-50' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 144.99 277.083)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-56' y='208.035'/>
+<use x='121.25' xlink:href='#g2-57' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 203.659 289.767)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-55' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -84.455 248.765)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-51' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -25.786 267.756)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-51' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 32.883 267.689)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-51' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 91.552 266.078)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-53' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 150.221 280.64)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-56' y='208.035'/>
+<use x='121.25' xlink:href='#g2-52' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 208.89 292.921)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-54' y='208.035'/>
+<use x='121.25' xlink:href='#g2-54' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -79.225 271.379)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-56' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -20.556 260.106)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-52' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 38.113 269.366)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 96.782 275.741)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 155.451 276.48)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-48' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 214.12 307.617)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-52' y='208.035'/>
+<use x='121.25' xlink:href='#g2-52' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -73.994 266.279)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-48' y='208.035'/>
+<use x='121.25' xlink:href='#g2-53' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -15.325 262.253)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 43.344 262.589)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-49' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 102.013 230.914)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-53' y='208.035'/>
+<use x='121.25' xlink:href='#g2-56' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 160.682 274.265)'>
+<use x='114.487' xlink:href='#g2-48' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-57' y='208.035'/>
+<use x='121.25' xlink:href='#g2-51' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 219.351 258.495)'>
+<use x='114.487' xlink:href='#g2-49' y='208.035'/>
+<use x='117.133' xlink:href='#g2-46' y='208.035'/>
+<use x='118.603' xlink:href='#g2-49' y='208.035'/>
+<use x='121.25' xlink:href='#g2-55' y='208.035'/>
+</g>
+<g transform='matrix(0 -1 1 0 -148.675 311.091)'>
+<use x='114.487' xlink:href='#g1-82' y='208.035'/>
+<use x='120.457' xlink:href='#g1-101' y='208.035'/>
+<use x='124.553' xlink:href='#g1-108' y='208.035'/>
+<use x='126.753' xlink:href='#g1-97' y='208.035'/>
+<use x='131.181' xlink:href='#g1-116' y='208.035'/>
+<use x='134.509' xlink:href='#g1-105' y='208.035'/>
+<use x='136.709' xlink:href='#g1-118' y='208.035'/>
+<use x='140.957' xlink:href='#g1-101' y='208.035'/>
+<use x='148.124' xlink:href='#g1-114' y='208.035'/>
+<use x='151.272' xlink:href='#g1-115' y='208.035'/>
+<use x='154.805' xlink:href='#g1-115' y='208.035'/>
+<use x='161.409' xlink:href='#g3-40' y='208.035'/>
+<use x='164.702' xlink:href='#g3-108' y='208.035'/>
+<use x='166.722' xlink:href='#g3-111' y='208.035'/>
+<use x='170.721' xlink:href='#g3-119' y='208.035'/>
+<use x='176.27' xlink:href='#g3-101' y='208.035'/>
+<use x='180.034' xlink:href='#g3-114' y='208.035'/>
+<use x='185.749' xlink:href='#g3-105' y='208.035'/>
+<use x='187.769' xlink:href='#g3-115' y='208.035'/>
+<use x='193.838' xlink:href='#g3-98' y='208.035'/>
+<use x='198.446' xlink:href='#g3-101' y='208.035'/>
+<use x='202.209' xlink:href='#g3-116' y='208.035'/>
+<use x='205.267' xlink:href='#g3-116' y='208.035'/>
+<use x='208.325' xlink:href='#g3-101' y='208.035'/>
+<use x='212.089' xlink:href='#g3-114' y='208.035'/>
+<use x='214.981' xlink:href='#g3-41' y='208.035'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='255.738pt' version='1.1' viewBox='106.736 54.996 381.624 255.738' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip8'>
+<path d='M135.949 249.281H487.961V81.519H135.949Z'/>
+</clipPath>
+<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/>
+<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/>
+<use id='g3-45' transform='scale(1.143)' xlink:href='#g0-45'/>
+<use id='g3-49' transform='scale(1.143)' xlink:href='#g0-49'/>
+<use id='g3-54' transform='scale(1.143)' xlink:href='#g0-54'/>
+<use id='g3-56' transform='scale(1.143)' xlink:href='#g0-56'/>
+<use id='g3-58' transform='scale(1.143)' xlink:href='#g0-58'/>
+<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/>
+<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/>
+<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/>
+<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/>
+<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/>
+<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/>
+<use id='g3-103' transform='scale(1.143)' xlink:href='#g0-103'/>
+<use id='g3-104' transform='scale(1.143)' xlink:href='#g0-104'/>
+<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/>
+<use id='g3-106' transform='scale(1.143)' xlink:href='#g0-106'/>
+<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/>
+<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/>
+<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/>
+<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/>
+<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/>
+<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/>
+<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/>
+<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/>
+<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/>
+<use id='g3-120' transform='scale(1.143)' xlink:href='#g0-120'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g1-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g1-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/>
+<use id='g2-44' transform='scale(0.714)' xlink:href='#g0-44'/>
+<use id='g2-45' transform='scale(0.714)' xlink:href='#g0-45'/>
+<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/>
+<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/>
+<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/>
+<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/>
+<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/>
+<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/>
+<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/>
+<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/>
+<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/>
+<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/>
+<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/>
+<use id='g2-64' transform='scale(0.714)' xlink:href='#g0-64'/>
+<use id='g2-67' transform='scale(0.714)' xlink:href='#g0-67'/>
+<use id='g2-71' transform='scale(0.714)' xlink:href='#g0-71'/>
+<use id='g2-73' transform='scale(0.714)' xlink:href='#g0-73'/>
+<use id='g2-85' transform='scale(0.714)' xlink:href='#g0-85'/>
+<use id='g2-88' transform='scale(0.714)' xlink:href='#g0-88'/>
+<use id='g2-97' transform='scale(0.714)' xlink:href='#g0-97'/>
+<use id='g2-98' transform='scale(0.714)' xlink:href='#g0-98'/>
+<use id='g2-99' transform='scale(0.714)' xlink:href='#g0-99'/>
+<use id='g2-100' transform='scale(0.714)' xlink:href='#g0-100'/>
+<use id='g2-101' transform='scale(0.714)' xlink:href='#g0-101'/>
+<use id='g2-103' transform='scale(0.714)' xlink:href='#g0-103'/>
+<use id='g2-104' transform='scale(0.714)' xlink:href='#g0-104'/>
+<use id='g2-108' transform='scale(0.714)' xlink:href='#g0-108'/>
+<use id='g2-109' transform='scale(0.714)' xlink:href='#g0-109'/>
+<use id='g2-110' transform='scale(0.714)' xlink:href='#g0-110'/>
+<use id='g2-111' transform='scale(0.714)' xlink:href='#g0-111'/>
+<use id='g2-112' transform='scale(0.714)' xlink:href='#g0-112'/>
+<use id='g2-114' transform='scale(0.714)' xlink:href='#g0-114'/>
+<use id='g2-115' transform='scale(0.714)' xlink:href='#g0-115'/>
+<use id='g2-116' transform='scale(0.714)' xlink:href='#g0-116'/>
+<use id='g2-117' transform='scale(0.714)' xlink:href='#g0-117'/>
+<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/>
+<use id='g2-122' transform='scale(0.714)' xlink:href='#g0-122'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/>
+<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/>
+<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/>
+<path d='M1.339 -0.007V-0.628H0.711V0H0.907L0.704 0.893H1.018L1.339 -0.007Z' id='g0-44'/>
+<path d='M2.05 -1.332V-1.771H0.084V-1.332H2.05Z' id='g0-45'/>
+<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/>
+<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/>
+<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/>
+<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/>
+<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/>
+<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/>
+<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/>
+<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/>
+<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/>
+<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/>
+<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/>
+<path d='M1.339 -3.096H0.711V-2.469H1.339V-3.096ZM0.711 -0.628V0H1.339V-0.628H0.711Z' id='g0-58'/>
+<path d='M4.142 -0.614C4.038 -0.614 4.024 -0.614 3.968 -0.586C3.626 -0.467 3.271 -0.391 2.901 -0.391C1.778 -0.391 0.976 -1.339 0.976 -2.42C0.976 -3.592 1.883 -4.449 2.859 -4.449C3.055 -4.449 3.515 -4.4 3.745 -3.843C3.55 -3.954 3.333 -4.003 3.152 -4.003C2.406 -4.003 1.778 -3.306 1.778 -2.42C1.778 -1.513 2.427 -0.837 3.145 -0.837C3.689 -0.837 4.519 -1.276 4.519 -2.518C4.519 -3.222 4.47 -4.91 2.866 -4.91C1.541 -4.91 0.411 -3.815 0.411 -2.42C0.411 -1.039 1.527 0.07 2.873 0.07C3.515 0.07 4.115 -0.195 4.519 -0.614H4.142ZM3.152 -1.297C2.72 -1.297 2.343 -1.778 2.343 -2.42C2.343 -3.082 2.734 -3.543 3.145 -3.543C3.578 -3.543 3.954 -3.062 3.954 -2.42C3.954 -1.757 3.564 -1.297 3.152 -1.297Z' id='g0-64'/>
+<path d='M4.317 -0.851C3.829 -0.551 3.605 -0.418 2.908 -0.418C1.827 -0.418 1.172 -1.43 1.172 -2.434C1.172 -3.466 1.89 -4.435 2.908 -4.435C3.368 -4.435 3.843 -4.289 4.163 -4.045L4.275 -4.679C3.787 -4.861 3.396 -4.917 2.887 -4.917C1.506 -4.917 0.474 -3.773 0.474 -2.427C0.474 -0.99 1.569 0.07 2.929 0.07C3.612 0.07 3.898 -0.07 4.359 -0.321L4.317 -0.851Z' id='g0-67'/>
+<path d='M4.442 -2.085H2.88V-1.625H3.829V-0.558C3.522 -0.481 3.222 -0.418 2.908 -0.418C1.834 -0.418 1.172 -1.43 1.172 -2.427C1.172 -3.382 1.82 -4.435 2.873 -4.435C3.515 -4.435 3.919 -4.24 4.268 -3.947L4.38 -4.582C3.898 -4.812 3.473 -4.924 2.943 -4.924C1.534 -4.924 0.474 -3.822 0.474 -2.427C0.474 -1.067 1.527 0.07 2.901 0.07C3.403 0.07 3.996 -0.042 4.442 -0.272V-2.085Z' id='g0-71'/>
+<path d='M1.381 -4.84H0.676V0H1.381V-4.84Z' id='g0-73'/>
+<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/>
+<path d='M4.4 -4.84H3.794V-1.625C3.794 -0.69 3.166 -0.265 2.566 -0.265S1.381 -0.697 1.381 -1.618V-4.84H0.676V-1.632C0.676 -0.607 1.555 0.146 2.559 0.146C3.557 0.146 4.4 -0.614 4.4 -1.632V-4.84Z' id='g0-85'/>
+<path d='M2.755 -2.552L4.519 -4.84H3.759L2.413 -3.055L1.039 -4.84H0.209L2.071 -2.552L0.105 0H0.865L2.413 -2.099L3.996 0H4.826L2.755 -2.552Z' id='g0-88'/>
+<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/>
+<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/>
+<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/>
+<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/>
+<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/>
+<path d='M3.508 -3.166C3.354 -3.166 2.887 -3.159 2.357 -2.957L2.343 -2.95C2.092 -3.117 1.848 -3.166 1.646 -3.166C0.962 -3.166 0.453 -2.629 0.453 -2.029C0.453 -1.785 0.537 -1.534 0.697 -1.339C0.6 -1.22 0.495 -1.025 0.495 -0.76C0.495 -0.488 0.607 -0.314 0.669 -0.23C0.286 -0.007 0.209 0.314 0.209 0.481C0.209 1.011 0.941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 0.481C3.487 -0.502 2.267 -0.502 1.967 -0.502H1.318C1.206 -0.502 0.907 -0.502 0.907 -0.865C0.907 -1.004 0.955 -1.074 0.962 -1.088C1.206 -0.934 1.451 -0.886 1.639 -0.886C2.322 -0.886 2.831 -1.423 2.831 -2.022C2.831 -2.246 2.769 -2.448 2.643 -2.636C2.615 -2.678 2.615 -2.685 2.615 -2.692C2.615 -2.72 3.034 -2.72 3.068 -2.72C3.075 -2.72 3.34 -2.72 3.592 -2.692L3.508 -3.166ZM1.646 -1.318C1.269 -1.318 0.99 -1.555 0.99 -2.022C0.99 -2.566 1.339 -2.734 1.639 -2.734C2.015 -2.734 2.294 -2.497 2.294 -2.029C2.294 -1.485 1.946 -1.318 1.646 -1.318ZM1.974 0.042C2.134 0.042 2.957 0.042 2.957 0.488C2.957 0.788 2.434 0.997 1.848 0.997S0.739 0.788 0.739 0.488C0.739 0.453 0.739 0.042 1.304 0.042H1.974Z' id='g0-103'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.625 -3.166 1.304 -2.817 1.165 -2.671V-4.84H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-104'/>
+<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/>
+<path d='M1.381 -4.784H0.676V-4.08H1.381V-4.784ZM-0.453 1.186C-0.133 1.36 0.181 1.423 0.446 1.423C0.928 1.423 1.381 1.053 1.381 0.411V-3.096H0.795V0.46C0.795 0.586 0.795 0.697 0.649 0.816C0.488 0.934 0.293 0.934 0.23 0.934C-0.063 0.934 -0.244 0.802 -0.328 0.725L-0.453 1.186Z' id='g0-106'/>
+<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/>
+<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/>
+<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/>
+<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/>
+<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/>
+<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/>
+<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/>
+<path d='M3.243 -3.096H2.636V-1.074C2.636 -0.516 2.162 -0.342 1.757 -0.342C1.241 -0.342 1.186 -0.481 1.186 -0.802V-3.096H0.579V-0.76C0.579 -0.139 0.851 0.07 1.339 0.07C1.625 0.07 2.239 0.014 2.657 -0.321V0H3.243V-3.096Z' id='g0-117'/>
+<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/>
+<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/>
+<path d='M2.957 -2.803V-3.096H0.307V-2.65H1.332C1.416 -2.65 1.499 -2.657 1.583 -2.657H2.127L0.209 -0.307V0H2.978V-0.467H1.897C1.813 -0.467 1.73 -0.46 1.646 -0.46H1.039L2.957 -2.803Z' id='g0-122'/>
+</defs>
+<g id='page8'>
+<path d='M194.617 258.141V249.281M253.285 258.141V249.281M311.953 258.141V249.281M370.625 258.141V249.281M429.293 258.141V249.281M194.617 72.66V81.519M253.285 72.66V81.519M311.953 72.66V81.519M370.625 72.66V81.519M429.293 72.66V81.519' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.266V81.519M223.953 77.266V81.519M282.621 77.266V81.519M341.289 77.266V81.519M399.957 77.266V81.519M458.629 77.266V81.519' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.519H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.519H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 249.281V81.519H487.961V249.281H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 74.992)'>
+<use x='168.285' xlink:href='#g3-97' y='188.688'/>
+<use x='172.353' xlink:href='#g3-108' y='188.688'/>
+<use x='174.373' xlink:href='#g3-108' y='188.688'/>
+<use x='176.393' xlink:href='#g3-111' y='188.688'/>
+<use x='180.863' xlink:href='#g3-99' y='188.688'/>
+<use x='184.627' xlink:href='#g3-45' y='188.688'/>
+<use x='187.449' xlink:href='#g3-116' y='188.688'/>
+<use x='190.507' xlink:href='#g3-101' y='188.688'/>
+<use x='194.271' xlink:href='#g3-115' y='188.688'/>
+<use x='197.517' xlink:href='#g3-116' y='188.688'/>
+<use x='200.575' xlink:href='#g3-49' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 74.992)'>
+<use x='168.285' xlink:href='#g3-97' y='188.688'/>
+<use x='172.353' xlink:href='#g3-108' y='188.688'/>
+<use x='174.373' xlink:href='#g3-108' y='188.688'/>
+<use x='176.393' xlink:href='#g3-111' y='188.688'/>
+<use x='180.863' xlink:href='#g3-99' y='188.688'/>
+<use x='184.627' xlink:href='#g3-45' y='188.688'/>
+<use x='187.449' xlink:href='#g3-116' y='188.688'/>
+<use x='190.507' xlink:href='#g3-101' y='188.688'/>
+<use x='194.271' xlink:href='#g3-115' y='188.688'/>
+<use x='197.517' xlink:href='#g3-116' y='188.688'/>
+<use x='200.575' xlink:href='#g3-78' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 74.992)'>
+<use x='168.285' xlink:href='#g3-115' y='188.688'/>
+<use x='171.531' xlink:href='#g3-104' y='188.688'/>
+<use x='175.904' xlink:href='#g3-54' y='188.688'/>
+<use x='180.138' xlink:href='#g3-98' y='188.688'/>
+<use x='184.746' xlink:href='#g3-101' y='188.688'/>
+<use x='188.509' xlink:href='#g3-110' y='188.688'/>
+<use x='192.882' xlink:href='#g3-99' y='188.688'/>
+<use x='196.646' xlink:href='#g3-104' y='188.688'/>
+<use x='201.018' xlink:href='#g3-78' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 74.992)'>
+<use x='168.285' xlink:href='#g3-115' y='188.688'/>
+<use x='171.531' xlink:href='#g3-104' y='188.688'/>
+<use x='175.904' xlink:href='#g3-56' y='188.688'/>
+<use x='180.138' xlink:href='#g3-98' y='188.688'/>
+<use x='184.746' xlink:href='#g3-101' y='188.688'/>
+<use x='188.509' xlink:href='#g3-110' y='188.688'/>
+<use x='192.882' xlink:href='#g3-99' y='188.688'/>
+<use x='196.646' xlink:href='#g3-104' y='188.688'/>
+<use x='201.018' xlink:href='#g3-78' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 74.992)'>
+<use x='168.285' xlink:href='#g3-120' y='188.688'/>
+<use x='172.187' xlink:href='#g3-109' y='188.688'/>
+<use x='178.912' xlink:href='#g3-97' y='188.688'/>
+<use x='182.98' xlink:href='#g3-108' y='188.688'/>
+<use x='185' xlink:href='#g3-108' y='188.688'/>
+<use x='187.02' xlink:href='#g3-111' y='188.688'/>
+<use x='191.49' xlink:href='#g3-99' y='188.688'/>
+<use x='195.254' xlink:href='#g3-45' y='188.688'/>
+<use x='198.076' xlink:href='#g3-116' y='188.688'/>
+<use x='201.134' xlink:href='#g3-101' y='188.688'/>
+<use x='204.898' xlink:href='#g3-115' y='188.688'/>
+<use x='208.144' xlink:href='#g3-116' y='188.688'/>
+<use x='211.202' xlink:href='#g3-78' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 74.992)'>
+<use x='168.285' xlink:href='#g3-99' y='188.688'/>
+<use x='172.049' xlink:href='#g3-97' y='188.688'/>
+<use x='176.117' xlink:href='#g3-99' y='188.688'/>
+<use x='179.88' xlink:href='#g3-104' y='188.688'/>
+<use x='184.253' xlink:href='#g3-101' y='188.688'/>
+<use x='188.017' xlink:href='#g3-45' y='188.688'/>
+<use x='190.839' xlink:href='#g3-115' y='188.688'/>
+<use x='194.086' xlink:href='#g3-99' y='188.688'/>
+<use x='197.849' xlink:href='#g3-114' y='188.688'/>
+<use x='200.741' xlink:href='#g3-97' y='188.688'/>
+<use x='204.81' xlink:href='#g3-116' y='188.688'/>
+<use x='207.868' xlink:href='#g3-99' y='188.688'/>
+<use x='211.631' xlink:href='#g3-104' y='188.688'/>
+<use x='216.004' xlink:href='#g3-78' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 62.23)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.677)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -4.876)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -38.43)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.983)'>
+<use x='168.285' xlink:href='#g2-50' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -105.536)'>
+<use x='168.285' xlink:href='#g2-50' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-120' y='188.688'/>
+</g>
+<path clip-path='url(#clip8)' d='M135.949 182.176H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M142.742 249.281H145.981V182.176H142.742ZM201.41 249.281H204.649V182.176H201.41ZM260.078 249.281H263.317V182.176H260.078ZM318.75 249.281H321.988V182.176H318.75ZM377.418 249.281H380.656V182.176H377.418ZM436.086 249.281H439.324V182.176H436.086Z' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M142.742 249.281H145.981V182.176H142.742ZM201.41 249.281H204.649V182.176H201.41ZM260.078 249.281H263.317V182.176H260.078ZM318.75 249.281H321.988V182.176H318.75ZM377.418 249.281H380.656V182.176H377.418ZM436.086 249.281H439.324V182.176H436.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M144.359 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M142.367 182.176H146.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M144.359 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M142.367 182.176H146.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M203.031 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M201.035 182.176H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M203.031 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M201.035 182.176H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M261.699 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M259.707 182.176H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M261.699 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M259.707 182.176H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M320.367 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M318.375 182.176H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M320.367 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M318.375 182.176H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M379.035 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M377.043 182.176H381.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M379.035 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M377.043 182.176H381.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M437.707 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M435.711 182.176H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M437.707 182.176V182.176' fill='#ffffff'/>
+<path clip-path='url(#clip8)' d='M435.711 182.176H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M147.973 249.281H151.211V164.73H147.973ZM206.641 249.281H209.879V161.977H206.641ZM265.309 249.281H268.547V183.25H265.309ZM323.981 249.281H327.219V209.891H323.981ZM382.649 249.281H385.887V224.184H382.649ZM441.317 249.281H444.555V141.242H441.317Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M147.973 249.281H151.211V164.73H147.973ZM206.641 249.281H209.879V161.977H206.641ZM265.309 249.281H268.547V183.25H265.309ZM323.981 249.281H327.219V209.891H323.981ZM382.649 249.281H385.887V224.184H382.649ZM441.317 249.281H444.555V141.242H441.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M149.59 164.73V164.73' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M147.598 164.73H151.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M149.59 164.73V164.73' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M147.598 164.73H151.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M208.262 161.977V161.977' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M206.266 161.976H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M208.262 161.977V161.977' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M206.266 161.976H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M266.93 183.25V183.25' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M264.938 183.25H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M266.93 183.25V183.25' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M264.938 183.25H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M325.598 209.891V209.891' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M323.606 209.891H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M325.598 209.891V209.891' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M323.606 209.891H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M384.266 224.184V224.184' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M382.274 224.183H386.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M384.266 224.184V224.184' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M382.274 224.183H386.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M442.938 141.242V141.242' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M440.942 141.242H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M442.938 141.242V141.242' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M440.942 141.242H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M153.203 249.281H156.442V185.129H153.203ZM211.871 249.281H215.11V177.883H211.871ZM270.539 249.281H273.777V181.437H270.539ZM329.211 249.281H332.449V192.848H329.211ZM387.879 249.281H391.117V183.719H387.879ZM446.547 249.281H449.785V145H446.547Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M153.203 249.281H156.442V185.129H153.203ZM211.871 249.281H215.11V177.883H211.871ZM270.539 249.281H273.777V181.437H270.539ZM329.211 249.281H332.449V192.848H329.211ZM387.879 249.281H391.117V183.719H387.879ZM446.547 249.281H449.785V145H446.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M154.82 185.129V185.129' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M152.828 185.129H156.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M154.82 185.129V185.129' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M152.828 185.129H156.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M213.492 177.883V177.883' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M211.496 177.883H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M213.492 177.883V177.883' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M211.496 177.883H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M272.16 181.437V181.437' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M270.168 181.438H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M272.16 181.437V181.437' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M270.168 181.438H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M330.828 192.848V192.848' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M328.836 192.848H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M330.828 192.848V192.848' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M328.836 192.848H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M389.496 183.719V183.719' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M387.504 183.718H391.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M389.496 183.719V183.719' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M387.504 183.718H391.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M448.168 145V145' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M446.172 145H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M448.168 145V145' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M446.172 145H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M158.434 249.281H161.672V180.969H158.434ZM217.102 249.281H220.34V172.043H217.102ZM275.77 249.281H279.008V172.312H275.77ZM334.442 249.281H337.68V194.996H334.442ZM393.109 249.281H396.348V195.531H393.109ZM451.777 249.281H455.016V180.098H451.777Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M158.434 249.281H161.672V180.969H158.434ZM217.102 249.281H220.34V172.043H217.102ZM275.77 249.281H279.008V172.312H275.77ZM334.442 249.281H337.68V194.996H334.442ZM393.109 249.281H396.348V195.531H393.109ZM451.777 249.281H455.016V180.098H451.777Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M160.051 180.969V180.969' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M158.058 180.969H162.042' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M160.051 180.969V180.969' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M158.058 180.969H162.042' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M218.723 172.043V172.043' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M216.726 172.043H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M218.723 172.043V172.043' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M216.726 172.043H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M277.391 172.312V172.312' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M275.398 172.312H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M277.391 172.312V172.312' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M275.398 172.312H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M336.059 194.996V194.996' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M334.066 194.996H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M336.059 194.996V194.996' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M334.066 194.996H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M394.727 195.531V195.531' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M392.734 195.531H396.718' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M394.727 195.531V195.531' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M392.734 195.531H396.718' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M453.399 180.098V180.098' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M451.402 180.098H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M453.399 180.098V180.098' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M451.402 180.098H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M163.664 249.281H166.903V180.363H163.664ZM222.332 249.281H225.57V144.465H222.332ZM281 249.281H284.238V171.707H281ZM339.672 249.281H342.91V191.641H339.672ZM398.34 249.281H401.578V81.519H398.34ZM457.008 249.281H460.246V190.027H457.008Z' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M163.664 249.281H166.903V180.363H163.664ZM222.332 249.281H225.57V144.465H222.332ZM281 249.281H284.238V171.707H281ZM339.672 249.281H342.91V191.641H339.672ZM398.34 249.281H401.578V81.519H398.34ZM457.008 249.281H460.246V190.027H457.008Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M165.281 180.363V180.363' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M163.289 180.363H167.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M165.281 180.363V180.363' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M163.289 180.363H167.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M223.953 144.465V144.465' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M221.957 144.464H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M223.953 144.465V144.465' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M221.957 144.464H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M282.621 171.707V171.707' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M280.629 171.707H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M282.621 171.707V171.707' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M280.629 171.707H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M341.289 191.641V191.641' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M339.297 191.641H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M341.289 191.641V191.641' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M339.297 191.641H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M399.957 81.519V81.519' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M397.965 81.52H401.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M399.957 81.519V81.519' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M397.965 81.52H401.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M458.629 190.027V190.027' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M456.633 190.027H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M458.629 190.027V190.027' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M456.633 190.027H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M168.895 249.281H172.133V157.348H168.895ZM227.563 249.281H230.801V81.519H227.563ZM286.231 249.281H289.469V141.711H286.231ZM344.902 249.281H348.141V124.601H344.902ZM403.57 249.281H406.809V132.25H403.57ZM462.238 249.281H465.477V189.894H462.238Z' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M168.895 249.281H172.133V157.348H168.895ZM227.563 249.281H230.801V81.519H227.563ZM286.231 249.281H289.469V141.711H286.231ZM344.902 249.281H348.141V124.601H344.902ZM403.57 249.281H406.809V132.25H403.57ZM462.238 249.281H465.477V189.894H462.238Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M170.512 157.348V157.348' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M168.519 157.348H172.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M170.512 157.348V157.348' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M168.519 157.348H172.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M229.184 81.519V81.519' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M227.187 81.52H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M229.184 81.519V81.519' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M227.187 81.52H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M287.852 141.711V141.711' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M285.859 141.711H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M287.852 141.711V141.711' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M285.859 141.711H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M346.52 124.601V124.601' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M344.527 124.602H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M346.52 124.601V124.601' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M344.527 124.602H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M405.188 132.25V132.25' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M403.195 132.25H407.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M405.188 132.25V132.25' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M403.195 132.25H407.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M463.859 189.894V189.894' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M461.863 189.894H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M463.859 189.894V189.894' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M461.863 189.894H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M174.125 249.281H177.363V171.574H174.125ZM232.793 249.281H236.031V146.344H232.793ZM291.461 249.281H294.699V169.426H291.461ZM350.133 249.281H353.371V204.254H350.133ZM408.801 249.281H412.039V224.992H408.801ZM467.469 249.281H470.707V163.254H467.469Z' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M174.125 249.281H177.363V171.574H174.125ZM232.793 249.281H236.031V146.344H232.793ZM291.461 249.281H294.699V169.426H291.461ZM350.133 249.281H353.371V204.254H350.133ZM408.801 249.281H412.039V224.992H408.801ZM467.469 249.281H470.707V163.254H467.469Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M175.742 171.574V171.574' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M173.75 171.574H177.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M175.742 171.574V171.574' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M173.75 171.574H177.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M234.414 146.344V146.344' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M232.418 146.343H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M234.414 146.344V146.344' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M232.418 146.343H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M293.082 169.426V169.426' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M291.09 169.426H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M293.082 169.426V169.426' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M291.09 169.426H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M351.75 204.254V204.254' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M349.758 204.254H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M351.75 204.254V204.254' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M349.758 204.254H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M410.418 224.992V224.992' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M408.426 224.992H412.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M410.418 224.992V224.992' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M408.426 224.992H412.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M469.09 163.254V163.254' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M467.094 163.254H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M469.09 163.254V163.254' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M467.094 163.254H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M179.356 249.281H182.594V176.004H179.356ZM238.024 249.281H241.262V169.16H238.024ZM296.692 249.281H299.93V149.699H296.692ZM355.363 249.281H358.602V121.043H355.363ZM414.031 249.281H417.27V214.051H414.031ZM472.699 249.281H475.938V194.121H472.699Z' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M179.356 249.281H182.594V176.004H179.356ZM238.024 249.281H241.262V169.16H238.024ZM296.692 249.281H299.93V149.699H296.692ZM355.363 249.281H358.602V121.043H355.363ZM414.031 249.281H417.27V214.051H414.031ZM472.699 249.281H475.938V194.121H472.699Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M180.973 176.004V176.004' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M178.98 176.004H182.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M180.973 176.004V176.004' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M178.98 176.004H182.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M239.645 169.16V169.16' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M237.648 169.16H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M239.645 169.16V169.16' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M237.648 169.16H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M298.313 149.699V149.699' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M296.32 149.7H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M298.313 149.699V149.699' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M296.32 149.7H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M356.981 121.043V121.043' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M354.988 121.043H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M356.981 121.043V121.043' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M354.988 121.043H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M415.649 214.051V214.051' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M413.656 214.05H417.64' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M415.649 214.051V214.051' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M413.656 214.05H417.64' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M474.32 194.121V194.121' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M472.324 194.121H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M474.32 194.121V194.121' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M472.324 194.121H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M184.586 249.281H187.824V181.641H184.586ZM243.254 249.281H246.492V115.137H243.254ZM301.922 249.281H305.16V176.605H301.922ZM360.594 249.281H363.832V185.734H360.594ZM419.262 249.281H422.5V164.125H419.262ZM477.93 249.281H481.168V179.828H477.93Z' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M184.586 249.281H187.824V181.641H184.586ZM243.254 249.281H246.492V115.137H243.254ZM301.922 249.281H305.16V176.605H301.922ZM360.594 249.281H363.832V185.734H360.594ZM419.262 249.281H422.5V164.125H419.262ZM477.93 249.281H481.168V179.828H477.93Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M186.203 181.641V181.641' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M184.211 181.64H188.196' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M186.203 181.641V181.641' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M184.211 181.64H188.196' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M244.875 115.137V115.137' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M242.879 115.137H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M244.875 115.137V115.137' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M242.879 115.137H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M303.543 176.605V176.605' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M301.551 176.605H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M303.543 176.605V176.605' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M301.551 176.605H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M362.211 185.734V185.734' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M360.219 185.735H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M362.211 185.734V185.734' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M360.219 185.735H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M420.879 164.125V164.125' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M418.887 164.125H422.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M420.879 164.125V164.125' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M418.887 164.125H422.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M479.551 179.828V179.828' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M477.555 179.828H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M479.551 179.828V179.828' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M477.555 179.828H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M420.539 310.336H487.762V276.324H420.539Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 255.575 118.327)'>
+<use x='168.285' xlink:href='#g2-99' y='164.777'/>
+<use x='170.637' xlink:href='#g2-53' y='164.777'/>
+<use x='173.284' xlink:href='#g2-45' y='164.777'/>
+<use x='175.048' xlink:href='#g2-49' y='164.777'/>
+<use x='177.694' xlink:href='#g2-56' y='164.777'/>
+<use x='180.341' xlink:href='#g2-120' y='164.777'/>
+<use x='182.779' xlink:href='#g2-108' y='164.777'/>
+<use x='184.042' xlink:href='#g2-97' y='164.777'/>
+<use x='186.438' xlink:href='#g2-114' y='164.777'/>
+<use x='188.245' xlink:href='#g2-103' y='164.777'/>
+<use x='190.891' xlink:href='#g2-101' y='164.777'/>
+<use x='193.244' xlink:href='#g2-44' y='164.777'/>
+<use x='196.478' xlink:href='#g2-49' y='164.777'/>
+<use x='199.124' xlink:href='#g2-52' y='164.777'/>
+<use x='201.771' xlink:href='#g2-52' y='164.777'/>
+<use x='204.417' xlink:href='#g2-71' y='164.777'/>
+<use x='207.946' xlink:href='#g2-98' y='164.777'/>
+<use x='168.285' xlink:href='#g2-55' y='170.755'/>
+<use x='170.931' xlink:href='#g2-50' y='170.755'/>
+<use x='175.342' xlink:href='#g2-112' y='170.755'/>
+<use x='177.928' xlink:href='#g2-114' y='170.755'/>
+<use x='179.735' xlink:href='#g2-111' y='170.755'/>
+<use x='182.529' xlink:href='#g2-99' y='170.755'/>
+<use x='186.645' xlink:href='#g2-73' y='170.755'/>
+<use x='188.115' xlink:href='#g2-110' y='170.755'/>
+<use x='190.848' xlink:href='#g2-116' y='170.755'/>
+<use x='192.759' xlink:href='#g2-101' y='170.755'/>
+<use x='195.112' xlink:href='#g2-108' y='170.755'/>
+<use x='198.139' xlink:href='#g2-88' y='170.755'/>
+<use x='201.667' xlink:href='#g2-101' y='170.755'/>
+<use x='204.019' xlink:href='#g2-111' y='170.755'/>
+<use x='206.666' xlink:href='#g2-110' y='170.755'/>
+<use x='211.163' xlink:href='#g2-64' y='170.755'/>
+<use x='214.691' xlink:href='#g2-51' y='170.755'/>
+<use x='217.338' xlink:href='#g2-71' y='170.755'/>
+<use x='220.866' xlink:href='#g2-104' y='170.755'/>
+<use x='223.599' xlink:href='#g2-122' y='170.755'/>
+<use x='168.285' xlink:href='#g2-85' y='176.733'/>
+<use x='171.917' xlink:href='#g2-98' y='176.733'/>
+<use x='174.65' xlink:href='#g2-117' y='176.733'/>
+<use x='177.383' xlink:href='#g2-110' y='176.733'/>
+<use x='180.116' xlink:href='#g2-116' y='176.733'/>
+<use x='182.027' xlink:href='#g2-117' y='176.733'/>
+<use x='186.524' xlink:href='#g2-49' y='176.733'/>
+<use x='189.17' xlink:href='#g2-56' y='176.733'/>
+<use x='191.817' xlink:href='#g2-46' y='176.733'/>
+<use x='193.287' xlink:href='#g2-48' y='176.733'/>
+<use x='195.933' xlink:href='#g2-52' y='176.733'/>
+<use x='198.58' xlink:href='#g2-46' y='176.733'/>
+<use x='200.05' xlink:href='#g2-49' y='176.733'/>
+<use x='202.696' xlink:href='#g2-44' y='176.733'/>
+<use x='205.931' xlink:href='#g2-71' y='176.733'/>
+<use x='209.459' xlink:href='#g2-67' y='176.733'/>
+<use x='212.841' xlink:href='#g2-67' y='176.733'/>
+<use x='217.986' xlink:href='#g2-55' y='176.733'/>
+<use x='220.633' xlink:href='#g2-46' y='176.733'/>
+<use x='222.103' xlink:href='#g2-52' y='176.733'/>
+<use x='224.749' xlink:href='#g2-46' y='176.733'/>
+<use x='226.219' xlink:href='#g2-48' y='176.733'/>
+<use x='168.285' xlink:href='#g2-51' y='182.71'/>
+<use x='170.931' xlink:href='#g2-54' y='182.71'/>
+<use x='175.342' xlink:href='#g2-99' y='182.71'/>
+<use x='177.694' xlink:href='#g2-111' y='182.71'/>
+<use x='180.193' xlink:href='#g2-114' y='182.71'/>
+<use x='182.001' xlink:href='#g2-101' y='182.71'/>
+<use x='184.353' xlink:href='#g2-115' y='182.71'/>
+<use x='188.146' xlink:href='#g2-111' y='182.71'/>
+<use x='190.793' xlink:href='#g2-110' y='182.71'/>
+<use x='195.29' xlink:href='#g2-50' y='182.71'/>
+<use x='199.7' xlink:href='#g2-110' y='182.71'/>
+<use x='202.433' xlink:href='#g2-117' y='182.71'/>
+<use x='205.166' xlink:href='#g2-109' y='182.71'/>
+<use x='209.369' xlink:href='#g2-97' y='182.71'/>
+<use x='213.676' xlink:href='#g2-110' y='182.71'/>
+<use x='216.409' xlink:href='#g2-111' y='182.71'/>
+<use x='219.202' xlink:href='#g2-100' y='182.71'/>
+<use x='221.935' xlink:href='#g2-101' y='182.71'/>
+<use x='224.287' xlink:href='#g2-115' y='182.71'/>
+<use x='168.285' xlink:href='#g2-50' y='188.688'/>
+<use x='170.931' xlink:href='#g2-48' y='188.688'/>
+<use x='173.578' xlink:href='#g2-50' y='188.688'/>
+<use x='176.224' xlink:href='#g2-48' y='188.688'/>
+<use x='178.87' xlink:href='#g2-45' y='188.688'/>
+<use x='180.635' xlink:href='#g2-48' y='188.688'/>
+<use x='183.281' xlink:href='#g2-49' y='188.688'/>
+<use x='185.927' xlink:href='#g2-45' y='188.688'/>
+<use x='187.692' xlink:href='#g2-49' y='188.688'/>
+<use x='190.338' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -42.693 344.258)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 15.976 344.258)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 74.645 344.258)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 133.314 344.258)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 191.983 344.258)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 250.652 344.258)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -37.462 326.81)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-50' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.207 324.059)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-51' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 79.876 345.332)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-57' y='188.688'/>
+<use x='175.048' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 138.545 371.973)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-57' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 197.214 386.266)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-51' y='188.688'/>
+<use x='175.048' xlink:href='#g2-55' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 255.882 303.323)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-54' y='188.688'/>
+<use x='175.048' xlink:href='#g2-49' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -32.232 347.211)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-57' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.437 339.963)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.106 343.52)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-49' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 143.775 354.928)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-52' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.444 345.801)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-57' y='188.688'/>
+<use x='175.048' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 261.113 307.081)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-53' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -27.002 343.05)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-50' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.667 334.125)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-49' y='188.688'/>
+<use x='175.048' xlink:href='#g2-53' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 90.336 334.393)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-49' y='188.688'/>
+<use x='175.048' xlink:href='#g2-53' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 149.005 357.075)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-49' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 207.674 357.612)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 266.343 342.178)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-51' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -21.771 342.446)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-51' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.898 306.544)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.567 333.789)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-49' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 154.236 353.72)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 212.905 243.599)'>
+<use x='163.396' xlink:href='#g4-1' y='188.688'/>
+<use x='166.901' xlink:href='#g4-1' y='188.688'/>
+<use x='170.407' xlink:href='#g4-1' y='188.688'/>
+<use x='173.912' xlink:href='#g2-50' y='188.688'/>
+<use x='176.558' xlink:href='#g2-55' y='188.688'/>
+<use x='179.205' xlink:href='#g2-46' y='188.688'/>
+<use x='180.675' xlink:href='#g2-51' y='188.688'/>
+<use x='183.321' xlink:href='#g2-51' y='188.688'/>
+<use x='185.968' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 271.574 352.109)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -16.541 319.429)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-51' y='188.688'/>
+<use x='175.048' xlink:href='#g2-55' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 42.128 243.599)'>
+<use x='163.396' xlink:href='#g4-1' y='188.688'/>
+<use x='166.901' xlink:href='#g4-1' y='188.688'/>
+<use x='170.407' xlink:href='#g4-1' y='188.688'/>
+<use x='173.912' xlink:href='#g2-51' y='188.688'/>
+<use x='176.558' xlink:href='#g2-46' y='188.688'/>
+<use x='178.029' xlink:href='#g2-51' y='188.688'/>
+<use x='180.675' xlink:href='#g2-54' y='188.688'/>
+<use x='183.321' xlink:href='#g2-120' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.797 303.793)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-54' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 159.466 286.681)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 218.135 294.331)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-55' y='188.688'/>
+<use x='175.048' xlink:href='#g2-52' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 276.804 351.975)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-57' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -11.31 333.655)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-49' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 47.359 308.423)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-51' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 106.028 331.508)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-49' y='188.688'/>
+<use x='175.048' xlink:href='#g2-57' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 164.697 366.336)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-54' y='188.688'/>
+<use x='175.048' xlink:href='#g2-55' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 223.366 387.072)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-51' y='188.688'/>
+<use x='175.048' xlink:href='#g2-54' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 282.035 325.334)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-50' y='188.688'/>
+<use x='175.048' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -6.08 338.084)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-57' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 52.589 331.239)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-49' y='188.688'/>
+<use x='175.048' xlink:href='#g2-57' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 111.258 311.779)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-52' y='188.688'/>
+<use x='175.048' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 169.927 283.124)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-57' y='188.688'/>
+<use x='175.048' xlink:href='#g2-49' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 228.596 376.133)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-53' y='188.688'/>
+<use x='175.048' xlink:href='#g2-50' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 287.265 356.203)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-56' y='188.688'/>
+<use x='175.048' xlink:href='#g2-50' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -0.849 343.721)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-49' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 57.82 277.219)'>
+<use x='168.285' xlink:href='#g2-50' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-48' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 116.489 338.688)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-56' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 175.158 347.815)'>
+<use x='168.285' xlink:href='#g2-48' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-57' y='188.688'/>
+<use x='175.048' xlink:href='#g2-53' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 233.827 326.206)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-50' y='188.688'/>
+<use x='175.048' xlink:href='#g2-55' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 292.496 341.909)'>
+<use x='168.285' xlink:href='#g2-49' y='188.688'/>
+<use x='170.931' xlink:href='#g2-46' y='188.688'/>
+<use x='172.401' xlink:href='#g2-48' y='188.688'/>
+<use x='175.048' xlink:href='#g2-52' y='188.688'/>
+</g>
+<g transform='matrix(0 -1 1 0 -75.53 385.58)'>
+<use x='168.285' xlink:href='#g1-82' y='188.688'/>
+<use x='174.255' xlink:href='#g1-101' y='188.688'/>
+<use x='178.351' xlink:href='#g1-108' y='188.688'/>
+<use x='180.551' xlink:href='#g1-97' y='188.688'/>
+<use x='184.979' xlink:href='#g1-116' y='188.688'/>
+<use x='188.307' xlink:href='#g1-105' y='188.688'/>
+<use x='190.507' xlink:href='#g1-118' y='188.688'/>
+<use x='194.755' xlink:href='#g1-101' y='188.688'/>
+<use x='201.922' xlink:href='#g1-114' y='188.688'/>
+<use x='205.07' xlink:href='#g1-115' y='188.688'/>
+<use x='208.603' xlink:href='#g1-115' y='188.688'/>
+<use x='215.207' xlink:href='#g3-40' y='188.688'/>
+<use x='218.5' xlink:href='#g3-108' y='188.688'/>
+<use x='220.521' xlink:href='#g3-111' y='188.688'/>
+<use x='224.52' xlink:href='#g3-119' y='188.688'/>
+<use x='230.068' xlink:href='#g3-101' y='188.688'/>
+<use x='233.832' xlink:href='#g3-114' y='188.688'/>
+<use x='239.547' xlink:href='#g3-105' y='188.688'/>
+<use x='241.567' xlink:href='#g3-115' y='188.688'/>
+<use x='247.636' xlink:href='#g3-98' y='188.688'/>
+<use x='252.244' xlink:href='#g3-101' y='188.688'/>
+<use x='256.008' xlink:href='#g3-116' y='188.688'/>
+<use x='259.066' xlink:href='#g3-116' y='188.688'/>
+<use x='262.124' xlink:href='#g3-101' y='188.688'/>
+<use x='265.887' xlink:href='#g3-114' y='188.688'/>
+<use x='268.779' xlink:href='#g3-41' y='188.688'/>
+</g>
+<path d='M136.149 309.68H341.363V279.68H136.149Z' fill='#ffffff'/>
+<path d='M136.149 309.68H341.363V279.68H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#ffffff'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -40.354 114.479)'>
+<use x='195.372' xlink:href='#g3-120' y='175.681'/>
+<use x='199.274' xlink:href='#g3-109' y='175.681'/>
+<use x='205.999' xlink:href='#g3-105' y='175.681'/>
+<use x='208.019' xlink:href='#g3-58' y='175.681'/>
+<use x='210.371' xlink:href='#g0-54' y='175.681'/>
+<use x='214.076' xlink:href='#g0-57' y='175.681'/>
+</g>
+<path d='M184.145 290.168H187.133V282.199H184.145ZM190.121 290.168H193.109V284.191H190.121Z' fill='#f0e0f0'/>
+<path d='M184.145 290.168H187.133V282.199H184.145ZM190.121 290.168H193.109V284.191H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.441 114.036)'>
+<use x='239.382' xlink:href='#g3-116' y='175.681'/>
+<use x='242.44' xlink:href='#g3-99' y='175.681'/>
+<use x='246.204' xlink:href='#g3-58' y='175.681'/>
+<use x='248.556' xlink:href='#g0-54' y='175.681'/>
+<use x='252.261' xlink:href='#g0-54' y='175.681'/>
+</g>
+<path d='M227.356 290.168H230.344V282.199H227.356ZM233.332 290.168H236.32V284.191H233.332Z' fill='#e1c2e1'/>
+<path d='M227.356 290.168H230.344V282.199H227.356ZM233.332 290.168H236.32V284.191H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.04 114.479)'>
+<use x='281.863' xlink:href='#g3-106' y='175.681'/>
+<use x='284.119' xlink:href='#g3-101' y='175.681'/>
+<use x='287.882' xlink:href='#g3-58' y='175.681'/>
+<use x='290.235' xlink:href='#g0-54' y='175.681'/>
+<use x='293.94' xlink:href='#g0-54' y='175.681'/>
+</g>
+<path d='M269.106 290.168H272.094V282.199H269.106ZM275.086 290.168H278.074V284.191H275.086Z' fill='#d1a3d1'/>
+<path d='M269.106 290.168H272.094V282.199H269.106ZM275.086 290.168H278.074V284.191H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.932 114.515)'>
+<use x='321.287' xlink:href='#g3-116' y='175.681'/>
+<use x='324.345' xlink:href='#g3-98' y='175.681'/>
+<use x='328.717' xlink:href='#g3-98' y='175.681'/>
+<use x='333.09' xlink:href='#g3-58' y='175.681'/>
+<use x='335.442' xlink:href='#g0-54' y='175.681'/>
+<use x='339.147' xlink:href='#g0-53' y='175.681'/>
+</g>
+<path d='M306.203 290.168H309.191V282.199H306.203ZM312.18 290.168H315.168V284.191H312.18Z' fill='#c285c2'/>
+<path d='M306.203 290.168H309.191V282.199H306.203ZM312.18 290.168H315.168V284.191H312.18Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.662 114.036)'>
+<use x='356.019' xlink:href='#g3-114' y='175.681'/>
+<use x='358.911' xlink:href='#g3-112' y='175.681'/>
+<use x='363.284' xlink:href='#g3-58' y='175.681'/>
+<use x='365.636' xlink:href='#g0-52' y='175.681'/>
+<use x='369.341' xlink:href='#g0-52' y='175.681'/>
+</g>
+<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' fill='#b366b3'/>
+<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -43.882 114.515)'>
+<use x='195.372' xlink:href='#g3-104' y='188.688'/>
+<use x='199.744' xlink:href='#g3-111' y='188.688'/>
+<use x='203.978' xlink:href='#g3-97' y='188.688'/>
+<use x='207.811' xlink:href='#g3-114' y='188.688'/>
+<use x='210.703' xlink:href='#g3-100' y='188.688'/>
+<use x='215.076' xlink:href='#g3-58' y='188.688'/>
+<use x='217.428' xlink:href='#g0-51' y='188.688'/>
+<use x='221.133' xlink:href='#g0-54' y='188.688'/>
+</g>
+<path d='M184.145 303.176H187.133V295.207H184.145ZM190.121 303.176H193.109V297.199H190.121Z' fill='#a447a4'/>
+<path d='M184.145 303.176H187.133V295.207H184.145ZM190.121 303.176H193.109V297.199H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -43.084 114.515)'>
+<use x='239.382' xlink:href='#g3-109' y='188.688'/>
+<use x='246.107' xlink:href='#g3-101' y='188.688'/>
+<use x='249.871' xlink:href='#g3-115' y='188.688'/>
+<use x='253.117' xlink:href='#g3-104' y='188.688'/>
+<use x='257.489' xlink:href='#g3-58' y='188.688'/>
+<use x='259.842' xlink:href='#g0-54' y='188.688'/>
+<use x='263.547' xlink:href='#g0-49' y='188.688'/>
+</g>
+<path d='M227.356 303.176H230.344V295.207H227.356ZM233.332 303.176H236.32V297.199H233.332Z' fill='#942994'/>
+<path d='M227.356 303.176H230.344V295.207H227.356ZM233.332 303.176H236.32V297.199H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -42.353 114.515)'>
+<use x='281.863' xlink:href='#g3-103' y='188.688'/>
+<use x='286.097' xlink:href='#g3-108' y='188.688'/>
+<use x='288.118' xlink:href='#g3-105' y='188.688'/>
+<use x='290.138' xlink:href='#g3-98' y='188.688'/>
+<use x='294.746' xlink:href='#g3-99' y='188.688'/>
+<use x='298.509' xlink:href='#g3-58' y='188.688'/>
+<use x='300.862' xlink:href='#g0-54' y='188.688'/>
+<use x='304.567' xlink:href='#g0-52' y='188.688'/>
+</g>
+<path d='M269.106 303.176H272.094V295.207H269.106ZM275.086 303.176H278.074V297.199H275.086Z' fill='#850a85'/>
+<path d='M269.106 303.176H272.094V295.207H269.106ZM275.086 303.176H278.074V297.199H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -40.026 114.479)'>
+<use x='321.287' xlink:href='#g3-115' y='188.688'/>
+<use x='324.533' xlink:href='#g3-109' y='188.688'/>
+<use x='331.258' xlink:href='#g3-105' y='188.688'/>
+<use x='333.278' xlink:href='#g3-58' y='188.688'/>
+<use x='335.63' xlink:href='#g0-52' y='188.688'/>
+<use x='339.335' xlink:href='#g0-53' y='188.688'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip1'>
+<path d='M82.148 203.937H434.164V78.691H82.148Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page1'>
+<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 33.989)'>
+<use x='114.487' xlink:href='#g2-99' y='183.949'/>
+<use x='118.25' xlink:href='#g2-102' y='183.949'/>
+<use x='120.838' xlink:href='#g2-114' y='183.949'/>
+<use x='123.73' xlink:href='#g2-97' y='183.949'/>
+<use x='127.798' xlink:href='#g2-99' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 41.401 33.989)'>
+<use x='114.487' xlink:href='#g2-101' y='183.949'/>
+<use x='118.25' xlink:href='#g2-115' y='183.949'/>
+<use x='121.497' xlink:href='#g2-112' y='183.949'/>
+<use x='125.634' xlink:href='#g2-114' y='183.949'/>
+<use x='128.526' xlink:href='#g2-101' y='183.949'/>
+<use x='132.29' xlink:href='#g2-115' y='183.949'/>
+<use x='135.536' xlink:href='#g2-115' y='183.949'/>
+<use x='138.782' xlink:href='#g2-111' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 103.095 33.989)'>
+<use x='114.487' xlink:href='#g2-98' y='183.949'/>
+<use x='118.859' xlink:href='#g2-97' y='183.949'/>
+<use x='122.692' xlink:href='#g2-114' y='183.949'/>
+<use x='125.584' xlink:href='#g2-110' y='183.949'/>
+<use x='129.957' xlink:href='#g2-101' y='183.949'/>
+<use x='133.72' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 162.903 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-101' y='183.949'/>
+<use x='120.271' xlink:href='#g2-97' y='183.949'/>
+<use x='124.339' xlink:href='#g2-110' y='183.949'/>
+<use x='128.711' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 223.526 33.989)'>
+<use x='114.487' xlink:href='#g2-114' y='183.949'/>
+<use x='117.379' xlink:href='#g2-101' y='183.949'/>
+<use x='121.142' xlink:href='#g2-100' y='183.949'/>
+<use x='125.515' xlink:href='#g2-105' y='183.949'/>
+<use x='127.535' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 277.054 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-97' y='183.949'/>
+<use x='120.34' xlink:href='#g2-114' y='183.949'/>
+<use x='123.232' xlink:href='#g2-115' y='183.949'/>
+<use x='126.478' xlink:href='#g2-111' y='183.949'/>
+<use x='130.712' xlink:href='#g2-110' y='183.949'/>
+<use x='135.085' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 21.624)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.688)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.999)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -72.311)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.622)'>
+<use x='114.487' xlink:href='#g1-50' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<path clip-path='url(#clip1)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M93.18 141.316V141.191' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M93.18 141.316V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M91.184 141.191H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M93.18 141.316V141.441' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M93.18 141.316V141.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M95.172 141.442H91.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M151.848 141.316V141.316' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M151.848 141.316V141.316' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M210.516 141.316V141.004' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M210.516 141.316V141.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M208.523 141.004H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M210.516 141.316V141.629' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M210.516 141.316V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M212.508 141.629H208.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M269.184 141.316V141.066' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M269.184 141.316V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M267.191 141.067H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M269.184 141.316V141.566' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M269.184 141.316V141.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M271.179 141.567H267.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M327.856 141.316V140.625' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M327.856 141.316V140.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M325.859 140.625H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M327.856 141.316V142.004' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M327.856 141.316V142.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M329.847 142.004H325.863' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M386.524 141.316V141.004' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M386.524 141.316V141.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M384.531 141.004H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M386.524 141.316V141.629' fill='#e0e0f0'/>
+<path clip-path='url(#clip1)' d='M386.524 141.316V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M388.515 141.629H384.531' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M96.789 203.937H100.027V138.937H96.789ZM155.457 203.937H158.695V139.312H155.457ZM214.129 203.937H217.363V141.004H214.129ZM272.797 203.937H276.035V136.179H272.797ZM331.465 203.937H334.703V136.617H331.465ZM390.133 203.937H393.371V78.691H390.133Z' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M96.789 203.937H100.027V138.937H96.789ZM155.457 203.937H158.695V139.312H155.457ZM214.129 203.937H217.363V141.004H214.129ZM272.797 203.937H276.035V136.179H272.797ZM331.465 203.937H334.703V136.617H331.465ZM390.133 203.937H393.371V78.691H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M98.41 138.937V138.683' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M98.41 138.937V138.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M96.414 138.683H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M98.41 138.937V139.187' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M98.41 138.937V139.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M100.402 139.187H96.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M157.078 139.312V139.312' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M155.086 139.312H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M157.078 139.312V139.312' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M155.086 139.312H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M215.746 141.004V140.625' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M215.746 141.004V140.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M213.754 140.625H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M215.746 141.004V141.379' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M215.746 141.004V141.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M217.739 141.379H213.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M274.414 136.179V135.992' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M274.414 136.179V135.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M272.422 135.992H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M274.414 136.179V136.367' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M274.414 136.179V136.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M276.41 136.367H272.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M333.086 136.617V136.429' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M333.086 136.617V136.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M331.09 136.43H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M333.086 136.617V136.804' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M333.086 136.617V136.804' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M335.078 136.804H331.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M391.754 78.691V78.691' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M389.762 78.691H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M391.754 78.691V78.691' fill='#c2c2e1'/>
+<path clip-path='url(#clip1)' d='M389.762 78.691H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M102.02 203.937H105.258V138.433H102.02ZM160.688 203.937H163.926V136.742H160.688ZM219.359 203.937H222.594V141.004H219.359ZM278.027 203.937H281.266V137.933H278.027ZM336.695 203.937H339.934V132.234H336.695ZM395.363 203.937H398.602V78.691H395.363Z' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M102.02 203.937H105.258V138.433H102.02ZM160.688 203.937H163.926V136.742H160.688ZM219.359 203.937H222.594V141.004H219.359ZM278.027 203.937H281.266V137.933H278.027ZM336.695 203.937H339.934V132.234H336.695ZM395.363 203.937H398.602V78.691H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M103.641 138.433V138.121' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M103.641 138.433V138.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M101.644 138.122H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M103.641 138.433V138.746' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M103.641 138.433V138.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M105.633 138.746H101.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M162.309 136.742V135.867' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M162.309 136.742V135.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M160.316 135.867H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M162.309 136.742V137.621' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M162.309 136.742V137.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M164.301 137.622H160.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M220.977 141.004V140.562' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M220.977 141.004V140.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M218.984 140.563H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M220.977 141.004V141.441' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M220.977 141.004V141.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M222.969 141.442H218.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M279.645 137.933V137.496' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M279.645 137.933V137.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M277.652 137.496H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M279.645 137.933V138.371' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M279.645 137.933V138.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M281.64 138.371H277.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M338.317 132.234V131.859' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M338.317 132.234V131.859' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M336.32 131.859H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M338.317 132.234V132.609' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M338.317 132.234V132.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M340.308 132.61H336.324' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M396.984 78.691V78.691' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M394.992 78.691H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M396.984 78.691V78.691' fill='#a3a3d1'/>
+<path clip-path='url(#clip1)' d='M394.992 78.691H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M107.25 203.937H110.488V130.48H107.25ZM165.918 203.937H169.156V133.238H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V137.308H283.258ZM341.926 203.937H345.164V135.742H341.926ZM400.594 203.937H403.832V78.691H400.594Z' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M107.25 203.937H110.488V130.48H107.25ZM165.918 203.937H169.156V133.238H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V137.308H283.258ZM341.926 203.937H345.164V135.742H341.926ZM400.594 203.937H403.832V78.691H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M108.871 130.48V130.168' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M108.871 130.48V130.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M106.875 130.168H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M108.871 130.48V130.793' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M108.871 130.48V130.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M110.864 130.793H106.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M167.539 133.238V133.238' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M165.547 133.238H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M167.539 133.238V133.238' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M165.547 133.238H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M226.207 141.254V140.75' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M226.207 141.254V140.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M224.215 140.75H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M226.207 141.254V141.754' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M226.207 141.254V141.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M228.2 141.754H224.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M284.875 137.308V136.933' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M284.875 137.308V136.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M282.883 136.934H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M284.875 137.308V137.683' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M284.875 137.308V137.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M286.868 137.683H282.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M343.547 135.742V135.617' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M343.547 135.742V135.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M341.551 135.618H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M343.547 135.742V135.867' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M343.547 135.742V135.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M345.539 135.867H341.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M402.215 78.691V78.691' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M400.223 78.691H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M402.215 78.691V78.691' fill='#8585c2'/>
+<path clip-path='url(#clip1)' d='M400.223 78.691H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M112.481 203.937H115.719V137.871H112.481ZM171.149 203.937H174.387V133.238H171.149ZM229.82 203.937H233.055V141.254H229.82ZM288.488 203.937H291.727V132.797H288.488ZM347.156 203.937H350.395V136.554H347.156ZM405.824 203.937H409.063V103.742H405.824Z' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M112.481 203.937H115.719V137.871H112.481ZM171.149 203.937H174.387V133.238H171.149ZM229.82 203.937H233.055V141.254H229.82ZM288.488 203.937H291.727V132.797H288.488ZM347.156 203.937H350.395V136.554H347.156ZM405.824 203.937H409.063V103.742H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M114.098 137.871V137.683' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M114.098 137.871V137.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M112.105 137.683H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M114.098 137.871V138.058' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M114.098 137.871V138.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M116.094 138.059H112.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M172.77 133.238V133.238' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M170.777 133.238H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M172.77 133.238V133.238' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M170.777 133.238H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M231.438 141.254V141.129' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M231.438 141.254V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M229.445 141.128H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M231.438 141.254V141.379' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M231.438 141.254V141.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M233.43 141.379H229.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M290.106 132.797V132.547' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M290.106 132.797V132.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M288.113 132.547H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M290.106 132.797V133.051' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M290.106 132.797V133.051' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M292.098 133.051H288.113' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M348.777 136.554V134.992' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M348.777 136.554V134.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M346.781 134.992H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M348.777 136.554V138.121' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M348.777 136.554V138.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M350.769 138.122H346.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M407.445 103.742V102.363' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M407.445 103.742V102.363' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M405.453 102.364H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M407.445 103.742V105.121' fill='#6666b3'/>
+<path clip-path='url(#clip1)' d='M407.445 103.742V105.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M409.437 105.121H405.453' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M117.711 203.937H120.949V135.867H117.711ZM176.379 203.937H179.617V134.238H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V132.734H293.719ZM352.387 203.937H355.625V116.203H352.387ZM411.055 203.937H414.293V84.39H411.055Z' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M117.711 203.937H120.949V135.867H117.711ZM176.379 203.937H179.617V134.238H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V132.734H293.719ZM352.387 203.937H355.625V116.203H352.387ZM411.055 203.937H414.293V84.39H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M119.328 135.867V135.554' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M119.328 135.867V135.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M117.336 135.555H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M119.328 135.867V136.179' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M119.328 135.867V136.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M121.325 136.179H117.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M178 134.238V133.238' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M178 134.238V133.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M176.008 133.238H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M178 134.238V135.242' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M178 134.238V135.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M179.993 135.242H176.008' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M236.668 140.941V140.687' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M236.668 140.941V140.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M234.676 140.687H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M236.668 140.941V141.191' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M236.668 140.941V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M238.66 141.191H234.675' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M295.336 132.734V132.609' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M295.336 132.734V132.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M293.344 132.61H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M295.336 132.734V132.859' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M295.336 132.734V132.859' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M297.328 132.859H293.343' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M354.008 116.203V115.39' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M354.008 116.203V115.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M352.012 115.39H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M354.008 116.203V117.015' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M354.008 116.203V117.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M355.999 117.016H352.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M412.676 84.39V83.89' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M412.676 84.39V83.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M410.684 83.891H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M412.676 84.39V84.89' fill='#4747a4'/>
+<path clip-path='url(#clip1)' d='M412.676 84.39V84.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M414.667 84.891H410.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M122.941 203.937H126.18V138.183H122.941ZM181.609 203.937H184.848V133.238H181.609ZM240.281 203.937H243.516V140.312H240.281ZM298.949 203.937H302.188V132.422H298.949ZM357.617 203.937H360.856V135.179H357.617ZM416.285 203.937H419.524V102.675H416.285Z' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M122.941 203.937H126.18V138.183H122.941ZM181.609 203.937H184.848V133.238H181.609ZM240.281 203.937H243.516V140.312H240.281ZM298.949 203.937H302.188V132.422H298.949ZM357.617 203.937H360.856V135.179H357.617ZM416.285 203.937H419.524V102.675H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M124.559 138.183V137.996' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M124.559 138.183V137.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M122.566 137.996H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M124.559 138.183V138.371' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M124.559 138.183V138.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M126.555 138.371H122.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M183.231 133.238V133.238' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M181.238 133.238H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M183.231 133.238V133.238' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M181.238 133.238H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M241.899 140.312V138.871' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M241.899 140.312V138.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M239.906 138.871H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M241.899 140.312V141.754' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M241.899 140.312V141.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M243.891 141.754H239.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M300.567 132.422V132.109' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M300.567 132.422V132.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M298.574 132.11H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M300.567 132.422V132.734' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M300.567 132.422V132.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M302.559 132.734H298.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M359.238 135.179V134.801' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M359.238 135.179V134.801' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M357.242 134.8H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M359.238 135.179V135.554' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M359.238 135.179V135.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M361.23 135.555H357.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M417.906 102.675V102.55' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M417.906 102.675V102.55' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M415.914 102.551H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M417.906 102.675V102.8' fill='#292994'/>
+<path clip-path='url(#clip1)' d='M417.906 102.675V102.8' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M419.898 102.801H415.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M128.172 203.937H131.41V123.969H128.172ZM186.84 203.937H190.078V127.851H186.84ZM245.512 203.937H248.746V141.504H245.512ZM304.18 203.937H307.418V137.746H304.18ZM362.848 203.937H366.086V104.492H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M128.172 203.937H131.41V123.969H128.172ZM186.84 203.937H190.078V127.851H186.84ZM245.512 203.937H248.746V141.504H245.512ZM304.18 203.937H307.418V137.746H304.18ZM362.848 203.937H366.086V104.492H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M129.789 123.969V123.781' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M129.789 123.969V123.781' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M127.797 123.781H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M129.789 123.969V124.156' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M129.789 123.969V124.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M131.785 124.157H127.8' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M188.461 127.851V126.91' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M188.461 127.851V126.91' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M186.469 126.91H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M188.461 127.851V128.789' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M188.461 127.851V128.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M190.453 128.789H186.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M247.129 141.504V141.254' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M247.129 141.504V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M245.137 141.254H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M247.129 141.504V141.754' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M247.129 141.504V141.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M249.121 141.754H245.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M305.797 137.746V137.558' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M305.797 137.746V137.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M303.804 137.559H307.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M305.797 137.746V137.933' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M305.797 137.746V137.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M307.789 137.934H303.804' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M364.469 104.492V103.742' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M364.469 104.492V103.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M362.473 103.742H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M364.469 104.492V105.246' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M364.469 104.492V105.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M366.46 105.246H362.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M423.137 78.691V78.691' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip1)' d='M423.137 78.691V78.691' fill='#0a0a85'/>
+<path clip-path='url(#clip1)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -89.137 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -30.468 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.201 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 86.87 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 145.539 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.208 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.906 247.398)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -25.237 247.774)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.432 249.464)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.101 244.642)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 150.77 245.081)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.439 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-50' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-56' y='183.949'/>
+<use x='126.877' xlink:href='#g1-52' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.676 246.897)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -20.007 245.206)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 38.662 249.464)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.331 246.396)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 156 240.697)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 214.669 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-51' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-49' y='183.949'/>
+<use x='126.877' xlink:href='#g1-52' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -73.445 238.944)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.776 241.699)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 43.893 249.715)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 102.562 245.77)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.231 244.204)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 219.9 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-50' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-48' y='183.949'/>
+<use x='126.877' xlink:href='#g1-55' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -68.215 246.333)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.546 241.699)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.123 249.715)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 107.792 241.261)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.461 245.018)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.13 212.204)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-54' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.984 244.329)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -4.315 242.701)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.354 249.402)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.023 241.198)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 171.692 224.666)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.361 192.853)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.754 246.646)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 0.915 241.699)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.584 248.776)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.253 240.885)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 176.922 243.64)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 235.591 211.139)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-54' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -52.524 232.431)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.145 236.314)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.814 249.965)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 123.483 246.208)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.152 212.955)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.821 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-50' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-49' y='183.949'/>
+<use x='126.877' xlink:href='#g1-49' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -124.589 311.062)'>
+<use x='114.487' xlink:href='#g0-82' y='183.949'/>
+<use x='120.457' xlink:href='#g0-101' y='183.949'/>
+<use x='124.553' xlink:href='#g0-108' y='183.949'/>
+<use x='126.753' xlink:href='#g0-97' y='183.949'/>
+<use x='131.181' xlink:href='#g0-116' y='183.949'/>
+<use x='134.509' xlink:href='#g0-105' y='183.949'/>
+<use x='136.709' xlink:href='#g0-118' y='183.949'/>
+<use x='140.957' xlink:href='#g0-101' y='183.949'/>
+<use x='148.124' xlink:href='#g0-116' y='183.949'/>
+<use x='151.452' xlink:href='#g0-105' y='183.949'/>
+<use x='153.652' xlink:href='#g0-109' y='183.949'/>
+<use x='160.972' xlink:href='#g0-101' y='183.949'/>
+<use x='168.139' xlink:href='#g2-40' y='183.949'/>
+<use x='171.432' xlink:href='#g2-108' y='183.949'/>
+<use x='173.453' xlink:href='#g2-111' y='183.949'/>
+<use x='177.452' xlink:href='#g2-119' y='183.949'/>
+<use x='183' xlink:href='#g2-101' y='183.949'/>
+<use x='186.764' xlink:href='#g2-114' y='183.949'/>
+<use x='192.479' xlink:href='#g2-105' y='183.949'/>
+<use x='194.499' xlink:href='#g2-115' y='183.949'/>
+<use x='200.568' xlink:href='#g2-98' y='183.949'/>
+<use x='205.176' xlink:href='#g2-101' y='183.949'/>
+<use x='208.94' xlink:href='#g2-116' y='183.949'/>
+<use x='211.998' xlink:href='#g2-116' y='183.949'/>
+<use x='215.056' xlink:href='#g2-101' y='183.949'/>
+<use x='218.819' xlink:href='#g2-114' y='183.949'/>
+<use x='221.711' xlink:href='#g2-41' y='183.949'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='165.084pt' version='1.1' viewBox='52.938 54.996 381.624 165.084' width='381.624pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip5'>
+<path d='M82.148 203.937H434.164V78.691H82.148Z'/>
+</clipPath>
+<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/>
+<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/>
+<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/>
+<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/>
+<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/>
+<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/>
+<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/>
+<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/>
+<use id='g3-102' transform='scale(1.143)' xlink:href='#g0-102'/>
+<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/>
+<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/>
+<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/>
+<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/>
+<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/>
+<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/>
+<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/>
+<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/>
+<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/>
+<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/>
+<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/>
+<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/>
+<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/>
+<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/>
+<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/>
+<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/>
+<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/>
+<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/>
+<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/>
+<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/>
+<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/>
+<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/>
+<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/>
+<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/>
+<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/>
+<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/>
+<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/>
+<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/>
+<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/>
+<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/>
+<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/>
+<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/>
+<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/>
+<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/>
+<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/>
+<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/>
+<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/>
+<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/>
+<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/>
+<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/>
+<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/>
+<path d='M1.325 -2.657H2.12V-3.096H1.304V-3.898C1.304 -4.38 1.743 -4.449 1.974 -4.449C2.12 -4.449 2.308 -4.428 2.566 -4.331V-4.84C2.385 -4.882 2.169 -4.91 1.981 -4.91C1.262 -4.91 0.739 -4.394 0.739 -3.703V-3.096H0.202V-2.657H0.739V0H1.325V-2.657Z' id='g0-102'/>
+<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/>
+<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/>
+<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/>
+<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/>
+<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/>
+<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/>
+<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/>
+<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/>
+<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/>
+<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/>
+</defs>
+<g id='page5'>
+<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 34.954)'>
+<use x='114.487' xlink:href='#g3-99' y='183.381'/>
+<use x='118.25' xlink:href='#g3-102' y='183.381'/>
+<use x='120.838' xlink:href='#g3-114' y='183.381'/>
+<use x='123.73' xlink:href='#g3-97' y='183.381'/>
+<use x='127.798' xlink:href='#g3-99' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 45.565 34.954)'>
+<use x='114.487' xlink:href='#g3-108' y='183.381'/>
+<use x='116.507' xlink:href='#g3-101' y='183.381'/>
+<use x='120.271' xlink:href='#g3-97' y='183.381'/>
+<use x='124.339' xlink:href='#g3-110' y='183.381'/>
+<use x='128.711' xlink:href='#g3-78' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 106.188 34.954)'>
+<use x='114.487' xlink:href='#g3-114' y='183.381'/>
+<use x='117.379' xlink:href='#g3-101' y='183.381'/>
+<use x='121.142' xlink:href='#g3-100' y='183.381'/>
+<use x='125.515' xlink:href='#g3-105' y='183.381'/>
+<use x='127.535' xlink:href='#g3-115' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 159.716 34.954)'>
+<use x='114.487' xlink:href='#g3-108' y='183.381'/>
+<use x='116.507' xlink:href='#g3-97' y='183.381'/>
+<use x='120.34' xlink:href='#g3-114' y='183.381'/>
+<use x='123.232' xlink:href='#g3-115' y='183.381'/>
+<use x='126.478' xlink:href='#g3-111' y='183.381'/>
+<use x='130.712' xlink:href='#g3-110' y='183.381'/>
+<use x='135.085' xlink:href='#g3-78' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 215.596 34.954)'>
+<use x='114.487' xlink:href='#g3-109' y='183.381'/>
+<use x='121.211' xlink:href='#g3-115' y='183.381'/>
+<use x='124.458' xlink:href='#g3-116' y='183.381'/>
+<use x='127.516' xlink:href='#g3-114' y='183.381'/>
+<use x='130.408' xlink:href='#g3-101' y='183.381'/>
+<use x='134.171' xlink:href='#g3-115' y='183.381'/>
+<use x='137.418' xlink:href='#g3-115' y='183.381'/>
+<use x='140.664' xlink:href='#g3-78' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 277.158 34.954)'>
+<use x='114.487' xlink:href='#g3-114' y='183.381'/>
+<use x='117.379' xlink:href='#g3-112' y='183.381'/>
+<use x='121.751' xlink:href='#g3-116' y='183.381'/>
+<use x='124.809' xlink:href='#g3-101' y='183.381'/>
+<use x='128.573' xlink:href='#g3-115' y='183.381'/>
+<use x='131.819' xlink:href='#g3-116' y='183.381'/>
+<use x='134.877' xlink:href='#g3-78' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 22.192)'>
+<use x='114.487' xlink:href='#g2-48' y='183.381'/>
+<use x='117.133' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.12)'>
+<use x='114.487' xlink:href='#g2-48' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-53' y='183.381'/>
+<use x='121.25' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.431)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.743)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-53' y='183.381'/>
+<use x='121.25' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.054)'>
+<use x='114.487' xlink:href='#g2-50' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-120' y='183.381'/>
+</g>
+<path clip-path='url(#clip5)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M88.945 203.937H92.18V141.316H88.945ZM147.613 203.937H150.852V141.316H147.613ZM206.281 203.937H209.52V141.316H206.281ZM264.949 203.937H268.188V141.316H264.949ZM323.621 203.937H326.859V141.316H323.621ZM382.289 203.937H385.527V141.316H382.289Z' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M88.945 203.937H92.18V141.316H88.945ZM147.613 203.937H150.852V141.316H147.613ZM206.281 203.937H209.52V141.316H206.281ZM264.949 203.937H268.188V141.316H264.949ZM323.621 203.937H326.859V141.316H323.621ZM382.289 203.937H385.527V141.316H382.289Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M90.563 141.316V141.129' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M90.563 141.316V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M88.57 141.129H92.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M90.563 141.316V141.504' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M90.563 141.316V141.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M92.555 141.504H88.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M149.231 141.316V140.937' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M149.231 141.316V140.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M147.238 140.937H151.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M149.231 141.316V141.691' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M149.231 141.316V141.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M151.223 141.692H147.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M207.902 141.316V139.562' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M207.902 141.316V139.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M205.906 139.563H209.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M207.902 141.316V143.07' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M207.902 141.316V143.07' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M209.895 143.071H205.91' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M266.57 141.316V140.25' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M266.57 141.316V140.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M264.578 140.25H268.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M266.57 141.316V142.379' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M266.57 141.316V142.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M268.562 142.379H264.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M325.238 141.316V139.312' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M325.238 141.316V139.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M323.246 139.312H327.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M325.238 141.316V143.32' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M325.238 141.316V143.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M327.231 143.32H323.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M383.906 141.316V139.875' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M383.906 141.316V139.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M381.914 139.875H385.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M383.906 141.316V142.754' fill='#993333'/>
+<path clip-path='url(#clip5)' d='M383.906 141.316V142.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M385.902 142.753H381.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M94.176 203.937H97.41V140.875H94.176ZM152.844 203.937H156.082V135.617H152.844ZM211.512 203.937H214.75V136.805H211.512ZM270.18 203.937H273.418V78.691H270.18ZM328.852 203.937H332.09V139.625H328.852ZM387.52 203.937H390.758V105.746H387.52Z' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M94.176 203.937H97.41V140.875H94.176ZM152.844 203.937H156.082V135.617H152.844ZM211.512 203.937H214.75V136.805H211.512ZM270.18 203.937H273.418V78.691H270.18ZM328.852 203.937H332.09V139.625H328.852ZM387.52 203.937H390.758V105.746H387.52Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M95.793 140.875V140.625' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M95.793 140.875V140.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M93.801 140.625H97.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M95.793 140.875V141.129' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M95.793 140.875V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M97.785 141.129H93.801' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M154.461 135.617V135.242' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M154.461 135.617V135.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M152.469 135.242H156.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M154.461 135.617V135.992' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M154.461 135.617V135.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M156.453 135.992H152.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M213.133 136.805V135.68' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M213.133 136.805V135.68' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M211.137 135.68H215.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M213.133 136.805V137.934' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M213.133 136.805V137.934' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M215.125 137.934H211.14' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M271.801 78.691V78.691' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M269.809 78.691H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M271.801 78.691V78.691' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M269.809 78.691H273.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M330.469 139.625V139.312' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M330.469 139.625V139.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M328.477 139.312H332.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M330.469 139.625V139.937' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M330.469 139.625V139.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M332.461 139.937H328.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M389.137 105.746V99.609' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M389.137 105.746V99.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M387.145 99.609H391.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M389.137 105.746V111.883' fill='#8080bf'/>
+<path clip-path='url(#clip5)' d='M389.137 105.746V111.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M391.132 111.883H387.144' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M99.406 203.937H102.641V139.437H99.406ZM158.074 203.937H161.313V140.437H158.074ZM216.742 203.937H219.981V132.922H216.742ZM275.41 203.937H278.649V78.691H275.41ZM334.082 203.937H337.32V106.996H334.082ZM392.75 203.937H395.988V78.691H392.75Z' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M99.406 203.937H102.641V139.437H99.406ZM158.074 203.937H161.313V140.437H158.074ZM216.742 203.937H219.981V132.922H216.742ZM275.41 203.937H278.649V78.691H275.41ZM334.082 203.937H337.32V106.996H334.082ZM392.75 203.937H395.988V78.691H392.75Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M101.024 139.437V139.25' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M101.024 139.437V139.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M99.031 139.25H103.016' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M101.024 139.437V139.625' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M101.024 139.437V139.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M103.016 139.625H99.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M159.691 140.437V140.062' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M159.691 140.437V140.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M157.699 140.063H161.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M159.691 140.437V140.812' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M159.691 140.437V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M161.684 140.812H157.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M218.363 132.922V131.547' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M218.363 132.922V131.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M216.367 131.547H220.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M218.363 132.922V134.301' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M218.363 132.922V134.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M220.356 134.3H216.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M277.031 78.691V78.691' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M275.039 78.691H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M277.031 78.691V78.691' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M275.039 78.691H279.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M335.699 106.996V105.621' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M335.699 106.996V105.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M333.707 105.621H337.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M335.699 106.996V108.375' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M335.699 106.996V108.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M337.692 108.375H333.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M394.367 78.691V78.691' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M392.375 78.691H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M394.367 78.691V78.691' fill='#ffb733'/>
+<path clip-path='url(#clip5)' d='M392.375 78.691H396.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M104.637 203.937H107.871V124.344H104.637ZM163.305 203.937H166.543V135.742H163.305ZM221.973 203.937H225.211V105.996H221.973ZM280.641 203.937H283.879V98.168H280.641ZM339.313 203.937H342.551V122.715H339.313ZM397.981 203.937H401.219V120.336H397.981Z' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M104.637 203.937H107.871V124.344H104.637ZM163.305 203.937H166.543V135.742H163.305ZM221.973 203.937H225.211V105.996H221.973ZM280.641 203.937H283.879V98.168H280.641ZM339.313 203.937H342.551V122.715H339.313ZM397.981 203.937H401.219V120.336H397.981Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M106.254 124.344V124.031' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M106.254 124.344V124.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M104.261 124.031H108.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M106.254 124.344V124.656' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M106.254 124.344V124.656' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M108.246 124.656H104.261' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M164.922 135.742V135.555' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M164.922 135.742V135.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M162.929 135.555H166.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M164.922 135.742V135.93' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M164.922 135.742V135.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M166.914 135.93H162.929' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M223.594 105.996V104.805' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M223.594 105.996V104.805' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M221.597 104.805H225.585' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M223.594 105.996V107.187' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M223.594 105.996V107.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M225.586 107.188H221.601' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M282.262 98.168V96.289' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M282.262 98.168V96.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M280.269 96.289H284.253' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M282.262 98.168V100.047' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M282.262 98.168V100.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M284.254 100.047H280.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M340.93 122.715V121.527' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M340.93 122.715V121.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M338.937 121.527H342.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M340.93 122.715V123.906' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M340.93 122.715V123.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M342.922 123.906H338.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M399.598 120.336V114.137' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M399.598 120.336V114.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M397.605 114.137H401.589' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M399.598 120.336V126.535' fill='#bf80bf'/>
+<path clip-path='url(#clip5)' d='M399.598 120.336V126.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M401.593 126.535H397.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M109.867 203.937H113.102V140.687H109.867ZM168.535 203.937H171.774V141.316H168.535ZM227.203 203.937H230.442V140.625H227.203ZM285.871 203.937H289.109V136.555H285.871ZM344.543 203.937H347.781V115.453H344.543ZM403.211 203.937H406.449V135.242H403.211Z' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M109.867 203.937H113.102V140.687H109.867ZM168.535 203.937H171.774V141.316H168.535ZM227.203 203.937H230.442V140.625H227.203ZM285.871 203.937H289.109V136.555H285.871ZM344.543 203.937H347.781V115.453H344.543ZM403.211 203.937H406.449V135.242H403.211Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M111.484 140.687V140.562' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M111.484 140.687V140.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M109.492 140.563H113.477' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M111.484 140.687V140.812' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M111.484 140.687V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M113.477 140.812H109.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M170.152 141.316V140.937' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M170.152 141.316V140.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M168.16 140.937H172.145' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M170.152 141.316V141.691' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M170.152 141.316V141.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M172.145 141.692H168.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M228.824 140.625V139.25' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M228.824 140.625V139.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M226.828 139.25H230.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M228.824 140.625V142.004' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M228.824 140.625V142.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M230.817 142.004H226.832' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M287.492 136.555V134.801' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M287.492 136.555V134.801' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M285.5 134.8H289.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M287.492 136.555V138.309' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M287.492 136.555V138.309' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M289.485 138.308H285.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M346.16 115.453V114.074' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M346.16 115.453V114.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M344.168 114.074H348.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M346.16 115.453V116.828' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M346.16 115.453V116.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M348.153 116.829H344.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M404.828 135.242V128.539' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M404.828 135.242V128.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M402.836 128.539H406.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M404.828 135.242V141.941' fill='#dfbf9f'/>
+<path clip-path='url(#clip5)' d='M404.828 135.242V141.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M406.824 141.941H402.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M115.098 203.937H118.332V136.055H115.098ZM173.766 203.937H177.004V128.539H173.766ZM232.434 203.937H235.672V116.016H232.434ZM291.102 203.937H294.34V78.691H291.102ZM349.774 203.937H353.012V78.691H349.774ZM408.442 203.937H411.68V78.691H408.442Z' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M115.098 203.937H118.332V136.055H115.098ZM173.766 203.937H177.004V128.539H173.766ZM232.434 203.937H235.672V116.016H232.434ZM291.102 203.937H294.34V78.691H291.102ZM349.774 203.937H353.012V78.691H349.774ZM408.442 203.937H411.68V78.691H408.442Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M116.715 136.055V135.93' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M116.715 136.055V135.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M114.722 135.93H118.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M116.715 136.055V136.18' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M116.715 136.055V136.18' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M118.707 136.18H114.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M175.383 128.539V126.723' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M175.383 128.539V126.723' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M173.39 126.723H177.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M175.383 128.539V130.355' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M175.383 128.539V130.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M177.375 130.355H173.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M234.055 116.016V114.449' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M234.055 116.016V114.449' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M232.058 114.449H236.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M234.055 116.016V117.582' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M234.055 116.016V117.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M236.047 117.582H232.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M292.723 78.691V78.691' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M290.73 78.691H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M292.723 78.691V78.691' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M290.73 78.691H294.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M351.391 78.691V78.691' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M349.398 78.691H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M351.391 78.691V78.691' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M349.398 78.691H353.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M410.059 78.691V78.691' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M408.066 78.691H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M410.059 78.691V78.691' fill='#80bf80'/>
+<path clip-path='url(#clip5)' d='M408.066 78.691H412.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M120.328 203.937H123.563V137.621H120.328ZM178.996 203.937H182.234V197.676H178.996ZM237.664 203.937H240.902V136.43H237.664ZM296.332 203.937H299.57V116.953H296.332ZM355.004 203.937H358.238V197.676H355.004ZM413.672 203.937H416.91V78.691H413.672Z' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M120.328 203.937H123.563V137.621H120.328ZM178.996 203.937H182.234V197.676H178.996ZM237.664 203.937H240.902V136.43H237.664ZM296.332 203.937H299.57V116.953H296.332ZM355.004 203.937H358.238V197.676H355.004ZM413.672 203.937H416.91V78.691H413.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M121.945 137.621V137.371' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M121.945 137.621V137.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M119.953 137.371H123.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M121.945 137.621V137.871' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M121.945 137.621V137.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M123.938 137.871H119.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M180.613 197.676V197.676' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M178.621 197.676H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M180.613 197.676V197.676' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M178.621 197.676H182.606' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M239.285 136.43V134.988' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M239.285 136.43V134.988' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M237.289 134.988H241.274' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M239.285 136.43V137.871' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M239.285 136.43V137.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M241.278 137.871H237.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M297.953 116.953V115.391' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M297.953 116.953V115.391' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M295.961 115.39H299.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M297.953 116.953V118.519' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M297.953 116.953V118.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M299.946 118.519H295.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M356.621 197.676V197.676' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M354.629 197.676H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M356.621 197.676V197.676' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M354.629 197.676H358.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M415.289 78.691V78.691' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M413.297 78.691H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M415.289 78.691V78.691' fill='#bfbf80'/>
+<path clip-path='url(#clip5)' d='M413.297 78.691H417.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M125.559 203.937H128.793V138.121H125.559ZM184.227 203.937H187.465V132.047H184.227ZM242.895 203.937H246.133V134.426H242.895ZM301.563 203.937H304.801V78.691H301.563ZM360.234 203.937H363.469V78.691H360.234ZM418.902 203.937H422.141V109.254H418.902Z' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M125.559 203.937H128.793V138.121H125.559ZM184.227 203.937H187.465V132.047H184.227ZM242.895 203.937H246.133V134.426H242.895ZM301.563 203.937H304.801V78.691H301.563ZM360.234 203.937H363.469V78.691H360.234ZM418.902 203.937H422.141V109.254H418.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M127.176 138.121V137.934' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M127.176 138.121V137.934' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M125.183 137.934H129.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M127.176 138.121V138.309' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M127.176 138.121V138.309' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M129.168 138.308H125.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M185.844 132.047V131.672' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M185.844 132.047V131.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M183.851 131.672H187.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M185.844 132.047V132.422' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M185.844 132.047V132.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M187.836 132.422H183.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M244.516 134.426V133.488' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M244.516 134.426V133.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M242.519 133.488H246.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M244.516 134.426V135.367' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M244.516 134.426V135.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M246.508 135.367H242.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M303.184 78.691V78.691' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M301.191 78.691H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M303.184 78.691V78.691' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M301.191 78.691H305.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M361.852 78.691V78.691' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M359.859 78.691H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M361.852 78.691V78.691' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M359.859 78.691H363.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M420.52 109.254V107.25' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M420.52 109.254V107.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M418.527 107.25H422.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M420.52 109.254V111.258' fill='#339999'/>
+<path clip-path='url(#clip5)' d='M420.52 109.254V111.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M422.512 111.258H418.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M130.789 203.937H134.024V139.187H130.789ZM189.457 203.937H192.695V139.312H189.457ZM248.125 203.937H251.363V140.062H248.125ZM306.793 203.937H310.031V126.035H306.793ZM365.465 203.937H368.699V103.176H365.465ZM424.133 203.937H427.371V113.762H424.133Z' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M130.789 203.937H134.024V139.187H130.789ZM189.457 203.937H192.695V139.312H189.457ZM248.125 203.937H251.363V140.062H248.125ZM306.793 203.937H310.031V126.035H306.793ZM365.465 203.937H368.699V103.176H365.465ZM424.133 203.937H427.371V113.762H424.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M132.406 139.187V138.934' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M132.406 139.187V138.934' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M130.414 138.933H134.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M132.406 139.187V139.437' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M132.406 139.187V139.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M134.399 139.437H130.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M191.074 139.312V139.062' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M191.074 139.312V139.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M189.082 139.063H193.067' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M191.074 139.312V139.562' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M191.074 139.312V139.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M193.067 139.563H189.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M249.746 140.062V138.871' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M249.746 140.062V138.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M247.75 138.871H251.735' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M249.746 140.062V141.254' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M249.746 140.062V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M251.739 141.254H247.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M308.414 126.035V125.031' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M308.414 126.035V125.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M306.422 125.031H310.407' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M308.414 126.035V127.035' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M308.414 126.035V127.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M310.407 127.035H306.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M367.082 103.176V101.613' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M367.082 103.176V101.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M365.09 101.613H369.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M367.082 103.176V104.742' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M367.082 103.176V104.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M369.075 104.742H365.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M425.75 113.762V105.184' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M425.75 113.762V105.184' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M423.758 105.184H427.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M425.75 113.762V122.34' fill='#bf8080'/>
+<path clip-path='url(#clip5)' d='M425.75 113.762V122.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M427.743 122.34H423.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -91.184 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -32.515 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.154 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 84.823 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 143.492 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.161 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -85.954 249.339)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -27.284 244.079)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-57' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.385 245.269)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-55' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 90.054 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-52' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-57' y='183.381'/>
+<use x='126.877' xlink:href='#g2-52' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 148.723 248.087)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-51' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 207.392 214.208)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-53' y='183.381'/>
+<use x='121.25' xlink:href='#g2-55' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -80.723 247.899)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-51' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -22.054 248.901)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.615 241.386)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-49' y='183.381'/>
+<use x='121.25' xlink:href='#g2-51' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.284 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-53' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-50' y='183.381'/>
+<use x='126.877' xlink:href='#g2-50' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 153.953 215.46)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-53' y='183.381'/>
+<use x='121.25' xlink:href='#g2-53' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 212.622 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-51' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-55' y='183.381'/>
+<use x='126.877' xlink:href='#g2-56' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -75.493 232.807)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-50' y='183.381'/>
+<use x='121.25' xlink:href='#g2-55' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -16.824 244.204)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-57' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 41.845 214.458)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-53' y='183.381'/>
+<use x='121.25' xlink:href='#g2-54' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.514 206.63)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-54' y='183.381'/>
+<use x='121.25' xlink:href='#g2-57' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 159.183 231.178)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-51' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 217.852 228.799)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-51' y='183.381'/>
+<use x='121.25' xlink:href='#g2-52' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -70.262 249.151)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -11.593 249.777)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 47.076 249.089)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 105.745 245.018)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-56' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 164.414 223.914)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-52' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 223.083 243.703)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-49' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -65.032 244.517)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-56' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -6.363 237.002)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-50' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 52.306 224.478)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-52' y='183.381'/>
+<use x='121.25' xlink:href='#g2-48' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 110.975 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-51' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-48' y='183.381'/>
+<use x='126.877' xlink:href='#g2-50' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 169.644 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-50' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-51' y='183.381'/>
+<use x='126.877' xlink:href='#g2-49' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 228.313 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-52' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-54' y='183.381'/>
+<use x='126.877' xlink:href='#g2-51' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -59.801 246.083)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-54' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -1.66 306.138)'>
+<use x='114.487' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 57.537 244.893)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-56' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 116.206 225.417)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-51' y='183.381'/>
+<use x='121.25' xlink:href='#g2-57' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 174.347 306.138)'>
+<use x='114.487' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 233.544 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-51' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-56' y='183.381'/>
+<use x='126.877' xlink:href='#g2-53' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -54.571 246.584)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-53' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 4.098 240.509)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-49' y='183.381'/>
+<use x='121.25' xlink:href='#g2-53' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 62.767 242.889)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-49' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 121.436 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-51' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-50' y='183.381'/>
+<use x='126.877' xlink:href='#g2-50' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 180.105 187.154)'>
+<use x='109.598' xlink:href='#g4-1' y='183.381'/>
+<use x='113.103' xlink:href='#g4-1' y='183.381'/>
+<use x='116.608' xlink:href='#g4-1' y='183.381'/>
+<use x='120.114' xlink:href='#g2-50' y='183.381'/>
+<use x='122.76' xlink:href='#g2-46' y='183.381'/>
+<use x='124.23' xlink:href='#g2-56' y='183.381'/>
+<use x='126.877' xlink:href='#g2-56' y='183.381'/>
+<use x='129.523' xlink:href='#g2-120' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 238.774 217.714)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-53' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -49.34 247.648)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-51' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 9.329 247.773)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-51' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 67.998 248.525)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-48' y='183.381'/>
+<use x='121.25' xlink:href='#g2-50' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 126.667 234.497)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-50' y='183.381'/>
+<use x='121.25' xlink:href='#g2-52' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 185.336 211.64)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-54' y='183.381'/>
+<use x='121.25' xlink:href='#g2-49' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 244.005 222.223)'>
+<use x='114.487' xlink:href='#g2-49' y='183.381'/>
+<use x='117.133' xlink:href='#g2-46' y='183.381'/>
+<use x='118.603' xlink:href='#g2-52' y='183.381'/>
+<use x='121.25' xlink:href='#g2-52' y='183.381'/>
+</g>
+<g transform='matrix(0 -1 1 0 -124.021 311.062)'>
+<use x='114.487' xlink:href='#g1-82' y='183.381'/>
+<use x='120.457' xlink:href='#g1-101' y='183.381'/>
+<use x='124.553' xlink:href='#g1-108' y='183.381'/>
+<use x='126.753' xlink:href='#g1-97' y='183.381'/>
+<use x='131.181' xlink:href='#g1-116' y='183.381'/>
+<use x='134.509' xlink:href='#g1-105' y='183.381'/>
+<use x='136.709' xlink:href='#g1-118' y='183.381'/>
+<use x='140.957' xlink:href='#g1-101' y='183.381'/>
+<use x='148.124' xlink:href='#g1-116' y='183.381'/>
+<use x='151.452' xlink:href='#g1-105' y='183.381'/>
+<use x='153.652' xlink:href='#g1-109' y='183.381'/>
+<use x='160.972' xlink:href='#g1-101' y='183.381'/>
+<use x='168.139' xlink:href='#g3-40' y='183.381'/>
+<use x='171.432' xlink:href='#g3-108' y='183.381'/>
+<use x='173.453' xlink:href='#g3-111' y='183.381'/>
+<use x='177.452' xlink:href='#g3-119' y='183.381'/>
+<use x='183' xlink:href='#g3-101' y='183.381'/>
+<use x='186.764' xlink:href='#g3-114' y='183.381'/>
+<use x='192.479' xlink:href='#g3-105' y='183.381'/>
+<use x='194.499' xlink:href='#g3-115' y='183.381'/>
+<use x='200.568' xlink:href='#g3-98' y='183.381'/>
+<use x='205.176' xlink:href='#g3-101' y='183.381'/>
+<use x='208.94' xlink:href='#g3-116' y='183.381'/>
+<use x='211.998' xlink:href='#g3-116' y='183.381'/>
+<use x='215.056' xlink:href='#g3-101' y='183.381'/>
+<use x='218.819' xlink:href='#g3-114' y='183.381'/>
+<use x='221.711' xlink:href='#g3-41' y='183.381'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='258.383pt' version='1.1' viewBox='106.736 54.996 381.623 258.383' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip6'>
+<path d='M135.949 251.93H487.961V84.164H135.949Z'/>
+</clipPath>
+<use id='g3-40' transform='scale(1.143)' xlink:href='#g0-40'/>
+<use id='g3-41' transform='scale(1.143)' xlink:href='#g0-41'/>
+<use id='g3-45' transform='scale(1.143)' xlink:href='#g0-45'/>
+<use id='g3-49' transform='scale(1.143)' xlink:href='#g0-49'/>
+<use id='g3-54' transform='scale(1.143)' xlink:href='#g0-54'/>
+<use id='g3-56' transform='scale(1.143)' xlink:href='#g0-56'/>
+<use id='g3-58' transform='scale(1.143)' xlink:href='#g0-58'/>
+<use id='g3-78' transform='scale(1.143)' xlink:href='#g0-78'/>
+<use id='g3-97' transform='scale(1.143)' xlink:href='#g0-97'/>
+<use id='g3-98' transform='scale(1.143)' xlink:href='#g0-98'/>
+<use id='g3-99' transform='scale(1.143)' xlink:href='#g0-99'/>
+<use id='g3-100' transform='scale(1.143)' xlink:href='#g0-100'/>
+<use id='g3-101' transform='scale(1.143)' xlink:href='#g0-101'/>
+<use id='g3-103' transform='scale(1.143)' xlink:href='#g0-103'/>
+<use id='g3-104' transform='scale(1.143)' xlink:href='#g0-104'/>
+<use id='g3-105' transform='scale(1.143)' xlink:href='#g0-105'/>
+<use id='g3-106' transform='scale(1.143)' xlink:href='#g0-106'/>
+<use id='g3-108' transform='scale(1.143)' xlink:href='#g0-108'/>
+<use id='g3-109' transform='scale(1.143)' xlink:href='#g0-109'/>
+<use id='g3-110' transform='scale(1.143)' xlink:href='#g0-110'/>
+<use id='g3-111' transform='scale(1.143)' xlink:href='#g0-111'/>
+<use id='g3-112' transform='scale(1.143)' xlink:href='#g0-112'/>
+<use id='g3-114' transform='scale(1.143)' xlink:href='#g0-114'/>
+<use id='g3-115' transform='scale(1.143)' xlink:href='#g0-115'/>
+<use id='g3-116' transform='scale(1.143)' xlink:href='#g0-116'/>
+<use id='g3-119' transform='scale(1.143)' xlink:href='#g0-119'/>
+<use id='g3-120' transform='scale(1.143)' xlink:href='#g0-120'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g1-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g1-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g1-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g1-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g1-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g1-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g1-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g1-118'/>
+<use id='g2-44' transform='scale(0.714)' xlink:href='#g0-44'/>
+<use id='g2-45' transform='scale(0.714)' xlink:href='#g0-45'/>
+<use id='g2-46' transform='scale(0.714)' xlink:href='#g0-46'/>
+<use id='g2-48' transform='scale(0.714)' xlink:href='#g0-48'/>
+<use id='g2-49' transform='scale(0.714)' xlink:href='#g0-49'/>
+<use id='g2-50' transform='scale(0.714)' xlink:href='#g0-50'/>
+<use id='g2-51' transform='scale(0.714)' xlink:href='#g0-51'/>
+<use id='g2-52' transform='scale(0.714)' xlink:href='#g0-52'/>
+<use id='g2-53' transform='scale(0.714)' xlink:href='#g0-53'/>
+<use id='g2-54' transform='scale(0.714)' xlink:href='#g0-54'/>
+<use id='g2-55' transform='scale(0.714)' xlink:href='#g0-55'/>
+<use id='g2-56' transform='scale(0.714)' xlink:href='#g0-56'/>
+<use id='g2-57' transform='scale(0.714)' xlink:href='#g0-57'/>
+<use id='g2-64' transform='scale(0.714)' xlink:href='#g0-64'/>
+<use id='g2-65' transform='scale(0.714)' xlink:href='#g0-65'/>
+<use id='g2-67' transform='scale(0.714)' xlink:href='#g0-67'/>
+<use id='g2-68' transform='scale(0.714)' xlink:href='#g0-68'/>
+<use id='g2-71' transform='scale(0.714)' xlink:href='#g0-71'/>
+<use id='g2-77' transform='scale(0.714)' xlink:href='#g0-77'/>
+<use id='g2-85' transform='scale(0.714)' xlink:href='#g0-85'/>
+<use id='g2-97' transform='scale(0.714)' xlink:href='#g0-97'/>
+<use id='g2-98' transform='scale(0.714)' xlink:href='#g0-98'/>
+<use id='g2-99' transform='scale(0.714)' xlink:href='#g0-99'/>
+<use id='g2-100' transform='scale(0.714)' xlink:href='#g0-100'/>
+<use id='g2-101' transform='scale(0.714)' xlink:href='#g0-101'/>
+<use id='g2-103' transform='scale(0.714)' xlink:href='#g0-103'/>
+<use id='g2-104' transform='scale(0.714)' xlink:href='#g0-104'/>
+<use id='g2-108' transform='scale(0.714)' xlink:href='#g0-108'/>
+<use id='g2-109' transform='scale(0.714)' xlink:href='#g0-109'/>
+<use id='g2-110' transform='scale(0.714)' xlink:href='#g0-110'/>
+<use id='g2-111' transform='scale(0.714)' xlink:href='#g0-111'/>
+<use id='g2-112' transform='scale(0.714)' xlink:href='#g0-112'/>
+<use id='g2-114' transform='scale(0.714)' xlink:href='#g0-114'/>
+<use id='g2-115' transform='scale(0.714)' xlink:href='#g0-115'/>
+<use id='g2-116' transform='scale(0.714)' xlink:href='#g0-116'/>
+<use id='g2-117' transform='scale(0.714)' xlink:href='#g0-117'/>
+<use id='g2-120' transform='scale(0.714)' xlink:href='#g0-120'/>
+<use id='g2-122' transform='scale(0.714)' xlink:href='#g0-122'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g4-1'/>
+<path d='M2.127 -5.23C2.008 -5.23 1.995 -5.23 1.911 -5.154C1.032 -4.387 0.586 -3.145 0.586 -1.743C0.586 -0.425 0.983 0.844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 0.063C1.276 -0.481 1.193 -1.053 1.193 -1.743C1.193 -4.156 2.322 -5.112 2.462 -5.23H2.127Z' id='g0-40'/>
+<path d='M0.746 1.743C0.865 1.743 0.879 1.743 0.962 1.667C1.841 0.9 2.287 -0.342 2.287 -1.743C2.287 -3.062 1.89 -4.331 0.969 -5.14C0.879 -5.23 0.865 -5.23 0.746 -5.23H0.411C0.432 -5.216 1.109 -4.638 1.43 -3.55C1.597 -3.006 1.681 -2.434 1.681 -1.743C1.681 0.669 0.551 1.625 0.411 1.743H0.746Z' id='g0-41'/>
+<path d='M1.339 -0.007V-0.628H0.711V0H0.907L0.704 0.893H1.018L1.339 -0.007Z' id='g0-44'/>
+<path d='M2.05 -1.332V-1.771H0.084V-1.332H2.05Z' id='g0-45'/>
+<path d='M1.339 -0.628H0.711V0H1.339V-0.628Z' id='g0-46'/>
+<path d='M3.403 -2.267C3.403 -2.601 3.403 -3.417 3.075 -3.989C2.72 -4.617 2.183 -4.721 1.848 -4.721C1.534 -4.721 0.99 -4.624 0.642 -4.024C0.307 -3.466 0.293 -2.706 0.293 -2.267C0.293 -1.75 0.321 -1.116 0.614 -0.586C0.921 -0.021 1.437 0.146 1.848 0.146C2.545 0.146 2.929 -0.258 3.138 -0.697C3.382 -1.193 3.403 -1.834 3.403 -2.267ZM1.848 -0.314C1.555 -0.314 1.22 -0.481 1.046 -0.983C0.907 -1.409 0.9 -1.848 0.9 -2.357C0.9 -2.999 0.9 -4.261 1.848 -4.261S2.797 -2.999 2.797 -2.357C2.797 -1.897 2.797 -1.374 2.629 -0.928C2.434 -0.425 2.078 -0.314 1.848 -0.314Z' id='g0-48'/>
+<path d='M2.239 -4.721H2.085C1.632 -4.303 1.06 -4.275 0.642 -4.261V-3.822C0.914 -3.829 1.262 -3.843 1.611 -3.982V-0.439H0.683V0H3.166V-0.439H2.239V-4.721Z' id='g0-49'/>
+<path d='M1.974 -0.537C1.89 -0.537 1.806 -0.53 1.723 -0.53H0.928L2.008 -1.485C2.134 -1.597 2.476 -1.855 2.608 -1.967C2.915 -2.246 3.327 -2.608 3.327 -3.215C3.327 -4.003 2.741 -4.721 1.743 -4.721C1.004 -4.721 0.544 -4.324 0.307 -3.612L0.635 -3.201C0.795 -3.787 1.039 -4.24 1.646 -4.24C2.232 -4.24 2.678 -3.829 2.678 -3.201C2.678 -2.622 2.336 -2.294 1.918 -1.897C1.778 -1.757 1.402 -1.444 1.255 -1.304C1.053 -1.123 0.572 -0.656 0.37 -0.481V0H3.327V-0.537H1.974Z' id='g0-50'/>
+<path d='M0.697 -3.578C0.983 -4.135 1.485 -4.289 1.82 -4.289C2.232 -4.289 2.538 -4.052 2.538 -3.654C2.538 -3.285 2.287 -2.831 1.757 -2.741C1.723 -2.734 1.695 -2.734 1.234 -2.699V-2.239H1.778C2.441 -2.239 2.685 -1.716 2.685 -1.276C2.685 -0.732 2.35 -0.314 1.806 -0.314C1.311 -0.314 0.746 -0.551 0.398 -0.997L0.307 -0.544C0.711 -0.091 1.276 0.146 1.82 0.146C2.734 0.146 3.389 -0.537 3.389 -1.269C3.389 -1.841 2.929 -2.301 2.378 -2.462C2.908 -2.734 3.18 -3.201 3.18 -3.654C3.18 -4.247 2.573 -4.721 1.827 -4.721C1.213 -4.721 0.704 -4.4 0.411 -3.982L0.697 -3.578Z' id='g0-51'/>
+<path d='M2.762 -1.165H3.487V-1.625H2.762V-4.575H2.071L0.209 -1.625V-1.165H2.162V0H2.762V-1.165ZM0.802 -1.625C1.011 -1.953 2.211 -3.815 2.211 -4.233V-1.625H0.802Z' id='g0-52'/>
+<path d='M1.144 -4.094H3.075V-4.575H0.586V-1.967H1.095C1.262 -2.343 1.59 -2.511 1.904 -2.511C2.19 -2.511 2.622 -2.315 2.622 -1.43C2.622 -0.516 2.043 -0.314 1.688 -0.314C1.227 -0.314 0.781 -0.558 0.544 -0.955L0.279 -0.537C0.621 -0.112 1.137 0.146 1.688 0.146C2.608 0.146 3.327 -0.565 3.327 -1.416C3.327 -2.28 2.685 -2.971 1.918 -2.971C1.618 -2.971 1.353 -2.866 1.144 -2.692V-4.094Z' id='g0-53'/>
+<path d='M3.062 -4.582C2.685 -4.721 2.42 -4.721 2.287 -4.721C1.227 -4.721 0.307 -3.724 0.307 -2.253C0.307 -0.363 1.158 0.146 1.862 0.146C2.427 0.146 2.72 -0.119 2.936 -0.342C3.382 -0.816 3.389 -1.311 3.389 -1.555C3.389 -2.469 2.894 -3.229 2.218 -3.229C1.534 -3.229 1.165 -2.873 0.962 -2.671C1.053 -3.626 1.541 -4.289 2.294 -4.289C2.434 -4.289 2.713 -4.275 3.062 -4.142V-4.582ZM0.969 -1.534C0.969 -1.576 0.969 -1.681 0.976 -1.716C0.976 -2.19 1.276 -2.769 1.897 -2.769C2.748 -2.769 2.748 -1.792 2.748 -1.555C2.748 -1.29 2.748 -0.997 2.559 -0.704C2.392 -0.453 2.183 -0.314 1.862 -0.314C1.123 -0.314 1.004 -1.227 0.969 -1.534Z' id='g0-54'/>
+<path d='M1.723 -4.038C1.806 -4.038 1.89 -4.045 1.974 -4.045H2.852C1.792 -3.006 1.116 -1.548 1.116 0.07H1.771C1.771 -1.967 2.762 -3.431 3.389 -4.087V-4.575H0.307V-4.038H1.723Z' id='g0-55'/>
+<path d='M2.385 -2.469C2.845 -2.615 3.285 -2.985 3.285 -3.501C3.285 -4.135 2.678 -4.721 1.848 -4.721S0.411 -4.135 0.411 -3.501C0.411 -2.978 0.865 -2.608 1.311 -2.469C0.697 -2.28 0.307 -1.806 0.307 -1.269C0.307 -0.523 0.969 0.146 1.848 0.146S3.389 -0.523 3.389 -1.269C3.389 -1.806 2.992 -2.28 2.385 -2.469ZM1.848 -2.699C1.353 -2.699 0.948 -2.985 0.948 -3.494C0.948 -3.94 1.262 -4.289 1.848 -4.289C2.427 -4.289 2.748 -3.94 2.748 -3.494C2.748 -2.999 2.357 -2.699 1.848 -2.699ZM1.848 -0.314C1.367 -0.314 0.941 -0.621 0.941 -1.276C0.941 -1.904 1.346 -2.239 1.848 -2.239S2.755 -1.897 2.755 -1.276C2.755 -0.621 2.322 -0.314 1.848 -0.314Z' id='g0-56'/>
+<path d='M0.537 -0.174C0.879 0.077 1.193 0.146 1.52 0.146C2.497 0.146 3.389 -0.837 3.389 -2.336C3.389 -4.24 2.545 -4.721 1.876 -4.721C1.255 -4.721 0.969 -4.428 0.767 -4.226C0.321 -3.773 0.307 -3.292 0.307 -3.02C0.307 -2.12 0.795 -1.346 1.478 -1.346C2.267 -1.346 2.699 -1.869 2.734 -1.911C2.636 -0.802 2.092 -0.314 1.52 -0.314C1.158 -0.314 0.934 -0.446 0.774 -0.579L0.537 -0.174ZM2.713 -3.027C2.72 -2.985 2.72 -2.915 2.72 -2.873C2.72 -2.357 2.406 -1.806 1.799 -1.806C1.534 -1.806 1.325 -1.883 1.144 -2.169C0.962 -2.441 0.948 -2.706 0.948 -3.02C0.948 -3.292 0.948 -3.605 1.165 -3.912C1.311 -4.122 1.52 -4.289 1.869 -4.289C2.545 -4.289 2.692 -3.473 2.713 -3.027Z' id='g0-57'/>
+<path d='M1.339 -3.096H0.711V-2.469H1.339V-3.096ZM0.711 -0.628V0H1.339V-0.628H0.711Z' id='g0-58'/>
+<path d='M4.142 -0.614C4.038 -0.614 4.024 -0.614 3.968 -0.586C3.626 -0.467 3.271 -0.391 2.901 -0.391C1.778 -0.391 0.976 -1.339 0.976 -2.42C0.976 -3.592 1.883 -4.449 2.859 -4.449C3.055 -4.449 3.515 -4.4 3.745 -3.843C3.55 -3.954 3.333 -4.003 3.152 -4.003C2.406 -4.003 1.778 -3.306 1.778 -2.42C1.778 -1.513 2.427 -0.837 3.145 -0.837C3.689 -0.837 4.519 -1.276 4.519 -2.518C4.519 -3.222 4.47 -4.91 2.866 -4.91C1.541 -4.91 0.411 -3.815 0.411 -2.42C0.411 -1.039 1.527 0.07 2.873 0.07C3.515 0.07 4.115 -0.195 4.519 -0.614H4.142ZM3.152 -1.297C2.72 -1.297 2.343 -1.778 2.343 -2.42C2.343 -3.082 2.734 -3.543 3.145 -3.543C3.578 -3.543 3.954 -3.062 3.954 -2.42C3.954 -1.757 3.564 -1.297 3.152 -1.297Z' id='g0-64'/>
+<path d='M2.803 -4.84H2.127L0.209 0H0.781L1.325 -1.381H3.445L3.989 0H4.721L2.803 -4.84ZM2.392 -4.31L3.271 -1.792H1.499L2.392 -4.31Z' id='g0-65'/>
+<path d='M4.317 -0.851C3.829 -0.551 3.605 -0.418 2.908 -0.418C1.827 -0.418 1.172 -1.43 1.172 -2.434C1.172 -3.466 1.89 -4.435 2.908 -4.435C3.368 -4.435 3.843 -4.289 4.163 -4.045L4.275 -4.679C3.787 -4.861 3.396 -4.917 2.887 -4.917C1.506 -4.917 0.474 -3.773 0.474 -2.427C0.474 -0.99 1.569 0.07 2.929 0.07C3.612 0.07 3.898 -0.07 4.359 -0.321L4.317 -0.851Z' id='g0-67'/>
+<path d='M0.683 -4.84V0H2.664C3.919 0 4.931 -1.06 4.931 -2.378C4.931 -3.745 3.912 -4.84 2.664 -4.84H0.683ZM1.367 -0.411V-4.428H2.476C3.431 -4.428 4.247 -3.668 4.247 -2.385C4.247 -1.088 3.396 -0.411 2.476 -0.411H1.367Z' id='g0-68'/>
+<path d='M4.442 -2.085H2.88V-1.625H3.829V-0.558C3.522 -0.481 3.222 -0.418 2.908 -0.418C1.834 -0.418 1.172 -1.43 1.172 -2.427C1.172 -3.382 1.82 -4.435 2.873 -4.435C3.515 -4.435 3.919 -4.24 4.268 -3.947L4.38 -4.582C3.898 -4.812 3.473 -4.924 2.943 -4.924C1.534 -4.924 0.474 -3.822 0.474 -2.427C0.474 -1.067 1.527 0.07 2.901 0.07C3.403 0.07 3.996 -0.042 4.442 -0.272V-2.085Z' id='g0-71'/>
+<path d='M3.884 -2.42C3.801 -2.211 3.299 -0.983 3.229 -0.69H3.222C3.173 -0.893 2.852 -1.695 2.783 -1.876L1.583 -4.84H0.732V0H1.318V-4.282H1.325C1.381 -4.038 1.743 -3.117 1.778 -3.041L2.943 -0.146H3.494L4.533 -2.713C4.533 -2.72 5.014 -3.905 5.133 -4.289H5.14V0H5.726V-4.84H4.868L3.884 -2.42Z' id='g0-77'/>
+<path d='M1.646 -4.84H0.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-0.551H3.933L1.646 -4.84Z' id='g0-78'/>
+<path d='M4.4 -4.84H3.794V-1.625C3.794 -0.69 3.166 -0.265 2.566 -0.265S1.381 -0.697 1.381 -1.618V-4.84H0.676V-1.632C0.676 -0.607 1.555 0.146 2.559 0.146C3.557 0.146 4.4 -0.614 4.4 -1.632V-4.84Z' id='g0-85'/>
+<path d='M2.971 -2.008C2.971 -2.72 2.427 -3.201 1.736 -3.201C1.297 -3.201 0.962 -3.11 0.572 -2.901L0.614 -2.392C0.844 -2.545 1.186 -2.755 1.736 -2.755C2.043 -2.755 2.364 -2.525 2.364 -2.001V-1.723C1.332 -1.688 0.314 -1.471 0.314 -0.823C0.314 -0.474 0.551 0.07 1.165 0.07C1.465 0.07 2.015 0.007 2.385 -0.265V0H2.971V-2.008ZM2.364 -0.99C2.364 -0.851 2.364 -0.669 2.12 -0.523C1.897 -0.398 1.625 -0.391 1.548 -0.391C1.165 -0.391 0.872 -0.565 0.872 -0.83C0.872 -1.276 2.05 -1.318 2.364 -1.332V-0.99Z' id='g0-97'/>
+<path d='M1.179 -4.84H0.593V0H1.2V-0.328C1.353 -0.195 1.688 0.07 2.197 0.07C2.957 0.07 3.571 -0.642 3.571 -1.555C3.571 -2.399 3.089 -3.166 2.392 -3.166C1.953 -3.166 1.527 -3.027 1.179 -2.769V-4.84ZM1.2 -2.197C1.2 -2.308 1.2 -2.392 1.444 -2.552C1.548 -2.615 1.736 -2.706 1.974 -2.706C2.441 -2.706 2.964 -2.392 2.964 -1.555C2.964 -0.704 2.385 -0.391 1.897 -0.391C1.639 -0.391 1.395 -0.509 1.2 -0.823V-2.197Z' id='g0-98'/>
+<path d='M3.034 -0.76C2.685 -0.537 2.308 -0.411 1.876 -0.411C1.234 -0.411 0.858 -0.928 0.858 -1.555C0.858 -2.092 1.137 -2.72 1.897 -2.72C2.371 -2.72 2.594 -2.622 2.95 -2.399L3.041 -2.901C2.622 -3.11 2.441 -3.201 1.897 -3.201C0.851 -3.201 0.251 -2.357 0.251 -1.548C0.251 -0.697 0.921 0.07 1.869 0.07C2.357 0.07 2.776 -0.077 3.075 -0.251L3.034 -0.76Z' id='g0-99'/>
+<path d='M3.229 -4.84H2.643V-2.797C2.197 -3.124 1.743 -3.166 1.541 -3.166C0.809 -3.166 0.251 -2.434 0.251 -1.548S0.802 0.07 1.52 0.07C1.953 0.07 2.357 -0.126 2.622 -0.363V0H3.229V-4.84ZM2.622 -0.865C2.448 -0.579 2.183 -0.391 1.848 -0.391C1.36 -0.391 0.858 -0.732 0.858 -1.541C0.858 -2.413 1.451 -2.706 1.925 -2.706C2.204 -2.706 2.441 -2.587 2.622 -2.35V-0.865Z' id='g0-100'/>
+<path d='M2.999 -0.76C2.608 -0.481 2.169 -0.391 1.869 -0.391C1.262 -0.391 0.802 -0.886 0.781 -1.527H3.068C3.068 -1.848 3.034 -2.315 2.762 -2.713C2.511 -3.068 2.092 -3.201 1.75 -3.201C0.9 -3.201 0.244 -2.455 0.244 -1.569C0.244 -0.676 0.941 0.07 1.862 0.07C2.267 0.07 2.685 -0.049 3.041 -0.265L2.999 -0.76ZM0.83 -1.946C0.99 -2.504 1.402 -2.741 1.75 -2.741C2.057 -2.741 2.511 -2.594 2.643 -1.946H0.83Z' id='g0-101'/>
+<path d='M3.508 -3.166C3.354 -3.166 2.887 -3.159 2.357 -2.957L2.343 -2.95C2.092 -3.117 1.848 -3.166 1.646 -3.166C0.962 -3.166 0.453 -2.629 0.453 -2.029C0.453 -1.785 0.537 -1.534 0.697 -1.339C0.6 -1.22 0.495 -1.025 0.495 -0.76C0.495 -0.488 0.607 -0.314 0.669 -0.23C0.286 -0.007 0.209 0.314 0.209 0.481C0.209 1.011 0.941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 0.481C3.487 -0.502 2.267 -0.502 1.967 -0.502H1.318C1.206 -0.502 0.907 -0.502 0.907 -0.865C0.907 -1.004 0.955 -1.074 0.962 -1.088C1.206 -0.934 1.451 -0.886 1.639 -0.886C2.322 -0.886 2.831 -1.423 2.831 -2.022C2.831 -2.246 2.769 -2.448 2.643 -2.636C2.615 -2.678 2.615 -2.685 2.615 -2.692C2.615 -2.72 3.034 -2.72 3.068 -2.72C3.075 -2.72 3.34 -2.72 3.592 -2.692L3.508 -3.166ZM1.646 -1.318C1.269 -1.318 0.99 -1.555 0.99 -2.022C0.99 -2.566 1.339 -2.734 1.639 -2.734C2.015 -2.734 2.294 -2.497 2.294 -2.029C2.294 -1.485 1.946 -1.318 1.646 -1.318ZM1.974 0.042C2.134 0.042 2.957 0.042 2.957 0.488C2.957 0.788 2.434 0.997 1.848 0.997S0.739 0.788 0.739 0.488C0.739 0.453 0.739 0.042 1.304 0.042H1.974Z' id='g0-103'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.625 -3.166 1.304 -2.817 1.165 -2.671V-4.84H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-104'/>
+<path d='M1.227 -4.784H0.523V-4.08H1.227V-4.784ZM1.172 -3.096H0.586V0H1.172V-3.096Z' id='g0-105'/>
+<path d='M1.381 -4.784H0.676V-4.08H1.381V-4.784ZM-0.453 1.186C-0.133 1.36 0.181 1.423 0.446 1.423C0.928 1.423 1.381 1.053 1.381 0.411V-3.096H0.795V0.46C0.795 0.586 0.795 0.697 0.649 0.816C0.488 0.934 0.293 0.934 0.23 0.934C-0.063 0.934 -0.244 0.802 -0.328 0.725L-0.453 1.186Z' id='g0-106'/>
+<path d='M1.172 -4.84H0.586V0H1.172V-4.84Z' id='g0-108'/>
+<path d='M5.3 -2.064C5.3 -2.608 5.14 -3.166 4.282 -3.166C3.696 -3.166 3.333 -2.824 3.166 -2.601C3.096 -2.79 2.922 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-1.695C3.243 -2.155 3.438 -2.706 3.975 -2.706C4.693 -2.706 4.693 -2.218 4.693 -2.015V0H5.3V-2.064Z' id='g0-109'/>
+<path d='M3.243 -2.064C3.243 -2.608 3.082 -3.166 2.225 -3.166C1.827 -3.166 1.444 -3.006 1.137 -2.636V-3.145H0.579V0H1.186V-1.695C1.186 -2.155 1.381 -2.706 1.918 -2.706C2.636 -2.706 2.636 -2.218 2.636 -2.015V0H3.243V-2.064Z' id='g0-110'/>
+<path d='M3.487 -1.527C3.487 -2.448 2.755 -3.201 1.848 -3.201S0.209 -2.441 0.209 -1.527C0.209 -0.642 0.948 0.07 1.848 0.07C2.755 0.07 3.487 -0.642 3.487 -1.527ZM1.848 -0.411C1.297 -0.411 0.816 -0.816 0.816 -1.604S1.332 -2.741 1.848 -2.741C2.371 -2.741 2.88 -2.378 2.88 -1.604C2.88 -0.809 2.385 -0.411 1.848 -0.411Z' id='g0-111'/>
+<path d='M1.2 -0.328C1.569 0.007 1.967 0.07 2.204 0.07C2.943 0.07 3.571 -0.635 3.571 -1.555C3.571 -2.392 3.11 -3.166 2.42 -3.166C2.106 -3.166 1.583 -3.075 1.179 -2.762V-3.096H0.593V1.353H1.2V-0.328ZM1.2 -2.315C1.36 -2.511 1.632 -2.685 1.967 -2.685C2.525 -2.685 2.964 -2.169 2.964 -1.555C2.964 -0.865 2.441 -0.391 1.897 -0.391C1.792 -0.391 1.618 -0.404 1.437 -0.551C1.227 -0.711 1.2 -0.816 1.2 -0.948V-2.315Z' id='g0-112'/>
+<path d='M1.179 -1.485C1.179 -2.239 1.806 -2.643 2.42 -2.65V-3.166C1.834 -3.159 1.409 -2.873 1.13 -2.504V-3.145H0.593V0H1.179V-1.485Z' id='g0-114'/>
+<path d='M2.545 -2.985C2.071 -3.18 1.723 -3.201 1.471 -3.201C1.297 -3.201 0.244 -3.201 0.244 -2.273C0.244 -1.946 0.425 -1.764 0.516 -1.681C0.76 -1.437 1.053 -1.381 1.423 -1.311C1.75 -1.248 2.127 -1.179 2.127 -0.844C2.127 -0.404 1.548 -0.404 1.451 -0.404C1.004 -0.404 0.586 -0.565 0.307 -0.76L0.209 -0.237C0.446 -0.119 0.872 0.07 1.451 0.07C1.764 0.07 2.071 0.021 2.329 -0.167C2.587 -0.363 2.671 -0.669 2.671 -0.907C2.671 -1.032 2.657 -1.304 2.364 -1.569C2.106 -1.799 1.855 -1.848 1.52 -1.911C1.109 -1.988 0.788 -2.05 0.788 -2.357C0.788 -2.755 1.297 -2.755 1.402 -2.755C1.799 -2.755 2.106 -2.671 2.455 -2.49L2.545 -2.985Z' id='g0-115'/>
+<path d='M1.311 -2.657H2.343V-3.096H1.311V-3.982H0.774V-3.096H0.139V-2.657H0.753V-0.893C0.753 -0.425 0.872 0.07 1.374 0.07S2.26 -0.091 2.469 -0.188L2.35 -0.635C2.12 -0.467 1.876 -0.411 1.681 -0.411C1.388 -0.411 1.311 -0.697 1.311 -1.018V-2.657Z' id='g0-116'/>
+<path d='M3.243 -3.096H2.636V-1.074C2.636 -0.516 2.162 -0.342 1.757 -0.342C1.241 -0.342 1.186 -0.481 1.186 -0.802V-3.096H0.579V-0.76C0.579 -0.139 0.851 0.07 1.339 0.07C1.625 0.07 2.239 0.014 2.657 -0.321V0H3.243V-3.096Z' id='g0-117'/>
+<path d='M4.951 -3.096H4.407C4.345 -2.901 3.954 -1.723 3.738 -0.997C3.682 -0.795 3.612 -0.572 3.592 -0.411H3.585C3.543 -0.697 3.299 -1.451 3.285 -1.499L2.769 -3.096H2.239C2.036 -2.497 1.513 -0.934 1.458 -0.425H1.451C1.395 -0.921 0.879 -2.462 0.767 -2.797C0.711 -2.964 0.711 -2.978 0.676 -3.096H0.105L1.123 0H1.709C1.716 -0.028 1.904 -0.579 2.148 -1.353C2.253 -1.695 2.462 -2.364 2.497 -2.671L2.504 -2.678C2.518 -2.532 2.559 -2.378 2.608 -2.204S2.706 -1.841 2.755 -1.681L3.292 0H3.933L4.951 -3.096Z' id='g0-119'/>
+<path d='M1.932 -1.597L3.285 -3.096H2.671L1.681 -1.953L0.669 -3.096H0.042L1.437 -1.597L0 0H0.621L1.681 -1.311L2.783 0H3.41L1.932 -1.597Z' id='g0-120'/>
+<path d='M2.957 -2.803V-3.096H0.307V-2.65H1.332C1.416 -2.65 1.499 -2.657 1.583 -2.657H2.127L0.209 -0.307V0H2.978V-0.467H1.897C1.813 -0.467 1.73 -0.46 1.646 -0.46H1.039L2.957 -2.803Z' id='g0-122'/>
+</defs>
+<g id='page6'>
+<path d='M194.617 260.785V251.93M253.285 260.785V251.93M311.953 260.785V251.93M370.625 260.785V251.93M429.293 260.785V251.93M194.617 75.308V84.164M253.285 75.308V84.164M311.953 75.308V84.164M370.625 75.308V84.164M429.293 75.308V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 256.18V251.93M223.953 256.18V251.93M282.621 256.18V251.93M341.289 256.18V251.93M399.957 256.18V251.93M458.629 256.18V251.93M165.281 79.91V84.164M223.953 79.91V84.164M282.621 79.91V84.164M341.289 79.91V84.164M399.957 79.91V84.164M458.629 79.91V84.164' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 251.93H140.199M135.949 218.375H140.199M135.949 184.824H140.199M135.949 151.269H140.199M135.949 117.719H140.199M135.949 84.164H140.199M487.961 251.93H483.711M487.961 218.375H483.711M487.961 184.824H483.711M487.961 151.269H483.711M487.961 117.719H483.711M487.961 84.164H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 251.93V84.164H487.961V251.93H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 74.992)'>
+<use x='168.285' xlink:href='#g3-97' y='191.334'/>
+<use x='172.353' xlink:href='#g3-108' y='191.334'/>
+<use x='174.373' xlink:href='#g3-108' y='191.334'/>
+<use x='176.393' xlink:href='#g3-111' y='191.334'/>
+<use x='180.863' xlink:href='#g3-99' y='191.334'/>
+<use x='184.627' xlink:href='#g3-45' y='191.334'/>
+<use x='187.449' xlink:href='#g3-116' y='191.334'/>
+<use x='190.507' xlink:href='#g3-101' y='191.334'/>
+<use x='194.271' xlink:href='#g3-115' y='191.334'/>
+<use x='197.517' xlink:href='#g3-116' y='191.334'/>
+<use x='200.575' xlink:href='#g3-49' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 74.992)'>
+<use x='168.285' xlink:href='#g3-97' y='191.334'/>
+<use x='172.353' xlink:href='#g3-108' y='191.334'/>
+<use x='174.373' xlink:href='#g3-108' y='191.334'/>
+<use x='176.393' xlink:href='#g3-111' y='191.334'/>
+<use x='180.863' xlink:href='#g3-99' y='191.334'/>
+<use x='184.627' xlink:href='#g3-45' y='191.334'/>
+<use x='187.449' xlink:href='#g3-116' y='191.334'/>
+<use x='190.507' xlink:href='#g3-101' y='191.334'/>
+<use x='194.271' xlink:href='#g3-115' y='191.334'/>
+<use x='197.517' xlink:href='#g3-116' y='191.334'/>
+<use x='200.575' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 74.992)'>
+<use x='168.285' xlink:href='#g3-115' y='191.334'/>
+<use x='171.531' xlink:href='#g3-104' y='191.334'/>
+<use x='175.904' xlink:href='#g3-54' y='191.334'/>
+<use x='180.138' xlink:href='#g3-98' y='191.334'/>
+<use x='184.746' xlink:href='#g3-101' y='191.334'/>
+<use x='188.509' xlink:href='#g3-110' y='191.334'/>
+<use x='192.882' xlink:href='#g3-99' y='191.334'/>
+<use x='196.646' xlink:href='#g3-104' y='191.334'/>
+<use x='201.018' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 74.992)'>
+<use x='168.285' xlink:href='#g3-115' y='191.334'/>
+<use x='171.531' xlink:href='#g3-104' y='191.334'/>
+<use x='175.904' xlink:href='#g3-56' y='191.334'/>
+<use x='180.138' xlink:href='#g3-98' y='191.334'/>
+<use x='184.746' xlink:href='#g3-101' y='191.334'/>
+<use x='188.509' xlink:href='#g3-110' y='191.334'/>
+<use x='192.882' xlink:href='#g3-99' y='191.334'/>
+<use x='196.646' xlink:href='#g3-104' y='191.334'/>
+<use x='201.018' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 74.992)'>
+<use x='168.285' xlink:href='#g3-120' y='191.334'/>
+<use x='172.187' xlink:href='#g3-109' y='191.334'/>
+<use x='178.912' xlink:href='#g3-97' y='191.334'/>
+<use x='182.98' xlink:href='#g3-108' y='191.334'/>
+<use x='185' xlink:href='#g3-108' y='191.334'/>
+<use x='187.02' xlink:href='#g3-111' y='191.334'/>
+<use x='191.49' xlink:href='#g3-99' y='191.334'/>
+<use x='195.254' xlink:href='#g3-45' y='191.334'/>
+<use x='198.076' xlink:href='#g3-116' y='191.334'/>
+<use x='201.134' xlink:href='#g3-101' y='191.334'/>
+<use x='204.898' xlink:href='#g3-115' y='191.334'/>
+<use x='208.144' xlink:href='#g3-116' y='191.334'/>
+<use x='211.202' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 74.992)'>
+<use x='168.285' xlink:href='#g3-99' y='191.334'/>
+<use x='172.049' xlink:href='#g3-97' y='191.334'/>
+<use x='176.117' xlink:href='#g3-99' y='191.334'/>
+<use x='179.88' xlink:href='#g3-104' y='191.334'/>
+<use x='184.253' xlink:href='#g3-101' y='191.334'/>
+<use x='188.017' xlink:href='#g3-45' y='191.334'/>
+<use x='190.839' xlink:href='#g3-115' y='191.334'/>
+<use x='194.086' xlink:href='#g3-99' y='191.334'/>
+<use x='197.849' xlink:href='#g3-114' y='191.334'/>
+<use x='200.741' xlink:href='#g3-97' y='191.334'/>
+<use x='204.81' xlink:href='#g3-116' y='191.334'/>
+<use x='207.868' xlink:href='#g3-99' y='191.334'/>
+<use x='211.631' xlink:href='#g3-104' y='191.334'/>
+<use x='216.004' xlink:href='#g3-78' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 62.23)'>
+<use x='168.285' xlink:href='#g2-48' y='191.334'/>
+<use x='170.931' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.677)'>
+<use x='168.285' xlink:href='#g2-48' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -4.876)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -38.43)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.983)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -105.536)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-120' y='191.334'/>
+</g>
+<path clip-path='url(#clip6)' d='M135.949 184.824H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M142.742 251.93H145.981V184.824H142.742ZM201.41 251.93H204.649V184.824H201.41ZM260.078 251.93H263.317V184.824H260.078ZM318.75 251.93H321.988V184.824H318.75ZM377.418 251.93H380.656V184.824H377.418ZM436.086 251.93H439.324V184.824H436.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M144.359 184.824V184.488' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M144.359 184.824V184.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M142.367 184.489H146.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M144.359 184.824V185.16' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M144.359 184.824V185.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M146.352 185.161H142.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M203.031 184.824V184.488' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M203.031 184.824V184.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M201.039 184.489H205.023' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M203.031 184.824V185.16' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M203.031 184.824V185.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M205.023 185.161H201.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M261.699 184.824V182.742' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M261.699 184.824V182.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M259.707 182.742H263.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M261.699 184.824V186.902' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M261.699 184.824V186.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M263.691 186.902H259.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M320.367 184.824V183.012' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M320.367 184.824V183.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M318.375 183.012H322.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M320.367 184.824V186.637' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M320.367 184.824V186.637' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M322.359 186.637H318.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M379.035 184.824V184.352' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M379.035 184.824V184.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M377.043 184.351H381.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M379.035 184.824V185.293' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M379.035 184.824V185.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M381.027 185.293H377.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M437.707 184.824V183.949' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M437.707 184.824V183.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M435.715 183.95H439.699' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M437.707 184.824V185.695' fill='#993333'/>
+<path clip-path='url(#clip6)' d='M437.707 184.824V185.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M439.699 185.695H435.711' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M147.973 251.93H151.211V184.285H147.973ZM206.641 251.93H209.879V179.926H206.641ZM265.309 251.93H268.547V98.523H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M147.973 251.93H151.211V184.285H147.973ZM206.641 251.93H209.879V179.926H206.641ZM265.309 251.93H268.547V98.523H265.309ZM323.981 251.93H327.219V84.164H323.981ZM382.649 251.93H385.887V84.164H382.649ZM441.317 251.93H444.555V84.164H441.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M149.59 184.285V183.949' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M149.59 184.285V183.949' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M147.598 183.95H151.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M149.59 184.285V184.621' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M149.59 184.285V184.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M151.582 184.621H147.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M208.262 179.926V179.523' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M208.262 179.926V179.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M206.27 179.524H210.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M208.262 179.926V180.328' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M208.262 179.926V180.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M210.253 180.328H206.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M266.93 98.523V94.902' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M266.93 98.523V94.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M264.938 94.902H268.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M266.93 98.523V102.148' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M266.93 98.523V102.148' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M268.921 102.148H264.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M325.598 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M325.598 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M323.606 84.164H327.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M384.266 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M384.266 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M382.274 84.164H386.262' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M442.938 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M442.938 84.164V84.164' fill='#8080bf'/>
+<path clip-path='url(#clip6)' d='M440.946 84.164H444.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M153.203 251.93H156.442V178.715H153.203ZM211.871 251.93H215.11V178.047H211.871ZM270.539 251.93H273.777V85.773H270.539ZM329.211 251.93H332.449V88.996H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M153.203 251.93H156.442V178.715H153.203ZM211.871 251.93H215.11V178.047H211.871ZM270.539 251.93H273.777V85.773H270.539ZM329.211 251.93H332.449V88.996H329.211ZM387.879 251.93H391.117V84.164H387.879ZM446.547 251.93H449.785V84.164H446.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M154.82 178.715V178.047' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M154.82 178.715V178.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M152.828 178.047H156.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M154.82 178.715V179.387' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M154.82 178.715V179.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M156.813 179.386H152.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M213.492 178.047V177.574' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M213.492 178.047V177.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M211.5 177.575H215.484' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M213.492 178.047V178.516' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M213.492 178.047V178.516' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M215.484 178.516H211.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M272.16 85.773V83.558' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M272.16 85.773V83.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M270.168 83.559H274.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M272.16 85.773V87.988' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M272.16 85.773V87.988' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M274.152 87.988H270.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M330.828 88.996V86.715' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M330.828 88.996V86.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M328.836 86.715H332.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M330.828 88.996V91.277' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M330.828 88.996V91.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M332.82 91.277H328.836' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M389.496 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M389.496 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M387.504 84.164H391.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M448.168 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M448.168 84.164V84.164' fill='#ffb733'/>
+<path clip-path='url(#clip6)' d='M446.176 84.164H450.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M158.434 251.93H161.672V155.164H158.434ZM217.102 251.93H220.34V156.305H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V84.164H334.442ZM393.109 251.93H396.348V131.609H393.109ZM451.777 251.93H455.016V183.949H451.777Z' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M158.434 251.93H161.672V155.164H158.434ZM217.102 251.93H220.34V156.305H217.102ZM275.77 251.93H279.008V84.164H275.77ZM334.442 251.93H337.68V84.164H334.442ZM393.109 251.93H396.348V131.609H393.109ZM451.777 251.93H455.016V183.949H451.777Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M160.051 155.164V154.758' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M160.051 155.164V154.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M158.058 154.758H162.046' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M160.051 155.164V155.566' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M160.051 155.164V155.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M162.043 155.567H158.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M218.723 156.305V156.102' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M218.723 156.305V156.102' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M216.73 156.102H220.714' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M218.723 156.305V156.504' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M218.723 156.305V156.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M220.714 156.504H216.726' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M277.391 84.164V84.164' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M277.391 84.164V84.164' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M275.398 84.164H279.382' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M336.059 84.164V84.164' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M334.066 84.164H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M336.059 84.164V84.164' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M334.066 84.164H338.05' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M394.727 131.609V131.406' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M394.727 131.609V131.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M392.734 131.407H396.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M394.727 131.609V131.808' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M394.727 131.609V131.808' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M396.718 131.808H392.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M453.399 183.949V182.809' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M453.399 183.949V182.809' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M451.406 182.809H455.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M453.399 183.949V185.09' fill='#bf80bf'/>
+<path clip-path='url(#clip6)' d='M453.399 183.949V185.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M455.39 185.089H451.402' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M163.664 251.93H166.903V180.664H163.664ZM222.332 251.93H225.57V183.078H222.332ZM281 251.93H284.238V174.355H281ZM339.672 251.93H342.91V183.144H339.672ZM398.34 251.93H401.578V198.914H398.34ZM457.008 251.93H460.246V184.555H457.008Z' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M163.664 251.93H166.903V180.664H163.664ZM222.332 251.93H225.57V183.078H222.332ZM281 251.93H284.238V174.355H281ZM339.672 251.93H342.91V183.144H339.672ZM398.34 251.93H401.578V198.914H398.34ZM457.008 251.93H460.246V184.555H457.008Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M165.281 180.664V180.461' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M165.281 180.664V180.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M163.289 180.461H167.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M165.281 180.664V180.863' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M165.281 180.664V180.863' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M167.274 180.864H163.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M223.953 183.078V182.809' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M223.953 183.078V182.809' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M221.961 182.809H225.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M223.953 183.078V183.348' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M223.953 183.078V183.348' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M225.945 183.348H221.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M282.621 174.355V174.355' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M280.629 174.355H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M282.621 174.355V174.355' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M280.629 174.355H284.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M341.289 183.144V182.473' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M341.289 183.144V182.473' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M339.297 182.472H343.281' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M341.289 183.144V183.816' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M341.289 183.144V183.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M343.281 183.816H339.297' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M399.957 198.914V197.977' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M399.957 198.914V197.977' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M397.965 197.977H401.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M399.957 198.914V199.855' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M399.957 198.914V199.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M401.949 199.856H397.965' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M458.629 184.555V184.555' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M456.637 184.555H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M458.629 184.555V184.555' fill='#dfbf9f'/>
+<path clip-path='url(#clip6)' d='M456.637 184.555H460.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M168.895 251.93H172.133V173.684H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M168.895 251.93H172.133V173.684H168.895ZM227.563 251.93H230.801V84.164H227.563ZM286.231 251.93H289.469V84.164H286.231ZM344.902 251.93H348.141V84.164H344.902ZM403.57 251.93H406.809V84.164H403.57ZM462.238 251.93H465.477V84.164H462.238Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M170.512 173.684V173.348' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M170.512 173.684V173.348' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M168.519 173.348H172.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M170.512 173.684V174.019' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M170.512 173.684V174.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M172.504 174.02H168.519' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M229.184 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M229.184 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M227.191 84.164H231.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M287.852 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M287.852 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M285.859 84.164H289.843' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M346.52 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M346.52 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M344.527 84.164H348.511' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M405.188 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M405.188 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M403.195 84.164H407.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M463.859 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M463.859 84.164V84.164' fill='#80bf80'/>
+<path clip-path='url(#clip6)' d='M461.867 84.164H465.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M174.125 251.93H177.363V147.109H174.125ZM232.793 251.93H236.031V139.93H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V245.219H350.133ZM408.801 251.93H412.039V245.219H408.801ZM467.469 251.93H470.707V183.144H467.469Z' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M174.125 251.93H177.363V147.109H174.125ZM232.793 251.93H236.031V139.93H232.793ZM291.461 251.93H294.699V84.164H291.461ZM350.133 251.93H353.371V245.219H350.133ZM408.801 251.93H412.039V245.219H408.801ZM467.469 251.93H470.707V183.144H467.469Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M175.742 147.109V144.289' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M175.742 147.109V144.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M173.75 144.289H177.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M175.742 147.109V149.93' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M175.742 147.109V149.93' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M177.735 149.93H173.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M234.414 139.93V130.937' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M234.414 139.93V130.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M232.422 130.938H236.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M234.414 139.93V148.922' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M234.414 139.93V148.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M236.403 148.922H232.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M293.082 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M293.082 84.164V84.164' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M291.09 84.164H295.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M351.75 245.219V245.219' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M349.758 245.219H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M351.75 245.219V245.219' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M349.758 245.219H353.742' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M410.418 245.219V245.219' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M408.426 245.219H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M410.418 245.219V245.219' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M408.426 245.219H412.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M469.09 183.144V181.734' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M469.09 183.144V181.734' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M467.098 181.734H471.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M469.09 183.144V184.555' fill='#bfbf80'/>
+<path clip-path='url(#clip6)' d='M469.09 183.144V184.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M471.082 184.555H467.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M179.356 251.93H182.594V169.254H179.356ZM238.024 251.93H241.262V169.387H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M179.356 251.93H182.594V169.254H179.356ZM238.024 251.93H241.262V169.387H238.024ZM296.692 251.93H299.93V84.164H296.692ZM355.363 251.93H358.602V84.164H355.363ZM414.031 251.93H417.27V84.164H414.031ZM472.699 251.93H475.938V84.164H472.699Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M180.973 169.254V168.719' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M180.973 169.254V168.719' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M178.98 168.719H182.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M180.973 169.254V169.793' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M180.973 169.254V169.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M182.965 169.793H178.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M239.645 169.387V169.187' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M239.645 169.387V169.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M237.652 169.187H241.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M239.645 169.387V169.59' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M239.645 169.387V169.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M241.633 169.59H237.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M298.313 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M298.313 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M296.32 84.164H300.304' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M356.981 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M356.981 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M354.988 84.164H358.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M415.649 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M415.649 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M413.656 84.164H417.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M474.32 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M474.32 84.164V84.164' fill='#339999'/>
+<path clip-path='url(#clip6)' d='M472.328 84.164H476.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M184.586 251.93H187.824V180.328H184.586ZM243.254 251.93H246.492V179.59H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V107.516H360.594ZM419.262 251.93H422.5V175.43H419.262ZM477.93 251.93H481.168V182.406H477.93Z' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M184.586 251.93H187.824V180.328H184.586ZM243.254 251.93H246.492V179.59H243.254ZM301.922 251.93H305.16V84.164H301.922ZM360.594 251.93H363.832V107.516H360.594ZM419.262 251.93H422.5V175.43H419.262ZM477.93 251.93H481.168V182.406H477.93Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M186.203 180.328V179.992' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M186.203 180.328V179.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M184.211 179.992H188.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M186.203 180.328V180.664' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M186.203 180.328V180.664' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M188.196 180.664H184.211' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M244.875 179.59V179.187' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M244.875 179.59V179.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M242.883 179.187H246.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M244.875 179.59V179.992' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M244.875 179.59V179.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M246.864 179.992H242.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M303.543 84.164V84.164' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M303.543 84.164V84.164' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M301.551 84.164H305.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M362.211 107.516V104.094' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M362.211 107.516V104.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M360.219 104.093H364.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M362.211 107.516V110.937' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M362.211 107.516V110.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M364.203 110.937H360.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M420.879 175.43V175.16' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M420.879 175.43V175.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M418.887 175.16H422.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M420.879 175.43V175.695' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M420.879 175.43V175.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M422.871 175.696H418.887' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M479.551 182.406V181.199' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M479.551 182.406V181.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M477.559 181.199H481.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M479.551 182.406V183.613' fill='#bf8080'/>
+<path clip-path='url(#clip6)' d='M479.551 182.406V183.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M481.543 183.613H477.555' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M420.539 312.98H487.762V278.973H420.539Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 255.575 118.327)'>
+<use x='168.285' xlink:href='#g2-114' y='167.424'/>
+<use x='170.092' xlink:href='#g2-53' y='167.424'/>
+<use x='172.739' xlink:href='#g2-97' y='167.424'/>
+<use x='175.281' xlink:href='#g2-45' y='167.424'/>
+<use x='177.046' xlink:href='#g2-49' y='167.424'/>
+<use x='179.692' xlink:href='#g2-50' y='167.424'/>
+<use x='182.338' xlink:href='#g2-120' y='167.424'/>
+<use x='184.777' xlink:href='#g2-108' y='167.424'/>
+<use x='186.04' xlink:href='#g2-97' y='167.424'/>
+<use x='188.435' xlink:href='#g2-114' y='167.424'/>
+<use x='190.243' xlink:href='#g2-103' y='167.424'/>
+<use x='192.889' xlink:href='#g2-101' y='167.424'/>
+<use x='195.241' xlink:href='#g2-44' y='167.424'/>
+<use x='198.476' xlink:href='#g2-51' y='167.424'/>
+<use x='201.122' xlink:href='#g2-56' y='167.424'/>
+<use x='203.769' xlink:href='#g2-52' y='167.424'/>
+<use x='206.415' xlink:href='#g2-71' y='167.424'/>
+<use x='209.943' xlink:href='#g2-98' y='167.424'/>
+<use x='168.285' xlink:href='#g2-52' y='173.401'/>
+<use x='170.931' xlink:href='#g2-56' y='173.401'/>
+<use x='175.342' xlink:href='#g2-112' y='173.401'/>
+<use x='177.928' xlink:href='#g2-114' y='173.401'/>
+<use x='179.735' xlink:href='#g2-111' y='173.401'/>
+<use x='182.529' xlink:href='#g2-99' y='173.401'/>
+<use x='186.645' xlink:href='#g2-65' y='173.401'/>
+<use x='190.174' xlink:href='#g2-77' y='173.401'/>
+<use x='194.792' xlink:href='#g2-68' y='173.401'/>
+<use x='200.378' xlink:href='#g2-64' y='173.401'/>
+<use x='203.907' xlink:href='#g2-50' y='173.401'/>
+<use x='206.553' xlink:href='#g2-46' y='173.401'/>
+<use x='208.024' xlink:href='#g2-53' y='173.401'/>
+<use x='210.67' xlink:href='#g2-71' y='173.401'/>
+<use x='214.198' xlink:href='#g2-104' y='173.401'/>
+<use x='216.931' xlink:href='#g2-122' y='173.401'/>
+<use x='168.285' xlink:href='#g2-85' y='179.379'/>
+<use x='171.917' xlink:href='#g2-98' y='179.379'/>
+<use x='174.65' xlink:href='#g2-117' y='179.379'/>
+<use x='177.383' xlink:href='#g2-110' y='179.379'/>
+<use x='180.116' xlink:href='#g2-116' y='179.379'/>
+<use x='182.027' xlink:href='#g2-117' y='179.379'/>
+<use x='186.524' xlink:href='#g2-49' y='179.379'/>
+<use x='189.17' xlink:href='#g2-56' y='179.379'/>
+<use x='191.817' xlink:href='#g2-46' y='179.379'/>
+<use x='193.287' xlink:href='#g2-48' y='179.379'/>
+<use x='195.933' xlink:href='#g2-52' y='179.379'/>
+<use x='198.58' xlink:href='#g2-46' y='179.379'/>
+<use x='200.05' xlink:href='#g2-49' y='179.379'/>
+<use x='202.696' xlink:href='#g2-44' y='179.379'/>
+<use x='205.931' xlink:href='#g2-71' y='179.379'/>
+<use x='209.459' xlink:href='#g2-67' y='179.379'/>
+<use x='212.841' xlink:href='#g2-67' y='179.379'/>
+<use x='217.986' xlink:href='#g2-55' y='179.379'/>
+<use x='220.633' xlink:href='#g2-46' y='179.379'/>
+<use x='222.103' xlink:href='#g2-52' y='179.379'/>
+<use x='224.749' xlink:href='#g2-46' y='179.379'/>
+<use x='226.219' xlink:href='#g2-48' y='179.379'/>
+<use x='168.285' xlink:href='#g2-50' y='185.357'/>
+<use x='170.931' xlink:href='#g2-52' y='185.357'/>
+<use x='175.342' xlink:href='#g2-99' y='185.357'/>
+<use x='177.694' xlink:href='#g2-111' y='185.357'/>
+<use x='180.193' xlink:href='#g2-114' y='185.357'/>
+<use x='182.001' xlink:href='#g2-101' y='185.357'/>
+<use x='184.353' xlink:href='#g2-115' y='185.357'/>
+<use x='188.146' xlink:href='#g2-111' y='185.357'/>
+<use x='190.793' xlink:href='#g2-110' y='185.357'/>
+<use x='195.29' xlink:href='#g2-51' y='185.357'/>
+<use x='199.7' xlink:href='#g2-110' y='185.357'/>
+<use x='202.433' xlink:href='#g2-117' y='185.357'/>
+<use x='205.166' xlink:href='#g2-109' y='185.357'/>
+<use x='209.369' xlink:href='#g2-97' y='185.357'/>
+<use x='213.676' xlink:href='#g2-110' y='185.357'/>
+<use x='216.409' xlink:href='#g2-111' y='185.357'/>
+<use x='219.202' xlink:href='#g2-100' y='185.357'/>
+<use x='221.935' xlink:href='#g2-101' y='185.357'/>
+<use x='224.287' xlink:href='#g2-115' y='185.357'/>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-48' y='191.334'/>
+<use x='173.578' xlink:href='#g2-50' y='191.334'/>
+<use x='176.224' xlink:href='#g2-48' y='191.334'/>
+<use x='178.87' xlink:href='#g2-45' y='191.334'/>
+<use x='180.635' xlink:href='#g2-48' y='191.334'/>
+<use x='183.281' xlink:href='#g2-49' y='191.334'/>
+<use x='185.927' xlink:href='#g2-45' y='191.334'/>
+<use x='187.692' xlink:href='#g2-49' y='191.334'/>
+<use x='190.338' xlink:href='#g2-54' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -45.339 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 13.33 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 71.999 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 130.668 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 189.337 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 248.006 346.904)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -40.108 346.367)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-49' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 18.561 342.005)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-55' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 77.23 260.606)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-50' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.899 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-53' y='191.334'/>
+<use x='176.558' xlink:href='#g2-54' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-54' y='191.334'/>
+<use x='183.321' xlink:href='#g2-52' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.568 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-55' y='191.334'/>
+<use x='179.205' xlink:href='#g2-50' y='191.334'/>
+<use x='181.851' xlink:href='#g2-46' y='191.334'/>
+<use x='183.321' xlink:href='#g2-48' y='191.334'/>
+<use x='185.968' xlink:href='#g2-51' y='191.334'/>
+<use x='188.614' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 253.236 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-55' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-50' y='191.334'/>
+<use x='183.321' xlink:href='#g2-57' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -34.878 340.797)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.791 340.126)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.46 247.855)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-52' y='191.334'/>
+<use x='175.048' xlink:href='#g2-56' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 141.129 251.077)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-52' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.798 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-52' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-55' y='191.334'/>
+<use x='180.675' xlink:href='#g2-55' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 258.467 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-55' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-49' y='191.334'/>
+<use x='183.321' xlink:href='#g2-48' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.648 317.243)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-52' y='191.334'/>
+<use x='175.048' xlink:href='#g2-52' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 29.021 318.384)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-52' y='191.334'/>
+<use x='175.048' xlink:href='#g2-50' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.69 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-52' y='191.334'/>
+<use x='180.675' xlink:href='#g2-56' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.359 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-57' y='191.334'/>
+<use x='180.675' xlink:href='#g2-51' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 205.028 293.689)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-55' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 263.697 346.032)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-49' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.417 342.743)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-54' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 34.252 345.159)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.921 336.435)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-54' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.59 345.226)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-50' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 210.259 360.996)'>
+<use x='168.285' xlink:href='#g2-48' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-55' y='191.334'/>
+<use x='175.048' xlink:href='#g2-57' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 268.928 346.636)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-48' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.187 335.764)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-55' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.482 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-53' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-51' y='191.334'/>
+<use x='180.675' xlink:href='#g2-53' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 98.151 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-51' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-57' y='191.334'/>
+<use x='183.321' xlink:href='#g2-50' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.82 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-53' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-54' y='191.334'/>
+<use x='180.675' xlink:href='#g2-48' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.489 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-55' y='191.334'/>
+<use x='176.558' xlink:href='#g2-49' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-54' y='191.334'/>
+<use x='183.321' xlink:href='#g2-57' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 274.158 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-53' y='191.334'/>
+<use x='180.675' xlink:href='#g2-54' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -13.956 309.19)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-53' y='191.334'/>
+<use x='175.048' xlink:href='#g2-54' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.713 302.01)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-54' y='191.334'/>
+<use x='175.048' xlink:href='#g2-55' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.382 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-51' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-51' y='191.334'/>
+<use x='183.321' xlink:href='#g2-55' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.523 407.299)'>
+<use x='168.285' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.192 407.299)'>
+<use x='168.285' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 279.389 345.226)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -8.726 331.335)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-50' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.943 331.47)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-50' y='191.334'/>
+<use x='175.048' xlink:href='#g2-51' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.612 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-49' y='191.334'/>
+<use x='176.558' xlink:href='#g2-55' y='191.334'/>
+<use x='179.205' xlink:href='#g2-46' y='191.334'/>
+<use x='180.675' xlink:href='#g2-55' y='191.334'/>
+<use x='183.321' xlink:href='#g2-52' y='191.334'/>
+<use x='185.968' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 167.281 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-52' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-57' y='191.334'/>
+<use x='180.675' xlink:href='#g2-57' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.95 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-53' y='191.334'/>
+<use x='180.675' xlink:href='#g2-53' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 284.619 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-53' y='191.334'/>
+<use x='180.675' xlink:href='#g2-57' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.495 342.408)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-55' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 55.174 341.67)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-56' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.843 246.245)'>
+<use x='163.396' xlink:href='#g4-1' y='191.334'/>
+<use x='166.901' xlink:href='#g4-1' y='191.334'/>
+<use x='170.407' xlink:href='#g4-1' y='191.334'/>
+<use x='173.912' xlink:href='#g2-51' y='191.334'/>
+<use x='176.558' xlink:href='#g2-46' y='191.334'/>
+<use x='178.029' xlink:href='#g2-50' y='191.334'/>
+<use x='180.675' xlink:href='#g2-48' y='191.334'/>
+<use x='183.321' xlink:href='#g2-120' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.512 269.598)'>
+<use x='168.285' xlink:href='#g2-50' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-53' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 231.181 337.509)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-49' y='191.334'/>
+<use x='175.048' xlink:href='#g2-52' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 289.85 344.488)'>
+<use x='168.285' xlink:href='#g2-49' y='191.334'/>
+<use x='170.931' xlink:href='#g2-46' y='191.334'/>
+<use x='172.401' xlink:href='#g2-48' y='191.334'/>
+<use x='175.048' xlink:href='#g2-52' y='191.334'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.176 391.591)'>
+<use x='168.285' xlink:href='#g1-82' y='191.334'/>
+<use x='174.255' xlink:href='#g1-101' y='191.334'/>
+<use x='178.351' xlink:href='#g1-108' y='191.334'/>
+<use x='180.551' xlink:href='#g1-97' y='191.334'/>
+<use x='184.979' xlink:href='#g1-116' y='191.334'/>
+<use x='188.307' xlink:href='#g1-105' y='191.334'/>
+<use x='190.507' xlink:href='#g1-118' y='191.334'/>
+<use x='194.755' xlink:href='#g1-101' y='191.334'/>
+<use x='201.922' xlink:href='#g1-116' y='191.334'/>
+<use x='205.25' xlink:href='#g1-105' y='191.334'/>
+<use x='207.45' xlink:href='#g1-109' y='191.334'/>
+<use x='214.77' xlink:href='#g1-101' y='191.334'/>
+<use x='221.937' xlink:href='#g3-40' y='191.334'/>
+<use x='225.231' xlink:href='#g3-108' y='191.334'/>
+<use x='227.251' xlink:href='#g3-111' y='191.334'/>
+<use x='231.25' xlink:href='#g3-119' y='191.334'/>
+<use x='236.799' xlink:href='#g3-101' y='191.334'/>
+<use x='240.562' xlink:href='#g3-114' y='191.334'/>
+<use x='246.277' xlink:href='#g3-105' y='191.334'/>
+<use x='248.297' xlink:href='#g3-115' y='191.334'/>
+<use x='254.366' xlink:href='#g3-98' y='191.334'/>
+<use x='258.974' xlink:href='#g3-101' y='191.334'/>
+<use x='262.738' xlink:href='#g3-116' y='191.334'/>
+<use x='265.796' xlink:href='#g3-116' y='191.334'/>
+<use x='268.854' xlink:href='#g3-101' y='191.334'/>
+<use x='272.618' xlink:href='#g3-114' y='191.334'/>
+<use x='275.51' xlink:href='#g3-41' y='191.334'/>
+</g>
+<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='#ffffff'/>
+<path d='M136.149 312.324H341.363V282.324H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='#993333'/>
+<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -40.354 114.479)'>
+<use x='195.372' xlink:href='#g3-120' y='178.327'/>
+<use x='199.274' xlink:href='#g3-109' y='178.327'/>
+<use x='205.999' xlink:href='#g3-105' y='178.327'/>
+<use x='208.019' xlink:href='#g3-58' y='178.327'/>
+<use x='210.371' xlink:href='#g0-57' y='178.327'/>
+<use x='214.076' xlink:href='#g0-57' y='178.327'/>
+</g>
+<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='#8080bf'/>
+<path d='M184.145 292.816H187.133V284.844H184.145ZM190.121 292.816H193.109V286.836H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.441 114.036)'>
+<use x='239.382' xlink:href='#g3-116' y='178.327'/>
+<use x='242.44' xlink:href='#g3-99' y='178.327'/>
+<use x='246.204' xlink:href='#g3-58' y='178.327'/>
+<use x='248.556' xlink:href='#g0-53' y='178.327'/>
+<use x='252.261' xlink:href='#g0-54' y='178.327'/>
+</g>
+<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='#ffb733'/>
+<path d='M227.356 292.816H230.344V284.844H227.356ZM233.332 292.816H236.32V286.836H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.04 114.479)'>
+<use x='281.863' xlink:href='#g3-106' y='178.327'/>
+<use x='284.119' xlink:href='#g3-101' y='178.327'/>
+<use x='287.882' xlink:href='#g3-58' y='178.327'/>
+<use x='290.235' xlink:href='#g0-53' y='178.327'/>
+<use x='293.94' xlink:href='#g0-50' y='178.327'/>
+</g>
+<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='#bf80bf'/>
+<path d='M269.106 292.816H272.094V284.844H269.106ZM275.086 292.816H278.074V286.836H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.932 114.515)'>
+<use x='321.287' xlink:href='#g3-116' y='178.327'/>
+<use x='324.345' xlink:href='#g3-98' y='178.327'/>
+<use x='328.717' xlink:href='#g3-98' y='178.327'/>
+<use x='333.09' xlink:href='#g3-58' y='178.327'/>
+<use x='335.442' xlink:href='#g0-53' y='178.327'/>
+<use x='339.147' xlink:href='#g0-51' y='178.327'/>
+</g>
+<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='#dfbf9f'/>
+<path d='M306.203 292.816H309.191V284.844H306.203ZM312.18 292.816H315.168V286.836H312.18Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.662 114.036)'>
+<use x='356.019' xlink:href='#g3-114' y='178.327'/>
+<use x='358.911' xlink:href='#g3-112' y='178.327'/>
+<use x='363.284' xlink:href='#g3-58' y='178.327'/>
+<use x='365.636' xlink:href='#g0-56' y='178.327'/>
+<use x='369.341' xlink:href='#g0-54' y='178.327'/>
+</g>
+<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='#80bf80'/>
+<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -43.882 114.515)'>
+<use x='195.372' xlink:href='#g3-104' y='191.334'/>
+<use x='199.744' xlink:href='#g3-111' y='191.334'/>
+<use x='203.978' xlink:href='#g3-97' y='191.334'/>
+<use x='207.811' xlink:href='#g3-114' y='191.334'/>
+<use x='210.703' xlink:href='#g3-100' y='191.334'/>
+<use x='215.076' xlink:href='#g3-58' y='191.334'/>
+<use x='217.428' xlink:href='#g0-51' y='191.334'/>
+<use x='221.133' xlink:href='#g0-51' y='191.334'/>
+</g>
+<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='#bfbf80'/>
+<path d='M184.145 305.82H187.133V297.852H184.145ZM190.121 305.82H193.109V299.844H190.121Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -43.084 114.515)'>
+<use x='239.382' xlink:href='#g3-109' y='191.334'/>
+<use x='246.107' xlink:href='#g3-101' y='191.334'/>
+<use x='249.871' xlink:href='#g3-115' y='191.334'/>
+<use x='253.117' xlink:href='#g3-104' y='191.334'/>
+<use x='257.489' xlink:href='#g3-58' y='191.334'/>
+<use x='259.842' xlink:href='#g0-51' y='191.334'/>
+<use x='263.547' xlink:href='#g0-52' y='191.334'/>
+</g>
+<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='#339999'/>
+<path d='M227.356 305.82H230.344V297.852H227.356ZM233.332 305.82H236.32V299.844H233.332Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -42.353 114.515)'>
+<use x='281.863' xlink:href='#g3-103' y='191.334'/>
+<use x='286.097' xlink:href='#g3-108' y='191.334'/>
+<use x='288.118' xlink:href='#g3-105' y='191.334'/>
+<use x='290.138' xlink:href='#g3-98' y='191.334'/>
+<use x='294.746' xlink:href='#g3-99' y='191.334'/>
+<use x='298.509' xlink:href='#g3-58' y='191.334'/>
+<use x='300.862' xlink:href='#g0-52' y='191.334'/>
+<use x='304.567' xlink:href='#g0-51' y='191.334'/>
+</g>
+<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='#bf8080'/>
+<path d='M269.106 305.82H272.094V297.852H269.106ZM275.086 305.82H278.074V299.844H275.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -40.026 114.479)'>
+<use x='321.287' xlink:href='#g3-115' y='191.334'/>
+<use x='324.533' xlink:href='#g3-109' y='191.334'/>
+<use x='331.258' xlink:href='#g3-105' y='191.334'/>
+<use x='333.278' xlink:href='#g3-58' y='191.334'/>
+<use x='335.63' xlink:href='#g0-54' y='191.334'/>
+<use x='339.335' xlink:href='#g0-57' y='191.334'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='243.704pt' version='1.1' viewBox='106.737 54.995 381.623 243.704' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip2'>
+<path d='M135.949 249.281H487.961V81.515H135.949Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/>
+<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/>
+<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/>
+<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/>
+<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/>
+<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/>
+<path d='M2.002 -3.457H1.519L0.149 0H0.558L0.946 -0.986H2.461L2.849 0H3.372L2.002 -3.457ZM1.709 -3.078L2.336 -1.28H1.071L1.709 -3.078Z' id='g1-65'/>
+<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/>
+<path d='M0.488 -3.457V0H1.903C2.8 0 3.522 -0.757 3.522 -1.699C3.522 -2.675 2.795 -3.457 1.903 -3.457H0.488ZM0.976 -0.294V-3.163H1.768C2.451 -3.163 3.034 -2.62 3.034 -1.704C3.034 -0.777 2.426 -0.294 1.768 -0.294H0.976Z' id='g1-68'/>
+<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/>
+<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/>
+<path d='M2.775 -1.729C2.715 -1.579 2.356 -0.702 2.306 -0.493H2.301C2.267 -0.638 2.037 -1.21 1.988 -1.34L1.131 -3.457H0.523V0H0.941V-3.059H0.946C0.986 -2.884 1.245 -2.227 1.27 -2.172L2.102 -0.105H2.496L3.238 -1.938C3.238 -1.943 3.582 -2.79 3.666 -3.064H3.671V0H4.09V-3.457H3.477L2.775 -1.729Z' id='g1-77'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M2.361 -2.212H1.958C1.554 -1.26 1.275 -0.618 1.255 -0.314C1.245 -0.453 1.156 -0.702 1.066 -0.936C0.986 -1.136 0.907 -1.335 0.817 -1.529L0.503 -2.212H0.075L1.106 0C1.046 0.144 0.946 0.374 0.917 0.438C0.812 0.648 0.742 0.717 0.608 0.717C0.588 0.717 0.403 0.717 0.189 0.628L0.219 0.976C0.264 0.986 0.448 1.016 0.603 1.016C0.802 1.016 0.981 0.941 1.191 0.463L2.361 -2.212Z' id='g1-121'/>
+<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page2'>
+<path d='M194.617 258.136V249.281M253.285 258.136V249.281M311.953 258.136V249.281M370.625 258.136V249.281M429.293 258.136V249.281M194.617 72.66V81.515M253.285 72.66V81.515M311.953 72.66V81.515M370.625 72.66V81.515M429.293 72.66V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.265V81.515M223.953 77.265V81.515M282.621 77.265V81.515M341.289 77.265V81.515M399.957 77.265V81.515M458.629 77.265V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.515H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.515H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 249.281V81.515H487.961V249.281H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 61.588)'>
+<use x='168.285' xlink:href='#g2-97' y='201.694'/>
+<use x='172.353' xlink:href='#g2-108' y='201.694'/>
+<use x='174.373' xlink:href='#g2-108' y='201.694'/>
+<use x='176.393' xlink:href='#g2-111' y='201.694'/>
+<use x='180.863' xlink:href='#g2-99' y='201.694'/>
+<use x='184.627' xlink:href='#g2-45' y='201.694'/>
+<use x='187.449' xlink:href='#g2-116' y='201.694'/>
+<use x='190.507' xlink:href='#g2-101' y='201.694'/>
+<use x='194.271' xlink:href='#g2-115' y='201.694'/>
+<use x='197.517' xlink:href='#g2-116' y='201.694'/>
+<use x='200.575' xlink:href='#g2-49' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 61.588)'>
+<use x='168.285' xlink:href='#g2-97' y='201.694'/>
+<use x='172.353' xlink:href='#g2-108' y='201.694'/>
+<use x='174.373' xlink:href='#g2-108' y='201.694'/>
+<use x='176.393' xlink:href='#g2-111' y='201.694'/>
+<use x='180.863' xlink:href='#g2-99' y='201.694'/>
+<use x='184.627' xlink:href='#g2-45' y='201.694'/>
+<use x='187.449' xlink:href='#g2-116' y='201.694'/>
+<use x='190.507' xlink:href='#g2-101' y='201.694'/>
+<use x='194.271' xlink:href='#g2-115' y='201.694'/>
+<use x='197.517' xlink:href='#g2-116' y='201.694'/>
+<use x='200.575' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 61.588)'>
+<use x='168.285' xlink:href='#g2-115' y='201.694'/>
+<use x='171.531' xlink:href='#g2-104' y='201.694'/>
+<use x='175.904' xlink:href='#g2-54' y='201.694'/>
+<use x='180.138' xlink:href='#g2-98' y='201.694'/>
+<use x='184.746' xlink:href='#g2-101' y='201.694'/>
+<use x='188.509' xlink:href='#g2-110' y='201.694'/>
+<use x='192.882' xlink:href='#g2-99' y='201.694'/>
+<use x='196.646' xlink:href='#g2-104' y='201.694'/>
+<use x='201.018' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 61.588)'>
+<use x='168.285' xlink:href='#g2-115' y='201.694'/>
+<use x='171.531' xlink:href='#g2-104' y='201.694'/>
+<use x='175.904' xlink:href='#g2-56' y='201.694'/>
+<use x='180.138' xlink:href='#g2-98' y='201.694'/>
+<use x='184.746' xlink:href='#g2-101' y='201.694'/>
+<use x='188.509' xlink:href='#g2-110' y='201.694'/>
+<use x='192.882' xlink:href='#g2-99' y='201.694'/>
+<use x='196.646' xlink:href='#g2-104' y='201.694'/>
+<use x='201.018' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 61.588)'>
+<use x='168.285' xlink:href='#g2-120' y='201.694'/>
+<use x='172.187' xlink:href='#g2-109' y='201.694'/>
+<use x='178.912' xlink:href='#g2-97' y='201.694'/>
+<use x='182.98' xlink:href='#g2-108' y='201.694'/>
+<use x='185' xlink:href='#g2-108' y='201.694'/>
+<use x='187.02' xlink:href='#g2-111' y='201.694'/>
+<use x='191.49' xlink:href='#g2-99' y='201.694'/>
+<use x='195.254' xlink:href='#g2-45' y='201.694'/>
+<use x='198.076' xlink:href='#g2-116' y='201.694'/>
+<use x='201.134' xlink:href='#g2-101' y='201.694'/>
+<use x='204.898' xlink:href='#g2-115' y='201.694'/>
+<use x='208.144' xlink:href='#g2-116' y='201.694'/>
+<use x='211.202' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 61.588)'>
+<use x='168.285' xlink:href='#g2-99' y='201.694'/>
+<use x='172.049' xlink:href='#g2-97' y='201.694'/>
+<use x='176.117' xlink:href='#g2-99' y='201.694'/>
+<use x='179.88' xlink:href='#g2-104' y='201.694'/>
+<use x='184.253' xlink:href='#g2-101' y='201.694'/>
+<use x='188.017' xlink:href='#g2-45' y='201.694'/>
+<use x='190.839' xlink:href='#g2-115' y='201.694'/>
+<use x='194.086' xlink:href='#g2-99' y='201.694'/>
+<use x='197.849' xlink:href='#g2-114' y='201.694'/>
+<use x='200.741' xlink:href='#g2-97' y='201.694'/>
+<use x='204.81' xlink:href='#g2-116' y='201.694'/>
+<use x='207.868' xlink:href='#g2-99' y='201.694'/>
+<use x='211.631' xlink:href='#g2-104' y='201.694'/>
+<use x='216.004' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 49.223)'>
+<use x='168.285' xlink:href='#g1-48' y='201.694'/>
+<use x='170.931' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 15.67)'>
+<use x='168.285' xlink:href='#g1-48' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -17.883)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -51.436)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -84.989)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -118.543)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<path clip-path='url(#clip2)' d='M135.949 182.176H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M145.356 249.281H148.594V182.176H145.356ZM204.028 249.281H207.266V182.176H204.028ZM262.695 249.281H265.934V182.176H262.695ZM321.363 249.281H324.602V182.176H321.363ZM380.031 249.281H383.27V182.176H380.031ZM438.703 249.281H441.942V182.176H438.703Z' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M145.356 249.281H148.594V182.176H145.356ZM204.028 249.281H207.266V182.176H204.028ZM262.695 249.281H265.934V182.176H262.695ZM321.363 249.281H324.602V182.176H321.363ZM380.031 249.281H383.27V182.176H380.031ZM438.703 249.281H441.942V182.176H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M146.977 182.176V182.043' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M146.977 182.176V182.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M144.984 182.043H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M146.977 182.176V182.308' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M146.977 182.176V182.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M148.969 182.308H144.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M205.645 182.176V182.043' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M205.645 182.176V182.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M203.652 182.043H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M205.645 182.176V182.308' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M205.645 182.176V182.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M207.636 182.308H203.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M264.313 182.176V180.429' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M264.313 182.176V180.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M262.32 180.429H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M264.313 182.176V183.922' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M264.313 182.176V183.922' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M266.304 183.922H262.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M322.984 182.176V181.504' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M322.984 182.176V181.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M320.992 181.504H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M322.984 182.176V182.847' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M322.984 182.176V182.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M324.976 182.847H320.988' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M381.652 182.176V181.84' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M381.652 182.176V181.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M379.66 181.84H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M381.652 182.176V182.512' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M381.652 182.176V182.512' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M383.644 182.512H379.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M440.32 182.176V181.371' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M440.32 182.176V181.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M438.328 181.371H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M440.32 182.176V182.98' fill='#e0e0f0'/>
+<path clip-path='url(#clip2)' d='M440.32 182.176V182.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M442.312 182.98H438.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M150.586 249.281H153.824V180.765H150.586ZM209.258 249.281H212.496V173.117H209.258ZM267.926 249.281H271.164V158.086H267.926ZM326.594 249.281H329.832V81.515H326.594ZM385.262 249.281H388.5V81.515H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M150.586 249.281H153.824V180.765H150.586ZM209.258 249.281H212.496V173.117H209.258ZM267.926 249.281H271.164V158.086H267.926ZM326.594 249.281H329.832V81.515H326.594ZM385.262 249.281H388.5V81.515H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M152.207 180.765V180.633' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M152.207 180.765V180.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M150.215 180.633H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M152.207 180.765V180.902' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M152.207 180.765V180.902' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M154.2 180.902H150.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M210.875 173.117V172.914' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M210.875 173.117V172.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M208.883 172.915H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M210.875 173.117V173.316' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M210.875 173.117V173.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M212.867 173.316H208.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M269.543 158.086V157.48' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M269.543 158.086V157.48' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M267.551 157.48H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M269.543 158.086V158.687' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M269.543 158.086V158.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M271.535 158.687H267.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M328.215 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M326.223 81.516H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M328.215 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M326.223 81.516H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M386.883 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M384.891 81.516H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M386.883 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M384.891 81.516H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M445.551 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M445.551 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip2)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M155.817 249.281H159.055V175.668H155.817ZM214.488 249.281H217.727V172.648H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V148.152H331.824ZM390.492 249.281H393.731V130.57H390.492ZM449.164 249.281H452.402V81.515H449.164Z' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M155.817 249.281H159.055V175.668H155.817ZM214.488 249.281H217.727V172.648H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V148.152H331.824ZM390.492 249.281H393.731V130.57H390.492ZM449.164 249.281H452.402V81.515H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M157.438 175.668V174.39' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M157.438 175.668V174.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M155.445 174.391H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M157.438 175.668V176.941' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M157.438 175.668V176.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M159.43 176.942H155.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M216.106 172.648V172.648' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M214.113 172.648H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M216.106 172.648V172.648' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M214.113 172.648H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M274.774 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M274.774 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M333.445 148.152V146.945' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M333.445 148.152V146.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M331.453 146.945H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M333.445 148.152V149.359' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M333.445 148.152V149.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M335.437 149.359H331.449' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M392.113 130.57V129.566' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M392.113 130.57V129.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M390.121 129.566H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M392.113 130.57V131.578' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M392.113 130.57V131.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M394.105 131.578H390.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M450.781 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M448.789 81.516H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M450.781 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip2)' d='M448.789 81.516H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M161.047 249.281H164.285V157.949H161.047ZM219.719 249.281H222.957V144.664H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V156.879H337.055ZM395.723 249.281H398.961V162.984H395.723ZM454.395 249.281H457.633V179.426H454.395Z' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M161.047 249.281H164.285V157.949H161.047ZM219.719 249.281H222.957V144.664H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V156.879H337.055ZM395.723 249.281H398.961V162.984H395.723ZM454.395 249.281H457.633V179.426H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M162.668 157.949V157.883' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M162.668 157.949V157.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M160.676 157.883H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M162.668 157.949V158.019' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M162.668 157.949V158.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M164.661 158.02H160.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M221.336 144.664V144.261' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M221.336 144.664V144.261' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M219.344 144.261H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M221.336 144.664V145.066' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M221.336 144.664V145.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M223.329 145.066H219.344' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M280.004 81.515V81.515' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M280.004 81.515V81.515' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M338.676 156.879V156.004' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M338.676 156.879V156.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M336.684 156.004H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M338.676 156.879V157.75' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M338.676 156.879V157.75' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M340.668 157.75H336.68' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M397.344 162.984V162.582' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M397.344 162.984V162.582' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M395.352 162.582H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M397.344 162.984V163.387' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M397.344 162.984V163.387' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M399.336 163.386H395.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M456.012 179.426V178.621' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M456.012 179.426V178.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M454.02 178.622H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M456.012 179.426V180.23' fill='#8585c2'/>
+<path clip-path='url(#clip2)' d='M456.012 179.426V180.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M458.004 180.23H454.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M166.278 249.281H169.516V163.992H166.278ZM224.949 249.281H228.188V159.426H224.949ZM283.617 249.281H286.856V91.047H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M166.278 249.281H169.516V163.992H166.278ZM224.949 249.281H228.188V159.426H224.949ZM283.617 249.281H286.856V91.047H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M167.899 163.992V163.722' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M167.899 163.992V163.722' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M165.906 163.723H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M167.899 163.992V164.258' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M167.899 163.992V164.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M169.891 164.258H165.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M226.567 159.426V159.359' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M226.567 159.426V159.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M224.574 159.359H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M226.567 159.426V159.496' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M226.567 159.426V159.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M228.559 159.496H224.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M285.234 91.047V90.777' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M285.234 91.047V90.777' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M283.242 90.777H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M285.234 91.047V91.316' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M285.234 91.047V91.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M287.227 91.316H283.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M343.906 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M343.906 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M402.574 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M402.574 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M461.242 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M461.242 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip2)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M171.508 249.281H174.746V172.648H171.508ZM230.18 249.281H233.414V132.519H230.18ZM288.848 249.281H292.086V124.867H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M171.508 249.281H174.746V172.648H171.508ZM230.18 249.281H233.414V132.519H230.18ZM288.848 249.281H292.086V124.867H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M173.129 172.648V172.312' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M173.129 172.648V172.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M171.137 172.313H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M173.129 172.648V172.984' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M173.129 172.648V172.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M175.122 172.985H171.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M231.797 132.519V131.847' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M231.797 132.519V131.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M229.805 131.848H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M231.797 132.519V133.187' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M231.797 132.519V133.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M233.79 133.188H229.805' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M290.465 124.867V124.062' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M290.465 124.867V124.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M288.473 124.062H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M290.465 124.867V125.672' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M290.465 124.867V125.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M292.458 125.672H288.473' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M349.137 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M349.137 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M407.805 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M407.805 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M466.473 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M466.473 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip2)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M176.738 249.281H179.977V163.656H176.738ZM235.41 249.281H238.645V159.359H235.41ZM294.078 249.281H297.317V90.578H294.078ZM352.746 249.281H355.984V81.515H352.746ZM411.414 249.281H414.652V81.515H411.414ZM470.086 249.281H473.324V81.515H470.086Z' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M176.738 249.281H179.977V163.656H176.738ZM235.41 249.281H238.645V159.359H235.41ZM294.078 249.281H297.317V90.578H294.078ZM352.746 249.281H355.984V81.515H352.746ZM411.414 249.281H414.652V81.515H411.414ZM470.086 249.281H473.324V81.515H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M178.36 163.656V163.32' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M178.36 163.656V163.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M176.367 163.32H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M178.36 163.656V163.992' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M178.36 163.656V163.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M180.352 163.992H176.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M237.027 159.359V159.359' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M235.035 159.359H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M237.027 159.359V159.359' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M235.035 159.359H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M295.695 90.578V89.234' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M295.695 90.578V89.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M293.703 89.234H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M295.695 90.578V91.918' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M295.695 90.578V91.918' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M297.688 91.918H293.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M354.367 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M352.375 81.516H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M354.367 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M352.375 81.516H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M413.035 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M411.043 81.516H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M413.035 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M411.043 81.516H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M471.703 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M469.711 81.516H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M471.703 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip2)' d='M469.711 81.516H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M416.645 249.281H419.883V131.445H416.645ZM181.969 249.281H185.207V153.523H181.969ZM240.641 249.281H243.875V149.226H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V129.297H357.977ZM475.317 249.281H478.555V179.894H475.317Z' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M416.645 249.281H419.883V131.445H416.645ZM181.969 249.281H185.207V153.523H181.969ZM240.641 249.281H243.875V149.226H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V129.297H357.977ZM475.317 249.281H478.555V179.894H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M418.266 131.445V128.894' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M418.266 131.445V128.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M416.274 128.895H420.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M418.266 131.445V133.992' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M418.266 131.445V133.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M420.257 133.992H416.273' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M183.59 153.523V152.851' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M183.59 153.523V152.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M181.598 152.852H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M183.59 153.523V154.191' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M183.59 153.523V154.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M185.582 154.191H181.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M242.258 149.226V149.16' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M242.258 149.226V149.16' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M240.266 149.16H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M242.258 149.226V149.293' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M242.258 149.226V149.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M244.25 149.293H240.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M300.926 81.515V81.515' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M300.926 81.515V81.515' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M359.598 129.297V128.426' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M359.598 129.297V128.426' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M357.606 128.426H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M359.598 129.297V130.168' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M359.598 129.297V130.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M361.589 130.168H357.601' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M476.934 179.894V179.894' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M474.942 179.895H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M476.934 179.894V179.894' fill='#0a0a85'/>
+<path clip-path='url(#clip2)' d='M474.942 179.895H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip2)' d='M418.387 298.301H487.762V276.324H418.387Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 253.422 92.648)'>
+<use x='168.285' xlink:href='#g1-114' y='190.457'/>
+<use x='170.092' xlink:href='#g1-53' y='190.457'/>
+<use x='172.739' xlink:href='#g1-97' y='190.457'/>
+<use x='175.281' xlink:href='#g1-45' y='190.457'/>
+<use x='177.046' xlink:href='#g1-52' y='190.457'/>
+<use x='179.692' xlink:href='#g1-120' y='190.457'/>
+<use x='182.131' xlink:href='#g1-108' y='190.457'/>
+<use x='183.393' xlink:href='#g1-97' y='190.457'/>
+<use x='185.789' xlink:href='#g1-114' y='190.457'/>
+<use x='187.596' xlink:href='#g1-103' y='190.457'/>
+<use x='190.243' xlink:href='#g1-101' y='190.457'/>
+<use x='192.595' xlink:href='#g1-44' y='190.457'/>
+<use x='195.83' xlink:href='#g1-49' y='190.457'/>
+<use x='198.476' xlink:href='#g1-50' y='190.457'/>
+<use x='201.122' xlink:href='#g1-56' y='190.457'/>
+<use x='203.769' xlink:href='#g1-71' y='190.457'/>
+<use x='207.297' xlink:href='#g1-98' y='190.457'/>
+<use x='168.285' xlink:href='#g1-49' y='196.075'/>
+<use x='170.931' xlink:href='#g1-54' y='196.075'/>
+<use x='173.578' xlink:href='#g1-45' y='196.075'/>
+<use x='175.342' xlink:href='#g1-99' y='196.075'/>
+<use x='177.694' xlink:href='#g1-111' y='196.075'/>
+<use x='180.193' xlink:href='#g1-114' y='196.075'/>
+<use x='182.001' xlink:href='#g1-101' y='196.075'/>
+<use x='186.118' xlink:href='#g1-65' y='196.075'/>
+<use x='189.646' xlink:href='#g1-77' y='196.075'/>
+<use x='194.264' xlink:href='#g1-68' y='196.075'/>
+<use x='199.851' xlink:href='#g1-69' y='196.075'/>
+<use x='203.025' xlink:href='#g1-112' y='196.075'/>
+<use x='205.611' xlink:href='#g1-121' y='196.075'/>
+<use x='208.049' xlink:href='#g1-99' y='196.075'/>
+<use x='212.166' xlink:href='#g1-64' y='196.075'/>
+<use x='215.695' xlink:href='#g1-50' y='196.075'/>
+<use x='218.341' xlink:href='#g1-46' y='196.075'/>
+<use x='219.811' xlink:href='#g1-53' y='196.075'/>
+<use x='222.457' xlink:href='#g1-71' y='196.075'/>
+<use x='225.986' xlink:href='#g1-104' y='196.075'/>
+<use x='228.719' xlink:href='#g1-122' y='196.075'/>
+<use x='168.285' xlink:href='#g1-85' y='201.694'/>
+<use x='171.917' xlink:href='#g1-98' y='201.694'/>
+<use x='174.65' xlink:href='#g1-117' y='201.694'/>
+<use x='177.383' xlink:href='#g1-110' y='201.694'/>
+<use x='180.116' xlink:href='#g1-116' y='201.694'/>
+<use x='182.027' xlink:href='#g1-117' y='201.694'/>
+<use x='186.524' xlink:href='#g1-49' y='201.694'/>
+<use x='189.17' xlink:href='#g1-56' y='201.694'/>
+<use x='191.817' xlink:href='#g1-46' y='201.694'/>
+<use x='193.287' xlink:href='#g1-48' y='201.694'/>
+<use x='195.933' xlink:href='#g1-52' y='201.694'/>
+<use x='198.58' xlink:href='#g1-46' y='201.694'/>
+<use x='200.05' xlink:href='#g1-49' y='201.694'/>
+<use x='202.696' xlink:href='#g1-44' y='201.694'/>
+<use x='205.931' xlink:href='#g1-71' y='201.694'/>
+<use x='209.459' xlink:href='#g1-67' y='201.694'/>
+<use x='212.841' xlink:href='#g1-67' y='201.694'/>
+<use x='217.986' xlink:href='#g1-55' y='201.694'/>
+<use x='220.633' xlink:href='#g1-46' y='201.694'/>
+<use x='222.103' xlink:href='#g1-51' y='201.694'/>
+<use x='224.749' xlink:href='#g1-46' y='201.694'/>
+<use x='226.219' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -53.084 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 5.585 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.254 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 122.923 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 181.592 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.261 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -47.853 342.848)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-50' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 10.816 335.198)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-49' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 69.485 320.166)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 128.154 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-56' y='201.694'/>
+<use x='180.675' xlink:href='#g1-50' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 186.823 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-56' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-50' y='201.694'/>
+<use x='180.675' xlink:href='#g1-50' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 245.492 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-57' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-50' y='201.694'/>
+<use x='183.321' xlink:href='#g1-51' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -42.623 337.748)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-49' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 16.046 334.728)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-49' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 74.715 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-56' y='201.694'/>
+<use x='180.675' xlink:href='#g1-51' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 133.384 310.234)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 192.053 292.653)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-55' y='201.694'/>
+<use x='175.048' xlink:href='#g1-55' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 250.722 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-56' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-48' y='201.694'/>
+<use x='183.321' xlink:href='#g1-57' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -37.392 320.032)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.277 306.745)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 79.946 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-55' y='201.694'/>
+<use x='180.675' xlink:href='#g1-52' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 138.615 318.958)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-56' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 197.284 325.065)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-57' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 255.953 341.506)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -32.162 326.071)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-55' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.507 321.508)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.176 253.127)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 143.845 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-57' y='201.694'/>
+<use x='180.675' xlink:href='#g1-52' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.514 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-50' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-53' y='201.694'/>
+<use x='183.321' xlink:href='#g1-50' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 261.183 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-52' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-50' y='201.694'/>
+<use x='180.675' xlink:href='#g1-49' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -26.931 334.728)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-49' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.738 294.599)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-55' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 90.407 286.949)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-56' y='201.694'/>
+<use x='175.048' xlink:href='#g1-53' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 149.076 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-52' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-55' y='201.694'/>
+<use x='180.675' xlink:href='#g1-51' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 207.745 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-51' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-56' y='201.694'/>
+<use x='183.321' xlink:href='#g1-53' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 266.414 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-57' y='201.694'/>
+<use x='180.675' xlink:href='#g1-53' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -21.701 325.736)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-56' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.968 321.441)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.637 252.657)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-55' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 154.306 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-57' y='201.694'/>
+<use x='180.675' xlink:href='#g1-55' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 212.975 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-49' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-55' y='201.694'/>
+<use x='183.321' xlink:href='#g1-56' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 271.644 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-52' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-49' y='201.694'/>
+<use x='180.675' xlink:href='#g1-56' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 218.205 293.525)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-55' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -16.471 315.603)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-51' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 42.198 311.308)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-57' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.867 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-52' y='201.694'/>
+<use x='180.675' xlink:href='#g1-56' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 159.536 291.377)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-55' y='201.694'/>
+<use x='175.048' xlink:href='#g1-57' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 276.874 341.975)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-51' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -88.536 388.944)'>
+<use x='168.285' xlink:href='#g0-82' y='201.694'/>
+<use x='174.255' xlink:href='#g0-101' y='201.694'/>
+<use x='178.351' xlink:href='#g0-108' y='201.694'/>
+<use x='180.551' xlink:href='#g0-97' y='201.694'/>
+<use x='184.979' xlink:href='#g0-116' y='201.694'/>
+<use x='188.307' xlink:href='#g0-105' y='201.694'/>
+<use x='190.507' xlink:href='#g0-118' y='201.694'/>
+<use x='194.755' xlink:href='#g0-101' y='201.694'/>
+<use x='201.922' xlink:href='#g0-116' y='201.694'/>
+<use x='205.25' xlink:href='#g0-105' y='201.694'/>
+<use x='207.45' xlink:href='#g0-109' y='201.694'/>
+<use x='214.77' xlink:href='#g0-101' y='201.694'/>
+<use x='221.937' xlink:href='#g2-40' y='201.694'/>
+<use x='225.231' xlink:href='#g2-108' y='201.694'/>
+<use x='227.251' xlink:href='#g2-111' y='201.694'/>
+<use x='231.25' xlink:href='#g2-119' y='201.694'/>
+<use x='236.799' xlink:href='#g2-101' y='201.694'/>
+<use x='240.562' xlink:href='#g2-114' y='201.694'/>
+<use x='246.277' xlink:href='#g2-105' y='201.694'/>
+<use x='248.297' xlink:href='#g2-115' y='201.694'/>
+<use x='254.366' xlink:href='#g2-98' y='201.694'/>
+<use x='258.974' xlink:href='#g2-101' y='201.694'/>
+<use x='262.738' xlink:href='#g2-116' y='201.694'/>
+<use x='265.796' xlink:href='#g2-116' y='201.694'/>
+<use x='268.854' xlink:href='#g2-101' y='201.694'/>
+<use x='272.618' xlink:href='#g2-114' y='201.694'/>
+<use x='275.51' xlink:href='#g2-41' y='201.694'/>
+</g>
+<path d='M136.149 296.672H349.488V279.679H136.149Z' fill='#ffffff'/>
+<path d='M136.149 296.672H349.488V279.679H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#e0e0f0'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -33.522 88.465)'>
+<use x='185.011' xlink:href='#g2-109' y='201.694'/>
+<use x='191.736' xlink:href='#g2-105' y='201.694'/>
+</g>
+<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='#c2c2e1'/>
+<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.56 88.011)'>
+<use x='208.137' xlink:href='#g2-116' y='201.694'/>
+<use x='211.195' xlink:href='#g2-99' y='201.694'/>
+</g>
+<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='#a3a3d1'/>
+<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.159 88.465)'>
+<use x='229.9' xlink:href='#g2-106' y='201.694'/>
+<use x='232.155' xlink:href='#g2-101' y='201.694'/>
+</g>
+<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='#8585c2'/>
+<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.958 87.505)'>
+<use x='252.061' xlink:href='#g2-115' y='201.694'/>
+<use x='255.307' xlink:href='#g2-110' y='201.694'/>
+</g>
+<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='#6666b3'/>
+<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.781 87.505)'>
+<use x='274.845' xlink:href='#g2-114' y='201.694'/>
+<use x='277.737' xlink:href='#g2-112' y='201.694'/>
+</g>
+<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='#4747a4'/>
+<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.001 88.501)'>
+<use x='303.672' xlink:href='#g2-104' y='201.694'/>
+<use x='308.045' xlink:href='#g2-111' y='201.694'/>
+<use x='312.279' xlink:href='#g2-97' y='201.694'/>
+<use x='316.112' xlink:href='#g2-114' y='201.694'/>
+<use x='319.004' xlink:href='#g2-100' y='201.694'/>
+</g>
+<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='#292994'/>
+<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.472 88.501)'>
+<use x='337.19' xlink:href='#g2-103' y='201.694'/>
+<use x='341.424' xlink:href='#g2-108' y='201.694'/>
+<use x='343.444' xlink:href='#g2-105' y='201.694'/>
+<use x='345.464' xlink:href='#g2-98' y='201.694'/>
+<use x='350.072' xlink:href='#g2-99' y='201.694'/>
+</g>
+<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='#0a0a85'/>
+<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.051 88.501)'>
+<use x='366.757' xlink:href='#g2-116' y='201.694'/>
+<use x='369.815' xlink:href='#g2-98' y='201.694'/>
+<use x='374.187' xlink:href='#g2-98' y='201.694'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip7'>
+<path d='M82.148 203.937H434.164V78.691H82.148Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page7'>
+<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 33.989)'>
+<use x='114.487' xlink:href='#g2-99' y='183.949'/>
+<use x='118.25' xlink:href='#g2-102' y='183.949'/>
+<use x='120.838' xlink:href='#g2-114' y='183.949'/>
+<use x='123.73' xlink:href='#g2-97' y='183.949'/>
+<use x='127.798' xlink:href='#g2-99' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 41.401 33.989)'>
+<use x='114.487' xlink:href='#g2-101' y='183.949'/>
+<use x='118.25' xlink:href='#g2-115' y='183.949'/>
+<use x='121.497' xlink:href='#g2-112' y='183.949'/>
+<use x='125.634' xlink:href='#g2-114' y='183.949'/>
+<use x='128.526' xlink:href='#g2-101' y='183.949'/>
+<use x='132.29' xlink:href='#g2-115' y='183.949'/>
+<use x='135.536' xlink:href='#g2-115' y='183.949'/>
+<use x='138.782' xlink:href='#g2-111' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 103.095 33.989)'>
+<use x='114.487' xlink:href='#g2-98' y='183.949'/>
+<use x='118.859' xlink:href='#g2-97' y='183.949'/>
+<use x='122.692' xlink:href='#g2-114' y='183.949'/>
+<use x='125.584' xlink:href='#g2-110' y='183.949'/>
+<use x='129.957' xlink:href='#g2-101' y='183.949'/>
+<use x='133.72' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 162.903 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-101' y='183.949'/>
+<use x='120.271' xlink:href='#g2-97' y='183.949'/>
+<use x='124.339' xlink:href='#g2-110' y='183.949'/>
+<use x='128.711' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 223.526 33.989)'>
+<use x='114.487' xlink:href='#g2-114' y='183.949'/>
+<use x='117.379' xlink:href='#g2-101' y='183.949'/>
+<use x='121.142' xlink:href='#g2-100' y='183.949'/>
+<use x='125.515' xlink:href='#g2-105' y='183.949'/>
+<use x='127.535' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 277.054 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-97' y='183.949'/>
+<use x='120.34' xlink:href='#g2-114' y='183.949'/>
+<use x='123.232' xlink:href='#g2-115' y='183.949'/>
+<use x='126.478' xlink:href='#g2-111' y='183.949'/>
+<use x='130.712' xlink:href='#g2-110' y='183.949'/>
+<use x='135.085' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 21.624)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.688)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.999)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -72.311)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.622)'>
+<use x='114.487' xlink:href='#g1-50' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<path clip-path='url(#clip7)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M91.559 203.937H94.797V141.316H91.559ZM150.227 203.937H153.465V141.316H150.227ZM208.899 203.937H212.133V141.316H208.899ZM267.567 203.937H270.805V141.316H267.567ZM326.234 203.937H329.473V141.316H326.234ZM384.902 203.937H388.141V141.316H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M93.18 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M91.184 141.316H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M93.18 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M91.184 141.316H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M151.848 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M151.848 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M149.855 141.316H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M210.516 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M208.523 141.316H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M210.516 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M208.523 141.316H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M269.184 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M267.191 141.316H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M269.184 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M267.191 141.316H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M327.856 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M325.859 141.316H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M327.856 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M325.859 141.316H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M386.524 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M384.531 141.316H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M386.524 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip7)' d='M384.531 141.316H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M96.789 203.937H100.027V94.222H96.789ZM155.457 203.937H158.695V78.691H155.457ZM214.129 203.937H217.363V138.246H214.129ZM272.797 203.937H276.035V154.652H272.797ZM331.465 203.937H334.703V129.793H331.465ZM390.133 203.937H393.371V138.808H390.133Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M96.789 203.937H100.027V94.222H96.789ZM155.457 203.937H158.695V78.691H155.457ZM214.129 203.937H217.363V138.246H214.129ZM272.797 203.937H276.035V154.652H272.797ZM331.465 203.937H334.703V129.793H331.465ZM390.133 203.937H393.371V138.808H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M98.41 94.222V94.222' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M96.414 94.223H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M98.41 94.222V94.222' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M96.414 94.223H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M157.078 78.691V78.691' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M155.086 78.691H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M157.078 78.691V78.691' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M155.086 78.691H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M215.746 138.246V138.246' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M213.754 138.246H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M215.746 138.246V138.246' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M213.754 138.246H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M274.414 154.652V154.652' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M272.422 154.652H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M274.414 154.652V154.652' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M272.422 154.652H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M333.086 129.793V129.793' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M331.09 129.793H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M333.086 129.793V129.793' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M331.09 129.793H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M391.754 138.808V138.808' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M389.762 138.808H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M391.754 138.808V138.808' fill='#e1c2e1'/>
+<path clip-path='url(#clip7)' d='M389.762 138.808H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M102.02 203.937H105.258V115.828H102.02ZM160.688 203.937H163.926V108.187H160.688ZM219.359 203.937H222.594V139.625H219.359ZM278.027 203.937H281.266V141.379H278.027ZM336.695 203.937H339.934V137.246H336.695ZM395.363 203.937H398.602V122.09H395.363Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M102.02 203.937H105.258V115.828H102.02ZM160.688 203.937H163.926V108.187H160.688ZM219.359 203.937H222.594V139.625H219.359ZM278.027 203.937H281.266V141.379H278.027ZM336.695 203.937H339.934V137.246H336.695ZM395.363 203.937H398.602V122.09H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M103.641 115.828V115.828' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M101.644 115.828H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M103.641 115.828V115.828' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M101.644 115.828H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M162.309 108.187V108.187' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M160.316 108.188H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M162.309 108.187V108.187' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M160.316 108.188H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M220.977 139.625V139.625' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M218.984 139.625H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M220.977 139.625V139.625' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M218.984 139.625H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M279.645 141.379V141.379' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M277.652 141.379H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M279.645 141.379V141.379' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M277.652 141.379H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M338.317 137.246V137.246' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M336.32 137.246H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M338.317 137.246V137.246' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M336.32 137.246H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M396.984 122.09V122.09' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M394.992 122.09H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M396.984 122.09V122.09' fill='#d1a3d1'/>
+<path clip-path='url(#clip7)' d='M394.992 122.09H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M107.25 203.937H110.488V123.469H107.25ZM165.918 203.937H169.156V112.133H165.918ZM224.59 203.937H227.824V140.187H224.59ZM283.258 203.937H286.496V140.312H283.258ZM341.926 203.937H345.164V137.933H341.926ZM400.594 203.937H403.832V126.347H400.594Z' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M107.25 203.937H110.488V123.469H107.25ZM165.918 203.937H169.156V112.133H165.918ZM224.59 203.937H227.824V140.187H224.59ZM283.258 203.937H286.496V140.312H283.258ZM341.926 203.937H345.164V137.933H341.926ZM400.594 203.937H403.832V126.347H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M108.871 123.469V123.469' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M106.875 123.469H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M108.871 123.469V123.469' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M106.875 123.469H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M167.539 112.133V112.133' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M165.547 112.133H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M167.539 112.133V112.133' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M165.547 112.133H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M226.207 140.187V140.187' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M224.215 140.187H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M226.207 140.187V140.187' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M224.215 140.187H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M284.875 140.312V140.312' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M282.883 140.312H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M284.875 140.312V140.312' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M282.883 140.312H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M343.547 137.933V137.933' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M341.551 137.934H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M343.547 137.933V137.933' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M341.551 137.934H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M402.215 126.347V126.347' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M400.223 126.347H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M402.215 126.347V126.347' fill='#c285c2'/>
+<path clip-path='url(#clip7)' d='M400.223 126.347H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M112.481 203.937H115.719V139H112.481ZM171.149 203.937H174.387V143.82H171.149ZM229.82 203.937H233.055V141.316H229.82ZM288.488 203.937H291.727V133.176H288.488ZM347.156 203.937H350.395V140H347.156ZM405.824 203.937H409.063V133.176H405.824Z' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M112.481 203.937H115.719V139H112.481ZM171.149 203.937H174.387V143.82H171.149ZM229.82 203.937H233.055V141.316H229.82ZM288.488 203.937H291.727V133.176H288.488ZM347.156 203.937H350.395V140H347.156ZM405.824 203.937H409.063V133.176H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M114.098 139V139' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M112.105 139H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M114.098 139V139' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M112.105 139H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M172.77 143.82V143.82' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M170.777 143.82H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M172.77 143.82V143.82' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M170.777 143.82H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M231.438 141.316V141.316' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M229.445 141.316H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M231.438 141.316V141.316' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M229.445 141.316H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M290.106 133.176V133.176' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M288.113 133.176H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M290.106 133.176V133.176' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M288.113 133.176H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M348.777 140V140' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M346.781 140H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M348.777 140V140' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M346.781 140H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M407.445 133.176V133.176' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M405.453 133.176H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M407.445 133.176V133.176' fill='#b366b3'/>
+<path clip-path='url(#clip7)' d='M405.453 133.176H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M117.711 203.937H120.949V111.32H117.711ZM176.379 203.937H179.617V78.691H176.379ZM235.051 203.937H238.285V139.75H235.051ZM293.719 203.937H296.957V125.785H293.719ZM352.387 203.937H355.625V124.906H352.387ZM411.055 203.937H414.293V132.359H411.055Z' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M117.711 203.937H120.949V111.32H117.711ZM176.379 203.937H179.617V78.691H176.379ZM235.051 203.937H238.285V139.75H235.051ZM293.719 203.937H296.957V125.785H293.719ZM352.387 203.937H355.625V124.906H352.387ZM411.055 203.937H414.293V132.359H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M119.328 111.32V111.32' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M117.336 111.32H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M119.328 111.32V111.32' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M117.336 111.32H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M178 78.691V78.691' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M176.008 78.691H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M178 78.691V78.691' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M176.008 78.691H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M236.668 139.75V139.75' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M234.676 139.75H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M236.668 139.75V139.75' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M234.676 139.75H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M295.336 125.785V125.785' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M293.344 125.785H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M295.336 125.785V125.785' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M293.344 125.785H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M354.008 124.906V124.906' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M352.012 124.906H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M354.008 124.906V124.906' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M352.012 124.906H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M412.676 132.359V132.359' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M410.684 132.359H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M412.676 132.359V132.359' fill='#a447a4'/>
+<path clip-path='url(#clip7)' d='M410.684 132.359H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M122.941 203.937H126.18V143.57H122.941ZM181.609 203.937H184.848V154.34H181.609ZM240.281 203.937H243.516V141.504H240.281ZM298.949 203.937H302.188V133.363H298.949ZM357.617 203.937H360.856V139.937H357.617ZM416.285 203.937H419.524V133.426H416.285Z' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M122.941 203.937H126.18V143.57H122.941ZM181.609 203.937H184.848V154.34H181.609ZM240.281 203.937H243.516V141.504H240.281ZM298.949 203.937H302.188V133.363H298.949ZM357.617 203.937H360.856V139.937H357.617ZM416.285 203.937H419.524V133.426H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M124.559 143.57V143.57' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M122.566 143.571H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M124.559 143.57V143.57' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M122.566 143.571H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M183.231 154.34V154.34' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M181.238 154.34H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M183.231 154.34V154.34' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M181.238 154.34H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M241.899 141.504V141.504' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M239.906 141.504H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M241.899 141.504V141.504' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M239.906 141.504H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M300.567 133.363V133.363' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M298.574 133.363H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M300.567 133.363V133.363' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M298.574 133.363H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M359.238 139.937V139.937' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M357.242 139.938H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M359.238 139.937V139.937' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M357.242 139.938H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M417.906 133.426V133.426' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M415.914 133.426H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M417.906 133.426V133.426' fill='#942994'/>
+<path clip-path='url(#clip7)' d='M415.914 133.426H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M128.172 203.937H131.41V118.457H128.172ZM186.84 203.937H190.078V113.699H186.84ZM245.512 203.937H248.746V140.062H245.512ZM304.18 203.937H307.418V133.613H304.18ZM362.848 203.937H366.086V97.101H362.848ZM421.516 203.937H424.754V137.371H421.516Z' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M128.172 203.937H131.41V118.457H128.172ZM186.84 203.937H190.078V113.699H186.84ZM245.512 203.937H248.746V140.062H245.512ZM304.18 203.937H307.418V133.613H304.18ZM362.848 203.937H366.086V97.101H362.848ZM421.516 203.937H424.754V137.371H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M129.789 118.457V118.457' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M127.797 118.457H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M129.789 118.457V118.457' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M127.797 118.457H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M188.461 113.699V113.699' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M186.469 113.7H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M188.461 113.699V113.699' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M186.469 113.7H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M247.129 140.062V140.062' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M245.137 140.063H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M247.129 140.062V140.062' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M245.137 140.063H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M305.797 133.613V133.613' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M303.804 133.614H307.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M305.797 133.613V133.613' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M303.804 133.614H307.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M364.469 97.101V97.101' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M362.473 97.102H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M364.469 97.101V97.101' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M362.473 97.102H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M423.137 137.371V137.371' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M421.144 137.371H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip7)' d='M423.137 137.371V137.371' fill='#850a85'/>
+<path clip-path='url(#clip7)' d='M421.144 137.371H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -89.137 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -30.468 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.201 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 86.87 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 145.539 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.208 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.906 202.685)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -25.237 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-50' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-48' y='183.949'/>
+<use x='126.877' xlink:href='#g1-55' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.432 246.709)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.101 263.116)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 150.77 238.255)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.439 247.273)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.676 224.29)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -20.007 216.65)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 38.662 248.087)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.331 249.84)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 156 245.707)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 214.669 230.552)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-51' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -73.445 231.93)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.776 220.595)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 43.893 248.65)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 102.562 248.776)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.231 246.396)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 219.9 234.811)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -68.215 247.46)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.546 252.282)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.123 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 107.792 241.637)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.461 248.462)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.13 241.637)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.984 219.781)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -4.315 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-52' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-51' y='183.949'/>
+<use x='126.877' xlink:href='#g1-54' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.354 248.212)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.023 234.247)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 171.692 233.37)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.361 240.822)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.754 252.032)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 0.915 262.803)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.584 249.965)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.253 241.824)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 176.922 248.4)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 235.591 241.887)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -52.524 226.92)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-51' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.145 222.161)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.814 248.525)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 123.483 242.075)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.152 205.566)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.821 245.832)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -124.589 307.697)'>
+<use x='114.487' xlink:href='#g0-82' y='183.949'/>
+<use x='120.457' xlink:href='#g0-101' y='183.949'/>
+<use x='124.553' xlink:href='#g0-108' y='183.949'/>
+<use x='126.753' xlink:href='#g0-97' y='183.949'/>
+<use x='131.181' xlink:href='#g0-116' y='183.949'/>
+<use x='134.509' xlink:href='#g0-105' y='183.949'/>
+<use x='136.709' xlink:href='#g0-118' y='183.949'/>
+<use x='140.957' xlink:href='#g0-101' y='183.949'/>
+<use x='148.124' xlink:href='#g0-114' y='183.949'/>
+<use x='151.272' xlink:href='#g0-115' y='183.949'/>
+<use x='154.805' xlink:href='#g0-115' y='183.949'/>
+<use x='161.409' xlink:href='#g2-40' y='183.949'/>
+<use x='164.702' xlink:href='#g2-108' y='183.949'/>
+<use x='166.722' xlink:href='#g2-111' y='183.949'/>
+<use x='170.721' xlink:href='#g2-119' y='183.949'/>
+<use x='176.27' xlink:href='#g2-101' y='183.949'/>
+<use x='180.034' xlink:href='#g2-114' y='183.949'/>
+<use x='185.749' xlink:href='#g2-105' y='183.949'/>
+<use x='187.769' xlink:href='#g2-115' y='183.949'/>
+<use x='193.838' xlink:href='#g2-98' y='183.949'/>
+<use x='198.446' xlink:href='#g2-101' y='183.949'/>
+<use x='202.209' xlink:href='#g2-116' y='183.949'/>
+<use x='205.267' xlink:href='#g2-116' y='183.949'/>
+<use x='208.325' xlink:href='#g2-101' y='183.949'/>
+<use x='212.089' xlink:href='#g2-114' y='183.949'/>
+<use x='214.981' xlink:href='#g2-41' y='183.949'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='196.567pt' version='1.1' viewBox='106.737 54.996 381.623 196.567' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip8'>
+<path d='M135.949 203.938H487.961V78.692H135.949Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/>
+<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/>
+<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/>
+<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/>
+<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/>
+<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/>
+<path d='M2.002 -3.457H1.519L0.149 0H0.558L0.946 -0.986H2.461L2.849 0H3.372L2.002 -3.457ZM1.709 -3.078L2.336 -1.28H1.071L1.709 -3.078Z' id='g1-65'/>
+<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/>
+<path d='M0.488 -3.457V0H1.903C2.8 0 3.522 -0.757 3.522 -1.699C3.522 -2.675 2.795 -3.457 1.903 -3.457H0.488ZM0.976 -0.294V-3.163H1.768C2.451 -3.163 3.034 -2.62 3.034 -1.704C3.034 -0.777 2.426 -0.294 1.768 -0.294H0.976Z' id='g1-68'/>
+<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/>
+<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/>
+<path d='M2.775 -1.729C2.715 -1.579 2.356 -0.702 2.306 -0.493H2.301C2.267 -0.638 2.037 -1.21 1.988 -1.34L1.131 -3.457H0.523V0H0.941V-3.059H0.946C0.986 -2.884 1.245 -2.227 1.27 -2.172L2.102 -0.105H2.496L3.238 -1.938C3.238 -1.943 3.582 -2.79 3.666 -3.064H3.671V0H4.09V-3.457H3.477L2.775 -1.729Z' id='g1-77'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M2.361 -2.212H1.958C1.554 -1.26 1.275 -0.618 1.255 -0.314C1.245 -0.453 1.156 -0.702 1.066 -0.936C0.986 -1.136 0.907 -1.335 0.817 -1.529L0.503 -2.212H0.075L1.106 0C1.046 0.144 0.946 0.374 0.917 0.438C0.812 0.648 0.742 0.717 0.608 0.717C0.588 0.717 0.403 0.717 0.189 0.628L0.219 0.976C0.264 0.986 0.448 1.016 0.603 1.016C0.802 1.016 0.981 0.941 1.191 0.463L2.361 -2.212Z' id='g1-121'/>
+<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page8'>
+<path d='M194.617 212.793V203.938M253.285 212.793V203.938M311.953 212.793V203.938M370.625 212.793V203.938M429.293 212.793V203.938M194.617 69.836V78.692M253.285 69.836V78.692M311.953 69.836V78.692M370.625 69.836V78.692M429.293 69.836V78.692' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 208.192V203.938M223.953 208.192V203.938M282.621 208.192V203.938M341.289 208.192V203.938M399.957 208.192V203.938M458.629 208.192V203.938M165.281 74.442V78.692M223.953 74.442V78.692M282.621 74.442V78.692M341.289 74.442V78.692M399.957 74.442V78.692M458.629 74.442V78.692' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 203.938H140.199M135.949 172.625H140.199M135.949 141.317H140.199M135.949 110.004H140.199M135.949 78.692H140.199M487.961 203.938H483.711M487.961 172.625H483.711M487.961 141.317H483.711M487.961 110.004H483.711M487.961 78.692H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 203.938V78.692H487.961V203.938H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 59.571)'>
+<use x='168.285' xlink:href='#g2-97' y='158.367'/>
+<use x='172.353' xlink:href='#g2-108' y='158.367'/>
+<use x='174.373' xlink:href='#g2-108' y='158.367'/>
+<use x='176.393' xlink:href='#g2-111' y='158.367'/>
+<use x='180.863' xlink:href='#g2-99' y='158.367'/>
+<use x='184.627' xlink:href='#g2-45' y='158.367'/>
+<use x='187.449' xlink:href='#g2-116' y='158.367'/>
+<use x='190.507' xlink:href='#g2-101' y='158.367'/>
+<use x='194.271' xlink:href='#g2-115' y='158.367'/>
+<use x='197.517' xlink:href='#g2-116' y='158.367'/>
+<use x='200.575' xlink:href='#g2-49' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 59.571)'>
+<use x='168.285' xlink:href='#g2-97' y='158.367'/>
+<use x='172.353' xlink:href='#g2-108' y='158.367'/>
+<use x='174.373' xlink:href='#g2-108' y='158.367'/>
+<use x='176.393' xlink:href='#g2-111' y='158.367'/>
+<use x='180.863' xlink:href='#g2-99' y='158.367'/>
+<use x='184.627' xlink:href='#g2-45' y='158.367'/>
+<use x='187.449' xlink:href='#g2-116' y='158.367'/>
+<use x='190.507' xlink:href='#g2-101' y='158.367'/>
+<use x='194.271' xlink:href='#g2-115' y='158.367'/>
+<use x='197.517' xlink:href='#g2-116' y='158.367'/>
+<use x='200.575' xlink:href='#g2-78' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 59.571)'>
+<use x='168.285' xlink:href='#g2-115' y='158.367'/>
+<use x='171.531' xlink:href='#g2-104' y='158.367'/>
+<use x='175.904' xlink:href='#g2-54' y='158.367'/>
+<use x='180.138' xlink:href='#g2-98' y='158.367'/>
+<use x='184.746' xlink:href='#g2-101' y='158.367'/>
+<use x='188.509' xlink:href='#g2-110' y='158.367'/>
+<use x='192.882' xlink:href='#g2-99' y='158.367'/>
+<use x='196.646' xlink:href='#g2-104' y='158.367'/>
+<use x='201.018' xlink:href='#g2-78' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 59.571)'>
+<use x='168.285' xlink:href='#g2-115' y='158.367'/>
+<use x='171.531' xlink:href='#g2-104' y='158.367'/>
+<use x='175.904' xlink:href='#g2-56' y='158.367'/>
+<use x='180.138' xlink:href='#g2-98' y='158.367'/>
+<use x='184.746' xlink:href='#g2-101' y='158.367'/>
+<use x='188.509' xlink:href='#g2-110' y='158.367'/>
+<use x='192.882' xlink:href='#g2-99' y='158.367'/>
+<use x='196.646' xlink:href='#g2-104' y='158.367'/>
+<use x='201.018' xlink:href='#g2-78' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 59.571)'>
+<use x='168.285' xlink:href='#g2-120' y='158.367'/>
+<use x='172.187' xlink:href='#g2-109' y='158.367'/>
+<use x='178.912' xlink:href='#g2-97' y='158.367'/>
+<use x='182.98' xlink:href='#g2-108' y='158.367'/>
+<use x='185' xlink:href='#g2-108' y='158.367'/>
+<use x='187.02' xlink:href='#g2-111' y='158.367'/>
+<use x='191.49' xlink:href='#g2-99' y='158.367'/>
+<use x='195.254' xlink:href='#g2-45' y='158.367'/>
+<use x='198.076' xlink:href='#g2-116' y='158.367'/>
+<use x='201.134' xlink:href='#g2-101' y='158.367'/>
+<use x='204.898' xlink:href='#g2-115' y='158.367'/>
+<use x='208.144' xlink:href='#g2-116' y='158.367'/>
+<use x='211.202' xlink:href='#g2-78' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 59.571)'>
+<use x='168.285' xlink:href='#g2-99' y='158.367'/>
+<use x='172.049' xlink:href='#g2-97' y='158.367'/>
+<use x='176.117' xlink:href='#g2-99' y='158.367'/>
+<use x='179.88' xlink:href='#g2-104' y='158.367'/>
+<use x='184.253' xlink:href='#g2-101' y='158.367'/>
+<use x='188.017' xlink:href='#g2-45' y='158.367'/>
+<use x='190.839' xlink:href='#g2-115' y='158.367'/>
+<use x='194.086' xlink:href='#g2-99' y='158.367'/>
+<use x='197.849' xlink:href='#g2-114' y='158.367'/>
+<use x='200.741' xlink:href='#g2-97' y='158.367'/>
+<use x='204.81' xlink:href='#g2-116' y='158.367'/>
+<use x='207.868' xlink:href='#g2-99' y='158.367'/>
+<use x='211.631' xlink:href='#g2-104' y='158.367'/>
+<use x='216.004' xlink:href='#g2-78' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 47.205)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-120' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 15.894)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-53' y='158.367'/>
+<use x='175.048' xlink:href='#g1-120' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -15.418)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-120' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -46.729)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-53' y='158.367'/>
+<use x='175.048' xlink:href='#g1-120' y='158.367'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -78.041)'>
+<use x='168.285' xlink:href='#g1-50' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-120' y='158.367'/>
+</g>
+<path clip-path='url(#clip8)' d='M135.949 141.317H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M145.356 203.938H148.594V141.317H145.356ZM204.028 203.938H207.266V141.317H204.028ZM262.695 203.938H265.934V141.317H262.695ZM321.363 203.938H324.602V141.317H321.363ZM380.031 203.938H383.27V141.317H380.031ZM438.703 203.938H441.942V141.317H438.703Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M145.356 203.938H148.594V141.317H145.356ZM204.028 203.938H207.266V141.317H204.028ZM262.695 203.938H265.934V141.317H262.695ZM321.363 203.938H324.602V141.317H321.363ZM380.031 203.938H383.27V141.317H380.031ZM438.703 203.938H441.942V141.317H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M146.977 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M144.984 141.317H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M146.977 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M144.984 141.317H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M205.645 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M203.652 141.317H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M205.645 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M203.652 141.317H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M264.313 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M262.32 141.317H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M264.313 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M262.32 141.317H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M322.984 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M320.992 141.317H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M322.984 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M320.992 141.317H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M381.652 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M379.66 141.317H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M381.652 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M379.66 141.317H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M440.32 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M438.328 141.317H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M440.32 141.317V141.317' fill='#f0e0f0'/>
+<path clip-path='url(#clip8)' d='M438.328 141.317H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M150.586 203.938H153.824V137.809H150.586ZM209.258 203.938H212.496V144.196H209.258ZM267.926 203.938H271.164V140.563H267.926ZM326.594 203.938H329.832V141.754H326.594ZM385.262 203.938H388.5V188.406H385.262ZM443.934 203.938H447.172V110.754H443.934Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M150.586 203.938H153.824V137.809H150.586ZM209.258 203.938H212.496V144.196H209.258ZM267.926 203.938H271.164V140.563H267.926ZM326.594 203.938H329.832V141.754H326.594ZM385.262 203.938H388.5V188.406H385.262ZM443.934 203.938H447.172V110.754H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M152.207 137.809V137.809' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M150.215 137.809H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M152.207 137.809V137.809' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M150.215 137.809H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M210.875 144.196V144.196' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M208.883 144.195H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M210.875 144.196V144.196' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M208.883 144.195H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M269.543 140.563V140.563' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M267.551 140.562H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M269.543 140.563V140.563' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M267.551 140.562H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M328.215 141.754V141.754' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M326.223 141.754H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M328.215 141.754V141.754' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M326.223 141.754H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M386.883 188.406V188.406' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M384.891 188.406H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M386.883 188.406V188.406' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M384.891 188.406H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M445.551 110.754V110.754' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M443.559 110.754H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M445.551 110.754V110.754' fill='#e1c2e1'/>
+<path clip-path='url(#clip8)' d='M443.559 110.754H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M155.817 203.938H159.055V140.313H155.817ZM214.488 203.938H217.727V147.453H214.488ZM273.156 203.938H276.395V139.625H273.156ZM331.824 203.938H335.063V130.043H331.824ZM390.492 203.938H393.731V170.809H390.492ZM449.164 203.938H452.402V120.024H449.164Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M155.817 203.938H159.055V140.313H155.817ZM214.488 203.938H217.727V147.453H214.488ZM273.156 203.938H276.395V139.625H273.156ZM331.824 203.938H335.063V130.043H331.824ZM390.492 203.938H393.731V170.809H390.492ZM449.164 203.938H452.402V120.024H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M157.438 140.313V140.313' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M155.445 140.313H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M157.438 140.313V140.313' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M155.445 140.313H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M216.106 147.453V147.453' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M214.113 147.453H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M216.106 147.453V147.453' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M214.113 147.453H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M274.774 139.625V139.625' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M272.781 139.625H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M274.774 139.625V139.625' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M272.781 139.625H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M333.445 130.043V130.043' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M331.453 130.043H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M333.445 130.043V130.043' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M331.453 130.043H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M392.113 170.809V170.809' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M390.121 170.808H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M392.113 170.809V170.809' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M390.121 170.808H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M450.781 120.024V120.024' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M448.789 120.023H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M450.781 120.024V120.024' fill='#d1a3d1'/>
+<path clip-path='url(#clip8)' d='M448.789 120.023H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M161.047 203.938H164.285V137.559H161.047ZM219.719 203.938H222.957V144.383H219.719ZM278.387 203.938H281.625V131.36H278.387ZM337.055 203.938H340.293V128.164H337.055ZM395.723 203.938H398.961V138.121H395.723ZM454.395 203.938H457.633V137.559H454.395Z' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M161.047 203.938H164.285V137.559H161.047ZM219.719 203.938H222.957V144.383H219.719ZM278.387 203.938H281.625V131.36H278.387ZM337.055 203.938H340.293V128.164H337.055ZM395.723 203.938H398.961V138.121H395.723ZM454.395 203.938H457.633V137.559H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M162.668 137.559V137.559' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M160.676 137.558H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M162.668 137.559V137.559' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M160.676 137.558H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M221.336 144.383V144.383' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M219.344 144.382H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M221.336 144.383V144.383' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M219.344 144.382H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M280.004 131.36V131.36' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M278.012 131.36H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M280.004 131.36V131.36' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M278.012 131.36H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M338.676 128.164V128.164' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M336.684 128.164H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M338.676 128.164V128.164' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M336.684 128.164H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M397.344 138.121V138.121' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M395.352 138.121H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M397.344 138.121V138.121' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M395.352 138.121H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M456.012 137.559V137.559' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M454.02 137.558H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M456.012 137.559V137.559' fill='#c285c2'/>
+<path clip-path='url(#clip8)' d='M454.02 137.558H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M166.278 203.938H169.516V126.723H166.278ZM224.949 203.938H228.188V141.629H224.949ZM283.617 203.938H286.856V104.055H283.617ZM342.285 203.938H345.524V122.84H342.285ZM400.953 203.938H404.192V186.215H400.953ZM459.625 203.938H462.863V140.188H459.625Z' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M166.278 203.938H169.516V126.723H166.278ZM224.949 203.938H228.188V141.629H224.949ZM283.617 203.938H286.856V104.055H283.617ZM342.285 203.938H345.524V122.84H342.285ZM400.953 203.938H404.192V186.215H400.953ZM459.625 203.938H462.863V140.188H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M167.899 126.723V126.723' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M165.906 126.723H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M167.899 126.723V126.723' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M165.906 126.723H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M226.567 141.629V141.629' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M224.574 141.629H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M226.567 141.629V141.629' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M224.574 141.629H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M285.234 104.055V104.055' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M283.242 104.055H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M285.234 104.055V104.055' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M283.242 104.055H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M343.906 122.84V122.84' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M341.914 122.84H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M343.906 122.84V122.84' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M341.914 122.84H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M402.574 186.215V186.215' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M400.582 186.215H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M402.574 186.215V186.215' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M400.582 186.215H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M461.242 140.188V140.188' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M459.25 140.188H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M461.242 140.188V140.188' fill='#b366b3'/>
+<path clip-path='url(#clip8)' d='M459.25 140.188H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M171.508 203.938H174.746V115.828H171.508ZM230.18 203.938H233.414V91.215H230.18ZM288.848 203.938H292.086V95.977H288.848ZM347.516 203.938H350.754V78.692H347.516ZM406.184 203.938H409.422V167.68H406.184ZM464.856 203.938H468.094V130.856H464.856Z' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M171.508 203.938H174.746V115.828H171.508ZM230.18 203.938H233.414V91.215H230.18ZM288.848 203.938H292.086V95.977H288.848ZM347.516 203.938H350.754V78.692H347.516ZM406.184 203.938H409.422V167.68H406.184ZM464.856 203.938H468.094V130.856H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M173.129 115.828V115.828' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M171.137 115.828H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M173.129 115.828V115.828' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M171.137 115.828H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M231.797 91.215V91.215' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M229.805 91.215H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M231.797 91.215V91.215' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M229.805 91.215H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M290.465 95.977V95.977' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M288.473 95.977H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M290.465 95.977V95.977' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M288.473 95.977H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M349.137 78.692V78.692' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M347.145 78.691H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M349.137 78.692V78.692' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M347.145 78.691H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M407.805 167.68V167.68' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M405.813 167.68H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M407.805 167.68V167.68' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M405.813 167.68H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M466.473 130.856V130.856' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M464.481 130.856H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M466.473 130.856V130.856' fill='#a447a4'/>
+<path clip-path='url(#clip8)' d='M464.481 130.856H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M176.738 203.938H179.977V126.973H176.738ZM235.41 203.938H238.645V141.754H235.41ZM294.078 203.938H297.317V104.18H294.078ZM352.746 203.938H355.984V122.903H352.746ZM411.414 203.938H414.652V186.278H411.414ZM470.086 203.938H473.324V140.688H470.086Z' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M176.738 203.938H179.977V126.973H176.738ZM235.41 203.938H238.645V141.754H235.41ZM294.078 203.938H297.317V104.18H294.078ZM352.746 203.938H355.984V122.903H352.746ZM411.414 203.938H414.652V186.278H411.414ZM470.086 203.938H473.324V140.688H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M178.36 126.973V126.973' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M176.367 126.972H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M178.36 126.973V126.973' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M176.367 126.972H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M237.027 141.754V141.754' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M235.035 141.754H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M237.027 141.754V141.754' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M235.035 141.754H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M295.695 104.18V104.18' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M293.703 104.179H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M295.695 104.18V104.18' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M293.703 104.179H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M354.367 122.903V122.903' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M352.375 122.903H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M354.367 122.903V122.903' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M352.375 122.903H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M413.035 186.278V186.278' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M411.043 186.277H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M413.035 186.278V186.278' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M411.043 186.277H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M471.703 140.688V140.688' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M469.711 140.688H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M471.703 140.688V140.688' fill='#942994'/>
+<path clip-path='url(#clip8)' d='M469.711 140.688H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M416.645 203.938H419.883V157.973H416.645ZM181.969 203.938H185.207V135.051H181.969ZM240.641 203.938H243.875V142.129H240.641ZM299.309 203.938H302.547V134.676H299.309ZM357.977 203.938H361.215V140.25H357.977ZM475.317 203.938H478.555V131.235H475.317Z' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M416.645 203.938H419.883V157.973H416.645ZM181.969 203.938H185.207V135.051H181.969ZM240.641 203.938H243.875V142.129H240.641ZM299.309 203.938H302.547V134.676H299.309ZM357.977 203.938H361.215V140.25H357.977ZM475.317 203.938H478.555V131.235H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M418.266 157.973V157.973' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M416.274 157.973H420.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M418.266 157.973V157.973' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M416.274 157.973H420.258' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M183.59 135.051V135.051' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M181.598 135.051H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M183.59 135.051V135.051' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M181.598 135.051H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M242.258 142.129V142.129' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M240.266 142.129H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M242.258 142.129V142.129' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M240.266 142.129H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M300.926 134.676V134.676' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M298.933 134.676H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M300.926 134.676V134.676' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M298.933 134.676H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M359.598 140.25V140.25' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M357.606 140.25H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M359.598 140.25V140.25' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M357.606 140.25H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M476.934 131.235V131.235' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M474.942 131.235H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M476.934 131.235V131.235' fill='#850a85'/>
+<path clip-path='url(#clip8)' d='M474.942 131.235H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip8)' d='M418.387 251.164H487.762V229.188H418.387Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 253.422 88.837)'>
+<use x='168.285' xlink:href='#g1-114' y='147.13'/>
+<use x='170.092' xlink:href='#g1-53' y='147.13'/>
+<use x='172.739' xlink:href='#g1-97' y='147.13'/>
+<use x='175.281' xlink:href='#g1-45' y='147.13'/>
+<use x='177.046' xlink:href='#g1-52' y='147.13'/>
+<use x='179.692' xlink:href='#g1-120' y='147.13'/>
+<use x='182.131' xlink:href='#g1-108' y='147.13'/>
+<use x='183.393' xlink:href='#g1-97' y='147.13'/>
+<use x='185.789' xlink:href='#g1-114' y='147.13'/>
+<use x='187.596' xlink:href='#g1-103' y='147.13'/>
+<use x='190.243' xlink:href='#g1-101' y='147.13'/>
+<use x='192.595' xlink:href='#g1-44' y='147.13'/>
+<use x='195.83' xlink:href='#g1-49' y='147.13'/>
+<use x='198.476' xlink:href='#g1-50' y='147.13'/>
+<use x='201.122' xlink:href='#g1-56' y='147.13'/>
+<use x='203.769' xlink:href='#g1-71' y='147.13'/>
+<use x='207.297' xlink:href='#g1-98' y='147.13'/>
+<use x='168.285' xlink:href='#g1-49' y='152.749'/>
+<use x='170.931' xlink:href='#g1-54' y='152.749'/>
+<use x='173.578' xlink:href='#g1-45' y='152.749'/>
+<use x='175.342' xlink:href='#g1-99' y='152.749'/>
+<use x='177.694' xlink:href='#g1-111' y='152.749'/>
+<use x='180.193' xlink:href='#g1-114' y='152.749'/>
+<use x='182.001' xlink:href='#g1-101' y='152.749'/>
+<use x='186.118' xlink:href='#g1-65' y='152.749'/>
+<use x='189.646' xlink:href='#g1-77' y='152.749'/>
+<use x='194.264' xlink:href='#g1-68' y='152.749'/>
+<use x='199.851' xlink:href='#g1-69' y='152.749'/>
+<use x='203.025' xlink:href='#g1-112' y='152.749'/>
+<use x='205.611' xlink:href='#g1-121' y='152.749'/>
+<use x='208.049' xlink:href='#g1-99' y='152.749'/>
+<use x='212.166' xlink:href='#g1-64' y='152.749'/>
+<use x='215.695' xlink:href='#g1-50' y='152.749'/>
+<use x='218.341' xlink:href='#g1-46' y='152.749'/>
+<use x='219.811' xlink:href='#g1-53' y='152.749'/>
+<use x='222.457' xlink:href='#g1-71' y='152.749'/>
+<use x='225.986' xlink:href='#g1-104' y='152.749'/>
+<use x='228.719' xlink:href='#g1-122' y='152.749'/>
+<use x='168.285' xlink:href='#g1-85' y='158.367'/>
+<use x='171.917' xlink:href='#g1-98' y='158.367'/>
+<use x='174.65' xlink:href='#g1-117' y='158.367'/>
+<use x='177.383' xlink:href='#g1-110' y='158.367'/>
+<use x='180.116' xlink:href='#g1-116' y='158.367'/>
+<use x='182.027' xlink:href='#g1-117' y='158.367'/>
+<use x='186.524' xlink:href='#g1-49' y='158.367'/>
+<use x='189.17' xlink:href='#g1-56' y='158.367'/>
+<use x='191.817' xlink:href='#g1-46' y='158.367'/>
+<use x='193.287' xlink:href='#g1-48' y='158.367'/>
+<use x='195.933' xlink:href='#g1-52' y='158.367'/>
+<use x='198.58' xlink:href='#g1-46' y='158.367'/>
+<use x='200.05' xlink:href='#g1-49' y='158.367'/>
+<use x='202.696' xlink:href='#g1-44' y='158.367'/>
+<use x='205.931' xlink:href='#g1-71' y='158.367'/>
+<use x='209.459' xlink:href='#g1-67' y='158.367'/>
+<use x='212.841' xlink:href='#g1-67' y='158.367'/>
+<use x='217.986' xlink:href='#g1-55' y='158.367'/>
+<use x='220.633' xlink:href='#g1-46' y='158.367'/>
+<use x='222.103' xlink:href='#g1-51' y='158.367'/>
+<use x='224.749' xlink:href='#g1-46' y='158.367'/>
+<use x='226.219' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.757 303.575)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 48.912 303.575)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 107.581 303.575)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.25 303.575)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 224.919 303.575)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 283.588 303.575)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 -4.526 300.068)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-54' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.143 306.456)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-53' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 112.812 302.824)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-49' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 171.481 304.013)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.15 350.668)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-53' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 288.819 273.015)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-52' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 0.704 302.573)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-50' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.373 309.712)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.042 301.884)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-51' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 176.711 292.303)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-49' y='158.367'/>
+<use x='175.048' xlink:href='#g1-56' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 235.38 333.071)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-53' y='158.367'/>
+<use x='175.048' xlink:href='#g1-51' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 294.049 282.283)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-51' y='158.367'/>
+<use x='175.048' xlink:href='#g1-52' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 5.935 299.818)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-54' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.604 306.644)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-53' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 123.273 293.618)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-49' y='158.367'/>
+<use x='175.048' xlink:href='#g1-54' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 181.942 290.424)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-49' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.611 300.381)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-53' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 299.28 299.818)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-54' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 11.165 288.984)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-51' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 69.834 303.888)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 128.503 266.314)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-53' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 187.172 285.101)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 245.841 348.476)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-56' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 304.51 302.448)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-50' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 16.396 278.088)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-52' y='158.367'/>
+<use x='175.048' xlink:href='#g1-49' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 75.065 253.477)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-56' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 133.734 258.236)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-55' y='158.367'/>
+<use x='175.048' xlink:href='#g1-50' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 192.403 240.952)'>
+<use x='163.396' xlink:href='#g3-1' y='158.367'/>
+<use x='166.901' xlink:href='#g3-1' y='158.367'/>
+<use x='170.407' xlink:href='#g3-1' y='158.367'/>
+<use x='173.912' xlink:href='#g1-50' y='158.367'/>
+<use x='176.558' xlink:href='#g1-46' y='158.367'/>
+<use x='178.029' xlink:href='#g1-52' y='158.367'/>
+<use x='180.675' xlink:href='#g1-54' y='158.367'/>
+<use x='183.321' xlink:href='#g1-120' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 251.072 329.939)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-53' y='158.367'/>
+<use x='175.048' xlink:href='#g1-56' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 309.741 293.117)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-49' y='158.367'/>
+<use x='175.048' xlink:href='#g1-55' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.626 289.234)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-51' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 80.295 304.013)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 138.964 266.44)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-53' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 197.633 285.164)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 256.302 348.538)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-50' y='158.367'/>
+<use x='175.048' xlink:href='#g1-56' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 314.971 302.949)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-49' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 261.532 320.233)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-55' y='158.367'/>
+<use x='175.048' xlink:href='#g1-51' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.856 297.313)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-49' y='158.367'/>
+<use x='175.048' xlink:href='#g1-48' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.525 304.389)'>
+<use x='168.285' xlink:href='#g1-48' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-57' y='158.367'/>
+<use x='175.048' xlink:href='#g1-57' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 144.194 296.937)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-49' y='158.367'/>
+<use x='175.048' xlink:href='#g1-49' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.863 302.511)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-48' y='158.367'/>
+<use x='175.048' xlink:href='#g1-50' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 320.201 293.493)'>
+<use x='168.285' xlink:href='#g1-49' y='158.367'/>
+<use x='170.931' xlink:href='#g1-46' y='158.367'/>
+<use x='172.401' xlink:href='#g1-49' y='158.367'/>
+<use x='175.048' xlink:href='#g1-54' y='158.367'/>
+</g>
+<g transform='matrix(0 -1 1 0 -45.209 361.494)'>
+<use x='168.285' xlink:href='#g0-82' y='158.367'/>
+<use x='174.255' xlink:href='#g0-101' y='158.367'/>
+<use x='178.351' xlink:href='#g0-108' y='158.367'/>
+<use x='180.551' xlink:href='#g0-97' y='158.367'/>
+<use x='184.979' xlink:href='#g0-116' y='158.367'/>
+<use x='188.307' xlink:href='#g0-105' y='158.367'/>
+<use x='190.507' xlink:href='#g0-118' y='158.367'/>
+<use x='194.755' xlink:href='#g0-101' y='158.367'/>
+<use x='201.922' xlink:href='#g0-114' y='158.367'/>
+<use x='205.07' xlink:href='#g0-115' y='158.367'/>
+<use x='208.603' xlink:href='#g0-115' y='158.367'/>
+<use x='215.207' xlink:href='#g2-40' y='158.367'/>
+<use x='218.5' xlink:href='#g2-108' y='158.367'/>
+<use x='220.521' xlink:href='#g2-111' y='158.367'/>
+<use x='224.52' xlink:href='#g2-119' y='158.367'/>
+<use x='230.068' xlink:href='#g2-101' y='158.367'/>
+<use x='233.832' xlink:href='#g2-114' y='158.367'/>
+<use x='239.547' xlink:href='#g2-105' y='158.367'/>
+<use x='241.567' xlink:href='#g2-115' y='158.367'/>
+<use x='247.636' xlink:href='#g2-98' y='158.367'/>
+<use x='252.244' xlink:href='#g2-101' y='158.367'/>
+<use x='256.008' xlink:href='#g2-116' y='158.367'/>
+<use x='259.066' xlink:href='#g2-116' y='158.367'/>
+<use x='262.124' xlink:href='#g2-101' y='158.367'/>
+<use x='265.887' xlink:href='#g2-114' y='158.367'/>
+<use x='268.779' xlink:href='#g2-41' y='158.367'/>
+</g>
+<path d='M136.149 249.309H349.488V232.317H136.149Z' fill='#ffffff'/>
+<path d='M136.149 249.309H349.488V232.317H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 242.804H142.324V234.835H139.336ZM145.313 242.804H148.301V236.828H145.313Z' fill='#f0e0f0'/>
+<path d='M139.336 242.804H142.324V234.835H139.336ZM145.313 242.804H148.301V236.828H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -33.522 84.43)'>
+<use x='185.011' xlink:href='#g2-109' y='158.367'/>
+<use x='191.736' xlink:href='#g2-105' y='158.367'/>
+</g>
+<path d='M163.422 242.805H166.41V234.836H163.422ZM169.398 242.805H172.391V236.828H169.398Z' fill='#e1c2e1'/>
+<path d='M163.422 242.804H166.41V234.835H163.422ZM169.398 242.804H172.391V236.828H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.56 83.976)'>
+<use x='208.137' xlink:href='#g2-116' y='158.367'/>
+<use x='211.195' xlink:href='#g2-99' y='158.367'/>
+</g>
+<path d='M185.586 242.805H188.574V234.836H185.586ZM191.563 242.805H194.555V236.828H191.563Z' fill='#d1a3d1'/>
+<path d='M185.586 242.804H188.574V234.835H185.586ZM191.563 242.804H194.555V236.828H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.159 84.43)'>
+<use x='229.9' xlink:href='#g2-106' y='158.367'/>
+<use x='232.155' xlink:href='#g2-101' y='158.367'/>
+</g>
+<path d='M206.949 242.805H209.938V234.836H206.949ZM212.926 242.805H215.914V236.828H212.926Z' fill='#c285c2'/>
+<path d='M206.949 242.804H209.938V234.835H206.949ZM212.926 242.804H215.914V236.828H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.958 83.47)'>
+<use x='252.061' xlink:href='#g2-115' y='158.367'/>
+<use x='255.307' xlink:href='#g2-110' y='158.367'/>
+</g>
+<path d='M229.91 242.805H232.898V234.836H229.91ZM235.887 242.805H238.875V236.828H235.887Z' fill='#b366b3'/>
+<path d='M229.91 242.804H232.898V234.835H229.91ZM235.887 242.804H238.875V236.828H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.781 83.47)'>
+<use x='274.845' xlink:href='#g2-114' y='158.367'/>
+<use x='277.737' xlink:href='#g2-112' y='158.367'/>
+</g>
+<path d='M252.516 242.805H255.504V234.836H252.516ZM258.496 242.805H261.484V236.828H258.496Z' fill='#a447a4'/>
+<path d='M252.516 242.804H255.504V234.835H252.516ZM258.496 242.804H261.484V236.828H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.001 84.467)'>
+<use x='303.672' xlink:href='#g2-104' y='158.367'/>
+<use x='308.045' xlink:href='#g2-111' y='158.367'/>
+<use x='312.279' xlink:href='#g2-97' y='158.367'/>
+<use x='316.112' xlink:href='#g2-114' y='158.367'/>
+<use x='319.004' xlink:href='#g2-100' y='158.367'/>
+</g>
+<path d='M287.563 242.805H290.551V234.836H287.563ZM293.543 242.805H296.531V236.828H293.543Z' fill='#942994'/>
+<path d='M287.563 242.804H290.551V234.835H287.563ZM293.543 242.804H296.531V236.828H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.472 84.467)'>
+<use x='337.19' xlink:href='#g2-103' y='158.367'/>
+<use x='341.424' xlink:href='#g2-108' y='158.367'/>
+<use x='343.444' xlink:href='#g2-105' y='158.367'/>
+<use x='345.464' xlink:href='#g2-98' y='158.367'/>
+<use x='350.072' xlink:href='#g2-99' y='158.367'/>
+</g>
+<path d='M319.551 242.805H322.539V234.836H319.551ZM325.527 242.805H328.52V236.828H325.527Z' fill='#850a85'/>
+<path d='M319.551 242.804H322.539V234.835H319.551ZM325.527 242.804H328.52V236.828H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.051 84.467)'>
+<use x='366.757' xlink:href='#g2-116' y='158.367'/>
+<use x='369.815' xlink:href='#g2-98' y='158.367'/>
+<use x='374.187' xlink:href='#g2-98' y='158.367'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='182.025pt' version='1.1' viewBox='106.736 51.674 270.486 182.025' width='270.486pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<defs>
+<clipPath id='clip6'>
+<path d='M135.949 186.074H355.586V60.828H135.949Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-46' transform='scale(1.6)' xlink:href='#g1-46'/>
+<use id='g2-48' transform='scale(1.6)' xlink:href='#g1-48'/>
+<use id='g2-50' transform='scale(1.6)' xlink:href='#g1-50'/>
+<use id='g2-51' transform='scale(1.6)' xlink:href='#g1-51'/>
+<use id='g2-52' transform='scale(1.6)' xlink:href='#g1-52'/>
+<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/>
+<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/>
+<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/>
+<use id='g2-107' transform='scale(1.6)' xlink:href='#g1-107'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/>
+<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/>
+<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/>
+<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/>
+<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/>
+<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/>
+<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/>
+<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/>
+<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/>
+<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/>
+<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/>
+<path d='M1.489 -1.355L2.376 -2.212H1.893L0.827 -1.181V-3.457H0.438V0H0.807V-0.697L1.23 -1.106L2.052 0H2.491L1.489 -1.355Z' id='g1-107'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page6'>
+<path d='M190.86 194.93V186.074M245.766 194.93V186.074M300.676 194.93V186.074M190.86 51.973V60.828M245.766 51.973V60.828M300.676 51.973V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M163.403 190.324V186.074M218.313 190.324V186.074M273.223 190.324V186.074M328.133 190.324V186.074M163.403 56.574V60.828M218.313 56.574V60.828M273.223 56.574V60.828M328.133 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 186.074H140.199M135.949 154.762H140.199M135.949 123.449H140.199M135.949 92.141H140.199M135.949 60.828H140.199M355.586 186.074H351.336M355.586 154.762H351.336M355.586 123.449H351.336M355.586 92.141H351.336M355.586 60.828H351.336' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 186.074V60.828H355.586V186.074H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -18.291 59.571)'>
+<use x='168.285' xlink:href='#g2-54' y='140.503'/>
+<use x='172.519' xlink:href='#g2-48' y='140.503'/>
+<use x='176.753' xlink:href='#g2-50' y='140.503'/>
+<use x='180.987' xlink:href='#g2-46' y='140.503'/>
+<use x='183.34' xlink:href='#g2-103' y='140.503'/>
+<use x='187.574' xlink:href='#g2-99' y='140.503'/>
+<use x='191.338' xlink:href='#g2-99' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 27.05 59.571)'>
+<use x='168.285' xlink:href='#g2-54' y='140.503'/>
+<use x='172.519' xlink:href='#g2-50' y='140.503'/>
+<use x='176.753' xlink:href='#g2-48' y='140.503'/>
+<use x='180.987' xlink:href='#g2-46' y='140.503'/>
+<use x='183.34' xlink:href='#g2-111' y='140.503'/>
+<use x='187.574' xlink:href='#g2-109' y='140.503'/>
+<use x='194.299' xlink:href='#g2-110' y='140.503'/>
+<use x='198.671' xlink:href='#g2-101' y='140.503'/>
+<use x='202.435' xlink:href='#g2-116' y='140.503'/>
+<use x='205.493' xlink:href='#g2-112' y='140.503'/>
+<use x='209.866' xlink:href='#g2-112' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 78.694 59.571)'>
+<use x='168.285' xlink:href='#g2-54' y='140.503'/>
+<use x='172.519' xlink:href='#g2-50' y='140.503'/>
+<use x='176.753' xlink:href='#g2-51' y='140.503'/>
+<use x='180.987' xlink:href='#g2-46' y='140.503'/>
+<use x='183.34' xlink:href='#g2-120' y='140.503'/>
+<use x='187.242' xlink:href='#g2-97' y='140.503'/>
+<use x='191.31' xlink:href='#g2-108' y='140.503'/>
+<use x='193.33' xlink:href='#g2-97' y='140.503'/>
+<use x='197.398' xlink:href='#g2-110' y='140.503'/>
+<use x='201.771' xlink:href='#g2-99' y='140.503'/>
+<use x='205.535' xlink:href='#g2-98' y='140.503'/>
+<use x='209.907' xlink:href='#g2-109' y='140.503'/>
+<use x='216.632' xlink:href='#g2-107' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 134.081 59.571)'>
+<use x='168.285' xlink:href='#g2-54' y='140.503'/>
+<use x='172.519' xlink:href='#g2-52' y='140.503'/>
+<use x='176.753' xlink:href='#g2-56' y='140.503'/>
+<use x='180.987' xlink:href='#g2-46' y='140.503'/>
+<use x='183.34' xlink:href='#g2-101' y='140.503'/>
+<use x='187.103' xlink:href='#g2-120' y='140.503'/>
+<use x='191.006' xlink:href='#g2-99' y='140.503'/>
+<use x='194.769' xlink:href='#g2-104' y='140.503'/>
+<use x='199.142' xlink:href='#g2-97' y='140.503'/>
+<use x='203.21' xlink:href='#g2-110' y='140.503'/>
+<use x='207.582' xlink:href='#g2-103' y='140.503'/>
+<use x='211.817' xlink:href='#g2-101' y='140.503'/>
+<use x='215.58' xlink:href='#g2-50' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 47.205)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 15.894)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -15.418)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -46.729)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -78.041)'>
+<use x='168.285' xlink:href='#g1-50' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<path clip-path='url(#clip6)' d='M135.949 123.449H355.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M140.863 186.074H144.102V123.449H140.863ZM195.77 186.074H199.008V123.449H195.77ZM250.68 186.074H253.918V123.449H250.68ZM305.59 186.074H308.828V123.449H305.59Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M140.863 186.074H144.102V123.449H140.863ZM195.77 186.074H199.008V123.449H195.77ZM250.68 186.074H253.918V123.449H250.68ZM305.59 186.074H308.828V123.449H305.59Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M142.481 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M140.488 123.449H144.472' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M142.481 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M140.488 123.449H144.472' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M197.391 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M195.398 123.449H199.383' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M197.391 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M195.398 123.449H199.383' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M252.301 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M250.308 123.449H254.292' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M252.301 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M250.308 123.449H254.292' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M307.211 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M305.219 123.449H309.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M307.211 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip6)' d='M305.219 123.449H309.203' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M146.094 186.074H149.332V123.262H146.094ZM201 186.074H204.238V123.137H201ZM255.91 186.074H259.149V124.141H255.91ZM310.82 186.074H314.059V73.664H310.82Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M146.094 186.074H149.332V123.262H146.094ZM201 186.074H204.238V123.137H201ZM255.91 186.074H259.149V124.141H255.91ZM310.82 186.074H314.059V73.664H310.82Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M147.711 123.262V123.262' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M145.719 123.262H149.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M147.711 123.262V123.262' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M145.719 123.262H149.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M202.621 123.137V123.137' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M200.629 123.137H204.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M202.621 123.137V123.137' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M200.629 123.137H204.613' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M257.531 124.141V124.141' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M255.539 124.141H259.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M257.531 124.141V124.141' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M255.539 124.141H259.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M312.442 73.664V73.664' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M310.449 73.664H314.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M312.442 73.664V73.664' fill='#e1c2e1'/>
+<path clip-path='url(#clip6)' d='M310.449 73.664H314.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M151.324 186.074H154.563V121.762H151.324ZM206.231 186.074H209.469V123.891H206.231ZM261.141 186.074H264.379V121.321H261.141ZM316.051 186.074H319.289V94.52H316.051Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M151.324 186.074H154.563V121.762H151.324ZM206.231 186.074H209.469V123.891H206.231ZM261.141 186.074H264.379V121.321H261.141ZM316.051 186.074H319.289V94.52H316.051Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M152.942 121.762V121.762' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M150.949 121.762H154.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M152.942 121.762V121.762' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M150.949 121.762H154.933' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M207.852 123.891V123.891' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M205.86 123.89H209.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M207.852 123.891V123.891' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M205.86 123.89H209.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M262.762 121.321V121.321' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M260.769 121.321H264.753' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M262.762 121.321V121.321' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M260.769 121.321H264.753' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M317.672 94.52V94.52' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M315.68 94.52H319.664' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M317.672 94.52V94.52' fill='#d1a3d1'/>
+<path clip-path='url(#clip6)' d='M315.68 94.52H319.664' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M156.555 186.074H159.793V122.449H156.555ZM211.461 186.074H214.699V124.328H211.461ZM266.371 186.074H269.609V124.953H266.371ZM321.281 186.074H324.52V106.168H321.281Z' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M156.555 186.074H159.793V122.449H156.555ZM211.461 186.074H214.699V124.328H211.461ZM266.371 186.074H269.609V124.953H266.371ZM321.281 186.074H324.52V106.168H321.281Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M158.172 122.449V122.449' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M156.18 122.449H160.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M158.172 122.449V122.449' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M156.18 122.449H160.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M213.082 124.328V124.328' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M211.09 124.329H215.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M213.082 124.328V124.328' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M211.09 124.329H215.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M267.992 124.953V124.953' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M266 124.953H269.985' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M267.992 124.953V124.953' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M266 124.953H269.985' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M322.902 106.168V106.168' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M320.91 106.168H324.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M322.902 106.168V106.168' fill='#c285c2'/>
+<path clip-path='url(#clip6)' d='M320.91 106.168H324.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M161.785 186.074H165.024V123.891H161.785ZM216.692 186.074H219.93V122.262H216.692ZM271.602 186.074H274.84V127.395H271.602ZM326.512 186.074H329.75V125.328H326.512Z' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M161.785 186.074H165.024V123.891H161.785ZM216.692 186.074H219.93V122.262H216.692ZM271.602 186.074H274.84V127.395H271.602ZM326.512 186.074H329.75V125.328H326.512Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M163.403 123.891V123.891' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M161.41 123.89H165.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M163.403 123.891V123.891' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M161.41 123.89H165.394' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M218.313 122.262V122.262' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M216.321 122.262H220.305' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M218.313 122.262V122.262' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M216.321 122.262H220.305' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M273.223 127.395V127.395' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M271.23 127.394H275.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M273.223 127.395V127.395' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M271.23 127.394H275.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M328.133 125.328V125.328' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M326.141 125.329H330.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M328.133 125.328V125.328' fill='#b366b3'/>
+<path clip-path='url(#clip6)' d='M326.141 125.329H330.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M167.016 186.074H170.254V104.914H167.016ZM221.922 186.074H225.16V113.18H221.922ZM276.832 186.074H280.07V100.781H276.832ZM331.742 186.074H334.981V71.848H331.742Z' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M167.016 186.074H170.254V104.914H167.016ZM221.922 186.074H225.16V113.18H221.922ZM276.832 186.074H280.07V100.781H276.832ZM331.742 186.074H334.981V71.848H331.742Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M168.633 104.914V104.914' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M166.641 104.914H170.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M168.633 104.914V104.914' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M166.641 104.914H170.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M223.543 113.18V113.18' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M221.551 113.18H225.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M223.543 113.18V113.18' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M221.551 113.18H225.535' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M278.453 100.781V100.781' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M276.461 100.781H280.446' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M278.453 100.781V100.781' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M276.461 100.781H280.446' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M333.363 71.848V71.848' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M331.371 71.848H335.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M333.363 71.848V71.848' fill='#a447a4'/>
+<path clip-path='url(#clip6)' d='M331.371 71.848H335.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M172.246 186.074H175.485V123.891H172.246ZM227.153 186.074H230.391V122.324H227.153ZM282.063 186.074H285.301V127.395H282.063ZM336.973 186.074H340.211V123.891H336.973Z' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M172.246 186.074H175.485V123.891H172.246ZM227.153 186.074H230.391V122.324H227.153ZM282.063 186.074H285.301V127.395H282.063ZM336.973 186.074H340.211V123.891H336.973Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M173.863 123.891V123.891' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M171.871 123.89H175.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M173.863 123.891V123.891' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M171.871 123.89H175.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M228.774 122.324V122.324' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M226.782 122.325H230.766' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M228.774 122.324V122.324' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M226.782 122.325H230.766' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M283.684 127.395V127.395' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M281.691 127.394H285.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M283.684 127.395V127.395' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M281.691 127.394H285.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M338.594 123.891V123.891' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M336.602 123.89H340.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M338.594 123.891V123.891' fill='#942994'/>
+<path clip-path='url(#clip6)' d='M336.602 123.89H340.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M177.477 186.074H180.715V104.602H177.477ZM232.383 186.074H235.621V113.367H232.383ZM287.293 186.074H290.531V112.117H287.293ZM342.203 186.074H345.442V103.16H342.203Z' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M177.477 186.074H180.715V104.602H177.477ZM232.383 186.074H235.621V113.367H232.383ZM287.293 186.074H290.531V112.117H287.293ZM342.203 186.074H345.442V103.16H342.203Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M179.094 104.602V104.602' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M177.102 104.601H181.086' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M179.094 104.602V104.602' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M177.102 104.601H181.086' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M234.004 113.367V113.367' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M232.012 113.368H235.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M234.004 113.367V113.367' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M232.012 113.368H235.996' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M288.914 112.117V112.117' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M286.922 112.117H290.907' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M288.914 112.117V112.117' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M286.922 112.117H290.907' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M343.824 103.16V103.16' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M341.832 103.16H345.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M343.824 103.16V103.16' fill='#850a85'/>
+<path clip-path='url(#clip6)' d='M341.832 103.16H345.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M182.707 186.074H185.945V123.324H182.707ZM237.613 186.074H240.852V117.754H237.613ZM292.524 186.074H295.762V121.508H292.524ZM347.434 186.074H350.672V117.375H347.434Z' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M182.707 186.074H185.945V123.324H182.707ZM237.613 186.074H240.852V117.754H237.613ZM292.524 186.074H295.762V121.508H292.524ZM347.434 186.074H350.672V117.375H347.434Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M184.324 123.324V123.324' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M182.332 123.325H186.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M184.324 123.324V123.324' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M182.332 123.325H186.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M239.234 117.754V117.754' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M237.243 117.754H241.227' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M239.234 117.754V117.754' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M237.243 117.754H241.227' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M294.145 121.508V121.508' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M292.152 121.508H296.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M294.145 121.508V121.508' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M292.152 121.508H296.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M349.055 117.375V117.375' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M347.063 117.375H351.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M349.055 117.375V117.375' fill='#760076'/>
+<path clip-path='url(#clip6)' d='M347.063 117.375H351.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip6)' d='M287.102 233.301H355.387V211.324H287.102Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 122.136 88.837)'>
+<use x='168.285' xlink:href='#g1-72' y='129.265'/>
+<use x='172.021' xlink:href='#g1-80' y='129.265'/>
+<use x='175.402' xlink:href='#g1-45' y='129.265'/>
+<use x='177.167' xlink:href='#g1-90' y='129.265'/>
+<use x='180.401' xlink:href='#g1-52' y='129.265'/>
+<use x='183.047' xlink:href='#g1-45' y='129.265'/>
+<use x='184.812' xlink:href='#g1-71' y='129.265'/>
+<use x='188.34' xlink:href='#g1-52' y='129.265'/>
+<use x='190.987' xlink:href='#g1-44' y='129.265'/>
+<use x='194.221' xlink:href='#g1-49' y='129.265'/>
+<use x='196.867' xlink:href='#g1-54' y='129.265'/>
+<use x='199.514' xlink:href='#g1-71' y='129.265'/>
+<use x='203.042' xlink:href='#g1-98' y='129.265'/>
+<use x='168.285' xlink:href='#g1-56' y='134.884'/>
+<use x='170.931' xlink:href='#g1-45' y='134.884'/>
+<use x='172.695' xlink:href='#g1-99' y='134.884'/>
+<use x='175.048' xlink:href='#g1-111' y='134.884'/>
+<use x='177.547' xlink:href='#g1-114' y='134.884'/>
+<use x='179.355' xlink:href='#g1-101' y='134.884'/>
+<use x='183.471' xlink:href='#g1-73' y='134.884'/>
+<use x='184.941' xlink:href='#g1-110' y='134.884'/>
+<use x='187.674' xlink:href='#g1-116' y='134.884'/>
+<use x='189.585' xlink:href='#g1-101' y='134.884'/>
+<use x='191.938' xlink:href='#g1-108' y='134.884'/>
+<use x='194.965' xlink:href='#g1-88' y='134.884'/>
+<use x='198.493' xlink:href='#g1-69' y='134.884'/>
+<use x='201.667' xlink:href='#g1-79' y='134.884'/>
+<use x='205.576' xlink:href='#g1-78' y='134.884'/>
+<use x='211.076' xlink:href='#g1-64' y='134.884'/>
+<use x='214.605' xlink:href='#g1-50' y='134.884'/>
+<use x='217.251' xlink:href='#g1-46' y='134.884'/>
+<use x='218.721' xlink:href='#g1-55' y='134.884'/>
+<use x='221.368' xlink:href='#g1-71' y='134.884'/>
+<use x='224.896' xlink:href='#g1-104' y='134.884'/>
+<use x='227.629' xlink:href='#g1-122' y='134.884'/>
+<use x='168.285' xlink:href='#g1-85' y='140.503'/>
+<use x='171.917' xlink:href='#g1-98' y='140.503'/>
+<use x='174.65' xlink:href='#g1-117' y='140.503'/>
+<use x='177.383' xlink:href='#g1-110' y='140.503'/>
+<use x='180.116' xlink:href='#g1-116' y='140.503'/>
+<use x='182.027' xlink:href='#g1-117' y='140.503'/>
+<use x='186.524' xlink:href='#g1-49' y='140.503'/>
+<use x='189.17' xlink:href='#g1-56' y='140.503'/>
+<use x='191.817' xlink:href='#g1-46' y='140.503'/>
+<use x='193.287' xlink:href='#g1-48' y='140.503'/>
+<use x='195.933' xlink:href='#g1-52' y='140.503'/>
+<use x='198.58' xlink:href='#g1-46' y='140.503'/>
+<use x='200.05' xlink:href='#g1-49' y='140.503'/>
+<use x='202.696' xlink:href='#g1-44' y='140.503'/>
+<use x='205.931' xlink:href='#g1-71' y='140.503'/>
+<use x='209.459' xlink:href='#g1-67' y='140.503'/>
+<use x='212.841' xlink:href='#g1-67' y='140.503'/>
+<use x='217.986' xlink:href='#g1-55' y='140.503'/>
+<use x='220.633' xlink:href='#g1-46' y='140.503'/>
+<use x='222.103' xlink:href='#g1-52' y='140.503'/>
+<use x='224.749' xlink:href='#g1-46' y='140.503'/>
+<use x='226.219' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 3.612 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 58.522 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.431 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 168.341 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 8.843 285.523)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 63.752 285.398)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.662 286.4)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 173.571 235.926)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-55' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 14.073 284.02)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 68.983 286.149)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 123.892 283.582)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 178.802 256.779)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-52' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 19.304 284.709)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 74.213 286.588)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 129.123 287.214)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-56' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 184.032 268.427)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-56' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 24.534 286.149)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 79.444 284.521)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 134.353 289.656)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-52' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 189.263 287.59)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 29.765 267.175)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-51' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 84.674 275.441)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 139.584 263.042)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-51' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.493 234.11)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-56' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 34.995 286.149)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 89.905 284.584)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 144.814 289.656)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-52' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.724 286.149)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 40.226 266.862)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-51' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.135 275.629)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 150.045 274.376)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-56' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.954 265.421)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-51' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 45.456 285.586)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.366 280.012)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 155.275 283.77)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 210.185 279.637)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -27.345 343.63)'>
+<use x='168.285' xlink:href='#g0-82' y='140.503'/>
+<use x='174.255' xlink:href='#g0-101' y='140.503'/>
+<use x='178.351' xlink:href='#g0-108' y='140.503'/>
+<use x='180.551' xlink:href='#g0-97' y='140.503'/>
+<use x='184.979' xlink:href='#g0-116' y='140.503'/>
+<use x='188.307' xlink:href='#g0-105' y='140.503'/>
+<use x='190.507' xlink:href='#g0-118' y='140.503'/>
+<use x='194.755' xlink:href='#g0-101' y='140.503'/>
+<use x='201.922' xlink:href='#g0-114' y='140.503'/>
+<use x='205.07' xlink:href='#g0-115' y='140.503'/>
+<use x='208.603' xlink:href='#g0-115' y='140.503'/>
+<use x='215.207' xlink:href='#g2-40' y='140.503'/>
+<use x='218.5' xlink:href='#g2-108' y='140.503'/>
+<use x='220.521' xlink:href='#g2-111' y='140.503'/>
+<use x='224.52' xlink:href='#g2-119' y='140.503'/>
+<use x='230.068' xlink:href='#g2-101' y='140.503'/>
+<use x='233.832' xlink:href='#g2-114' y='140.503'/>
+<use x='239.547' xlink:href='#g2-105' y='140.503'/>
+<use x='241.567' xlink:href='#g2-115' y='140.503'/>
+<use x='247.636' xlink:href='#g2-98' y='140.503'/>
+<use x='252.244' xlink:href='#g2-101' y='140.503'/>
+<use x='256.008' xlink:href='#g2-116' y='140.503'/>
+<use x='259.066' xlink:href='#g2-116' y='140.503'/>
+<use x='262.124' xlink:href='#g2-101' y='140.503'/>
+<use x='265.887' xlink:href='#g2-114' y='140.503'/>
+<use x='268.779' xlink:href='#g2-41' y='140.503'/>
+</g>
+<path d='M136.149 231.446H376.824V214.453H136.149Z' fill='#ffffff'/>
+<path d='M136.149 231.446H376.824V214.453H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='#f0e0f0'/>
+<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -33.522 84.43)'>
+<use x='185.011' xlink:href='#g2-109' y='140.503'/>
+<use x='191.736' xlink:href='#g2-105' y='140.503'/>
+</g>
+<path d='M163.422 224.941H166.41V216.973H163.422ZM169.398 224.941H172.391V218.965H169.398Z' fill='#e1c2e1'/>
+<path d='M163.422 224.941H166.41V216.972H163.422ZM169.398 224.941H172.391V218.964H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.56 83.976)'>
+<use x='208.137' xlink:href='#g2-116' y='140.503'/>
+<use x='211.195' xlink:href='#g2-99' y='140.503'/>
+</g>
+<path d='M185.586 224.941H188.574V216.973H185.586ZM191.563 224.941H194.555V218.965H191.563Z' fill='#d1a3d1'/>
+<path d='M185.586 224.941H188.574V216.972H185.586ZM191.563 224.941H194.555V218.964H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.159 84.43)'>
+<use x='229.9' xlink:href='#g2-106' y='140.503'/>
+<use x='232.155' xlink:href='#g2-101' y='140.503'/>
+</g>
+<path d='M206.949 224.941H209.938V216.973H206.949ZM212.926 224.941H215.914V218.965H212.926Z' fill='#c285c2'/>
+<path d='M206.949 224.941H209.938V216.972H206.949ZM212.926 224.941H215.914V218.964H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.958 83.47)'>
+<use x='252.061' xlink:href='#g2-115' y='140.503'/>
+<use x='255.307' xlink:href='#g2-110' y='140.503'/>
+</g>
+<path d='M229.91 224.941H232.898V216.973H229.91ZM235.887 224.941H238.875V218.965H235.887Z' fill='#b366b3'/>
+<path d='M229.91 224.941H232.898V216.972H229.91ZM235.887 224.941H238.875V218.964H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.781 83.47)'>
+<use x='274.845' xlink:href='#g2-114' y='140.503'/>
+<use x='277.737' xlink:href='#g2-112' y='140.503'/>
+</g>
+<path d='M252.516 224.941H255.504V216.973H252.516ZM258.496 224.941H261.484V218.965H258.496Z' fill='#a447a4'/>
+<path d='M252.516 224.941H255.504V216.972H252.516ZM258.496 224.941H261.484V218.964H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.001 84.467)'>
+<use x='303.672' xlink:href='#g2-104' y='140.503'/>
+<use x='308.045' xlink:href='#g2-111' y='140.503'/>
+<use x='312.279' xlink:href='#g2-97' y='140.503'/>
+<use x='316.112' xlink:href='#g2-114' y='140.503'/>
+<use x='319.004' xlink:href='#g2-100' y='140.503'/>
+</g>
+<path d='M287.563 224.941H290.551V216.973H287.563ZM293.543 224.941H296.531V218.965H293.543Z' fill='#942994'/>
+<path d='M287.563 224.941H290.551V216.972H287.563ZM293.543 224.941H296.531V218.964H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.472 84.467)'>
+<use x='337.19' xlink:href='#g2-103' y='140.503'/>
+<use x='341.424' xlink:href='#g2-108' y='140.503'/>
+<use x='343.444' xlink:href='#g2-105' y='140.503'/>
+<use x='345.464' xlink:href='#g2-98' y='140.503'/>
+<use x='350.072' xlink:href='#g2-99' y='140.503'/>
+</g>
+<path d='M319.551 224.941H322.539V216.973H319.551ZM325.527 224.941H328.52V218.965H325.527Z' fill='#850a85'/>
+<path d='M319.551 224.941H322.539V216.972H319.551ZM325.527 224.941H328.52V218.964H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.051 84.467)'>
+<use x='366.757' xlink:href='#g2-116' y='140.503'/>
+<use x='369.815' xlink:href='#g2-98' y='140.503'/>
+<use x='374.187' xlink:href='#g2-98' y='140.503'/>
+</g>
+<path d='M346.699 224.941H349.688V216.973H346.699ZM352.676 224.941H355.664V218.965H352.676Z' fill='#760076'/>
+<path d='M346.699 224.941H349.688V216.972H346.699ZM352.676 224.941H355.664V218.964H352.676Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.145 84.43)'>
+<use x='393.997' xlink:href='#g2-115' y='140.503'/>
+<use x='397.243' xlink:href='#g2-109' y='140.503'/>
+<use x='403.968' xlink:href='#g2-105' y='140.503'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='182.025pt' version='1.1' viewBox='52.938 51.674 270.487 182.025' width='270.487pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<defs>
+<clipPath id='clip5'>
+<path d='M82.148 186.074H301.789V60.828H82.148Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-46' transform='scale(1.6)' xlink:href='#g1-46'/>
+<use id='g2-48' transform='scale(1.6)' xlink:href='#g1-48'/>
+<use id='g2-50' transform='scale(1.6)' xlink:href='#g1-50'/>
+<use id='g2-51' transform='scale(1.6)' xlink:href='#g1-51'/>
+<use id='g2-52' transform='scale(1.6)' xlink:href='#g1-52'/>
+<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/>
+<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/>
+<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/>
+<use id='g2-107' transform='scale(1.6)' xlink:href='#g1-107'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/>
+<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/>
+<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/>
+<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/>
+<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/>
+<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/>
+<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/>
+<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/>
+<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/>
+<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/>
+<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/>
+<path d='M1.489 -1.355L2.376 -2.212H1.893L0.827 -1.181V-3.457H0.438V0H0.807V-0.697L1.23 -1.106L2.052 0H2.491L1.489 -1.355Z' id='g1-107'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page5'>
+<path d='M137.059 194.93V186.074M191.969 194.93V186.074M246.879 194.93V186.074M137.059 51.973V60.828M191.969 51.973V60.828M246.879 51.973V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M109.606 190.324V186.074M164.516 190.324V186.074M219.422 190.324V186.074M274.332 190.324V186.074M109.606 56.574V60.828M164.516 56.574V60.828M219.422 56.574V60.828M274.332 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 186.074H86.402M82.148 154.762H86.402M82.148 123.449H86.402M82.148 92.141H86.402M82.148 60.828H86.402M301.789 186.074H297.535M301.789 154.762H297.535M301.789 123.449H297.535M301.789 92.141H297.535M301.789 60.828H297.535' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 186.074V60.828H301.789V186.074H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -18.291 59.571)'>
+<use x='114.487' xlink:href='#g2-54' y='140.503'/>
+<use x='118.721' xlink:href='#g2-48' y='140.503'/>
+<use x='122.955' xlink:href='#g2-50' y='140.503'/>
+<use x='127.189' xlink:href='#g2-46' y='140.503'/>
+<use x='129.541' xlink:href='#g2-103' y='140.503'/>
+<use x='133.776' xlink:href='#g2-99' y='140.503'/>
+<use x='137.539' xlink:href='#g2-99' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 27.05 59.571)'>
+<use x='114.487' xlink:href='#g2-54' y='140.503'/>
+<use x='118.721' xlink:href='#g2-50' y='140.503'/>
+<use x='122.955' xlink:href='#g2-48' y='140.503'/>
+<use x='127.189' xlink:href='#g2-46' y='140.503'/>
+<use x='129.541' xlink:href='#g2-111' y='140.503'/>
+<use x='133.776' xlink:href='#g2-109' y='140.503'/>
+<use x='140.501' xlink:href='#g2-110' y='140.503'/>
+<use x='144.873' xlink:href='#g2-101' y='140.503'/>
+<use x='148.637' xlink:href='#g2-116' y='140.503'/>
+<use x='151.695' xlink:href='#g2-112' y='140.503'/>
+<use x='156.067' xlink:href='#g2-112' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 78.694 59.571)'>
+<use x='114.487' xlink:href='#g2-54' y='140.503'/>
+<use x='118.721' xlink:href='#g2-50' y='140.503'/>
+<use x='122.955' xlink:href='#g2-51' y='140.503'/>
+<use x='127.189' xlink:href='#g2-46' y='140.503'/>
+<use x='129.541' xlink:href='#g2-120' y='140.503'/>
+<use x='133.444' xlink:href='#g2-97' y='140.503'/>
+<use x='137.512' xlink:href='#g2-108' y='140.503'/>
+<use x='139.532' xlink:href='#g2-97' y='140.503'/>
+<use x='143.6' xlink:href='#g2-110' y='140.503'/>
+<use x='147.973' xlink:href='#g2-99' y='140.503'/>
+<use x='151.736' xlink:href='#g2-98' y='140.503'/>
+<use x='156.109' xlink:href='#g2-109' y='140.503'/>
+<use x='162.834' xlink:href='#g2-107' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 134.081 59.571)'>
+<use x='114.487' xlink:href='#g2-54' y='140.503'/>
+<use x='118.721' xlink:href='#g2-52' y='140.503'/>
+<use x='122.955' xlink:href='#g2-56' y='140.503'/>
+<use x='127.189' xlink:href='#g2-46' y='140.503'/>
+<use x='129.541' xlink:href='#g2-101' y='140.503'/>
+<use x='133.305' xlink:href='#g2-120' y='140.503'/>
+<use x='137.207' xlink:href='#g2-99' y='140.503'/>
+<use x='140.971' xlink:href='#g2-104' y='140.503'/>
+<use x='145.344' xlink:href='#g2-97' y='140.503'/>
+<use x='149.412' xlink:href='#g2-110' y='140.503'/>
+<use x='153.784' xlink:href='#g2-103' y='140.503'/>
+<use x='158.018' xlink:href='#g2-101' y='140.503'/>
+<use x='161.782' xlink:href='#g2-50' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 47.205)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 15.894)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-53' y='140.503'/>
+<use x='121.25' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -15.418)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -46.729)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-53' y='140.503'/>
+<use x='121.25' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -78.041)'>
+<use x='114.487' xlink:href='#g1-50' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-120' y='140.503'/>
+</g>
+<path clip-path='url(#clip5)' d='M82.148 123.449H301.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M87.063 186.074H90.301V123.449H87.063ZM141.973 186.074H145.211V123.449H141.973ZM196.883 186.074H200.121V123.449H196.883ZM251.793 186.074H255.031V123.449H251.793Z' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M87.063 186.074H90.301V123.449H87.063ZM141.973 186.074H145.211V123.449H141.973ZM196.883 186.074H200.121V123.449H196.883ZM251.793 186.074H255.031V123.449H251.793Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M88.684 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M86.691 123.449H90.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M88.684 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M86.691 123.449H90.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M143.594 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M141.602 123.449H145.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M143.594 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M141.602 123.449H145.586' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M198.5 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M196.511 123.449H200.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M198.5 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M196.511 123.449H200.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M253.41 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M251.418 123.449H255.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M253.41 123.449V123.449' fill='#e0e0f0'/>
+<path clip-path='url(#clip5)' d='M251.418 123.449H255.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M92.293 186.074H95.531V103.535H92.293ZM147.203 186.074H150.441V125.77H147.203ZM202.113 186.074H205.352V124.203H202.113ZM257.024 186.074H260.262V123.074H257.024Z' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M92.293 186.074H95.531V103.535H92.293ZM147.203 186.074H150.441V125.77H147.203ZM202.113 186.074H205.352V124.203H202.113ZM257.024 186.074H260.262V123.074H257.024Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M93.914 103.535V103.535' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M91.922 103.535H95.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M93.914 103.535V103.535' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M91.922 103.535H95.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M148.824 125.77V125.77' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M146.832 125.77H150.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M148.824 125.77V125.77' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M146.832 125.77H150.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M203.731 124.203V124.203' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M201.742 124.203H205.727' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M203.731 124.203V124.203' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M201.742 124.203H205.727' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M258.641 123.074V123.074' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M256.648 123.074H260.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M258.641 123.074V123.074' fill='#c2c2e1'/>
+<path clip-path='url(#clip5)' d='M256.648 123.074H260.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M97.524 186.074H100.762V123.324H97.524ZM152.434 186.074H155.672V123.828H152.434ZM207.344 186.074H210.582V124.203H207.344ZM262.254 186.074H265.492V123.137H262.254Z' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M97.524 186.074H100.762V123.324H97.524ZM152.434 186.074H155.672V123.828H152.434ZM207.344 186.074H210.582V124.203H207.344ZM262.254 186.074H265.492V123.137H262.254Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M99.145 123.324V123.324' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M97.152 123.325H101.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M99.145 123.324V123.324' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M97.152 123.325H101.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M154.055 123.828V123.828' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M152.063 123.829H156.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M154.055 123.828V123.828' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M152.063 123.829H156.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M208.961 124.203V124.203' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M206.972 124.203H210.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M208.961 124.203V124.203' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M206.972 124.203H210.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M263.871 123.137V123.137' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M261.879 123.137H265.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M263.871 123.137V123.137' fill='#a3a3d1'/>
+<path clip-path='url(#clip5)' d='M261.879 123.137H265.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M102.754 186.074H105.992V123.449H102.754ZM157.664 186.074H160.902V125.77H157.664ZM212.574 186.074H215.813V125.391H212.574ZM267.484 186.074H270.723V122.449H267.484Z' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M102.754 186.074H105.992V123.449H102.754ZM157.664 186.074H160.902V125.77H157.664ZM212.574 186.074H215.813V125.391H212.574ZM267.484 186.074H270.723V122.449H267.484Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M104.375 123.449V123.449' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M102.383 123.449H106.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M104.375 123.449V123.449' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M102.383 123.449H106.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M159.285 125.77V125.77' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M157.293 125.77H161.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M159.285 125.77V125.77' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M157.293 125.77H161.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M214.192 125.391V125.391' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M212.203 125.39H216.188' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M214.192 125.391V125.391' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M212.203 125.39H216.188' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M269.102 122.449V122.449' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M267.109 122.449H271.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M269.102 122.449V122.449' fill='#8585c2'/>
+<path clip-path='url(#clip5)' d='M267.109 122.449H271.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M107.984 186.074H111.223V122.699H107.984ZM162.895 186.074H166.133V117.188H162.895ZM217.805 186.074H221.043V104.727H217.805ZM272.715 186.074H275.953V122.762H272.715Z' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M107.984 186.074H111.223V122.699H107.984ZM162.895 186.074H166.133V117.188H162.895ZM217.805 186.074H221.043V104.727H217.805ZM272.715 186.074H275.953V122.762H272.715Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M109.606 122.699V122.699' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M107.613 122.699H111.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M109.606 122.699V122.699' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M107.613 122.699H111.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M164.516 117.188V117.188' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M162.524 117.188H166.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M164.516 117.188V117.188' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M162.524 117.188H166.508' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M219.422 104.727V104.727' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M217.433 104.727H221.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M219.422 104.727V104.727' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M217.433 104.727H221.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M274.332 122.762V122.762' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M272.34 122.762H276.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M274.332 122.762V122.762' fill='#6666b3'/>
+<path clip-path='url(#clip5)' d='M272.34 122.762H276.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M113.215 186.074H116.453V123.574H113.215ZM168.125 186.074H171.363V119.696H168.125ZM223.035 186.074H226.274V122.637H223.035ZM277.945 186.074H281.184V122.449H277.945Z' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M113.215 186.074H116.453V123.574H113.215ZM168.125 186.074H171.363V119.696H168.125ZM223.035 186.074H226.274V122.637H223.035ZM277.945 186.074H281.184V122.449H277.945Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M114.836 123.574V123.574' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M112.844 123.574H116.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M114.836 123.574V123.574' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M112.844 123.574H116.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M169.746 119.696V119.696' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M167.754 119.695H171.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M169.746 119.696V119.696' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M167.754 119.695H171.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M224.652 122.637V122.637' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M222.664 122.637H226.649' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M224.652 122.637V122.637' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M222.664 122.637H226.649' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M279.563 122.449V122.449' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M277.57 122.449H281.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M279.563 122.449V122.449' fill='#4747a4'/>
+<path clip-path='url(#clip5)' d='M277.57 122.449H281.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M118.445 186.074H121.684V122.574H118.445ZM173.356 186.074H176.594V117.25H173.356ZM228.266 186.074H231.504V105.477H228.266ZM283.176 186.074H286.414V121.887H283.176Z' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M118.445 186.074H121.684V122.574H118.445ZM173.356 186.074H176.594V117.25H173.356ZM228.266 186.074H231.504V105.477H228.266ZM283.176 186.074H286.414V121.887H283.176Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M120.066 122.574V122.574' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M118.074 122.574H122.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M120.066 122.574V122.574' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M118.074 122.574H122.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M174.977 117.25V117.25' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M172.985 117.25H176.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M174.977 117.25V117.25' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M172.985 117.25H176.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M229.883 105.477V105.477' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M227.894 105.477H231.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M229.883 105.477V105.477' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M227.894 105.477H231.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M284.793 121.887V121.887' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M282.801 121.886H286.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M284.793 121.887V121.887' fill='#292994'/>
+<path clip-path='url(#clip5)' d='M282.801 121.886H286.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M123.676 186.074H126.914V106.606H123.676ZM178.586 186.074H181.824V122.699H178.586ZM233.496 186.074H236.734V122.449H233.496ZM288.406 186.074H291.645V122.012H288.406Z' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M123.676 186.074H126.914V106.606H123.676ZM178.586 186.074H181.824V122.699H178.586ZM233.496 186.074H236.734V122.449H233.496ZM288.406 186.074H291.645V122.012H288.406Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M125.297 106.606V106.606' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M123.305 106.605H127.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M125.297 106.606V106.606' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M123.305 106.605H127.289' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M180.207 122.699V122.699' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M178.215 122.699H182.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M180.207 122.699V122.699' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M178.215 122.699H182.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M235.113 122.449V122.449' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M233.125 122.449H237.11' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M235.113 122.449V122.449' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M233.125 122.449H237.11' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M290.024 122.012V122.012' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M288.031 122.012H292.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M290.024 122.012V122.012' fill='#0a0a85'/>
+<path clip-path='url(#clip5)' d='M288.031 122.012H292.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M128.906 186.074H132.145V120.633H128.906ZM183.817 186.074H187.055V122.074H183.817ZM238.727 186.074H241.965V119.696H238.727ZM293.637 186.074H296.875V123.387H293.637Z' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M128.906 186.074H132.145V120.633H128.906ZM183.817 186.074H187.055V122.074H183.817ZM238.727 186.074H241.965V119.696H238.727ZM293.637 186.074H296.875V123.387H293.637Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M130.527 120.633V120.633' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M128.535 120.633H132.52' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M130.527 120.633V120.633' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M128.535 120.633H132.52' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M185.438 122.074V122.074' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M183.446 122.074H187.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M185.438 122.074V122.074' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M183.446 122.074H187.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M240.344 119.696V119.696' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M238.355 119.695H242.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M240.344 119.696V119.696' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M238.355 119.695H242.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M295.254 123.387V123.387' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M293.262 123.387H297.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M295.254 123.387V123.387' fill='#000076'/>
+<path clip-path='url(#clip5)' d='M293.262 123.387H297.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip5)' d='M233.301 233.301H301.59V211.324H233.301Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 122.136 88.837)'>
+<use x='114.487' xlink:href='#g1-72' y='129.265'/>
+<use x='118.223' xlink:href='#g1-80' y='129.265'/>
+<use x='121.604' xlink:href='#g1-45' y='129.265'/>
+<use x='123.368' xlink:href='#g1-90' y='129.265'/>
+<use x='126.603' xlink:href='#g1-52' y='129.265'/>
+<use x='129.249' xlink:href='#g1-45' y='129.265'/>
+<use x='131.013' xlink:href='#g1-71' y='129.265'/>
+<use x='134.542' xlink:href='#g1-52' y='129.265'/>
+<use x='137.188' xlink:href='#g1-44' y='129.265'/>
+<use x='140.423' xlink:href='#g1-49' y='129.265'/>
+<use x='143.069' xlink:href='#g1-54' y='129.265'/>
+<use x='145.715' xlink:href='#g1-71' y='129.265'/>
+<use x='149.244' xlink:href='#g1-98' y='129.265'/>
+<use x='114.487' xlink:href='#g1-56' y='134.884'/>
+<use x='117.133' xlink:href='#g1-45' y='134.884'/>
+<use x='118.897' xlink:href='#g1-99' y='134.884'/>
+<use x='121.25' xlink:href='#g1-111' y='134.884'/>
+<use x='123.749' xlink:href='#g1-114' y='134.884'/>
+<use x='125.556' xlink:href='#g1-101' y='134.884'/>
+<use x='129.673' xlink:href='#g1-73' y='134.884'/>
+<use x='131.143' xlink:href='#g1-110' y='134.884'/>
+<use x='133.876' xlink:href='#g1-116' y='134.884'/>
+<use x='135.787' xlink:href='#g1-101' y='134.884'/>
+<use x='138.14' xlink:href='#g1-108' y='134.884'/>
+<use x='141.166' xlink:href='#g1-88' y='134.884'/>
+<use x='144.695' xlink:href='#g1-69' y='134.884'/>
+<use x='147.869' xlink:href='#g1-79' y='134.884'/>
+<use x='151.778' xlink:href='#g1-78' y='134.884'/>
+<use x='157.278' xlink:href='#g1-64' y='134.884'/>
+<use x='160.807' xlink:href='#g1-50' y='134.884'/>
+<use x='163.453' xlink:href='#g1-46' y='134.884'/>
+<use x='164.923' xlink:href='#g1-55' y='134.884'/>
+<use x='167.57' xlink:href='#g1-71' y='134.884'/>
+<use x='171.098' xlink:href='#g1-104' y='134.884'/>
+<use x='173.831' xlink:href='#g1-122' y='134.884'/>
+<use x='114.487' xlink:href='#g1-85' y='140.503'/>
+<use x='118.119' xlink:href='#g1-98' y='140.503'/>
+<use x='120.852' xlink:href='#g1-117' y='140.503'/>
+<use x='123.585' xlink:href='#g1-110' y='140.503'/>
+<use x='126.317' xlink:href='#g1-116' y='140.503'/>
+<use x='128.229' xlink:href='#g1-117' y='140.503'/>
+<use x='132.726' xlink:href='#g1-49' y='140.503'/>
+<use x='135.372' xlink:href='#g1-56' y='140.503'/>
+<use x='138.018' xlink:href='#g1-46' y='140.503'/>
+<use x='139.489' xlink:href='#g1-48' y='140.503'/>
+<use x='142.135' xlink:href='#g1-52' y='140.503'/>
+<use x='144.781' xlink:href='#g1-46' y='140.503'/>
+<use x='146.252' xlink:href='#g1-49' y='140.503'/>
+<use x='148.898' xlink:href='#g1-44' y='140.503'/>
+<use x='152.132' xlink:href='#g1-71' y='140.503'/>
+<use x='155.661' xlink:href='#g1-67' y='140.503'/>
+<use x='159.042' xlink:href='#g1-67' y='140.503'/>
+<use x='164.188' xlink:href='#g1-55' y='140.503'/>
+<use x='166.834' xlink:href='#g1-46' y='140.503'/>
+<use x='168.305' xlink:href='#g1-52' y='140.503'/>
+<use x='170.951' xlink:href='#g1-46' y='140.503'/>
+<use x='172.421' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -50.186 231.913)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 4.724 231.913)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.633 231.913)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 114.543 231.913)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -44.955 211.999)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-51' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 9.954 234.23)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-57' y='140.503'/>
+<use x='121.25' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.864 232.665)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-57' y='140.503'/>
+<use x='121.25' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 119.773 231.537)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -39.725 231.788)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 15.185 232.289)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-57' y='140.503'/>
+<use x='121.25' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 70.094 232.665)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-57' y='140.503'/>
+<use x='121.25' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 125.004 231.6)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -34.494 231.913)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 20.415 234.23)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-57' y='140.503'/>
+<use x='121.25' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 75.325 233.854)'>
+<use x='114.487' xlink:href='#g1-48' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-57' y='140.503'/>
+<use x='121.25' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 130.234 230.911)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.264 231.162)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 25.646 225.651)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-49' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 80.555 213.189)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-51' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.465 231.224)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.033 232.038)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 30.876 228.156)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.786 231.099)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.695 230.911)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -18.803 231.036)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.107 225.713)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-49' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 91.016 213.94)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-50' y='140.503'/>
+<use x='121.25' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 145.926 230.348)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -13.572 215.068)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-50' y='140.503'/>
+<use x='121.25' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 41.337 231.162)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 96.247 230.911)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.156 230.473)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -8.342 229.095)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-52' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 46.568 230.535)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 101.477 228.156)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.387 231.85)'>
+<use x='114.487' xlink:href='#g1-49' y='140.503'/>
+<use x='117.133' xlink:href='#g1-46' y='140.503'/>
+<use x='118.603' xlink:href='#g1-48' y='140.503'/>
+<use x='121.25' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -81.143 293.197)'>
+<use x='114.487' xlink:href='#g0-82' y='140.503'/>
+<use x='120.457' xlink:href='#g0-101' y='140.503'/>
+<use x='124.553' xlink:href='#g0-108' y='140.503'/>
+<use x='126.753' xlink:href='#g0-97' y='140.503'/>
+<use x='131.181' xlink:href='#g0-116' y='140.503'/>
+<use x='134.509' xlink:href='#g0-105' y='140.503'/>
+<use x='136.709' xlink:href='#g0-118' y='140.503'/>
+<use x='140.957' xlink:href='#g0-101' y='140.503'/>
+<use x='148.124' xlink:href='#g0-116' y='140.503'/>
+<use x='151.452' xlink:href='#g0-105' y='140.503'/>
+<use x='153.652' xlink:href='#g0-109' y='140.503'/>
+<use x='160.972' xlink:href='#g0-101' y='140.503'/>
+<use x='168.139' xlink:href='#g2-40' y='140.503'/>
+<use x='171.432' xlink:href='#g2-108' y='140.503'/>
+<use x='173.453' xlink:href='#g2-111' y='140.503'/>
+<use x='177.452' xlink:href='#g2-119' y='140.503'/>
+<use x='183' xlink:href='#g2-101' y='140.503'/>
+<use x='186.764' xlink:href='#g2-114' y='140.503'/>
+<use x='192.479' xlink:href='#g2-105' y='140.503'/>
+<use x='194.499' xlink:href='#g2-115' y='140.503'/>
+<use x='200.568' xlink:href='#g2-98' y='140.503'/>
+<use x='205.176' xlink:href='#g2-101' y='140.503'/>
+<use x='208.94' xlink:href='#g2-116' y='140.503'/>
+<use x='211.998' xlink:href='#g2-116' y='140.503'/>
+<use x='215.056' xlink:href='#g2-101' y='140.503'/>
+<use x='218.819' xlink:href='#g2-114' y='140.503'/>
+<use x='221.711' xlink:href='#g2-41' y='140.503'/>
+</g>
+<path d='M82.348 231.446H323.027V214.453H82.348Z' fill='#ffffff'/>
+<path d='M82.348 231.446H323.027V214.453H82.348Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M85.535 224.941H88.523V216.972H85.535ZM91.516 224.941H94.504V218.964H91.516Z' fill='#e0e0f0'/>
+<path d='M85.535 224.941H88.523V216.972H85.535ZM91.516 224.941H94.504V218.964H91.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -33.522 84.43)'>
+<use x='131.213' xlink:href='#g2-109' y='140.503'/>
+<use x='137.938' xlink:href='#g2-105' y='140.503'/>
+</g>
+<path d='M109.625 224.941H112.613V216.973H109.625ZM115.602 224.941H118.59V218.965H115.602Z' fill='#c2c2e1'/>
+<path d='M109.625 224.941H112.613V216.972H109.625ZM115.602 224.941H118.59V218.964H115.602Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.56 83.976)'>
+<use x='154.339' xlink:href='#g2-116' y='140.503'/>
+<use x='157.397' xlink:href='#g2-99' y='140.503'/>
+</g>
+<path d='M131.789 224.941H134.777V216.973H131.789ZM137.766 224.941H140.754V218.965H137.766Z' fill='#a3a3d1'/>
+<path d='M131.789 224.941H134.777V216.972H131.789ZM137.766 224.941H140.754V218.964H137.766Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.159 84.43)'>
+<use x='176.102' xlink:href='#g2-106' y='140.503'/>
+<use x='178.357' xlink:href='#g2-101' y='140.503'/>
+</g>
+<path d='M153.152 224.941H156.141V216.973H153.152ZM159.129 224.941H162.117V218.965H159.129Z' fill='#8585c2'/>
+<path d='M153.152 224.941H156.141V216.972H153.152ZM159.129 224.941H162.117V218.964H159.129Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.958 83.47)'>
+<use x='198.263' xlink:href='#g2-115' y='140.503'/>
+<use x='201.509' xlink:href='#g2-110' y='140.503'/>
+</g>
+<path d='M176.113 224.941H179.102V216.973H176.113ZM182.09 224.941H185.078V218.965H182.09Z' fill='#6666b3'/>
+<path d='M176.113 224.941H179.102V216.972H176.113ZM182.09 224.941H185.078V218.964H182.09Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.781 83.47)'>
+<use x='221.047' xlink:href='#g2-114' y='140.503'/>
+<use x='223.939' xlink:href='#g2-112' y='140.503'/>
+</g>
+<path d='M198.719 224.941H201.707V216.973H198.719ZM204.695 224.941H207.684V218.965H204.695Z' fill='#4747a4'/>
+<path d='M198.719 224.941H201.707V216.972H198.719ZM204.695 224.941H207.684V218.964H204.695Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.001 84.467)'>
+<use x='249.874' xlink:href='#g2-104' y='140.503'/>
+<use x='254.246' xlink:href='#g2-111' y='140.503'/>
+<use x='258.481' xlink:href='#g2-97' y='140.503'/>
+<use x='262.314' xlink:href='#g2-114' y='140.503'/>
+<use x='265.206' xlink:href='#g2-100' y='140.503'/>
+</g>
+<path d='M233.766 224.941H236.754V216.973H233.766ZM239.742 224.941H242.731V218.965H239.742Z' fill='#292994'/>
+<path d='M233.766 224.941H236.754V216.972H233.766ZM239.742 224.941H242.731V218.964H239.742Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.472 84.467)'>
+<use x='283.392' xlink:href='#g2-103' y='140.503'/>
+<use x='287.626' xlink:href='#g2-108' y='140.503'/>
+<use x='289.646' xlink:href='#g2-105' y='140.503'/>
+<use x='291.666' xlink:href='#g2-98' y='140.503'/>
+<use x='296.274' xlink:href='#g2-99' y='140.503'/>
+</g>
+<path d='M265.754 224.941H268.742V216.973H265.754ZM271.73 224.941H274.719V218.965H271.73Z' fill='#0a0a85'/>
+<path d='M265.754 224.941H268.742V216.972H265.754ZM271.73 224.941H274.719V218.964H271.73Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.051 84.467)'>
+<use x='312.959' xlink:href='#g2-116' y='140.503'/>
+<use x='316.017' xlink:href='#g2-98' y='140.503'/>
+<use x='320.389' xlink:href='#g2-98' y='140.503'/>
+</g>
+<path d='M292.898 224.941H295.887V216.973H292.898ZM298.879 224.941H301.867V218.965H298.879Z' fill='#000076'/>
+<path d='M292.898 224.941H295.887V216.972H292.898ZM298.879 224.941H301.867V218.964H298.879Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.145 84.43)'>
+<use x='340.198' xlink:href='#g2-115' y='140.503'/>
+<use x='343.444' xlink:href='#g2-109' y='140.503'/>
+<use x='350.169' xlink:href='#g2-105' y='140.503'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<defs>
+<clipPath id='clip3'>
+<path d='M82.148 203.937H434.164V78.691H82.148Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page3'>
+<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 33.989)'>
+<use x='114.487' xlink:href='#g2-99' y='183.949'/>
+<use x='118.25' xlink:href='#g2-102' y='183.949'/>
+<use x='120.838' xlink:href='#g2-114' y='183.949'/>
+<use x='123.73' xlink:href='#g2-97' y='183.949'/>
+<use x='127.798' xlink:href='#g2-99' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 41.401 33.989)'>
+<use x='114.487' xlink:href='#g2-101' y='183.949'/>
+<use x='118.25' xlink:href='#g2-115' y='183.949'/>
+<use x='121.497' xlink:href='#g2-112' y='183.949'/>
+<use x='125.634' xlink:href='#g2-114' y='183.949'/>
+<use x='128.526' xlink:href='#g2-101' y='183.949'/>
+<use x='132.29' xlink:href='#g2-115' y='183.949'/>
+<use x='135.536' xlink:href='#g2-115' y='183.949'/>
+<use x='138.782' xlink:href='#g2-111' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 103.095 33.989)'>
+<use x='114.487' xlink:href='#g2-98' y='183.949'/>
+<use x='118.859' xlink:href='#g2-97' y='183.949'/>
+<use x='122.692' xlink:href='#g2-114' y='183.949'/>
+<use x='125.584' xlink:href='#g2-110' y='183.949'/>
+<use x='129.957' xlink:href='#g2-101' y='183.949'/>
+<use x='133.72' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 162.903 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-101' y='183.949'/>
+<use x='120.271' xlink:href='#g2-97' y='183.949'/>
+<use x='124.339' xlink:href='#g2-110' y='183.949'/>
+<use x='128.711' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 223.526 33.989)'>
+<use x='114.487' xlink:href='#g2-114' y='183.949'/>
+<use x='117.379' xlink:href='#g2-101' y='183.949'/>
+<use x='121.142' xlink:href='#g2-100' y='183.949'/>
+<use x='125.515' xlink:href='#g2-105' y='183.949'/>
+<use x='127.535' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 277.054 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-97' y='183.949'/>
+<use x='120.34' xlink:href='#g2-114' y='183.949'/>
+<use x='123.232' xlink:href='#g2-115' y='183.949'/>
+<use x='126.478' xlink:href='#g2-111' y='183.949'/>
+<use x='130.712' xlink:href='#g2-110' y='183.949'/>
+<use x='135.085' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 21.624)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.688)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.999)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -72.311)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.622)'>
+<use x='114.487' xlink:href='#g1-50' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<path clip-path='url(#clip3)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M87.949 141.316V141.004' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M87.949 141.316V141.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M85.953 141.004H89.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M87.949 141.316V141.629' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M87.949 141.316V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M89.941 141.629H85.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M146.617 141.316V138.937' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M146.617 141.316V138.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M144.625 138.938H148.61' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M146.617 141.316V143.695' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M146.617 141.316V143.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M148.61 143.695H144.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M205.285 141.316V141.066' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M205.285 141.316V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M203.293 141.067H207.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M205.285 141.316V141.566' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M205.285 141.316V141.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M207.278 141.567H203.293' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M263.953 141.316V141.066' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M263.953 141.316V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M261.961 141.067H265.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M263.953 141.316V141.566' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M263.953 141.316V141.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M265.949 141.567H261.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M322.625 141.316V140.812' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M322.625 141.316V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M320.629 140.812H324.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M322.625 141.316V141.816' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M322.625 141.316V141.816' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M324.617 141.816H320.633' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M381.293 141.316V140' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M381.293 141.316V140' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M379.301 140H383.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M381.293 141.316V142.629' fill='#e0e0f0'/>
+<path clip-path='url(#clip3)' d='M381.293 141.316V142.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M383.285 142.629H379.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M91.559 203.937H94.797V139.562H91.559ZM150.227 203.937H153.465V138.621H150.227ZM208.899 203.937H212.133V141.441H208.899ZM267.567 203.937H270.805V138.683H267.567ZM326.234 203.937H329.473V137.871H326.234ZM384.902 203.937H388.141V129.855H384.902Z' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M91.559 203.937H94.797V139.562H91.559ZM150.227 203.937H153.465V138.621H150.227ZM208.899 203.937H212.133V141.441H208.899ZM267.567 203.937H270.805V138.683H267.567ZM326.234 203.937H329.473V137.871H326.234ZM384.902 203.937H388.141V129.855H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M93.18 139.562V139.562' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M91.184 139.563H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M93.18 139.562V139.562' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M91.184 139.563H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M151.848 138.621V138.621' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M149.855 138.621H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M151.848 138.621V138.621' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M149.855 138.621H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M210.516 141.441V141.254' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M210.516 141.441V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M208.523 141.254H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M210.516 141.441V141.629' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M210.516 141.441V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M212.508 141.629H208.523' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M269.184 138.683V138.621' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M269.184 138.683V138.621' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M267.191 138.621H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M269.184 138.683V138.746' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M269.184 138.683V138.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M271.179 138.746H267.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M327.856 137.871V137.558' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M327.856 137.871V137.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M325.859 137.559H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M327.856 137.871V138.183' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M327.856 137.871V138.183' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M329.847 138.183H325.863' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M386.524 129.855V129.543' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M386.524 129.855V129.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M384.531 129.543H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M386.524 129.855V130.168' fill='#c2c2e1'/>
+<path clip-path='url(#clip3)' d='M386.524 129.855V130.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M388.515 130.168H384.531' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M96.789 203.937H100.027V138.746H96.789ZM155.457 203.937H158.695V135.867H155.457ZM214.129 203.937H217.363V141.379H214.129ZM272.797 203.937H276.035V140.25H272.797ZM331.465 203.937H334.703V130.918H331.465ZM390.133 203.937H393.371V115.515H390.133Z' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M96.789 203.937H100.027V138.746H96.789ZM155.457 203.937H158.695V135.867H155.457ZM214.129 203.937H217.363V141.379H214.129ZM272.797 203.937H276.035V140.25H272.797ZM331.465 203.937H334.703V130.918H331.465ZM390.133 203.937H393.371V115.515H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M98.41 138.746V138.558' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M98.41 138.746V138.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M96.414 138.559H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M98.41 138.746V138.937' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M98.41 138.746V138.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M100.402 138.938H96.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M157.078 135.867V135.867' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M155.086 135.867H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M157.078 135.867V135.867' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M155.086 135.867H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M215.746 141.379V141.129' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M215.746 141.379V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M213.754 141.128H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M215.746 141.379V141.629' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M215.746 141.379V141.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M217.739 141.629H213.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M274.414 140.25V140.187' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M274.414 140.25V140.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M272.422 140.187H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M274.414 140.25V140.312' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M274.414 140.25V140.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M276.41 140.312H272.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M333.086 130.918V130.73' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M333.086 130.918V130.73' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M331.09 130.73H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M333.086 130.918V131.109' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M333.086 130.918V131.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M335.078 131.11H331.094' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M391.754 115.515V114.636' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M391.754 115.515V114.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M389.762 114.637H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M391.754 115.515V116.39' fill='#a3a3d1'/>
+<path clip-path='url(#clip3)' d='M391.754 115.515V116.39' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M393.746 116.39H389.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M102.02 203.937H105.258V130.293H102.02ZM160.688 203.937H163.926V133.176H160.688ZM219.359 203.937H222.594V141.066H219.359ZM278.027 203.937H281.266V139.312H278.027ZM336.695 203.937H339.934V136.679H336.695ZM395.363 203.937H398.602V96.789H395.363Z' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M102.02 203.937H105.258V130.293H102.02ZM160.688 203.937H163.926V133.176H160.688ZM219.359 203.937H222.594V141.066H219.359ZM278.027 203.937H281.266V139.312H278.027ZM336.695 203.937H339.934V136.679H336.695ZM395.363 203.937H398.602V96.789H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M103.641 130.293V129.98' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M103.641 130.293V129.98' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M101.644 129.981H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M103.641 130.293V130.605' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M103.641 130.293V130.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M105.633 130.606H101.648' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M162.309 133.176V133.176' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M160.316 133.176H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M162.309 133.176V133.176' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M160.316 133.176H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M220.977 141.066V140.941' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M220.977 141.066V140.941' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M218.984 140.942H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M220.977 141.066V141.191' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M220.977 141.066V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M222.969 141.191H218.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M279.645 139.312V139.125' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M279.645 139.312V139.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M277.652 139.125H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M279.645 139.312V139.5' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M279.645 139.312V139.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M281.64 139.5H277.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M338.317 136.679V136.554' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M338.317 136.679V136.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M336.32 136.555H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M338.317 136.679V136.804' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M338.317 136.679V136.804' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M340.308 136.804H336.324' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M396.984 96.789V96.164' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M396.984 96.789V96.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M394.992 96.164H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M396.984 96.789V97.418' fill='#8585c2'/>
+<path clip-path='url(#clip3)' d='M396.984 96.789V97.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M398.976 97.418H394.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M107.25 203.937H110.488V138.621H107.25ZM165.918 203.937H169.156V137.683H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V131.859H283.258ZM341.926 203.937H345.164V132.988H341.926ZM400.594 203.937H403.832V124.844H400.594Z' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M107.25 203.937H110.488V138.621H107.25ZM165.918 203.937H169.156V137.683H165.918ZM224.59 203.937H227.824V141.254H224.59ZM283.258 203.937H286.496V131.859H283.258ZM341.926 203.937H345.164V132.988H341.926ZM400.594 203.937H403.832V124.844H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M108.871 138.621V138.433' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M108.871 138.621V138.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M106.875 138.434H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M108.871 138.621V138.808' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M108.871 138.621V138.808' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M110.864 138.808H106.879' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M167.539 137.683V136.429' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M167.539 137.683V136.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M165.547 136.43H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M167.539 137.683V138.937' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M167.539 137.683V138.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M169.532 138.938H165.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M226.207 141.254V141.066' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M226.207 141.254V141.066' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M224.215 141.067H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M226.207 141.254V141.441' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M226.207 141.254V141.441' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M228.2 141.442H224.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M284.875 131.859V131.609' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M284.875 131.859V131.609' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M282.883 131.61H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M284.875 131.859V132.109' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M284.875 131.859V132.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M286.868 132.11H282.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M343.547 132.988V132.988' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M341.551 132.988H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M343.547 132.988V132.988' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M341.551 132.988H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M402.215 124.844V124.844' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M400.223 124.843H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M402.215 124.844V124.844' fill='#6666b3'/>
+<path clip-path='url(#clip3)' d='M400.223 124.843H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M112.481 203.937H115.719V136.179H112.481ZM171.149 203.937H174.387V133.176H171.149ZM229.82 203.937H233.055V140.941H229.82ZM288.488 203.937H291.727V134.051H288.488ZM347.156 203.937H350.395V109.129H347.156ZM405.824 203.937H409.063V123.469H405.824Z' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M112.481 203.937H115.719V136.179H112.481ZM171.149 203.937H174.387V133.176H171.149ZM229.82 203.937H233.055V140.941H229.82ZM288.488 203.937H291.727V134.051H288.488ZM347.156 203.937H350.395V109.129H347.156ZM405.824 203.937H409.063V123.469H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M114.098 136.179V135.867' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M114.098 136.179V135.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M112.105 135.867H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M114.098 136.179V136.492' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M114.098 136.179V136.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M116.094 136.492H112.109' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M172.77 133.176V133.176' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M170.777 133.176H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M172.77 133.176V133.176' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M170.777 133.176H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M231.438 140.941V140.687' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M231.438 140.941V140.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M229.445 140.687H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M231.438 140.941V141.191' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M231.438 140.941V141.191' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M233.43 141.191H229.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M290.106 134.051V133.926' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M290.106 134.051V133.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M288.113 133.926H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M290.106 134.051V134.176' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M290.106 134.051V134.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M292.098 134.176H288.113' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M348.777 109.129V108.937' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M348.777 109.129V108.937' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M346.781 108.937H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M348.777 109.129V109.316' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M348.777 109.129V109.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M350.769 109.316H346.785' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M407.445 123.469V122.465' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M407.445 123.469V122.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M405.453 122.465H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M407.445 123.469V124.469' fill='#4747a4'/>
+<path clip-path='url(#clip3)' d='M407.445 123.469V124.469' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M409.437 124.469H405.453' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M117.711 203.937H120.949V139.062H117.711ZM176.379 203.937H179.617V133.176H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V131.734H293.719ZM352.387 203.937H355.625V133.238H352.387ZM411.055 203.937H414.293V124.781H411.055Z' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M117.711 203.937H120.949V139.062H117.711ZM176.379 203.937H179.617V133.176H176.379ZM235.051 203.937H238.285V140.941H235.051ZM293.719 203.937H296.957V131.734H293.719ZM352.387 203.937H355.625V133.238H352.387ZM411.055 203.937H414.293V124.781H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M119.328 139.062V138.871' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M119.328 139.062V138.871' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M117.336 138.871H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M119.328 139.062V139.25' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M119.328 139.062V139.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M121.325 139.25H117.34' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M178 133.176V133.176' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M176.008 133.176H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M178 133.176V133.176' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M176.008 133.176H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M236.668 140.941V140.5' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M236.668 140.941V140.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M234.676 140.5H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M236.668 140.941V141.379' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M236.668 140.941V141.379' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M238.66 141.379H234.675' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M295.336 131.734V131.672' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M295.336 131.734V131.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M293.344 131.672H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M295.336 131.734V131.797' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M295.336 131.734V131.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M297.328 131.797H293.343' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M354.008 133.238V133.176' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M354.008 133.238V133.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M352.012 133.175H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M354.008 133.238V133.301' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M354.008 133.238V133.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M355.999 133.301H352.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M412.676 124.781V124.719' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M412.676 124.781V124.719' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M410.684 124.719H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M412.676 124.781V124.844' fill='#292994'/>
+<path clip-path='url(#clip3)' d='M412.676 124.781V124.844' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M414.667 124.843H410.683' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M122.941 203.937H126.18V127.601H122.941ZM181.609 203.937H184.848V131.797H181.609ZM240.281 203.937H243.516V141.316H240.281ZM298.949 203.937H302.188V140H298.949ZM357.617 203.937H360.856V109.691H357.617ZM416.285 203.937H419.524V105.308H416.285Z' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M122.941 203.937H126.18V127.601H122.941ZM181.609 203.937H184.848V131.797H181.609ZM240.281 203.937H243.516V141.316H240.281ZM298.949 203.937H302.188V140H298.949ZM357.617 203.937H360.856V109.691H357.617ZM416.285 203.937H419.524V105.308H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M124.559 127.601V127.351' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M124.559 127.601V127.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M122.566 127.351H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M124.559 127.601V127.851' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M124.559 127.601V127.851' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M126.555 127.851H122.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M183.231 131.797V129.418' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M183.231 131.797V129.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M181.238 129.418H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M183.231 131.797V134.176' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M183.231 131.797V134.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M185.223 134.176H181.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M241.899 141.316V141.129' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M241.899 141.316V141.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M239.906 141.128H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M241.899 141.316V141.504' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M241.899 141.316V141.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M243.891 141.504H239.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M300.567 140V139.875' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M300.567 140V139.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M298.574 139.875H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M300.567 140V140.125' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M300.567 140V140.125' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M302.559 140.125H298.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M359.238 109.691V108.812' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M359.238 109.691V108.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M357.242 108.813H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M359.238 109.691V110.566' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M359.238 109.691V110.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M361.23 110.566H357.246' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M417.906 105.308V104.554' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M417.906 105.308V104.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M415.914 104.555H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M417.906 105.308V106.058' fill='#0a0a85'/>
+<path clip-path='url(#clip3)' d='M417.906 105.308V106.058' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M419.898 106.059H415.914' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M128.172 203.937H131.41V116.828H128.172ZM186.84 203.937H190.078V126.785H186.84ZM245.512 203.937H248.746V144.195H245.512ZM362.848 203.937H366.086V117.582H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M128.172 203.937H131.41V116.828H128.172ZM186.84 203.937H190.078V126.785H186.84ZM245.512 203.937H248.746V144.195H245.512ZM362.848 203.937H366.086V117.582H362.848ZM421.516 203.937H424.754V78.691H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M129.789 116.828V116.515' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M129.789 116.828V116.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M127.797 116.516H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M129.789 116.828V117.144' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M129.789 116.828V117.144' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M131.785 117.145H127.8' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M188.461 126.785V124.219' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M188.461 126.785V124.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M186.469 124.219H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M188.461 126.785V129.355' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M188.461 126.785V129.355' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M190.453 129.355H186.468' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M247.129 144.195V144.07' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M247.129 144.195V144.07' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M245.137 144.071H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M247.129 144.195V144.32' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M247.129 144.195V144.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M249.121 144.32H245.136' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M364.469 117.582V117.269' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M364.469 117.582V117.269' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M362.473 117.269H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M364.469 117.582V117.894' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M364.469 117.582V117.894' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M366.46 117.894H362.476' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M423.137 78.691V78.691' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M423.137 78.691V78.691' fill='#000076'/>
+<path clip-path='url(#clip3)' d='M421.144 78.691H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M133.402 203.937H136.641V140.5H133.402ZM192.07 203.937H195.309V138.621H192.07ZM250.742 203.937H253.977V140.875H250.742ZM309.41 203.937H312.649V140.625H309.41ZM368.078 203.937H371.317V141.066H368.078ZM426.746 203.937H429.984V142.629H426.746Z' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M133.402 203.937H136.641V140.5H133.402ZM192.07 203.937H195.309V138.621H192.07ZM250.742 203.937H253.977V140.875H250.742ZM309.41 203.937H312.649V140.625H309.41ZM368.078 203.937H371.317V141.066H368.078ZM426.746 203.937H429.984V142.629H426.746Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M135.02 140.5V140.187' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M135.02 140.5V140.187' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M133.027 140.187H137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M135.02 140.5V140.812' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M135.02 140.5V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M137.016 140.812H133.031' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M193.692 138.621V138.621' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M191.699 138.621H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M193.692 138.621V138.621' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M191.699 138.621H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M252.359 140.875V140.5' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M252.359 140.875V140.5' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M250.367 140.5H254.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M252.359 140.875V141.254' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M252.359 140.875V141.254' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M254.352 141.254H250.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M311.027 140.625V140.375' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M311.027 140.625V140.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M309.035 140.375H313.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M311.027 140.625V140.875' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M311.027 140.625V140.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M313.02 140.875H309.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M369.699 141.066V140.812' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M369.699 141.066V140.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M367.703 140.812H371.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M369.699 141.066V141.316' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M369.699 141.066V141.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M371.692 141.316H367.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M428.367 142.629V140.062' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M428.367 142.629V140.062' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M426.375 140.063H430.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M428.367 142.629V145.199' fill='#000067'/>
+<path clip-path='url(#clip3)' d='M428.367 142.629V145.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip3)' d='M430.359 145.199H426.375' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -94.367 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.698 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 22.971 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 81.64 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.309 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 198.978 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -89.137 248.024)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -30.468 247.085)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.201 249.903)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 86.87 247.147)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 145.539 246.333)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.208 238.318)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.906 247.21)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -25.237 244.329)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.432 249.84)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.101 248.713)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 150.77 239.382)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.439 223.977)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.676 238.756)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -20.007 241.637)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 38.662 249.527)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.331 247.774)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 156 245.143)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 214.669 205.253)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -73.445 247.085)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.776 246.145)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 43.893 249.715)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 102.562 240.321)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.231 241.449)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 219.9 233.308)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -68.215 244.642)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.546 241.637)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.123 249.402)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 107.792 242.513)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.461 217.589)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.13 231.93)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.984 247.523)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -4.315 241.637)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.354 249.402)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.023 240.196)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 171.692 241.699)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.361 233.245)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.754 236.063)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 0.915 240.259)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.584 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.253 248.462)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 176.922 218.153)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 235.591 213.769)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -52.524 225.292)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-51' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.145 235.249)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.814 252.658)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.152 226.043)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-51' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.821 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-50' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-52' y='183.949'/>
+<use x='126.877' xlink:href='#g1-52' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -47.293 248.963)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 11.376 247.085)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 70.045 249.339)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 128.714 249.089)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 187.383 249.527)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 246.052 251.093)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -124.589 311.062)'>
+<use x='114.487' xlink:href='#g0-82' y='183.949'/>
+<use x='120.457' xlink:href='#g0-101' y='183.949'/>
+<use x='124.553' xlink:href='#g0-108' y='183.949'/>
+<use x='126.753' xlink:href='#g0-97' y='183.949'/>
+<use x='131.181' xlink:href='#g0-116' y='183.949'/>
+<use x='134.509' xlink:href='#g0-105' y='183.949'/>
+<use x='136.709' xlink:href='#g0-118' y='183.949'/>
+<use x='140.957' xlink:href='#g0-101' y='183.949'/>
+<use x='148.124' xlink:href='#g0-116' y='183.949'/>
+<use x='151.452' xlink:href='#g0-105' y='183.949'/>
+<use x='153.652' xlink:href='#g0-109' y='183.949'/>
+<use x='160.972' xlink:href='#g0-101' y='183.949'/>
+<use x='168.139' xlink:href='#g2-40' y='183.949'/>
+<use x='171.432' xlink:href='#g2-108' y='183.949'/>
+<use x='173.453' xlink:href='#g2-111' y='183.949'/>
+<use x='177.452' xlink:href='#g2-119' y='183.949'/>
+<use x='183' xlink:href='#g2-101' y='183.949'/>
+<use x='186.764' xlink:href='#g2-114' y='183.949'/>
+<use x='192.479' xlink:href='#g2-105' y='183.949'/>
+<use x='194.499' xlink:href='#g2-115' y='183.949'/>
+<use x='200.568' xlink:href='#g2-98' y='183.949'/>
+<use x='205.176' xlink:href='#g2-101' y='183.949'/>
+<use x='208.94' xlink:href='#g2-116' y='183.949'/>
+<use x='211.998' xlink:href='#g2-116' y='183.949'/>
+<use x='215.056' xlink:href='#g2-101' y='183.949'/>
+<use x='218.819' xlink:href='#g2-114' y='183.949'/>
+<use x='221.711' xlink:href='#g2-41' y='183.949'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='243.704pt' version='1.1' viewBox='106.737 54.995 381.623 243.704' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<defs>
+<clipPath id='clip4'>
+<path d='M135.949 249.281H487.961V81.515H135.949Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/>
+<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/>
+<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/>
+<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/>
+<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/>
+<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/>
+<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/>
+<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/>
+<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/>
+<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/>
+<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/>
+<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/>
+<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/>
+<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/>
+<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M6.581 -2.663C6.581 -3.327 6.402 -4.08 5.317 -4.08C4.564 -4.08 4.142 -3.622 3.927 -3.344C3.865 -3.524 3.676 -4.08 2.762 -4.08C2.053 -4.08 1.623 -3.667 1.417 -3.398V-4.035H0.726V0H1.47V-2.188C1.47 -2.78 1.704 -3.497 2.385 -3.497C3.282 -3.497 3.282 -2.86 3.282 -2.6V0H4.026V-2.188C4.026 -2.78 4.259 -3.497 4.94 -3.497C5.837 -3.497 5.837 -2.86 5.837 -2.6V0H6.581V-2.663Z' id='g0-109'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page4'>
+<path d='M194.617 258.136V249.281M253.285 258.136V249.281M311.953 258.136V249.281M370.625 258.136V249.281M429.293 258.136V249.281M194.617 72.66V81.515M253.285 72.66V81.515M311.953 72.66V81.515M370.625 72.66V81.515M429.293 72.66V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.265V81.515M223.953 77.265V81.515M282.621 77.265V81.515M341.289 77.265V81.515M399.957 77.265V81.515M458.629 77.265V81.515' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.515H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.515H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 249.281V81.515H487.961V249.281H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 61.588)'>
+<use x='168.285' xlink:href='#g2-97' y='201.694'/>
+<use x='172.353' xlink:href='#g2-108' y='201.694'/>
+<use x='174.373' xlink:href='#g2-108' y='201.694'/>
+<use x='176.393' xlink:href='#g2-111' y='201.694'/>
+<use x='180.863' xlink:href='#g2-99' y='201.694'/>
+<use x='184.627' xlink:href='#g2-45' y='201.694'/>
+<use x='187.449' xlink:href='#g2-116' y='201.694'/>
+<use x='190.507' xlink:href='#g2-101' y='201.694'/>
+<use x='194.271' xlink:href='#g2-115' y='201.694'/>
+<use x='197.517' xlink:href='#g2-116' y='201.694'/>
+<use x='200.575' xlink:href='#g2-49' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 61.588)'>
+<use x='168.285' xlink:href='#g2-97' y='201.694'/>
+<use x='172.353' xlink:href='#g2-108' y='201.694'/>
+<use x='174.373' xlink:href='#g2-108' y='201.694'/>
+<use x='176.393' xlink:href='#g2-111' y='201.694'/>
+<use x='180.863' xlink:href='#g2-99' y='201.694'/>
+<use x='184.627' xlink:href='#g2-45' y='201.694'/>
+<use x='187.449' xlink:href='#g2-116' y='201.694'/>
+<use x='190.507' xlink:href='#g2-101' y='201.694'/>
+<use x='194.271' xlink:href='#g2-115' y='201.694'/>
+<use x='197.517' xlink:href='#g2-116' y='201.694'/>
+<use x='200.575' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 61.588)'>
+<use x='168.285' xlink:href='#g2-115' y='201.694'/>
+<use x='171.531' xlink:href='#g2-104' y='201.694'/>
+<use x='175.904' xlink:href='#g2-54' y='201.694'/>
+<use x='180.138' xlink:href='#g2-98' y='201.694'/>
+<use x='184.746' xlink:href='#g2-101' y='201.694'/>
+<use x='188.509' xlink:href='#g2-110' y='201.694'/>
+<use x='192.882' xlink:href='#g2-99' y='201.694'/>
+<use x='196.646' xlink:href='#g2-104' y='201.694'/>
+<use x='201.018' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 61.588)'>
+<use x='168.285' xlink:href='#g2-115' y='201.694'/>
+<use x='171.531' xlink:href='#g2-104' y='201.694'/>
+<use x='175.904' xlink:href='#g2-56' y='201.694'/>
+<use x='180.138' xlink:href='#g2-98' y='201.694'/>
+<use x='184.746' xlink:href='#g2-101' y='201.694'/>
+<use x='188.509' xlink:href='#g2-110' y='201.694'/>
+<use x='192.882' xlink:href='#g2-99' y='201.694'/>
+<use x='196.646' xlink:href='#g2-104' y='201.694'/>
+<use x='201.018' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 61.588)'>
+<use x='168.285' xlink:href='#g2-120' y='201.694'/>
+<use x='172.187' xlink:href='#g2-109' y='201.694'/>
+<use x='178.912' xlink:href='#g2-97' y='201.694'/>
+<use x='182.98' xlink:href='#g2-108' y='201.694'/>
+<use x='185' xlink:href='#g2-108' y='201.694'/>
+<use x='187.02' xlink:href='#g2-111' y='201.694'/>
+<use x='191.49' xlink:href='#g2-99' y='201.694'/>
+<use x='195.254' xlink:href='#g2-45' y='201.694'/>
+<use x='198.076' xlink:href='#g2-116' y='201.694'/>
+<use x='201.134' xlink:href='#g2-101' y='201.694'/>
+<use x='204.898' xlink:href='#g2-115' y='201.694'/>
+<use x='208.144' xlink:href='#g2-116' y='201.694'/>
+<use x='211.202' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 61.588)'>
+<use x='168.285' xlink:href='#g2-99' y='201.694'/>
+<use x='172.049' xlink:href='#g2-97' y='201.694'/>
+<use x='176.117' xlink:href='#g2-99' y='201.694'/>
+<use x='179.88' xlink:href='#g2-104' y='201.694'/>
+<use x='184.253' xlink:href='#g2-101' y='201.694'/>
+<use x='188.017' xlink:href='#g2-45' y='201.694'/>
+<use x='190.839' xlink:href='#g2-115' y='201.694'/>
+<use x='194.086' xlink:href='#g2-99' y='201.694'/>
+<use x='197.849' xlink:href='#g2-114' y='201.694'/>
+<use x='200.741' xlink:href='#g2-97' y='201.694'/>
+<use x='204.81' xlink:href='#g2-116' y='201.694'/>
+<use x='207.868' xlink:href='#g2-99' y='201.694'/>
+<use x='211.631' xlink:href='#g2-104' y='201.694'/>
+<use x='216.004' xlink:href='#g2-78' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 49.223)'>
+<use x='168.285' xlink:href='#g1-48' y='201.694'/>
+<use x='170.931' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 15.67)'>
+<use x='168.285' xlink:href='#g1-48' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -17.883)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -51.436)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -84.989)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -118.543)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-53' y='201.694'/>
+<use x='175.048' xlink:href='#g1-120' y='201.694'/>
+</g>
+<path clip-path='url(#clip4)' d='M135.949 182.176H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M141.746 182.176V181.906' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M141.746 182.176V181.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M139.754 181.907H143.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M141.746 182.176V182.445' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M141.746 182.176V182.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M143.739 182.446H139.754' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M200.414 182.176V181.773' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M200.414 182.176V181.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M198.422 181.774H202.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M200.414 182.176V182.578' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M200.414 182.176V182.578' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M202.406 182.578H198.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M259.082 182.176V180.297' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M259.082 182.176V180.297' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M257.09 180.297H261.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M259.082 182.176V184.054' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M259.082 182.176V184.054' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M261.074 184.055H257.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M317.754 182.176V181.57' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M317.754 182.176V181.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M315.762 181.57H319.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M317.754 182.176V182.781' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M317.754 182.176V182.781' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M319.746 182.781H315.758' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M376.422 182.176V181.035' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M376.422 182.176V181.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M374.43 181.035H378.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M376.422 182.176V183.316' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M376.422 182.176V183.316' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M378.414 183.316H374.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M435.09 182.176V179.156' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M435.09 182.176V179.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M433.098 179.156H437.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M435.09 182.176V185.195' fill='#e0e0f0'/>
+<path clip-path='url(#clip4)' d='M435.09 182.176V185.195' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M437.082 185.195H433.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M145.356 249.281H148.594V181.371H145.356ZM204.028 249.281H207.266V179.492H204.028ZM262.695 249.281H265.934V149.898H262.695ZM321.363 249.281H324.602V81.515H321.363ZM380.031 249.281H383.27V81.515H380.031ZM438.703 249.281H441.942V81.515H438.703Z' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M145.356 249.281H148.594V181.371H145.356ZM204.028 249.281H207.266V179.492H204.028ZM262.695 249.281H265.934V149.898H262.695ZM321.363 249.281H324.602V81.515H321.363ZM380.031 249.281H383.27V81.515H380.031ZM438.703 249.281H441.942V81.515H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M146.977 181.371V181.238' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M146.977 181.371V181.238' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M144.984 181.239H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M146.977 181.371V181.504' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M146.977 181.371V181.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M148.969 181.504H144.984' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M205.645 179.492V179.359' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M205.645 179.492V179.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M203.652 179.36H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M205.645 179.492V179.625' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M205.645 179.492V179.625' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M207.636 179.625H203.652' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M264.313 149.898V149.359' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M264.313 149.898V149.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M262.32 149.359H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M264.313 149.898V150.433' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M264.313 149.898V150.433' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M266.304 150.434H262.32' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M322.984 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M320.992 81.516H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M322.984 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M320.992 81.516H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M381.652 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M379.66 81.516H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M381.652 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M379.66 81.516H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M440.32 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M438.328 81.516H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M440.32 81.515V81.515' fill='#c2c2e1'/>
+<path clip-path='url(#clip4)' d='M438.328 81.516H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M150.586 249.281H153.824V178.687H150.586ZM209.258 249.281H212.496V177.679H209.258ZM267.926 249.281H271.164V81.515H267.926ZM326.594 249.281H329.832V133.39H326.594ZM385.262 249.281H388.5V110.91H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M150.586 249.281H153.824V178.687H150.586ZM209.258 249.281H212.496V177.679H209.258ZM267.926 249.281H271.164V81.515H267.926ZM326.594 249.281H329.832V133.39H326.594ZM385.262 249.281H388.5V110.91H385.262ZM443.934 249.281H447.172V81.515H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M152.207 178.687V178.418' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M152.207 178.687V178.418' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M150.215 178.418H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M152.207 178.687V178.953' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M152.207 178.687V178.953' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M154.2 178.953H150.215' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M210.875 177.679V177.547' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M210.875 177.679V177.547' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M208.883 177.547H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M210.875 177.679V177.812' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M210.875 177.679V177.812' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M212.867 177.812H208.883' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M269.543 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M267.551 81.516H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M269.543 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M267.551 81.516H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M328.215 133.39V131.176' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M328.215 133.39V131.176' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M326.223 131.176H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M328.215 133.39V135.605' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M328.215 133.39V135.605' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M330.207 135.606H326.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M386.883 110.91V110.371' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M386.883 110.91V110.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M384.891 110.371H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M386.883 110.91V111.445' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M386.883 110.91V111.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M388.875 111.445H384.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M445.551 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M445.551 81.515V81.515' fill='#a3a3d1'/>
+<path clip-path='url(#clip4)' d='M443.559 81.516H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M155.817 249.281H159.055V161.91H155.817ZM214.488 249.281H217.727V158.219H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V150.097H331.824ZM390.492 249.281H393.731V162.445H390.492ZM449.164 249.281H452.402V181.101H449.164Z' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M155.817 249.281H159.055V161.91H155.817ZM214.488 249.281H217.727V158.219H214.488ZM273.156 249.281H276.395V81.515H273.156ZM331.824 249.281H335.063V150.097H331.824ZM390.492 249.281H393.731V162.445H390.492ZM449.164 249.281H452.402V181.101H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M157.438 161.91V161.777' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M157.438 161.91V161.777' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M155.445 161.777H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M157.438 161.91V162.043' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M157.438 161.91V162.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M159.43 162.043H155.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M216.106 158.219V158.019' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M216.106 158.219V158.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M214.113 158.02H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M216.106 158.219V158.422' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M216.106 158.219V158.422' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M218.098 158.422H214.113' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M274.774 81.515V81.515' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M274.774 81.515V81.515' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M272.781 81.516H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M333.445 150.097V149.496' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M333.445 150.097V149.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M331.453 149.496H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M333.445 150.097V150.703' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M333.445 150.097V150.703' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M335.437 150.703H331.449' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M392.113 162.445V162.179' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M392.113 162.445V162.179' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M390.121 162.18H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M392.113 162.445V162.715' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M392.113 162.445V162.715' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M394.105 162.714H390.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M450.781 181.101V177.41' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M450.781 181.101V177.41' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M448.789 177.411H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M450.781 181.101V184.793' fill='#8585c2'/>
+<path clip-path='url(#clip4)' d='M450.781 181.101V184.793' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M452.773 184.793H448.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M161.047 249.281H164.285V169.023H161.047ZM219.719 249.281H222.957V168.152H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V81.515H337.055ZM395.723 249.281H398.961V81.515H395.723ZM454.395 249.281H457.633V81.515H454.395Z' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M161.047 249.281H164.285V169.023H161.047ZM219.719 249.281H222.957V168.152H219.719ZM278.387 249.281H281.625V81.515H278.387ZM337.055 249.281H340.293V81.515H337.055ZM395.723 249.281H398.961V81.515H395.723ZM454.395 249.281H457.633V81.515H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M162.668 169.023V168.957' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M162.668 169.023V168.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M160.676 168.957H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M162.668 169.023V169.09' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M162.668 169.023V169.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M164.661 169.089H160.676' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M221.336 168.152V168.015' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M221.336 168.152V168.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M219.344 168.016H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M221.336 168.152V168.285' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M221.336 168.152V168.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M223.329 168.285H219.344' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M280.004 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M280.004 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M278.012 81.516H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M338.676 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M336.684 81.516H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M338.676 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M336.684 81.516H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M397.344 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M395.352 81.516H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M397.344 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M395.352 81.516H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M456.012 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M454.02 81.516H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M456.012 81.515V81.515' fill='#6666b3'/>
+<path clip-path='url(#clip4)' d='M454.02 81.516H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M166.278 249.281H169.516V175.734H166.278ZM224.949 249.281H228.188V169.023H224.949ZM283.617 249.281H286.856V107.488H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M166.278 249.281H169.516V175.734H166.278ZM224.949 249.281H228.188V169.023H224.949ZM283.617 249.281H286.856V107.488H283.617ZM342.285 249.281H345.524V81.515H342.285ZM400.953 249.281H404.192V81.515H400.953ZM459.625 249.281H462.863V81.515H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M167.899 175.734V175.465' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M167.899 175.734V175.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M165.906 175.465H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M167.899 175.734V176.004' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M167.899 175.734V176.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M169.891 176.004H165.906' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M226.567 169.023V168.554' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M226.567 169.023V168.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M224.574 168.555H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M226.567 169.023V169.492' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M226.567 169.023V169.492' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M228.559 169.492H224.574' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M285.234 107.488V107.015' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M285.234 107.488V107.015' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M283.242 107.015H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M285.234 107.488V107.957' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M285.234 107.488V107.957' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M287.227 107.957H283.242' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M343.906 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M343.906 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M341.914 81.516H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M402.574 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M402.574 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M400.582 81.516H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M461.242 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M461.242 81.515V81.515' fill='#4747a4'/>
+<path clip-path='url(#clip4)' d='M459.25 81.516H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M171.508 249.281H174.746V168.82H171.508ZM230.18 249.281H233.414V168.621H230.18ZM288.848 249.281H292.086V81.515H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M171.508 249.281H174.746V168.82H171.508ZM230.18 249.281H233.414V168.621H230.18ZM288.848 249.281H292.086V81.515H288.848ZM347.516 249.281H350.754V81.515H347.516ZM406.184 249.281H409.422V81.515H406.184ZM464.856 249.281H468.094V81.515H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M173.129 168.82V168.554' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M173.129 168.82V168.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M171.137 168.555H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M173.129 168.82V169.09' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M173.129 168.82V169.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M175.122 169.089H171.137' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M231.797 168.621V168.554' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M231.797 168.621V168.554' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M229.805 168.555H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M231.797 168.621V168.687' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M231.797 168.621V168.687' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M233.79 168.688H229.805' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M290.465 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M288.473 81.516H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M290.465 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M288.473 81.516H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M349.137 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M349.137 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M347.145 81.516H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M407.805 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M407.805 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M405.813 81.516H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M466.473 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M466.473 81.515V81.515' fill='#292994'/>
+<path clip-path='url(#clip4)' d='M464.481 81.516H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M411.414 249.281H414.652V133.59H411.414ZM176.738 249.281H179.977V162.113H176.738ZM235.41 249.281H238.645V162.648H235.41ZM294.078 249.281H297.317V81.515H294.078ZM352.746 249.281H355.984V125.875H352.746ZM470.086 249.281H473.324V181.035H470.086Z' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M411.414 249.281H414.652V133.59H411.414ZM176.738 249.281H179.977V162.113H176.738ZM235.41 249.281H238.645V162.648H235.41ZM294.078 249.281H297.317V81.515H294.078ZM352.746 249.281H355.984V125.875H352.746ZM470.086 249.281H473.324V181.035H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M413.035 133.59V126.211' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M413.035 133.59V126.211' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M411.043 126.211H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M413.035 133.59V140.972' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M413.035 133.59V140.972' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M415.027 140.973H411.043' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M178.36 162.113V161.777' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M178.36 162.113V161.777' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M176.367 161.777H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M178.36 162.113V162.445' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M178.36 162.113V162.445' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M180.352 162.445H176.367' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M237.027 162.648V162.515' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M237.027 162.648V162.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M235.035 162.516H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M237.027 162.648V162.781' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M237.027 162.648V162.781' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M239.02 162.781H235.035' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M295.695 81.515V81.515' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M293.703 81.516H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M295.695 81.515V81.515' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M293.703 81.516H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M354.367 125.875V125.672' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M354.367 125.875V125.672' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M352.375 125.672H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M354.367 125.875V126.074' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M354.367 125.875V126.074' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M356.359 126.074H352.371' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M471.703 181.035V178.219' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M471.703 181.035V178.219' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M469.711 178.219H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M471.703 181.035V183.855' fill='#0a0a85'/>
+<path clip-path='url(#clip4)' d='M471.703 181.035V183.855' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M473.695 183.856H469.711' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M181.969 249.281H185.207V154.594H181.969ZM240.641 249.281H243.875V149.695H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V81.515H357.977ZM475.317 249.281H478.555V81.515H475.317Z' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M181.969 249.281H185.207V154.594H181.969ZM240.641 249.281H243.875V149.695H240.641ZM299.309 249.281H302.547V81.515H299.309ZM357.977 249.281H361.215V81.515H357.977ZM475.317 249.281H478.555V81.515H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M183.59 154.594V154.461' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M183.59 154.594V154.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M181.598 154.461H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M183.59 154.594V154.73' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M183.59 154.594V154.73' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M185.582 154.731H181.597' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M242.258 149.695V149.562' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M242.258 149.695V149.562' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M240.266 149.563H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M242.258 149.695V149.832' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M242.258 149.695V149.832' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M244.25 149.832H240.265' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M300.926 81.515V81.515' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M300.926 81.515V81.515' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M298.933 81.516H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M359.598 81.515V81.515' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M357.606 81.516H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M359.598 81.515V81.515' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M357.606 81.516H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M476.934 81.515V81.515' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M474.942 81.516H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M476.934 81.515V81.515' fill='#000076'/>
+<path clip-path='url(#clip4)' d='M474.942 81.516H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M187.199 249.281H190.438V181.64H187.199ZM245.871 249.281H249.106V181.64H245.871ZM304.539 249.281H307.777V164.258H304.539ZM363.207 249.281H366.445V151.105H363.207ZM421.875 249.281H425.113V179.828H421.875ZM480.547 249.281H483.785V181.371H480.547Z' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M187.199 249.281H190.438V181.64H187.199ZM245.871 249.281H249.106V181.64H245.871ZM304.539 249.281H307.777V164.258H304.539ZM363.207 249.281H366.445V151.105H363.207ZM421.875 249.281H425.113V179.828H421.875ZM480.547 249.281H483.785V181.371H480.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M188.82 181.64V181.57' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M188.82 181.64V181.57' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M186.828 181.57H190.813' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M188.82 181.64V181.707' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M188.82 181.64V181.707' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M190.813 181.707H186.828' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M247.488 181.64V181.437' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M247.488 181.64V181.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M245.496 181.437H249.481' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M247.488 181.64V181.84' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M247.488 181.64V181.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M249.481 181.84H245.496' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M306.156 164.258V163.992' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M306.156 164.258V163.992' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M304.164 163.992H308.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M306.156 164.258V164.527' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M306.156 164.258V164.527' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M308.149 164.527H304.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M364.828 151.105V150.168' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M364.828 151.105V150.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M362.836 150.168H366.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M364.828 151.105V152.047' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M364.828 151.105V152.047' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M366.82 152.047H362.832' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M423.496 179.828V179.09' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M423.496 179.828V179.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M421.504 179.09H425.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M423.496 179.828V180.566' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M423.496 179.828V180.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M425.488 180.567H421.504' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M482.164 181.371V178.148' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M482.164 181.371V178.148' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M480.172 178.149H484.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M482.164 181.371V184.594' fill='#000067'/>
+<path clip-path='url(#clip4)' d='M482.164 181.371V184.594' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M484.156 184.594H480.172' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip4)' d='M419.477 298.301H487.762V276.324H419.477Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 254.512 92.648)'>
+<use x='168.285' xlink:href='#g1-72' y='190.457'/>
+<use x='172.021' xlink:href='#g1-80' y='190.457'/>
+<use x='175.402' xlink:href='#g1-45' y='190.457'/>
+<use x='177.167' xlink:href='#g1-90' y='190.457'/>
+<use x='180.401' xlink:href='#g1-52' y='190.457'/>
+<use x='183.047' xlink:href='#g1-45' y='190.457'/>
+<use x='184.812' xlink:href='#g1-71' y='190.457'/>
+<use x='188.34' xlink:href='#g1-52' y='190.457'/>
+<use x='190.987' xlink:href='#g1-44' y='190.457'/>
+<use x='194.221' xlink:href='#g1-49' y='190.457'/>
+<use x='196.867' xlink:href='#g1-54' y='190.457'/>
+<use x='199.514' xlink:href='#g1-71' y='190.457'/>
+<use x='203.042' xlink:href='#g1-98' y='190.457'/>
+<use x='168.285' xlink:href='#g1-56' y='196.075'/>
+<use x='170.931' xlink:href='#g1-45' y='196.075'/>
+<use x='172.695' xlink:href='#g1-99' y='196.075'/>
+<use x='175.048' xlink:href='#g1-111' y='196.075'/>
+<use x='177.547' xlink:href='#g1-114' y='196.075'/>
+<use x='179.355' xlink:href='#g1-101' y='196.075'/>
+<use x='183.471' xlink:href='#g1-73' y='196.075'/>
+<use x='184.941' xlink:href='#g1-110' y='196.075'/>
+<use x='187.674' xlink:href='#g1-116' y='196.075'/>
+<use x='189.585' xlink:href='#g1-101' y='196.075'/>
+<use x='191.938' xlink:href='#g1-108' y='196.075'/>
+<use x='194.965' xlink:href='#g1-88' y='196.075'/>
+<use x='198.493' xlink:href='#g1-69' y='196.075'/>
+<use x='201.667' xlink:href='#g1-79' y='196.075'/>
+<use x='205.576' xlink:href='#g1-78' y='196.075'/>
+<use x='211.076' xlink:href='#g1-64' y='196.075'/>
+<use x='214.605' xlink:href='#g1-50' y='196.075'/>
+<use x='217.251' xlink:href='#g1-46' y='196.075'/>
+<use x='218.721' xlink:href='#g1-55' y='196.075'/>
+<use x='221.368' xlink:href='#g1-71' y='196.075'/>
+<use x='224.896' xlink:href='#g1-104' y='196.075'/>
+<use x='227.629' xlink:href='#g1-122' y='196.075'/>
+<use x='168.285' xlink:href='#g1-85' y='201.694'/>
+<use x='171.917' xlink:href='#g1-98' y='201.694'/>
+<use x='174.65' xlink:href='#g1-117' y='201.694'/>
+<use x='177.383' xlink:href='#g1-110' y='201.694'/>
+<use x='180.116' xlink:href='#g1-116' y='201.694'/>
+<use x='182.027' xlink:href='#g1-117' y='201.694'/>
+<use x='186.524' xlink:href='#g1-49' y='201.694'/>
+<use x='189.17' xlink:href='#g1-56' y='201.694'/>
+<use x='191.817' xlink:href='#g1-46' y='201.694'/>
+<use x='193.287' xlink:href='#g1-48' y='201.694'/>
+<use x='195.933' xlink:href='#g1-52' y='201.694'/>
+<use x='198.58' xlink:href='#g1-46' y='201.694'/>
+<use x='200.05' xlink:href='#g1-49' y='201.694'/>
+<use x='202.696' xlink:href='#g1-44' y='201.694'/>
+<use x='205.931' xlink:href='#g1-71' y='201.694'/>
+<use x='209.459' xlink:href='#g1-67' y='201.694'/>
+<use x='212.841' xlink:href='#g1-67' y='201.694'/>
+<use x='217.986' xlink:href='#g1-55' y='201.694'/>
+<use x='220.633' xlink:href='#g1-46' y='201.694'/>
+<use x='222.103' xlink:href='#g1-52' y='201.694'/>
+<use x='224.749' xlink:href='#g1-46' y='201.694'/>
+<use x='226.219' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -58.314 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 0.355 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.024 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 117.693 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 176.362 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 235.031 344.257)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -53.084 343.452)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 5.585 341.573)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.254 311.979)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-56' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 122.923 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-54' y='201.694'/>
+<use x='180.675' xlink:href='#g1-53' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 181.592 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-53' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-48' y='201.694'/>
+<use x='180.675' xlink:href='#g1-54' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.261 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-49' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-56' y='201.694'/>
+<use x='183.321' xlink:href='#g1-51' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -47.853 340.768)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-53' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 10.816 339.761)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-55' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 69.485 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-51' y='201.694'/>
+<use x='180.675' xlink:href='#g1-54' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 128.154 295.471)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-55' y='201.694'/>
+<use x='175.048' xlink:href='#g1-51' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 186.823 272.99)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 245.492 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-50' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-48' y='201.694'/>
+<use x='183.321' xlink:href='#g1-55' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -42.623 323.991)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 16.046 320.3)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 74.715 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-56' y='201.694'/>
+<use x='180.675' xlink:href='#g1-57' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 133.384 312.18)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-56' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 192.053 324.528)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-57' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 250.722 343.183)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-50' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -37.392 331.104)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.277 330.232)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 79.946 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-54' y='201.694'/>
+<use x='180.675' xlink:href='#g1-53' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 138.615 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-53' y='201.694'/>
+<use x='180.675' xlink:href='#g1-49' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 197.284 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-53' y='201.694'/>
+<use x='180.675' xlink:href='#g1-49' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 255.953 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-54' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-49' y='201.694'/>
+<use x='180.675' xlink:href='#g1-56' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -32.162 337.815)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-49' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.507 331.104)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.176 269.568)'>
+<use x='168.285' xlink:href='#g1-50' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-49' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 143.845 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-48' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-50' y='201.694'/>
+<use x='183.321' xlink:href='#g1-50' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.514 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-49' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-52' y='201.694'/>
+<use x='183.321' xlink:href='#g1-50' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 261.183 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-55' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-48' y='201.694'/>
+<use x='180.675' xlink:href='#g1-49' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -26.931 330.903)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.738 330.702)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 90.407 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-50' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-54' y='201.694'/>
+<use x='180.675' xlink:href='#g1-55' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 149.076 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-54' y='201.694'/>
+<use x='180.675' xlink:href='#g1-48' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 207.745 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-53' y='201.694'/>
+<use x='180.675' xlink:href='#g1-49' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 266.414 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-53' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-55' y='201.694'/>
+<use x='180.675' xlink:href='#g1-54' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 212.975 295.672)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-55' y='201.694'/>
+<use x='175.048' xlink:href='#g1-50' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -21.701 324.192)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-51' y='201.694'/>
+<use x='175.048' xlink:href='#g1-48' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.968 324.729)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-57' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.637 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-51' y='201.694'/>
+<use x='180.675' xlink:href='#g1-55' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 154.306 287.955)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-56' y='201.694'/>
+<use x='175.048' xlink:href='#g1-52' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 271.644 343.116)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-50' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -16.471 316.676)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 42.198 311.778)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-56' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.867 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-54' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-48' y='201.694'/>
+<use x='180.675' xlink:href='#g1-54' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 159.536 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-51' y='201.694'/>
+<use x='176.558' xlink:href='#g1-46' y='201.694'/>
+<use x='178.029' xlink:href='#g1-49' y='201.694'/>
+<use x='180.675' xlink:href='#g1-52' y='201.694'/>
+<use x='183.321' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 276.874 243.598)'>
+<use x='163.396' xlink:href='#g3-1' y='201.694'/>
+<use x='166.901' xlink:href='#g3-1' y='201.694'/>
+<use x='170.407' xlink:href='#g3-1' y='201.694'/>
+<use x='173.912' xlink:href='#g1-49' y='201.694'/>
+<use x='176.558' xlink:href='#g1-49' y='201.694'/>
+<use x='179.205' xlink:href='#g1-46' y='201.694'/>
+<use x='180.675' xlink:href='#g1-56' y='201.694'/>
+<use x='183.321' xlink:href='#g1-56' y='201.694'/>
+<use x='185.968' xlink:href='#g1-120' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -11.24 343.72)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 47.429 343.72)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 106.098 326.34)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-50' y='201.694'/>
+<use x='175.048' xlink:href='#g1-55' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 164.767 313.187)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-52' y='201.694'/>
+<use x='175.048' xlink:href='#g1-54' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 223.436 341.908)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-51' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 282.105 343.452)'>
+<use x='168.285' xlink:href='#g1-49' y='201.694'/>
+<use x='170.931' xlink:href='#g1-46' y='201.694'/>
+<use x='172.401' xlink:href='#g1-48' y='201.694'/>
+<use x='175.048' xlink:href='#g1-49' y='201.694'/>
+</g>
+<g transform='matrix(0 -1 1 0 -88.536 388.944)'>
+<use x='168.285' xlink:href='#g0-82' y='201.694'/>
+<use x='174.255' xlink:href='#g0-101' y='201.694'/>
+<use x='178.351' xlink:href='#g0-108' y='201.694'/>
+<use x='180.551' xlink:href='#g0-97' y='201.694'/>
+<use x='184.979' xlink:href='#g0-116' y='201.694'/>
+<use x='188.307' xlink:href='#g0-105' y='201.694'/>
+<use x='190.507' xlink:href='#g0-118' y='201.694'/>
+<use x='194.755' xlink:href='#g0-101' y='201.694'/>
+<use x='201.922' xlink:href='#g0-116' y='201.694'/>
+<use x='205.25' xlink:href='#g0-105' y='201.694'/>
+<use x='207.45' xlink:href='#g0-109' y='201.694'/>
+<use x='214.77' xlink:href='#g0-101' y='201.694'/>
+<use x='221.937' xlink:href='#g2-40' y='201.694'/>
+<use x='225.231' xlink:href='#g2-108' y='201.694'/>
+<use x='227.251' xlink:href='#g2-111' y='201.694'/>
+<use x='231.25' xlink:href='#g2-119' y='201.694'/>
+<use x='236.799' xlink:href='#g2-101' y='201.694'/>
+<use x='240.562' xlink:href='#g2-114' y='201.694'/>
+<use x='246.277' xlink:href='#g2-105' y='201.694'/>
+<use x='248.297' xlink:href='#g2-115' y='201.694'/>
+<use x='254.366' xlink:href='#g2-98' y='201.694'/>
+<use x='258.974' xlink:href='#g2-101' y='201.694'/>
+<use x='262.738' xlink:href='#g2-116' y='201.694'/>
+<use x='265.796' xlink:href='#g2-116' y='201.694'/>
+<use x='268.854' xlink:href='#g2-101' y='201.694'/>
+<use x='272.618' xlink:href='#g2-114' y='201.694'/>
+<use x='275.51' xlink:href='#g2-41' y='201.694'/>
+</g>
+<path d='M136.149 296.672H402.137V279.679H136.149Z' fill='#ffffff'/>
+<path d='M136.149 296.672H402.137V279.679H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#e0e0f0'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -33.522 88.465)'>
+<use x='185.011' xlink:href='#g2-109' y='201.694'/>
+<use x='191.736' xlink:href='#g2-105' y='201.694'/>
+</g>
+<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='#c2c2e1'/>
+<path d='M163.422 290.168H166.41V282.199H163.422ZM169.398 290.168H172.391V284.191H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.56 88.011)'>
+<use x='208.137' xlink:href='#g2-116' y='201.694'/>
+<use x='211.195' xlink:href='#g2-99' y='201.694'/>
+</g>
+<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='#a3a3d1'/>
+<path d='M185.586 290.168H188.574V282.199H185.586ZM191.563 290.168H194.555V284.191H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.159 88.465)'>
+<use x='229.9' xlink:href='#g2-106' y='201.694'/>
+<use x='232.155' xlink:href='#g2-101' y='201.694'/>
+</g>
+<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='#8585c2'/>
+<path d='M206.949 290.168H209.938V282.199H206.949ZM212.926 290.168H215.914V284.191H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.958 87.505)'>
+<use x='252.061' xlink:href='#g2-115' y='201.694'/>
+<use x='255.307' xlink:href='#g2-110' y='201.694'/>
+</g>
+<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='#6666b3'/>
+<path d='M229.91 290.168H232.898V282.199H229.91ZM235.887 290.168H238.875V284.191H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.781 87.505)'>
+<use x='274.845' xlink:href='#g2-114' y='201.694'/>
+<use x='277.737' xlink:href='#g2-112' y='201.694'/>
+</g>
+<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='#4747a4'/>
+<path d='M252.516 290.168H255.504V282.199H252.516ZM258.496 290.168H261.484V284.191H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.001 88.501)'>
+<use x='303.672' xlink:href='#g2-104' y='201.694'/>
+<use x='308.045' xlink:href='#g2-111' y='201.694'/>
+<use x='312.279' xlink:href='#g2-97' y='201.694'/>
+<use x='316.112' xlink:href='#g2-114' y='201.694'/>
+<use x='319.004' xlink:href='#g2-100' y='201.694'/>
+</g>
+<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='#292994'/>
+<path d='M287.563 290.168H290.551V282.199H287.563ZM293.543 290.168H296.531V284.191H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.472 88.501)'>
+<use x='337.19' xlink:href='#g2-103' y='201.694'/>
+<use x='341.424' xlink:href='#g2-108' y='201.694'/>
+<use x='343.444' xlink:href='#g2-105' y='201.694'/>
+<use x='345.464' xlink:href='#g2-98' y='201.694'/>
+<use x='350.072' xlink:href='#g2-99' y='201.694'/>
+</g>
+<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='#0a0a85'/>
+<path d='M319.551 290.168H322.539V282.199H319.551ZM325.527 290.168H328.52V284.191H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.051 88.501)'>
+<use x='366.757' xlink:href='#g2-116' y='201.694'/>
+<use x='369.815' xlink:href='#g2-98' y='201.694'/>
+<use x='374.187' xlink:href='#g2-98' y='201.694'/>
+</g>
+<path d='M346.699 290.168H349.688V282.199H346.699ZM352.676 290.168H355.664V284.191H352.676Z' fill='#000076'/>
+<path d='M346.699 290.168H349.688V282.199H346.699ZM352.676 290.168H355.664V284.191H352.676Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -34.135 87.505)'>
+<use x='392.986' xlink:href='#g2-115' y='201.694'/>
+<use x='396.233' xlink:href='#g2-109' y='201.694'/>
+</g>
+<path d='M372.012 290.168H375V282.199H372.012ZM377.988 290.168H380.977V284.191H377.988Z' fill='#000067'/>
+<path d='M372.012 290.168H375V282.199H372.012ZM377.988 290.168H380.977V284.191H377.988Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.145 88.465)'>
+<use x='419.31' xlink:href='#g2-115' y='201.694'/>
+<use x='422.556' xlink:href='#g2-109' y='201.694'/>
+<use x='429.281' xlink:href='#g2-105' y='201.694'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='164.687pt' version='1.1' viewBox='52.938 54.996 381.625 164.687' width='381.625pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<defs>
+<clipPath id='clip9'>
+<path d='M82.148 203.937H434.164V78.691H82.148Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-102' transform='scale(1.6)' xlink:href='#g1-102'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M0.946 -1.898H1.514V-2.212H0.932V-2.785C0.932 -3.128 1.245 -3.178 1.41 -3.178C1.514 -3.178 1.649 -3.163 1.833 -3.093V-3.457C1.704 -3.487 1.549 -3.507 1.415 -3.507C0.902 -3.507 0.528 -3.138 0.528 -2.645V-2.212H0.144V-1.898H0.528V0H0.946V-1.898Z' id='g1-102'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M1.445 -1.245C1.445 -1.41 1.305 -1.549 1.141 -1.549S0.837 -1.41 0.837 -1.245S0.976 -0.941 1.141 -0.941S1.445 -1.081 1.445 -1.245Z' id='g3-1'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page9'>
+<path d='M140.82 212.793V203.937M199.488 212.793V203.937M258.156 212.793V203.937M316.824 212.793V203.937M375.496 212.793V203.937M140.82 69.836V78.691M199.488 69.836V78.691M258.156 69.836V78.691M316.824 69.836V78.691M375.496 69.836V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M111.484 208.191V203.937M170.152 208.191V203.937M228.824 208.191V203.937M287.492 208.191V203.937M346.16 208.191V203.937M404.828 208.191V203.937M111.484 74.441V78.691M170.152 74.441V78.691M228.824 74.441V78.691M287.492 74.441V78.691M346.16 74.441V78.691M404.828 74.441V78.691' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937H86.402M82.148 172.625H86.402M82.148 141.316H86.402M82.148 110.004H86.402M82.148 78.691H86.402M434.164 203.937H429.91M434.164 172.625H429.91M434.164 141.316H429.91M434.164 110.004H429.91M434.164 78.691H429.91' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M82.148 203.937V78.691H434.164V203.937H82.148Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -11.54 33.989)'>
+<use x='114.487' xlink:href='#g2-99' y='183.949'/>
+<use x='118.25' xlink:href='#g2-102' y='183.949'/>
+<use x='120.838' xlink:href='#g2-114' y='183.949'/>
+<use x='123.73' xlink:href='#g2-97' y='183.949'/>
+<use x='127.798' xlink:href='#g2-99' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 41.401 33.989)'>
+<use x='114.487' xlink:href='#g2-101' y='183.949'/>
+<use x='118.25' xlink:href='#g2-115' y='183.949'/>
+<use x='121.497' xlink:href='#g2-112' y='183.949'/>
+<use x='125.634' xlink:href='#g2-114' y='183.949'/>
+<use x='128.526' xlink:href='#g2-101' y='183.949'/>
+<use x='132.29' xlink:href='#g2-115' y='183.949'/>
+<use x='135.536' xlink:href='#g2-115' y='183.949'/>
+<use x='138.782' xlink:href='#g2-111' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 103.095 33.989)'>
+<use x='114.487' xlink:href='#g2-98' y='183.949'/>
+<use x='118.859' xlink:href='#g2-97' y='183.949'/>
+<use x='122.692' xlink:href='#g2-114' y='183.949'/>
+<use x='125.584' xlink:href='#g2-110' y='183.949'/>
+<use x='129.957' xlink:href='#g2-101' y='183.949'/>
+<use x='133.72' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 162.903 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-101' y='183.949'/>
+<use x='120.271' xlink:href='#g2-97' y='183.949'/>
+<use x='124.339' xlink:href='#g2-110' y='183.949'/>
+<use x='128.711' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 223.526 33.989)'>
+<use x='114.487' xlink:href='#g2-114' y='183.949'/>
+<use x='117.379' xlink:href='#g2-101' y='183.949'/>
+<use x='121.142' xlink:href='#g2-100' y='183.949'/>
+<use x='125.515' xlink:href='#g2-105' y='183.949'/>
+<use x='127.535' xlink:href='#g2-115' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 277.054 33.989)'>
+<use x='114.487' xlink:href='#g2-108' y='183.949'/>
+<use x='116.507' xlink:href='#g2-97' y='183.949'/>
+<use x='120.34' xlink:href='#g2-114' y='183.949'/>
+<use x='123.232' xlink:href='#g2-115' y='183.949'/>
+<use x='126.478' xlink:href='#g2-111' y='183.949'/>
+<use x='130.712' xlink:href='#g2-110' y='183.949'/>
+<use x='135.085' xlink:href='#g2-78' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 21.624)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.688)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.999)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -72.311)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.622)'>
+<use x='114.487' xlink:href='#g1-50' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-120' y='183.949'/>
+</g>
+<path clip-path='url(#clip9)' d='M82.148 141.316H434.164' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M86.328 203.937H89.566V141.316H86.328ZM144.996 203.937H148.234V141.316H144.996ZM203.668 203.937H206.902V141.316H203.668ZM262.336 203.937H265.574V141.316H262.336ZM321.004 203.937H324.242V141.316H321.004ZM379.672 203.937H382.91V141.316H379.672Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M87.949 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M85.953 141.316H89.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M87.949 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M85.953 141.316H89.938' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M146.617 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M144.625 141.316H148.61' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M146.617 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M144.625 141.316H148.61' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M205.285 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M203.293 141.316H207.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M205.285 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M203.293 141.316H207.277' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M263.953 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M261.961 141.316H265.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M263.953 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M261.961 141.316H265.945' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M322.625 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M320.629 141.316H324.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M322.625 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M320.629 141.316H324.617' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M381.293 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M379.301 141.316H383.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M381.293 141.316V141.316' fill='#f0e0f0'/>
+<path clip-path='url(#clip9)' d='M379.301 141.316H383.285' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M91.559 203.937H94.797V93.156H91.559ZM150.227 203.937H153.465V78.691H150.227ZM208.899 203.937H212.133V138.246H208.899ZM267.567 203.937H270.805V145.949H267.567ZM326.234 203.937H329.473V130.23H326.234ZM384.902 203.937H388.141V140.25H384.902Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M91.559 203.937H94.797V93.156H91.559ZM150.227 203.937H153.465V78.691H150.227ZM208.899 203.937H212.133V138.246H208.899ZM267.567 203.937H270.805V145.949H267.567ZM326.234 203.937H329.473V130.23H326.234ZM384.902 203.937H388.141V140.25H384.902Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M93.18 93.156V93.156' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M91.184 93.156H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M93.18 93.156V93.156' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M91.184 93.156H95.168' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M151.848 78.691V78.691' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M149.855 78.691H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M151.848 78.691V78.691' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M149.855 78.691H153.84' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M210.516 138.246V138.246' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M208.523 138.246H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M210.516 138.246V138.246' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M208.523 138.246H212.507' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M269.184 145.949V145.949' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M267.191 145.949H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M269.184 145.949V145.949' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M267.191 145.949H271.175' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M327.856 130.23V130.23' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M325.859 130.23H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M327.856 130.23V130.23' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M325.859 130.23H329.847' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M386.524 140.25V140.25' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M384.531 140.25H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M386.524 140.25V140.25' fill='#e1c2e1'/>
+<path clip-path='url(#clip9)' d='M384.531 140.25H388.515' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M96.789 203.937H100.027V110.816H96.789ZM155.457 203.937H158.695V104.679H155.457ZM214.129 203.937H217.363V139.75H214.129ZM272.797 203.937H276.035V141.254H272.797ZM331.465 203.937H334.703V137.496H331.465ZM390.133 203.937H393.371V132.109H390.133Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M96.789 203.937H100.027V110.816H96.789ZM155.457 203.937H158.695V104.679H155.457ZM214.129 203.937H217.363V139.75H214.129ZM272.797 203.937H276.035V141.254H272.797ZM331.465 203.937H334.703V137.496H331.465ZM390.133 203.937H393.371V132.109H390.133Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M98.41 110.816V110.816' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M96.414 110.817H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M98.41 110.816V110.816' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M96.414 110.817H100.399' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M157.078 104.679V104.679' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M155.086 104.68H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M157.078 104.679V104.679' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M155.086 104.68H159.071' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M215.746 139.75V139.75' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M213.754 139.75H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M215.746 139.75V139.75' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M213.754 139.75H217.739' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M274.414 141.254V141.254' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M272.422 141.254H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M274.414 141.254V141.254' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M272.422 141.254H276.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M333.086 137.496V137.496' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M331.09 137.496H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M333.086 137.496V137.496' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M331.09 137.496H335.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M391.754 132.109V132.109' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M389.762 132.11H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M391.754 132.109V132.109' fill='#d1a3d1'/>
+<path clip-path='url(#clip9)' d='M389.762 132.11H393.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M102.02 203.937H105.258V121.777H102.02ZM160.688 203.937H163.926V110.066H160.688ZM219.359 203.937H222.594V140.312H219.359ZM278.027 203.937H281.266V140.437H278.027ZM336.695 203.937H339.934V138.058H336.695ZM395.363 203.937H398.602V125.16H395.363Z' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M102.02 203.937H105.258V121.777H102.02ZM160.688 203.937H163.926V110.066H160.688ZM219.359 203.937H222.594V140.312H219.359ZM278.027 203.937H281.266V140.437H278.027ZM336.695 203.937H339.934V138.058H336.695ZM395.363 203.937H398.602V125.16H395.363Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M103.641 121.777V121.777' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M101.644 121.777H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M103.641 121.777V121.777' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M101.644 121.777H105.629' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M162.309 110.066V110.066' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M160.316 110.066H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M162.309 110.066V110.066' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M160.316 110.066H164.301' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M220.977 140.312V140.312' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M218.984 140.312H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M220.977 140.312V140.312' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M218.984 140.312H222.969' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M279.645 140.437V140.437' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M277.652 140.438H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M279.645 140.437V140.437' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M277.652 140.438H281.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M338.317 138.058V138.058' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M336.32 138.059H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M338.317 138.058V138.058' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M336.32 138.059H340.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M396.984 125.16V125.16' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M394.992 125.161H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M396.984 125.16V125.16' fill='#c285c2'/>
+<path clip-path='url(#clip9)' d='M394.992 125.161H398.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M107.25 203.937H110.488V138.433H107.25ZM165.918 203.937H169.156V141.754H165.918ZM224.59 203.937H227.824V141.379H224.59ZM283.258 203.937H286.496V131.172H283.258ZM341.926 203.937H345.164V140.5H341.926ZM400.594 203.937H403.832V134.238H400.594Z' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M107.25 203.937H110.488V138.433H107.25ZM165.918 203.937H169.156V141.754H165.918ZM224.59 203.937H227.824V141.379H224.59ZM283.258 203.937H286.496V131.172H283.258ZM341.926 203.937H345.164V140.5H341.926ZM400.594 203.937H403.832V134.238H400.594Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M108.871 138.433V138.433' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M106.875 138.434H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M108.871 138.433V138.433' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M106.875 138.434H110.86' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M167.539 141.754V141.754' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M165.547 141.754H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M167.539 141.754V141.754' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M165.547 141.754H169.532' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M226.207 141.379V141.379' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M224.215 141.379H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M226.207 141.379V141.379' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M224.215 141.379H228.2' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M284.875 131.172V131.172' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M282.883 131.172H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M284.875 131.172V131.172' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M282.883 131.172H286.868' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M343.547 140.5V140.5' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M341.551 140.5H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M343.547 140.5V140.5' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M341.551 140.5H345.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M402.215 134.238V134.238' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M400.223 134.238H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M402.215 134.238V134.238' fill='#b366b3'/>
+<path clip-path='url(#clip9)' d='M400.223 134.238H404.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M112.481 203.937H115.719V108.687H112.481ZM171.149 203.937H174.387V78.691H171.149ZM229.82 203.937H233.055V139.812H229.82ZM288.488 203.937H291.727V125.785H288.488ZM347.156 203.937H350.395V125.41H347.156ZM405.824 203.937H409.063V131.672H405.824Z' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M112.481 203.937H115.719V108.687H112.481ZM171.149 203.937H174.387V78.691H171.149ZM229.82 203.937H233.055V139.812H229.82ZM288.488 203.937H291.727V125.785H288.488ZM347.156 203.937H350.395V125.41H347.156ZM405.824 203.937H409.063V131.672H405.824Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M114.098 108.687V108.687' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M112.105 108.688H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M114.098 108.687V108.687' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M112.105 108.688H116.09' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M172.77 78.691V78.691' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M170.777 78.691H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M172.77 78.691V78.691' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M170.777 78.691H174.762' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M231.438 139.812V139.812' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M229.445 139.812H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M231.438 139.812V139.812' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M229.445 139.812H233.43' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M290.106 125.785V125.785' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M288.113 125.785H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M290.106 125.785V125.785' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M288.113 125.785H292.098' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M348.777 125.41V125.41' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M346.781 125.41H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M348.777 125.41V125.41' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M346.781 125.41H350.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M407.445 131.672V131.672' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M405.453 131.672H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M407.445 131.672V131.672' fill='#a447a4'/>
+<path clip-path='url(#clip9)' d='M405.453 131.672H409.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M117.711 203.937H120.949V141.316H117.711ZM176.379 203.937H179.617V153.402H176.379ZM235.051 203.937H238.285V141.566H235.051ZM293.719 203.937H296.957V131.922H293.719ZM352.387 203.937H355.625V140.562H352.387ZM411.055 203.937H414.293V134.613H411.055Z' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M117.711 203.937H120.949V141.316H117.711ZM176.379 203.937H179.617V153.402H176.379ZM235.051 203.937H238.285V141.566H235.051ZM293.719 203.937H296.957V131.922H293.719ZM352.387 203.937H355.625V140.562H352.387ZM411.055 203.937H414.293V134.613H411.055Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M119.328 141.316V141.316' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M117.336 141.316H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M119.328 141.316V141.316' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M117.336 141.316H121.321' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M178 153.402V153.402' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M176.008 153.403H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M178 153.402V153.402' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M176.008 153.403H179.993' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M236.668 141.566V141.566' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M234.676 141.567H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M236.668 141.566V141.566' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M234.676 141.567H238.661' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M295.336 131.922V131.922' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M293.344 131.922H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M295.336 131.922V131.922' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M293.344 131.922H297.329' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M354.008 140.562V140.562' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M352.012 140.563H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M354.008 140.562V140.562' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M352.012 140.563H356' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M412.676 134.613V134.613' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M410.684 134.614H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M412.676 134.613V134.613' fill='#942994'/>
+<path clip-path='url(#clip9)' d='M410.684 134.614H414.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M122.941 203.937H126.18V116.765H122.941ZM181.609 203.937H184.848V112.32H181.609ZM240.281 203.937H243.516V140.125H240.281ZM298.949 203.937H302.188V131.734H298.949ZM357.617 203.937H360.856V97.168H357.617ZM416.285 203.937H419.524V136.804H416.285Z' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M122.941 203.937H126.18V116.765H122.941ZM181.609 203.937H184.848V112.32H181.609ZM240.281 203.937H243.516V140.125H240.281ZM298.949 203.937H302.188V131.734H298.949ZM357.617 203.937H360.856V97.168H357.617ZM416.285 203.937H419.524V136.804H416.285Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M124.559 116.765V116.765' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M122.566 116.766H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M124.559 116.765V116.765' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M122.566 116.766H126.551' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M183.231 112.32V112.32' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M181.238 112.32H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M183.231 112.32V112.32' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M181.238 112.32H185.223' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M241.899 140.125V140.125' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M239.906 140.125H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M241.899 140.125V140.125' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M239.906 140.125H243.891' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M300.567 131.734V131.734' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M298.574 131.734H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M300.567 131.734V131.734' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M298.574 131.734H302.559' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M359.238 97.168V97.168' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M357.242 97.168H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M359.238 97.168V97.168' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M357.242 97.168H361.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M417.906 136.804V136.804' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M415.914 136.804H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M417.906 136.804V136.804' fill='#850a85'/>
+<path clip-path='url(#clip9)' d='M415.914 136.804H419.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M128.172 203.937H131.41V104.992H128.172ZM186.84 203.937H190.078V90.09H186.84ZM245.512 203.937H248.746V133.238H245.512ZM362.848 203.937H366.086V124.906H362.848ZM421.516 203.937H424.754V148.453H421.516Z' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M128.172 203.937H131.41V104.992H128.172ZM186.84 203.937H190.078V90.09H186.84ZM245.512 203.937H248.746V133.238H245.512ZM362.848 203.937H366.086V124.906H362.848ZM421.516 203.937H424.754V148.453H421.516Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M129.789 104.992V104.992' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M127.797 104.992H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M129.789 104.992V104.992' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M127.797 104.992H131.782' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M188.461 90.09V90.09' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M186.469 90.09H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M188.461 90.09V90.09' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M186.469 90.09H190.454' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M247.129 133.238V133.238' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M245.137 133.238H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M247.129 133.238V133.238' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M245.137 133.238H249.122' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M364.469 124.906V124.906' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M362.473 124.906H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M364.469 124.906V124.906' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M362.473 124.906H366.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M423.137 148.453V148.453' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M421.144 148.453H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M423.137 148.453V148.453' fill='#760076'/>
+<path clip-path='url(#clip9)' d='M421.144 148.453H425.128' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M133.402 203.937H136.641V138.746H133.402ZM192.07 203.937H195.309V107.058H192.07ZM250.742 203.937H253.977V141.316H250.742ZM309.41 203.937H312.649V129.355H309.41ZM368.078 203.937H371.317V140.125H368.078ZM426.746 203.937H429.984V140.375H426.746Z' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M133.402 203.937H136.641V138.746H133.402ZM192.07 203.937H195.309V107.058H192.07ZM250.742 203.937H253.977V141.316H250.742ZM309.41 203.937H312.649V129.355H309.41ZM368.078 203.937H371.317V140.125H368.078ZM426.746 203.937H429.984V140.375H426.746Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M135.02 138.746V138.746' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M133.027 138.746H137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M135.02 138.746V138.746' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M133.027 138.746H137.012' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M193.692 107.058V107.058' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M191.699 107.058H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M193.692 107.058V107.058' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M191.699 107.058H195.684' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M252.359 141.316V141.316' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M250.367 141.316H254.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M252.359 141.316V141.316' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M250.367 141.316H254.352' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M311.027 129.355V129.355' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M309.035 129.355H313.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M311.027 129.355V129.355' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M309.035 129.355H313.02' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M369.699 140.125V140.125' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M367.703 140.125H371.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M369.699 140.125V140.125' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M367.703 140.125H371.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M428.367 140.375V140.375' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M426.375 140.375H430.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip9)' d='M428.367 140.375V140.375' fill='#670067'/>
+<path clip-path='url(#clip9)' d='M426.375 140.375H430.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(0 -1 1 0 -94.367 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.698 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 22.971 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 81.64 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.309 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 198.978 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -89.137 201.62)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -30.468 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-50' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-49' y='183.949'/>
+<use x='126.877' xlink:href='#g1-52' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.201 246.709)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 86.87 254.412)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 145.539 238.693)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.208 248.713)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.906 219.28)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -25.237 213.143)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.432 248.212)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.101 249.715)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 150.77 245.958)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.439 240.572)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.676 230.239)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-51' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -20.007 218.529)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 38.662 248.776)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.331 248.901)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 156 246.521)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 214.669 233.621)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -73.445 246.897)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.776 250.216)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-57' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 43.893 249.84)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 102.562 239.633)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.231 248.963)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 219.9 242.701)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -68.215 217.151)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.546 187.155)'>
+<use x='109.598' xlink:href='#g3-1' y='183.949'/>
+<use x='113.103' xlink:href='#g3-1' y='183.949'/>
+<use x='116.608' xlink:href='#g3-1' y='183.949'/>
+<use x='120.114' xlink:href='#g1-52' y='183.949'/>
+<use x='122.76' xlink:href='#g1-46' y='183.949'/>
+<use x='124.23' xlink:href='#g1-53' y='183.949'/>
+<use x='126.877' xlink:href='#g1-50' y='183.949'/>
+<use x='129.523' xlink:href='#g1-120' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.123 248.275)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 107.792 234.247)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.461 233.871)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.13 240.134)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.984 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -4.315 261.864)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-56' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.354 250.028)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.023 240.384)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 171.692 249.026)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.361 243.077)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.754 225.229)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-51' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 0.915 220.783)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-52' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 59.584 248.588)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.253 240.196)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 176.922 205.628)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-55' y='183.949'/>
+<use x='121.25' xlink:href='#g1-49' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 235.591 245.269)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-55' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -52.524 213.456)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-56' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.145 198.552)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-56' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 64.814 241.699)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-51' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.152 233.37)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-50' y='183.949'/>
+<use x='121.25' xlink:href='#g1-54' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 240.821 256.917)'>
+<use x='114.487' xlink:href='#g1-48' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-56' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -47.293 247.21)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-52' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 11.376 215.523)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-53' y='183.949'/>
+<use x='121.25' xlink:href='#g1-53' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 70.045 249.778)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-48' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 128.714 237.817)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-49' y='183.949'/>
+<use x='121.25' xlink:href='#g1-57' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 187.383 248.588)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 246.052 248.838)'>
+<use x='114.487' xlink:href='#g1-49' y='183.949'/>
+<use x='117.133' xlink:href='#g1-46' y='183.949'/>
+<use x='118.603' xlink:href='#g1-48' y='183.949'/>
+<use x='121.25' xlink:href='#g1-50' y='183.949'/>
+</g>
+<g transform='matrix(0 -1 1 0 -124.589 307.697)'>
+<use x='114.487' xlink:href='#g0-82' y='183.949'/>
+<use x='120.457' xlink:href='#g0-101' y='183.949'/>
+<use x='124.553' xlink:href='#g0-108' y='183.949'/>
+<use x='126.753' xlink:href='#g0-97' y='183.949'/>
+<use x='131.181' xlink:href='#g0-116' y='183.949'/>
+<use x='134.509' xlink:href='#g0-105' y='183.949'/>
+<use x='136.709' xlink:href='#g0-118' y='183.949'/>
+<use x='140.957' xlink:href='#g0-101' y='183.949'/>
+<use x='148.124' xlink:href='#g0-114' y='183.949'/>
+<use x='151.272' xlink:href='#g0-115' y='183.949'/>
+<use x='154.805' xlink:href='#g0-115' y='183.949'/>
+<use x='161.409' xlink:href='#g2-40' y='183.949'/>
+<use x='164.702' xlink:href='#g2-108' y='183.949'/>
+<use x='166.722' xlink:href='#g2-111' y='183.949'/>
+<use x='170.721' xlink:href='#g2-119' y='183.949'/>
+<use x='176.27' xlink:href='#g2-101' y='183.949'/>
+<use x='180.034' xlink:href='#g2-114' y='183.949'/>
+<use x='185.749' xlink:href='#g2-105' y='183.949'/>
+<use x='187.769' xlink:href='#g2-115' y='183.949'/>
+<use x='193.838' xlink:href='#g2-98' y='183.949'/>
+<use x='198.446' xlink:href='#g2-101' y='183.949'/>
+<use x='202.209' xlink:href='#g2-116' y='183.949'/>
+<use x='205.267' xlink:href='#g2-116' y='183.949'/>
+<use x='208.325' xlink:href='#g2-101' y='183.949'/>
+<use x='212.089' xlink:href='#g2-114' y='183.949'/>
+<use x='214.981' xlink:href='#g2-41' y='183.949'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4.2 -->
+<svg height='182.025pt' version='1.1' viewBox='106.736 51.674 381.623 182.025' width='381.623pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<defs>
+<clipPath id='clip10'>
+<path d='M135.949 186.074H487.961V60.828H135.949Z'/>
+</clipPath>
+<use id='g2-40' transform='scale(1.6)' xlink:href='#g1-40'/>
+<use id='g2-41' transform='scale(1.6)' xlink:href='#g1-41'/>
+<use id='g2-45' transform='scale(1.6)' xlink:href='#g1-45'/>
+<use id='g2-49' transform='scale(1.6)' xlink:href='#g1-49'/>
+<use id='g2-54' transform='scale(1.6)' xlink:href='#g1-54'/>
+<use id='g2-56' transform='scale(1.6)' xlink:href='#g1-56'/>
+<use id='g2-78' transform='scale(1.6)' xlink:href='#g1-78'/>
+<use id='g2-97' transform='scale(1.6)' xlink:href='#g1-97'/>
+<use id='g2-98' transform='scale(1.6)' xlink:href='#g1-98'/>
+<use id='g2-99' transform='scale(1.6)' xlink:href='#g1-99'/>
+<use id='g2-100' transform='scale(1.6)' xlink:href='#g1-100'/>
+<use id='g2-101' transform='scale(1.6)' xlink:href='#g1-101'/>
+<use id='g2-103' transform='scale(1.6)' xlink:href='#g1-103'/>
+<use id='g2-104' transform='scale(1.6)' xlink:href='#g1-104'/>
+<use id='g2-105' transform='scale(1.6)' xlink:href='#g1-105'/>
+<use id='g2-106' transform='scale(1.6)' xlink:href='#g1-106'/>
+<use id='g2-108' transform='scale(1.6)' xlink:href='#g1-108'/>
+<use id='g2-109' transform='scale(1.6)' xlink:href='#g1-109'/>
+<use id='g2-110' transform='scale(1.6)' xlink:href='#g1-110'/>
+<use id='g2-111' transform='scale(1.6)' xlink:href='#g1-111'/>
+<use id='g2-112' transform='scale(1.6)' xlink:href='#g1-112'/>
+<use id='g2-114' transform='scale(1.6)' xlink:href='#g1-114'/>
+<use id='g2-115' transform='scale(1.6)' xlink:href='#g1-115'/>
+<use id='g2-116' transform='scale(1.6)' xlink:href='#g1-116'/>
+<use id='g2-119' transform='scale(1.6)' xlink:href='#g1-119'/>
+<use id='g2-120' transform='scale(1.6)' xlink:href='#g1-120'/>
+<path d='M1.519 -3.736C1.435 -3.736 1.425 -3.736 1.365 -3.681C0.737 -3.133 0.418 -2.247 0.418 -1.245C0.418 -0.304 0.702 0.603 1.36 1.181C1.425 1.245 1.435 1.245 1.519 1.245H1.758C1.743 1.235 1.26 0.822 1.031 0.045C0.912 -0.344 0.852 -0.752 0.852 -1.245C0.852 -2.969 1.659 -3.651 1.758 -3.736H1.519Z' id='g1-40'/>
+<path d='M0.533 1.245C0.618 1.245 0.628 1.245 0.687 1.191C1.315 0.643 1.634 -0.244 1.634 -1.245C1.634 -2.187 1.35 -3.093 0.692 -3.671C0.628 -3.736 0.618 -3.736 0.533 -3.736H0.294C0.309 -3.726 0.792 -3.313 1.021 -2.535C1.141 -2.147 1.2 -1.738 1.2 -1.245C1.2 0.478 0.394 1.161 0.294 1.245H0.533Z' id='g1-41'/>
+<path d='M0.956 -0.005V-0.448H0.508V0H0.648L0.503 0.638H0.727L0.956 -0.005Z' id='g1-44'/>
+<path d='M1.465 -0.951V-1.265H0.06V-0.951H1.465Z' id='g1-45'/>
+<path d='M0.956 -0.448H0.508V0H0.956V-0.448Z' id='g1-46'/>
+<path d='M2.431 -1.619C2.431 -1.858 2.431 -2.441 2.197 -2.849C1.943 -3.298 1.559 -3.372 1.32 -3.372C1.096 -3.372 0.707 -3.303 0.458 -2.874C0.219 -2.476 0.209 -1.933 0.209 -1.619C0.209 -1.25 0.229 -0.797 0.438 -0.418C0.658 -0.015 1.026 0.105 1.32 0.105C1.818 0.105 2.092 -0.184 2.242 -0.498C2.416 -0.852 2.431 -1.31 2.431 -1.619ZM1.32 -0.224C1.111 -0.224 0.872 -0.344 0.747 -0.702C0.648 -1.006 0.643 -1.32 0.643 -1.684C0.643 -2.142 0.643 -3.044 1.32 -3.044S1.998 -2.142 1.998 -1.684C1.998 -1.355 1.998 -0.981 1.878 -0.663C1.738 -0.304 1.484 -0.224 1.32 -0.224Z' id='g1-48'/>
+<path d='M1.599 -3.372H1.489C1.166 -3.073 0.757 -3.054 0.458 -3.044V-2.73C0.653 -2.735 0.902 -2.745 1.151 -2.844V-0.314H0.488V0H2.262V-0.314H1.599V-3.372Z' id='g1-49'/>
+<path d='M1.41 -0.384C1.35 -0.384 1.29 -0.379 1.23 -0.379H0.663L1.435 -1.061C1.524 -1.141 1.768 -1.325 1.863 -1.405C2.082 -1.604 2.376 -1.863 2.376 -2.296C2.376 -2.859 1.958 -3.372 1.245 -3.372C0.717 -3.372 0.389 -3.088 0.219 -2.58L0.453 -2.286C0.568 -2.705 0.742 -3.029 1.176 -3.029C1.594 -3.029 1.913 -2.735 1.913 -2.286C1.913 -1.873 1.669 -1.639 1.37 -1.355C1.27 -1.255 1.001 -1.031 0.897 -0.932C0.752 -0.802 0.408 -0.468 0.264 -0.344V0H2.376V-0.384H1.41Z' id='g1-50'/>
+<path d='M0.498 -2.555C0.702 -2.954 1.061 -3.064 1.3 -3.064C1.594 -3.064 1.813 -2.894 1.813 -2.61C1.813 -2.346 1.634 -2.022 1.255 -1.958C1.23 -1.953 1.21 -1.953 0.882 -1.928V-1.599H1.27C1.743 -1.599 1.918 -1.225 1.918 -0.912C1.918 -0.523 1.679 -0.224 1.29 -0.224C0.936 -0.224 0.533 -0.394 0.284 -0.712L0.219 -0.389C0.508 -0.065 0.912 0.105 1.3 0.105C1.953 0.105 2.421 -0.384 2.421 -0.907C2.421 -1.315 2.092 -1.644 1.699 -1.758C2.077 -1.953 2.271 -2.286 2.271 -2.61C2.271 -3.034 1.838 -3.372 1.305 -3.372C0.867 -3.372 0.503 -3.143 0.294 -2.844L0.498 -2.555Z' id='g1-51'/>
+<path d='M1.973 -0.832H2.491V-1.161H1.973V-3.268H1.479L0.149 -1.161V-0.832H1.544V0H1.973V-0.832ZM0.573 -1.161C0.722 -1.395 1.579 -2.725 1.579 -3.024V-1.161H0.573Z' id='g1-52'/>
+<path d='M0.817 -2.924H2.197V-3.268H0.418V-1.405H0.782C0.902 -1.674 1.136 -1.793 1.36 -1.793C1.564 -1.793 1.873 -1.654 1.873 -1.021C1.873 -0.369 1.46 -0.224 1.205 -0.224C0.877 -0.224 0.558 -0.399 0.389 -0.682L0.199 -0.384C0.443 -0.08 0.812 0.105 1.205 0.105C1.863 0.105 2.376 -0.403 2.376 -1.011C2.376 -1.629 1.918 -2.122 1.37 -2.122C1.156 -2.122 0.966 -2.047 0.817 -1.923V-2.924Z' id='g1-53'/>
+<path d='M2.187 -3.273C1.918 -3.372 1.729 -3.372 1.634 -3.372C0.877 -3.372 0.219 -2.66 0.219 -1.609C0.219 -0.259 0.827 0.105 1.33 0.105C1.733 0.105 1.943 -0.085 2.097 -0.244C2.416 -0.583 2.421 -0.936 2.421 -1.111C2.421 -1.763 2.067 -2.306 1.584 -2.306C1.096 -2.306 0.832 -2.052 0.687 -1.908C0.752 -2.59 1.101 -3.064 1.639 -3.064C1.738 -3.064 1.938 -3.054 2.187 -2.959V-3.273ZM0.692 -1.096C0.692 -1.126 0.692 -1.2 0.697 -1.225C0.697 -1.564 0.912 -1.978 1.355 -1.978C1.963 -1.978 1.963 -1.28 1.963 -1.111C1.963 -0.922 1.963 -0.712 1.828 -0.503C1.709 -0.324 1.559 -0.224 1.33 -0.224C0.802 -0.224 0.717 -0.877 0.692 -1.096Z' id='g1-54'/>
+<path d='M1.23 -2.884C1.29 -2.884 1.35 -2.889 1.41 -2.889H2.037C1.28 -2.147 0.797 -1.106 0.797 0.05H1.265C1.265 -1.405 1.973 -2.451 2.421 -2.919V-3.268H0.219V-2.884H1.23Z' id='g1-55'/>
+<path d='M1.704 -1.763C2.032 -1.868 2.346 -2.132 2.346 -2.501C2.346 -2.954 1.913 -3.372 1.32 -3.372S0.294 -2.954 0.294 -2.501C0.294 -2.127 0.618 -1.863 0.936 -1.763C0.498 -1.629 0.219 -1.29 0.219 -0.907C0.219 -0.374 0.692 0.105 1.32 0.105S2.421 -0.374 2.421 -0.907C2.421 -1.29 2.137 -1.629 1.704 -1.763ZM1.32 -1.928C0.966 -1.928 0.677 -2.132 0.677 -2.496C0.677 -2.814 0.902 -3.064 1.32 -3.064C1.733 -3.064 1.963 -2.814 1.963 -2.496C1.963 -2.142 1.684 -1.928 1.32 -1.928ZM1.32 -0.224C0.976 -0.224 0.672 -0.443 0.672 -0.912C0.672 -1.36 0.961 -1.599 1.32 -1.599S1.968 -1.355 1.968 -0.912C1.968 -0.443 1.659 -0.224 1.32 -0.224Z' id='g1-56'/>
+<path d='M0.384 -0.125C0.628 0.055 0.852 0.105 1.086 0.105C1.783 0.105 2.421 -0.598 2.421 -1.669C2.421 -3.029 1.818 -3.372 1.34 -3.372C0.897 -3.372 0.692 -3.163 0.548 -3.019C0.229 -2.695 0.219 -2.351 0.219 -2.157C0.219 -1.514 0.568 -0.961 1.056 -0.961C1.619 -0.961 1.928 -1.335 1.953 -1.365C1.883 -0.573 1.494 -0.224 1.086 -0.224C0.827 -0.224 0.667 -0.319 0.553 -0.413L0.384 -0.125ZM1.938 -2.162C1.943 -2.132 1.943 -2.082 1.943 -2.052C1.943 -1.684 1.719 -1.29 1.285 -1.29C1.096 -1.29 0.946 -1.345 0.817 -1.549C0.687 -1.743 0.677 -1.933 0.677 -2.157C0.677 -2.351 0.677 -2.575 0.832 -2.795C0.936 -2.944 1.086 -3.064 1.335 -3.064C1.818 -3.064 1.923 -2.481 1.938 -2.162Z' id='g1-57'/>
+<path d='M2.959 -0.438C2.884 -0.438 2.874 -0.438 2.834 -0.418C2.59 -0.334 2.336 -0.279 2.072 -0.279C1.27 -0.279 0.697 -0.956 0.697 -1.729C0.697 -2.565 1.345 -3.178 2.042 -3.178C2.182 -3.178 2.511 -3.143 2.675 -2.745C2.535 -2.824 2.381 -2.859 2.252 -2.859C1.719 -2.859 1.27 -2.361 1.27 -1.729C1.27 -1.081 1.733 -0.598 2.247 -0.598C2.635 -0.598 3.228 -0.912 3.228 -1.798C3.228 -2.301 3.193 -3.507 2.047 -3.507C1.101 -3.507 0.294 -2.725 0.294 -1.729C0.294 -0.742 1.091 0.05 2.052 0.05C2.511 0.05 2.939 -0.139 3.228 -0.438H2.959ZM2.252 -0.927C1.943 -0.927 1.674 -1.27 1.674 -1.729C1.674 -2.202 1.953 -2.531 2.247 -2.531C2.555 -2.531 2.824 -2.187 2.824 -1.729C2.824 -1.255 2.545 -0.927 2.252 -0.927Z' id='g1-64'/>
+<path d='M3.083 -0.608C2.735 -0.394 2.575 -0.299 2.077 -0.299C1.305 -0.299 0.837 -1.021 0.837 -1.738C0.837 -2.476 1.35 -3.168 2.077 -3.168C2.406 -3.168 2.745 -3.064 2.974 -2.889L3.054 -3.342C2.705 -3.472 2.426 -3.512 2.062 -3.512C1.076 -3.512 0.339 -2.695 0.339 -1.733C0.339 -0.707 1.121 0.05 2.092 0.05C2.58 0.05 2.785 -0.05 3.113 -0.229L3.083 -0.608Z' id='g1-67'/>
+<path d='M2.725 -1.624V-1.953H0.986V-3.098H1.714C1.773 -3.098 1.833 -3.093 1.893 -3.093H2.874V-3.442H0.483V0H2.949V-0.389H2.501C2.082 -0.389 1.664 -0.379 1.245 -0.379H0.986V-1.624H2.725Z' id='g1-69'/>
+<path d='M3.173 -1.489H2.057V-1.161H2.735V-0.399C2.516 -0.344 2.301 -0.299 2.077 -0.299C1.31 -0.299 0.837 -1.021 0.837 -1.733C0.837 -2.416 1.3 -3.168 2.052 -3.168C2.511 -3.168 2.8 -3.029 3.049 -2.819L3.128 -3.273C2.785 -3.437 2.481 -3.517 2.102 -3.517C1.096 -3.517 0.339 -2.73 0.339 -1.733C0.339 -0.762 1.091 0.05 2.072 0.05C2.431 0.05 2.854 -0.03 3.173 -0.194V-1.489Z' id='g1-71'/>
+<path d='M3.248 -3.457H2.745V-1.963H0.986V-3.457H0.483V0H0.986V-1.634H2.745V0H3.248V-3.457Z' id='g1-72'/>
+<path d='M0.986 -3.457H0.483V0H0.986V-3.457Z' id='g1-73'/>
+<path d='M1.176 -3.457H0.498V0H0.917V-3.064H0.922L2.555 0H3.233V-3.457H2.814V-0.394H2.809L1.176 -3.457Z' id='g1-78'/>
+<path d='M3.611 -1.714C3.611 -2.745 2.854 -3.562 1.953 -3.562S0.294 -2.745 0.294 -1.714S1.061 0.105 1.953 0.105C2.849 0.105 3.611 -0.687 3.611 -1.714ZM1.953 -0.249C1.35 -0.249 0.797 -0.852 0.797 -1.793C0.797 -2.675 1.355 -3.218 1.953 -3.218S3.108 -2.675 3.108 -1.793C3.108 -0.847 2.555 -0.249 1.953 -0.249Z' id='g1-79'/>
+<path d='M1.868 -1.42C2.511 -1.42 3.083 -1.873 3.083 -2.446C3.083 -2.979 2.555 -3.457 1.833 -3.457H0.488V0H0.991V-1.42H1.868ZM1.709 -3.163C2.271 -3.163 2.63 -2.864 2.63 -2.446C2.63 -2.037 2.291 -1.729 1.709 -1.729H0.976V-3.163H1.709Z' id='g1-80'/>
+<path d='M3.143 -3.457H2.71V-1.161C2.71 -0.493 2.262 -0.189 1.833 -0.189S0.986 -0.498 0.986 -1.156V-3.457H0.483V-1.166C0.483 -0.433 1.111 0.105 1.828 0.105C2.54 0.105 3.143 -0.438 3.143 -1.166V-3.457Z' id='g1-85'/>
+<path d='M1.968 -1.823L3.228 -3.457H2.685L1.724 -2.182L0.742 -3.457H0.149L1.479 -1.823L0.075 0H0.618L1.724 -1.499L2.854 0H3.447L1.968 -1.823Z' id='g1-88'/>
+<path d='M2.934 -3.238V-3.457H0.369V-3.123H1.41C1.479 -3.123 1.539 -3.128 1.609 -3.128H2.291L0.294 -0.229V0H2.964V-0.354H2.466C1.958 -0.354 1.45 -0.344 0.941 -0.344L2.934 -3.238Z' id='g1-90'/>
+<path d='M2.122 -1.435C2.122 -1.943 1.733 -2.286 1.24 -2.286C0.927 -2.286 0.687 -2.222 0.408 -2.072L0.438 -1.709C0.603 -1.818 0.847 -1.968 1.24 -1.968C1.46 -1.968 1.689 -1.803 1.689 -1.43V-1.23C0.951 -1.205 0.224 -1.051 0.224 -0.588C0.224 -0.339 0.394 0.05 0.832 0.05C1.046 0.05 1.44 0.005 1.704 -0.189V0H2.122V-1.435ZM1.689 -0.707C1.689 -0.608 1.689 -0.478 1.514 -0.374C1.355 -0.284 1.161 -0.279 1.106 -0.279C0.832 -0.279 0.623 -0.403 0.623 -0.593C0.623 -0.912 1.465 -0.941 1.689 -0.951V-0.707Z' id='g1-97'/>
+<path d='M0.842 -3.457H0.423V0H0.857V-0.234C0.966 -0.139 1.205 0.05 1.569 0.05C2.112 0.05 2.55 -0.458 2.55 -1.111C2.55 -1.714 2.207 -2.262 1.709 -2.262C1.395 -2.262 1.091 -2.162 0.842 -1.978V-3.457ZM0.857 -1.569C0.857 -1.649 0.857 -1.709 1.031 -1.823C1.106 -1.868 1.24 -1.933 1.41 -1.933C1.743 -1.933 2.117 -1.709 2.117 -1.111C2.117 -0.503 1.704 -0.279 1.355 -0.279C1.171 -0.279 0.996 -0.364 0.857 -0.588V-1.569Z' id='g1-98'/>
+<path d='M2.167 -0.543C1.918 -0.384 1.649 -0.294 1.34 -0.294C0.882 -0.294 0.613 -0.663 0.613 -1.111C0.613 -1.494 0.812 -1.943 1.355 -1.943C1.694 -1.943 1.853 -1.873 2.107 -1.714L2.172 -2.072C1.873 -2.222 1.743 -2.286 1.355 -2.286C0.608 -2.286 0.179 -1.684 0.179 -1.106C0.179 -0.498 0.658 0.05 1.335 0.05C1.684 0.05 1.983 -0.055 2.197 -0.179L2.167 -0.543Z' id='g1-99'/>
+<path d='M2.306 -3.457H1.888V-1.998C1.569 -2.232 1.245 -2.262 1.101 -2.262C0.578 -2.262 0.179 -1.738 0.179 -1.106S0.573 0.05 1.086 0.05C1.395 0.05 1.684 -0.09 1.873 -0.259V0H2.306V-3.457ZM1.873 -0.618C1.748 -0.413 1.559 -0.279 1.32 -0.279C0.971 -0.279 0.613 -0.523 0.613 -1.101C0.613 -1.724 1.036 -1.933 1.375 -1.933C1.574 -1.933 1.743 -1.848 1.873 -1.679V-0.618Z' id='g1-100'/>
+<path d='M2.142 -0.543C1.863 -0.344 1.549 -0.279 1.335 -0.279C0.902 -0.279 0.573 -0.633 0.558 -1.091H2.192C2.192 -1.32 2.167 -1.654 1.973 -1.938C1.793 -2.192 1.494 -2.286 1.25 -2.286C0.643 -2.286 0.174 -1.753 0.174 -1.121C0.174 -0.483 0.672 0.05 1.33 0.05C1.619 0.05 1.918 -0.035 2.172 -0.189L2.142 -0.543ZM0.593 -1.39C0.707 -1.788 1.001 -1.958 1.25 -1.958C1.469 -1.958 1.793 -1.853 1.888 -1.39H0.593Z' id='g1-101'/>
+<path d='M2.506 -2.262C2.396 -2.262 2.062 -2.257 1.684 -2.112L1.674 -2.107C1.494 -2.227 1.32 -2.262 1.176 -2.262C0.687 -2.262 0.324 -1.878 0.324 -1.45C0.324 -1.275 0.384 -1.096 0.498 -0.956C0.428 -0.872 0.354 -0.732 0.354 -0.543C0.354 -0.349 0.433 -0.224 0.478 -0.164C0.204 -0.005 0.149 0.224 0.149 0.344C0.149 0.722 0.672 1.021 1.32 1.021C1.973 1.021 2.491 0.722 2.491 0.344C2.491 -0.359 1.619 -0.359 1.405 -0.359H0.941C0.862 -0.359 0.648 -0.359 0.648 -0.618C0.648 -0.717 0.682 -0.767 0.687 -0.777C0.862 -0.667 1.036 -0.633 1.171 -0.633C1.659 -0.633 2.022 -1.016 2.022 -1.445C2.022 -1.604 1.978 -1.748 1.888 -1.883C1.868 -1.913 1.868 -1.918 1.868 -1.923C1.868 -1.943 2.167 -1.943 2.192 -1.943C2.197 -1.943 2.386 -1.943 2.565 -1.923L2.506 -2.262ZM1.176 -0.941C0.907 -0.941 0.707 -1.111 0.707 -1.445C0.707 -1.833 0.956 -1.953 1.171 -1.953C1.44 -1.953 1.639 -1.783 1.639 -1.45C1.639 -1.061 1.39 -0.941 1.176 -0.941ZM1.41 0.03C1.524 0.03 2.112 0.03 2.112 0.349C2.112 0.563 1.738 0.712 1.32 0.712S0.528 0.563 0.528 0.349C0.528 0.324 0.528 0.03 0.932 0.03H1.41Z' id='g1-103'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.161 -2.262 0.932 -2.012 0.832 -1.908V-3.457H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-104'/>
+<path d='M0.877 -3.417H0.374V-2.914H0.877V-3.417ZM0.837 -2.212H0.418V0H0.837V-2.212Z' id='g1-105'/>
+<path d='M0.986 -3.417H0.483V-2.914H0.986V-3.417ZM-0.324 0.847C-0.095 0.971 0.13 1.016 0.319 1.016C0.663 1.016 0.986 0.752 0.986 0.294V-2.212H0.568V0.329C0.568 0.418 0.568 0.498 0.463 0.583C0.349 0.667 0.209 0.667 0.164 0.667C-0.045 0.667 -0.174 0.573 -0.234 0.518L-0.324 0.847Z' id='g1-106'/>
+<path d='M0.837 -3.457H0.418V0H0.837V-3.457Z' id='g1-108'/>
+<path d='M3.786 -1.474C3.786 -1.863 3.671 -2.262 3.059 -2.262C2.64 -2.262 2.381 -2.017 2.262 -1.858C2.212 -1.993 2.087 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.21C2.316 -1.539 2.456 -1.933 2.839 -1.933C3.352 -1.933 3.352 -1.584 3.352 -1.44V0H3.786V-1.474Z' id='g1-109'/>
+<path d='M2.316 -1.474C2.316 -1.863 2.202 -2.262 1.589 -2.262C1.305 -2.262 1.031 -2.147 0.812 -1.883V-2.247H0.413V0H0.847V-1.21C0.847 -1.539 0.986 -1.933 1.37 -1.933C1.883 -1.933 1.883 -1.584 1.883 -1.44V0H2.316V-1.474Z' id='g1-110'/>
+<path d='M2.491 -1.091C2.491 -1.748 1.968 -2.286 1.32 -2.286S0.149 -1.743 0.149 -1.091C0.149 -0.458 0.677 0.05 1.32 0.05C1.968 0.05 2.491 -0.458 2.491 -1.091ZM1.32 -0.294C0.927 -0.294 0.583 -0.583 0.583 -1.146S0.951 -1.958 1.32 -1.958C1.694 -1.958 2.057 -1.699 2.057 -1.146C2.057 -0.578 1.704 -0.294 1.32 -0.294Z' id='g1-111'/>
+<path d='M0.857 -0.234C1.121 0.005 1.405 0.05 1.574 0.05C2.102 0.05 2.55 -0.453 2.55 -1.111C2.55 -1.709 2.222 -2.262 1.729 -2.262C1.504 -2.262 1.131 -2.197 0.842 -1.973V-2.212H0.423V0.966H0.857V-0.234ZM0.857 -1.654C0.971 -1.793 1.166 -1.918 1.405 -1.918C1.803 -1.918 2.117 -1.549 2.117 -1.111C2.117 -0.618 1.743 -0.279 1.355 -0.279C1.28 -0.279 1.156 -0.289 1.026 -0.394C0.877 -0.508 0.857 -0.583 0.857 -0.677V-1.654Z' id='g1-112'/>
+<path d='M0.842 -1.061C0.842 -1.599 1.29 -1.888 1.729 -1.893V-2.262C1.31 -2.257 1.006 -2.052 0.807 -1.788V-2.247H0.423V0H0.842V-1.061Z' id='g1-114'/>
+<path d='M1.818 -2.132C1.479 -2.271 1.23 -2.286 1.051 -2.286C0.927 -2.286 0.174 -2.286 0.174 -1.624C0.174 -1.39 0.304 -1.26 0.369 -1.2C0.543 -1.026 0.752 -0.986 1.016 -0.936C1.25 -0.892 1.519 -0.842 1.519 -0.603C1.519 -0.289 1.106 -0.289 1.036 -0.289C0.717 -0.289 0.418 -0.403 0.219 -0.543L0.149 -0.169C0.319 -0.085 0.623 0.05 1.036 0.05C1.26 0.05 1.479 0.015 1.664 -0.12C1.848 -0.259 1.908 -0.478 1.908 -0.648C1.908 -0.737 1.898 -0.932 1.689 -1.121C1.504 -1.285 1.325 -1.32 1.086 -1.365C0.792 -1.42 0.563 -1.465 0.563 -1.684C0.563 -1.968 0.927 -1.968 1.001 -1.968C1.285 -1.968 1.504 -1.908 1.753 -1.778L1.818 -2.132Z' id='g1-115'/>
+<path d='M0.936 -1.898H1.674V-2.212H0.936V-2.844H0.553V-2.212H0.1V-1.898H0.538V-0.638C0.538 -0.304 0.623 0.05 0.981 0.05S1.614 -0.065 1.763 -0.134L1.679 -0.453C1.514 -0.334 1.34 -0.294 1.2 -0.294C0.991 -0.294 0.936 -0.498 0.936 -0.727V-1.898Z' id='g1-116'/>
+<path d='M2.316 -2.212H1.883V-0.767C1.883 -0.369 1.544 -0.244 1.255 -0.244C0.887 -0.244 0.847 -0.344 0.847 -0.573V-2.212H0.413V-0.543C0.413 -0.1 0.608 0.05 0.956 0.05C1.161 0.05 1.599 0.01 1.898 -0.229V0H2.316V-2.212Z' id='g1-117'/>
+<path d='M3.537 -2.212H3.148C3.103 -2.072 2.824 -1.23 2.67 -0.712C2.63 -0.568 2.58 -0.408 2.565 -0.294H2.56C2.531 -0.498 2.356 -1.036 2.346 -1.071L1.978 -2.212H1.599C1.455 -1.783 1.081 -0.667 1.041 -0.304H1.036C0.996 -0.658 0.628 -1.758 0.548 -1.998C0.508 -2.117 0.508 -2.127 0.483 -2.212H0.075L0.802 0H1.22C1.225 -0.02 1.36 -0.413 1.534 -0.966C1.609 -1.21 1.758 -1.689 1.783 -1.908L1.788 -1.913C1.798 -1.808 1.828 -1.699 1.863 -1.574S1.933 -1.315 1.968 -1.2L2.351 0H2.809L3.537 -2.212Z' id='g1-119'/>
+<path d='M1.38 -1.141L2.346 -2.212H1.908L1.2 -1.395L0.478 -2.212H0.03L1.026 -1.141L0 0H0.443L1.2 -0.936L1.988 0H2.436L1.38 -1.141Z' id='g1-120'/>
+<path d='M2.112 -2.002V-2.212H0.219V-1.893H0.951C1.011 -1.893 1.071 -1.898 1.131 -1.898H1.519L0.149 -0.219V0H2.127V-0.334H1.355C1.295 -0.334 1.235 -0.329 1.176 -0.329H0.742L2.112 -2.002Z' id='g1-122'/>
+<path d='M3.891 -2.914C4.806 -3.165 5.452 -3.811 5.452 -4.546C5.452 -5.469 4.411 -6.223 3.129 -6.223H0.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891 -2.914ZM1.704 -3.407V-5.694H3.022C4.062 -5.694 4.671 -5.192 4.671 -4.546C4.671 -3.963 4.125 -3.407 3.022 -3.407H1.704Z' id='g0-82'/>
+<path d='M3.694 -2.591C3.694 -3.479 3.04 -4.133 2.152 -4.133C1.569 -4.133 1.139 -3.981 0.708 -3.739L0.762 -3.102C1.21 -3.434 1.65 -3.569 2.143 -3.569C2.645 -3.569 2.95 -3.165 2.95 -2.582V-2.206C1.408 -2.17 0.395 -1.766 0.395 -1.04C0.395 -0.619 0.672 0.099 1.453 0.099C1.632 0.099 2.412 0.081 2.977 -0.341V0H3.694V-2.591ZM2.95 -1.255C2.95 -1.067 2.95 -0.843 2.627 -0.655C2.403 -0.52 2.107 -0.484 1.928 -0.484C1.47 -0.484 1.085 -0.699 1.085 -1.058C1.085 -1.695 2.833 -1.722 2.95 -1.722V-1.255Z' id='g0-97'/>
+<path d='M3.829 -1.964C3.829 -2.242 3.82 -2.923 3.47 -3.461C3.093 -4.026 2.52 -4.133 2.179 -4.133C1.139 -4.133 0.314 -3.174 0.314 -2.026C0.314 -0.843 1.193 0.099 2.313 0.099C2.744 0.099 3.264 -0.009 3.784 -0.341L3.73 -0.959C3.165 -0.556 2.636 -0.484 2.322 -0.484C1.578 -0.484 1.004 -1.139 0.977 -1.964H3.829ZM1.031 -2.493C1.175 -3.067 1.614 -3.551 2.179 -3.551C2.511 -3.551 3.12 -3.398 3.291 -2.493H1.031Z' id='g0-101'/>
+<path d='M1.524 -6.133H0.664V-5.272H1.524V-6.133ZM1.453 -3.981H0.735V0H1.453V-3.981Z' id='g0-105'/>
+<path d='M1.453 -6.223H0.735V0H1.453V-6.223Z' id='g0-108'/>
+<path d='M1.462 -1.91C1.462 -2.851 2.197 -3.425 3.013 -3.434V-4.08C2.367 -4.071 1.775 -3.748 1.408 -3.219V-4.035H0.744V0H1.462V-1.91Z' id='g0-114'/>
+<path d='M3.165 -3.847C2.609 -4.098 2.197 -4.133 1.829 -4.133C1.623 -4.133 0.305 -4.133 0.305 -2.95C0.305 -2.52 0.565 -2.251 0.664 -2.152C1.004 -1.856 1.237 -1.811 1.847 -1.695C2.134 -1.641 2.645 -1.542 2.645 -1.085C2.645 -0.502 1.919 -0.502 1.802 -0.502C1.273 -0.502 0.762 -0.681 0.377 -0.95L0.26 -0.296C0.798 -0.009 1.345 0.099 1.802 0.099C2.385 0.099 3.318 -0.09 3.318 -1.157C3.318 -1.47 3.192 -1.784 2.878 -2.053C2.573 -2.313 2.304 -2.367 1.748 -2.475C1.426 -2.537 0.977 -2.618 0.977 -3.04C0.977 -3.569 1.614 -3.569 1.748 -3.569C2.403 -3.569 2.789 -3.362 3.049 -3.219L3.165 -3.847Z' id='g0-115'/>
+<path d='M1.623 -3.425H2.914V-3.981H1.623V-5.12H0.959V-3.981H0.17V-3.425H0.933V-1.13C0.933 -0.601 1.049 0.099 1.704 0.099C2.098 0.099 2.564 0.018 3.067 -0.233L2.914 -0.798C2.681 -0.619 2.367 -0.511 2.089 -0.511C1.739 -0.511 1.623 -0.825 1.623 -1.291V-3.425Z' id='g0-116'/>
+<path d='M4.116 -3.981H3.407L2.699 -2.161C2.52 -1.695 2.188 -0.825 2.143 -0.493H2.125C2.107 -0.646 2.08 -0.816 1.587 -2.107C1.318 -2.833 0.879 -3.927 0.861 -3.981H0.126L1.704 0H2.537L4.116 -3.981Z' id='g0-118'/>
+</defs>
+<g id='page10'>
+<path d='M194.617 194.93V186.074M253.285 194.93V186.074M311.953 194.93V186.074M370.625 194.93V186.074M429.293 194.93V186.074M194.617 51.973V60.828M253.285 51.973V60.828M311.953 51.973V60.828M370.625 51.973V60.828M429.293 51.973V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M165.281 190.324V186.074M223.953 190.324V186.074M282.621 190.324V186.074M341.289 190.324V186.074M399.957 190.324V186.074M458.629 190.324V186.074M165.281 56.574V60.828M223.953 56.574V60.828M282.621 56.574V60.828M341.289 56.574V60.828M399.957 56.574V60.828M458.629 56.574V60.828' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 186.074H140.199M135.949 154.762H140.199M135.949 123.449H140.199M135.949 92.141H140.199M135.949 60.828H140.199M487.961 186.074H483.711M487.961 154.762H483.711M487.961 123.449H483.711M487.961 92.141H483.711M487.961 60.828H483.711' fill='none' stroke='#808080' stroke-miterlimit='10' stroke-width='0.199'/>
+<path d='M135.949 186.074V60.828H487.961V186.074H135.949Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -21.265 59.571)'>
+<use x='168.285' xlink:href='#g2-97' y='140.503'/>
+<use x='172.353' xlink:href='#g2-108' y='140.503'/>
+<use x='174.373' xlink:href='#g2-108' y='140.503'/>
+<use x='176.393' xlink:href='#g2-111' y='140.503'/>
+<use x='180.863' xlink:href='#g2-99' y='140.503'/>
+<use x='184.627' xlink:href='#g2-45' y='140.503'/>
+<use x='187.449' xlink:href='#g2-116' y='140.503'/>
+<use x='190.507' xlink:href='#g2-101' y='140.503'/>
+<use x='194.271' xlink:href='#g2-115' y='140.503'/>
+<use x='197.517' xlink:href='#g2-116' y='140.503'/>
+<use x='200.575' xlink:href='#g2-49' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 59.571)'>
+<use x='168.285' xlink:href='#g2-97' y='140.503'/>
+<use x='172.353' xlink:href='#g2-108' y='140.503'/>
+<use x='174.373' xlink:href='#g2-108' y='140.503'/>
+<use x='176.393' xlink:href='#g2-111' y='140.503'/>
+<use x='180.863' xlink:href='#g2-99' y='140.503'/>
+<use x='184.627' xlink:href='#g2-45' y='140.503'/>
+<use x='187.449' xlink:href='#g2-116' y='140.503'/>
+<use x='190.507' xlink:href='#g2-101' y='140.503'/>
+<use x='194.271' xlink:href='#g2-115' y='140.503'/>
+<use x='197.517' xlink:href='#g2-116' y='140.503'/>
+<use x='200.575' xlink:href='#g2-78' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 59.571)'>
+<use x='168.285' xlink:href='#g2-115' y='140.503'/>
+<use x='171.531' xlink:href='#g2-104' y='140.503'/>
+<use x='175.904' xlink:href='#g2-54' y='140.503'/>
+<use x='180.138' xlink:href='#g2-98' y='140.503'/>
+<use x='184.746' xlink:href='#g2-101' y='140.503'/>
+<use x='188.509' xlink:href='#g2-110' y='140.503'/>
+<use x='192.882' xlink:href='#g2-99' y='140.503'/>
+<use x='196.646' xlink:href='#g2-104' y='140.503'/>
+<use x='201.018' xlink:href='#g2-78' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 59.571)'>
+<use x='168.285' xlink:href='#g2-115' y='140.503'/>
+<use x='171.531' xlink:href='#g2-104' y='140.503'/>
+<use x='175.904' xlink:href='#g2-56' y='140.503'/>
+<use x='180.138' xlink:href='#g2-98' y='140.503'/>
+<use x='184.746' xlink:href='#g2-101' y='140.503'/>
+<use x='188.509' xlink:href='#g2-110' y='140.503'/>
+<use x='192.882' xlink:href='#g2-99' y='140.503'/>
+<use x='196.646' xlink:href='#g2-104' y='140.503'/>
+<use x='201.018' xlink:href='#g2-78' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 59.571)'>
+<use x='168.285' xlink:href='#g2-120' y='140.503'/>
+<use x='172.187' xlink:href='#g2-109' y='140.503'/>
+<use x='178.912' xlink:href='#g2-97' y='140.503'/>
+<use x='182.98' xlink:href='#g2-108' y='140.503'/>
+<use x='185' xlink:href='#g2-108' y='140.503'/>
+<use x='187.02' xlink:href='#g2-111' y='140.503'/>
+<use x='191.49' xlink:href='#g2-99' y='140.503'/>
+<use x='195.254' xlink:href='#g2-45' y='140.503'/>
+<use x='198.076' xlink:href='#g2-116' y='140.503'/>
+<use x='201.134' xlink:href='#g2-101' y='140.503'/>
+<use x='204.898' xlink:href='#g2-115' y='140.503'/>
+<use x='208.144' xlink:href='#g2-116' y='140.503'/>
+<use x='211.202' xlink:href='#g2-78' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 59.571)'>
+<use x='168.285' xlink:href='#g2-99' y='140.503'/>
+<use x='172.049' xlink:href='#g2-97' y='140.503'/>
+<use x='176.117' xlink:href='#g2-99' y='140.503'/>
+<use x='179.88' xlink:href='#g2-104' y='140.503'/>
+<use x='184.253' xlink:href='#g2-101' y='140.503'/>
+<use x='188.017' xlink:href='#g2-45' y='140.503'/>
+<use x='190.839' xlink:href='#g2-115' y='140.503'/>
+<use x='194.086' xlink:href='#g2-99' y='140.503'/>
+<use x='197.849' xlink:href='#g2-114' y='140.503'/>
+<use x='200.741' xlink:href='#g2-97' y='140.503'/>
+<use x='204.81' xlink:href='#g2-116' y='140.503'/>
+<use x='207.868' xlink:href='#g2-99' y='140.503'/>
+<use x='211.631' xlink:href='#g2-104' y='140.503'/>
+<use x='216.004' xlink:href='#g2-78' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 47.205)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 15.894)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -15.418)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -46.729)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -78.041)'>
+<use x='168.285' xlink:href='#g1-50' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-120' y='140.503'/>
+</g>
+<path clip-path='url(#clip10)' d='M135.949 123.449H487.961' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M140.125 186.074H143.363V123.449H140.125ZM198.797 186.074H202.035V123.449H198.797ZM257.465 186.074H260.703V123.449H257.465ZM316.133 186.074H319.371V123.449H316.133ZM374.801 186.074H378.039V123.449H374.801ZM433.473 186.074H436.711V123.449H433.473Z' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M140.125 186.074H143.363V123.449H140.125ZM198.797 186.074H202.035V123.449H198.797ZM257.465 186.074H260.703V123.449H257.465ZM316.133 186.074H319.371V123.449H316.133ZM374.801 186.074H378.039V123.449H374.801ZM433.473 186.074H436.711V123.449H433.473Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M141.746 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M139.754 123.449H143.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M141.746 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M139.754 123.449H143.738' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M200.414 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M198.422 123.449H202.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M200.414 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M198.422 123.449H202.406' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M259.082 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M257.09 123.449H261.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M259.082 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M257.09 123.449H261.078' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M317.754 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M315.762 123.449H319.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M317.754 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M315.762 123.449H319.746' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M376.422 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M374.43 123.449H378.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M376.422 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M374.43 123.449H378.414' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M435.09 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M433.098 123.449H437.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M435.09 123.449V123.449' fill='#f0e0f0'/>
+<path clip-path='url(#clip10)' d='M433.098 123.449H437.082' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M145.356 186.074H148.594V120.071H145.356ZM204.028 186.074H207.266V121.571H204.028ZM262.695 186.074H265.934V122.699H262.695ZM321.363 186.074H324.602V125.895H321.363ZM380.031 186.074H383.27V173.172H380.031ZM438.703 186.074H441.942V93.391H438.703Z' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M145.356 186.074H148.594V120.071H145.356ZM204.028 186.074H207.266V121.571H204.028ZM262.695 186.074H265.934V122.699H262.695ZM321.363 186.074H324.602V125.895H321.363ZM380.031 186.074H383.27V173.172H380.031ZM438.703 186.074H441.942V93.391H438.703Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M146.977 120.071V120.071' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M144.984 120.07H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M146.977 120.071V120.071' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M144.984 120.07H148.968' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M205.645 121.571V121.571' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M203.652 121.57H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M205.645 121.571V121.571' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M203.652 121.57H207.636' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M264.313 122.699V122.699' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M262.32 122.699H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M264.313 122.699V122.699' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M262.32 122.699H266.308' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M322.984 125.895V125.895' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M320.992 125.894H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M322.984 125.895V125.895' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M320.992 125.894H324.976' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M381.652 173.172V173.172' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M379.66 173.172H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M381.652 173.172V173.172' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M379.66 173.172H383.644' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M440.32 93.391V93.391' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M438.328 93.391H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M440.32 93.391V93.391' fill='#e1c2e1'/>
+<path clip-path='url(#clip10)' d='M438.328 93.391H442.312' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M150.586 186.074H153.824V122.699H150.586ZM209.258 186.074H212.496V124.766H209.258ZM267.926 186.074H271.164V121.762H267.926ZM326.594 186.074H329.832V118.692H326.594ZM385.262 186.074H388.5V154.324H385.262ZM443.934 186.074H447.172V111.238H443.934Z' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M150.586 186.074H153.824V122.699H150.586ZM209.258 186.074H212.496V124.766H209.258ZM267.926 186.074H271.164V121.762H267.926ZM326.594 186.074H329.832V118.692H326.594ZM385.262 186.074H388.5V154.324H385.262ZM443.934 186.074H447.172V111.238H443.934Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M152.207 122.699V122.699' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M150.215 122.699H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M152.207 122.699V122.699' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M150.215 122.699H154.199' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M210.875 124.766V124.766' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M208.883 124.766H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M210.875 124.766V124.766' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M208.883 124.766H212.867' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M269.543 121.762V121.762' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M267.551 121.762H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M269.543 121.762V121.762' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M267.551 121.762H271.539' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M328.215 118.692V118.692' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M326.223 118.691H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M328.215 118.692V118.692' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M326.223 118.691H330.207' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M386.883 154.324V154.324' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M384.891 154.324H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M386.883 154.324V154.324' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M384.891 154.324H388.875' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M445.551 111.238V111.238' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M443.559 111.238H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M445.551 111.238V111.238' fill='#d1a3d1'/>
+<path clip-path='url(#clip10)' d='M443.559 111.238H447.543' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M155.817 186.074H159.055V119.696H155.817ZM214.488 186.074H217.727V121.887H214.488ZM273.156 186.074H276.395V113.43H273.156ZM331.824 186.074H335.063V119.004H331.824ZM390.492 186.074H393.731V89.133H390.492ZM449.164 186.074H452.402V120.633H449.164Z' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M155.817 186.074H159.055V119.696H155.817ZM214.488 186.074H217.727V121.887H214.488ZM273.156 186.074H276.395V113.43H273.156ZM331.824 186.074H335.063V119.004H331.824ZM390.492 186.074H393.731V89.133H390.492ZM449.164 186.074H452.402V120.633H449.164Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M157.438 119.696V119.696' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M155.445 119.695H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M157.438 119.696V119.696' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M155.445 119.695H159.429' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M216.106 121.887V121.887' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M214.113 121.886H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M216.106 121.887V121.887' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M214.113 121.886H218.097' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M274.774 113.43V113.43' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M272.781 113.43H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M274.774 113.43V113.43' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M272.781 113.43H276.769' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M333.445 119.004V119.004' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M331.453 119.004H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M333.445 119.004V119.004' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M331.453 119.004H335.437' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M392.113 89.133V89.133' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M390.121 89.133H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M392.113 89.133V89.133' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M390.121 89.133H394.105' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M450.781 120.633V120.633' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M448.789 120.633H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M450.781 120.633V120.633' fill='#c285c2'/>
+<path clip-path='url(#clip10)' d='M448.789 120.633H452.773' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M161.047 186.074H164.285V109.738H161.047ZM219.719 186.074H222.957V112.555H219.719ZM278.387 186.074H281.625V86.192H278.387ZM337.055 186.074H340.293V106.543H337.055ZM395.723 186.074H398.961V172.172H395.723ZM454.395 186.074H457.633V122.949H454.395Z' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M161.047 186.074H164.285V109.738H161.047ZM219.719 186.074H222.957V112.555H219.719ZM278.387 186.074H281.625V86.192H278.387ZM337.055 186.074H340.293V106.543H337.055ZM395.723 186.074H398.961V172.172H395.723ZM454.395 186.074H457.633V122.949H454.395Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M162.668 109.738V109.738' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M160.676 109.738H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M162.668 109.738V109.738' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M160.676 109.738H164.66' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M221.336 112.555V112.555' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M219.344 112.554H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M221.336 112.555V112.555' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M219.344 112.554H223.328' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M280.004 86.192V86.192' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M278.012 86.191H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M280.004 86.192V86.192' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M278.012 86.191H282' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M338.676 106.543V106.543' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M336.684 106.543H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M338.676 106.543V106.543' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M336.684 106.543H340.668' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M397.344 172.172V172.172' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M395.352 172.172H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M397.344 172.172V172.172' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M395.352 172.172H399.336' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M456.012 122.949V122.949' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M454.02 122.949H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M456.012 122.949V122.949' fill='#b366b3'/>
+<path clip-path='url(#clip10)' d='M454.02 122.949H458.004' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M166.278 186.074H169.516V98.278H166.278ZM224.949 186.074H228.188V94.77H224.949ZM283.617 186.074H286.856V78.051H283.617ZM342.285 186.074H345.524V92.453H342.285ZM400.953 186.074H404.192V154.762H400.953ZM459.625 186.074H462.863V113.242H459.625Z' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M166.278 186.074H169.516V98.278H166.278ZM224.949 186.074H228.188V94.77H224.949ZM283.617 186.074H286.856V78.051H283.617ZM342.285 186.074H345.524V92.453H342.285ZM400.953 186.074H404.192V154.762H400.953ZM459.625 186.074H462.863V113.242H459.625Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M167.899 98.278V98.278' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M165.906 98.277H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M167.899 98.278V98.278' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M165.906 98.277H169.89' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M226.567 94.77V94.77' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M224.574 94.77H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M226.567 94.77V94.77' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M224.574 94.77H228.558' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M285.234 78.051V78.051' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M283.242 78.051H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M285.234 78.051V78.051' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M283.242 78.051H287.23' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M343.906 92.453V92.453' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M341.914 92.453H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M343.906 92.453V92.453' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M341.914 92.453H345.898' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M402.574 154.762V154.762' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M400.582 154.761H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M402.574 154.762V154.762' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M400.582 154.761H404.566' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M461.242 113.242V113.242' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M459.25 113.242H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M461.242 113.242V113.242' fill='#a447a4'/>
+<path clip-path='url(#clip10)' d='M459.25 113.242H463.234' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M171.508 186.074H174.746V109.172H171.508ZM230.18 186.074H233.414V112.617H230.18ZM288.848 186.074H292.086V86.254H288.848ZM347.516 186.074H350.754V107.418H347.516ZM406.184 186.074H409.422V172.235H406.184ZM464.856 186.074H468.094V124.266H464.856Z' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M171.508 186.074H174.746V109.172H171.508ZM230.18 186.074H233.414V112.617H230.18ZM288.848 186.074H292.086V86.254H288.848ZM347.516 186.074H350.754V107.418H347.516ZM406.184 186.074H409.422V172.235H406.184ZM464.856 186.074H468.094V124.266H464.856Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M173.129 109.172V109.172' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M171.137 109.172H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M173.129 109.172V109.172' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M171.137 109.172H175.121' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M231.797 112.617V112.617' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M229.805 112.617H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M231.797 112.617V112.617' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M229.805 112.617H233.789' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M290.465 86.254V86.254' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M288.473 86.254H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M290.465 86.254V86.254' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M288.473 86.254H292.461' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M349.137 107.418V107.418' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M347.145 107.418H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M349.137 107.418V107.418' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M347.145 107.418H351.129' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M407.805 172.235V172.235' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M405.813 172.234H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M407.805 172.235V172.235' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M405.813 172.234H409.797' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M466.473 124.266V124.266' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M464.481 124.266H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M466.473 124.266V124.266' fill='#942994'/>
+<path clip-path='url(#clip10)' d='M464.481 124.266H468.465' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M411.414 186.074H414.652V151.946H411.414ZM176.738 186.074H179.977V117.375H176.738ZM235.41 186.074H238.645V119.567H235.41ZM294.078 186.074H297.317V116.813H294.078ZM352.746 186.074H355.984V123.891H352.746ZM470.086 186.074H473.324V117.313H470.086Z' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M411.414 186.074H414.652V151.946H411.414ZM176.738 186.074H179.977V117.375H176.738ZM235.41 186.074H238.645V119.567H235.41ZM294.078 186.074H297.317V116.813H294.078ZM352.746 186.074H355.984V123.891H352.746ZM470.086 186.074H473.324V117.313H470.086Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M413.035 151.946V151.946' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M411.043 151.945H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M413.035 151.946V151.946' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M411.043 151.945H415.027' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M178.36 117.375V117.375' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M176.367 117.375H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M178.36 117.375V117.375' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M176.367 117.375H180.351' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M237.027 119.567V119.567' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M235.035 119.566H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M237.027 119.567V119.567' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M235.035 119.566H239.019' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M295.695 116.813V116.813' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M293.703 116.813H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M295.695 116.813V116.813' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M293.703 116.813H297.691' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M354.367 123.891V123.891' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M352.375 123.89H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M354.367 123.891V123.891' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M352.375 123.89H356.359' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M471.703 117.313V117.313' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M469.711 117.313H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M471.703 117.313V117.313' fill='#850a85'/>
+<path clip-path='url(#clip10)' d='M469.711 117.313H473.695' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M181.969 186.074H185.207V121.762H181.969ZM240.641 186.074H243.875V122.074H240.641ZM299.309 186.074H302.547V122.574H299.309ZM357.977 186.074H361.215V121.949H357.977ZM475.317 186.074H478.555V113.746H475.317Z' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M181.969 186.074H185.207V121.762H181.969ZM240.641 186.074H243.875V122.074H240.641ZM299.309 186.074H302.547V122.574H299.309ZM357.977 186.074H361.215V121.949H357.977ZM475.317 186.074H478.555V113.746H475.317Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M183.59 121.762V121.762' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M181.598 121.762H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M183.59 121.762V121.762' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M181.598 121.762H185.583' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M242.258 122.074V122.074' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M240.266 122.074H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M242.258 122.074V122.074' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M240.266 122.074H244.25' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M300.926 122.574V122.574' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M298.933 122.574H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M300.926 122.574V122.574' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M298.933 122.574H302.921' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M359.598 121.949V121.949' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M357.606 121.949H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M359.598 121.949V121.949' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M357.606 121.949H361.59' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M476.934 113.746V113.746' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M474.942 113.746H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M476.934 113.746V113.746' fill='#760076'/>
+<path clip-path='url(#clip10)' d='M474.942 113.746H478.926' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M187.199 186.074H190.438V122.887H187.199ZM245.871 186.074H249.106V122.637H245.871ZM304.539 186.074H307.777V123.387H304.539ZM363.207 186.074H366.445V125.391H363.207ZM421.875 186.074H425.113V169.164H421.875ZM480.547 186.074H483.785V121.571H480.547Z' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M187.199 186.074H190.438V122.887H187.199ZM245.871 186.074H249.106V122.637H245.871ZM304.539 186.074H307.777V123.387H304.539ZM363.207 186.074H366.445V125.391H363.207ZM421.875 186.074H425.113V169.164H421.875ZM480.547 186.074H483.785V121.571H480.547Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M188.82 122.887V122.887' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M186.828 122.886H190.813' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M188.82 122.887V122.887' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M186.828 122.886H190.813' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M247.488 122.637V122.637' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M245.496 122.637H249.481' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M247.488 122.637V122.637' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M245.496 122.637H249.481' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M306.156 123.387V123.387' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M304.164 123.387H308.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M306.156 123.387V123.387' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M304.164 123.387H308.152' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M364.828 125.391V125.391' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M362.836 125.39H366.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M364.828 125.391V125.391' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M362.836 125.39H366.82' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M423.496 169.164V169.164' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M421.504 169.164H425.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M423.496 169.164V169.164' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M421.504 169.164H425.488' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M482.164 121.571V121.571' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M480.172 121.57H484.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M482.164 121.571V121.571' fill='#670067'/>
+<path clip-path='url(#clip10)' d='M480.172 121.57H484.156' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path clip-path='url(#clip10)' d='M419.477 233.301H487.762V211.324H419.477Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 254.512 88.837)'>
+<use x='168.285' xlink:href='#g1-72' y='129.265'/>
+<use x='172.021' xlink:href='#g1-80' y='129.265'/>
+<use x='175.402' xlink:href='#g1-45' y='129.265'/>
+<use x='177.167' xlink:href='#g1-90' y='129.265'/>
+<use x='180.401' xlink:href='#g1-52' y='129.265'/>
+<use x='183.047' xlink:href='#g1-45' y='129.265'/>
+<use x='184.812' xlink:href='#g1-71' y='129.265'/>
+<use x='188.34' xlink:href='#g1-52' y='129.265'/>
+<use x='190.987' xlink:href='#g1-44' y='129.265'/>
+<use x='194.221' xlink:href='#g1-49' y='129.265'/>
+<use x='196.867' xlink:href='#g1-54' y='129.265'/>
+<use x='199.514' xlink:href='#g1-71' y='129.265'/>
+<use x='203.042' xlink:href='#g1-98' y='129.265'/>
+<use x='168.285' xlink:href='#g1-56' y='134.884'/>
+<use x='170.931' xlink:href='#g1-45' y='134.884'/>
+<use x='172.695' xlink:href='#g1-99' y='134.884'/>
+<use x='175.048' xlink:href='#g1-111' y='134.884'/>
+<use x='177.547' xlink:href='#g1-114' y='134.884'/>
+<use x='179.355' xlink:href='#g1-101' y='134.884'/>
+<use x='183.471' xlink:href='#g1-73' y='134.884'/>
+<use x='184.941' xlink:href='#g1-110' y='134.884'/>
+<use x='187.674' xlink:href='#g1-116' y='134.884'/>
+<use x='189.585' xlink:href='#g1-101' y='134.884'/>
+<use x='191.938' xlink:href='#g1-108' y='134.884'/>
+<use x='194.965' xlink:href='#g1-88' y='134.884'/>
+<use x='198.493' xlink:href='#g1-69' y='134.884'/>
+<use x='201.667' xlink:href='#g1-79' y='134.884'/>
+<use x='205.576' xlink:href='#g1-78' y='134.884'/>
+<use x='211.076' xlink:href='#g1-64' y='134.884'/>
+<use x='214.605' xlink:href='#g1-50' y='134.884'/>
+<use x='217.251' xlink:href='#g1-46' y='134.884'/>
+<use x='218.721' xlink:href='#g1-55' y='134.884'/>
+<use x='221.368' xlink:href='#g1-71' y='134.884'/>
+<use x='224.896' xlink:href='#g1-104' y='134.884'/>
+<use x='227.629' xlink:href='#g1-122' y='134.884'/>
+<use x='168.285' xlink:href='#g1-85' y='140.503'/>
+<use x='171.917' xlink:href='#g1-98' y='140.503'/>
+<use x='174.65' xlink:href='#g1-117' y='140.503'/>
+<use x='177.383' xlink:href='#g1-110' y='140.503'/>
+<use x='180.116' xlink:href='#g1-116' y='140.503'/>
+<use x='182.027' xlink:href='#g1-117' y='140.503'/>
+<use x='186.524' xlink:href='#g1-49' y='140.503'/>
+<use x='189.17' xlink:href='#g1-56' y='140.503'/>
+<use x='191.817' xlink:href='#g1-46' y='140.503'/>
+<use x='193.287' xlink:href='#g1-48' y='140.503'/>
+<use x='195.933' xlink:href='#g1-52' y='140.503'/>
+<use x='198.58' xlink:href='#g1-46' y='140.503'/>
+<use x='200.05' xlink:href='#g1-49' y='140.503'/>
+<use x='202.696' xlink:href='#g1-44' y='140.503'/>
+<use x='205.931' xlink:href='#g1-71' y='140.503'/>
+<use x='209.459' xlink:href='#g1-67' y='140.503'/>
+<use x='212.841' xlink:href='#g1-67' y='140.503'/>
+<use x='217.986' xlink:href='#g1-55' y='140.503'/>
+<use x='220.633' xlink:href='#g1-46' y='140.503'/>
+<use x='222.103' xlink:href='#g1-52' y='140.503'/>
+<use x='224.749' xlink:href='#g1-46' y='140.503'/>
+<use x='226.219' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 2.877 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 61.546 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 120.215 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 178.884 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 237.553 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 296.222 285.711)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 8.107 282.329)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-53' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 66.776 283.832)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 125.445 284.96)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 184.114 288.153)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 242.783 335.434)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 301.452 255.652)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-52' y='140.503'/>
+<use x='175.048' xlink:href='#g1-56' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 13.338 284.96)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 72.007 287.026)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-56' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 130.676 284.02)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 189.345 280.952)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-56' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 248.014 316.584)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 306.683 273.5)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 18.568 281.954)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 77.237 284.146)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.906 275.691)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.575 281.265)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 253.244 251.394)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-53' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 311.913 282.893)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-52' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.799 271.997)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.468 274.815)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 141.137 248.45)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-54' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.806 268.803)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 258.475 334.432)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 317.144 285.21)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 29.029 260.537)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-52' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.698 257.03)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-52' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.367 240.309)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-55' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 205.036 254.713)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-52' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 263.705 317.023)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 322.374 275.504)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 34.26 271.433)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.929 274.877)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.598 248.513)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 210.267 269.68)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 268.936 334.494)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 327.605 286.525)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 274.166 314.205)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-53' y='140.503'/>
+<use x='175.048' xlink:href='#g1-52' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.49 279.637)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 98.159 281.828)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.828 279.073)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.497 286.149)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-57' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 332.835 279.574)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.72 284.02)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.389 284.333)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 162.058 284.834)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.727 284.208)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-50' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 338.065 276.005)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-49' y='140.503'/>
+<use x='175.048' xlink:href='#g1-54' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.951 285.147)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.62 284.897)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-49' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 167.289 285.648)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-48' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.958 287.652)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-57' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 284.627 331.426)'>
+<use x='168.285' xlink:href='#g1-48' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-50' y='140.503'/>
+<use x='175.048' xlink:href='#g1-55' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 343.296 283.832)'>
+<use x='168.285' xlink:href='#g1-49' y='140.503'/>
+<use x='170.931' xlink:href='#g1-46' y='140.503'/>
+<use x='172.401' xlink:href='#g1-48' y='140.503'/>
+<use x='175.048' xlink:href='#g1-51' y='140.503'/>
+</g>
+<g transform='matrix(0 -1 1 0 -27.345 343.63)'>
+<use x='168.285' xlink:href='#g0-82' y='140.503'/>
+<use x='174.255' xlink:href='#g0-101' y='140.503'/>
+<use x='178.351' xlink:href='#g0-108' y='140.503'/>
+<use x='180.551' xlink:href='#g0-97' y='140.503'/>
+<use x='184.979' xlink:href='#g0-116' y='140.503'/>
+<use x='188.307' xlink:href='#g0-105' y='140.503'/>
+<use x='190.507' xlink:href='#g0-118' y='140.503'/>
+<use x='194.755' xlink:href='#g0-101' y='140.503'/>
+<use x='201.922' xlink:href='#g0-114' y='140.503'/>
+<use x='205.07' xlink:href='#g0-115' y='140.503'/>
+<use x='208.603' xlink:href='#g0-115' y='140.503'/>
+<use x='215.207' xlink:href='#g2-40' y='140.503'/>
+<use x='218.5' xlink:href='#g2-108' y='140.503'/>
+<use x='220.521' xlink:href='#g2-111' y='140.503'/>
+<use x='224.52' xlink:href='#g2-119' y='140.503'/>
+<use x='230.068' xlink:href='#g2-101' y='140.503'/>
+<use x='233.832' xlink:href='#g2-114' y='140.503'/>
+<use x='239.547' xlink:href='#g2-105' y='140.503'/>
+<use x='241.567' xlink:href='#g2-115' y='140.503'/>
+<use x='247.636' xlink:href='#g2-98' y='140.503'/>
+<use x='252.244' xlink:href='#g2-101' y='140.503'/>
+<use x='256.008' xlink:href='#g2-116' y='140.503'/>
+<use x='259.066' xlink:href='#g2-116' y='140.503'/>
+<use x='262.124' xlink:href='#g2-101' y='140.503'/>
+<use x='265.887' xlink:href='#g2-114' y='140.503'/>
+<use x='268.779' xlink:href='#g2-41' y='140.503'/>
+</g>
+<path d='M136.149 231.446H402.137V214.453H136.149Z' fill='#ffffff'/>
+<path d='M136.149 231.446H402.137V214.453H136.149Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='#f0e0f0'/>
+<path d='M139.336 224.941H142.324V216.972H139.336ZM145.313 224.941H148.301V218.964H145.313Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -33.522 84.43)'>
+<use x='185.011' xlink:href='#g2-109' y='140.503'/>
+<use x='191.736' xlink:href='#g2-105' y='140.503'/>
+</g>
+<path d='M163.422 224.941H166.41V216.973H163.422ZM169.398 224.941H172.391V218.965H169.398Z' fill='#e1c2e1'/>
+<path d='M163.422 224.941H166.41V216.972H163.422ZM169.398 224.941H172.391V218.964H169.398Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.56 83.976)'>
+<use x='208.137' xlink:href='#g2-116' y='140.503'/>
+<use x='211.195' xlink:href='#g2-99' y='140.503'/>
+</g>
+<path d='M185.586 224.941H188.574V216.973H185.586ZM191.563 224.941H194.555V218.965H191.563Z' fill='#d1a3d1'/>
+<path d='M185.586 224.941H188.574V216.972H185.586ZM191.563 224.941H194.555V218.964H191.563Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.159 84.43)'>
+<use x='229.9' xlink:href='#g2-106' y='140.503'/>
+<use x='232.155' xlink:href='#g2-101' y='140.503'/>
+</g>
+<path d='M206.949 224.941H209.938V216.973H206.949ZM212.926 224.941H215.914V218.965H212.926Z' fill='#c285c2'/>
+<path d='M206.949 224.941H209.938V216.972H206.949ZM212.926 224.941H215.914V218.964H212.926Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.958 83.47)'>
+<use x='252.061' xlink:href='#g2-115' y='140.503'/>
+<use x='255.307' xlink:href='#g2-110' y='140.503'/>
+</g>
+<path d='M229.91 224.941H232.898V216.973H229.91ZM235.887 224.941H238.875V218.965H235.887Z' fill='#b366b3'/>
+<path d='M229.91 224.941H232.898V216.972H229.91ZM235.887 224.941H238.875V218.964H235.887Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -32.781 83.47)'>
+<use x='274.845' xlink:href='#g2-114' y='140.503'/>
+<use x='277.737' xlink:href='#g2-112' y='140.503'/>
+</g>
+<path d='M252.516 224.941H255.504V216.973H252.516ZM258.496 224.941H261.484V218.965H258.496Z' fill='#a447a4'/>
+<path d='M252.516 224.941H255.504V216.972H252.516ZM258.496 224.941H261.484V218.964H258.496Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -39.001 84.467)'>
+<use x='303.672' xlink:href='#g2-104' y='140.503'/>
+<use x='308.045' xlink:href='#g2-111' y='140.503'/>
+<use x='312.279' xlink:href='#g2-97' y='140.503'/>
+<use x='316.112' xlink:href='#g2-114' y='140.503'/>
+<use x='319.004' xlink:href='#g2-100' y='140.503'/>
+</g>
+<path d='M287.563 224.941H290.551V216.973H287.563ZM293.543 224.941H296.531V218.965H293.543Z' fill='#942994'/>
+<path d='M287.563 224.941H290.551V216.972H287.563ZM293.543 224.941H296.531V218.964H293.543Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -37.472 84.467)'>
+<use x='337.19' xlink:href='#g2-103' y='140.503'/>
+<use x='341.424' xlink:href='#g2-108' y='140.503'/>
+<use x='343.444' xlink:href='#g2-105' y='140.503'/>
+<use x='345.464' xlink:href='#g2-98' y='140.503'/>
+<use x='350.072' xlink:href='#g2-99' y='140.503'/>
+</g>
+<path d='M319.551 224.941H322.539V216.973H319.551ZM325.527 224.941H328.52V218.965H325.527Z' fill='#850a85'/>
+<path d='M319.551 224.941H322.539V216.972H319.551ZM325.527 224.941H328.52V218.964H325.527Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.051 84.467)'>
+<use x='366.757' xlink:href='#g2-116' y='140.503'/>
+<use x='369.815' xlink:href='#g2-98' y='140.503'/>
+<use x='374.187' xlink:href='#g2-98' y='140.503'/>
+</g>
+<path d='M346.699 224.941H349.688V216.973H346.699ZM352.676 224.941H355.664V218.965H352.676Z' fill='#760076'/>
+<path d='M346.699 224.941H349.688V216.972H346.699ZM352.676 224.941H355.664V218.964H352.676Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -34.135 83.47)'>
+<use x='392.986' xlink:href='#g2-115' y='140.503'/>
+<use x='396.233' xlink:href='#g2-109' y='140.503'/>
+</g>
+<path d='M372.012 224.941H375V216.973H372.012ZM377.988 224.941H380.977V218.965H377.988Z' fill='#670067'/>
+<path d='M372.012 224.941H375V216.972H372.012ZM377.988 224.941H380.977V218.964H377.988Z' fill='none' stroke='#000000' stroke-miterlimit='10' stroke-width='0.399'/>
+<g transform='matrix(1 0 0 1 -35.145 84.43)'>
+<use x='419.31' xlink:href='#g2-115' y='140.503'/>
+<use x='422.556' xlink:href='#g2-109' y='140.503'/>
+<use x='429.281' xlink:href='#g2-105' y='140.503'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.629pt' height='170.383pt' viewBox='52.934 54.994 381.629 170.383'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip1'>
+<path d='M82.148 209.23H434.164V83.984H82.148Z'/>
+</clipPath>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+</defs>
+<g id='page1'>
+<path d='M140.82 218.086V209.23M199.488 218.086V209.23M258.156 218.086V209.23M316.824 218.086V209.23M375.496 218.086V209.23M140.82 75.129V83.984M199.488 75.129V83.984M258.156 75.129V83.984M316.824 75.129V83.984M375.496 75.129V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M111.484 213.484V209.23M170.152 213.484V209.23M228.824 213.484V209.23M287.492 213.484V209.23M346.16 213.484V209.23M404.828 213.484V209.23M111.484 79.734V83.984M170.152 79.734V83.984M228.824 79.734V83.984M287.492 79.734V83.984M346.16 79.734V83.984M404.828 79.734V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 209.23H86.402M82.148 177.918H86.402M82.148 146.609H86.402M82.148 115.297H86.402M82.148 83.984H86.402M434.164 209.23H429.91M434.164 177.918H429.91M434.164 146.609H429.91M434.164 115.297H429.91M434.164 83.984H429.91' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 209.23V83.984H434.164V209.23H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -11.54 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-99'/>
+<use x='118.25' y='188.674' xlink:href='#g3-102'/>
+<use x='120.838' y='188.674' xlink:href='#g3-114'/>
+<use x='123.73' y='188.674' xlink:href='#g3-97'/>
+<use x='127.798' y='188.674' xlink:href='#g3-99'/>
+</g>
+<g transform='matrix(1 0 0 1 45.565 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-108'/>
+<use x='116.507' y='188.674' xlink:href='#g3-101'/>
+<use x='120.271' y='188.674' xlink:href='#g3-97'/>
+<use x='124.339' y='188.674' xlink:href='#g3-110'/>
+<use x='128.711' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 106.188 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-114'/>
+<use x='117.379' y='188.674' xlink:href='#g3-101'/>
+<use x='121.142' y='188.674' xlink:href='#g3-100'/>
+<use x='125.515' y='188.674' xlink:href='#g3-105'/>
+<use x='127.535' y='188.674' xlink:href='#g3-115'/>
+</g>
+<g transform='matrix(1 0 0 1 159.716 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-108'/>
+<use x='116.507' y='188.674' xlink:href='#g3-97'/>
+<use x='120.34' y='188.674' xlink:href='#g3-114'/>
+<use x='123.232' y='188.674' xlink:href='#g3-115'/>
+<use x='126.478' y='188.674' xlink:href='#g3-111'/>
+<use x='130.712' y='188.674' xlink:href='#g3-110'/>
+<use x='135.085' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 215.596 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-109'/>
+<use x='121.211' y='188.674' xlink:href='#g3-115'/>
+<use x='124.458' y='188.674' xlink:href='#g3-116'/>
+<use x='127.516' y='188.674' xlink:href='#g3-114'/>
+<use x='130.408' y='188.674' xlink:href='#g3-101'/>
+<use x='134.171' y='188.674' xlink:href='#g3-115'/>
+<use x='137.418' y='188.674' xlink:href='#g3-115'/>
+<use x='140.664' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 277.158 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-114'/>
+<use x='117.379' y='188.674' xlink:href='#g3-112'/>
+<use x='121.751' y='188.674' xlink:href='#g3-116'/>
+<use x='124.809' y='188.674' xlink:href='#g3-101'/>
+<use x='128.573' y='188.674' xlink:href='#g3-115'/>
+<use x='131.819' y='188.674' xlink:href='#g3-116'/>
+<use x='134.877' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 22.192)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.12)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.431)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.743)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.054)'>
+<use x='114.487' y='188.674' xlink:href='#g2-50'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<path d='M82.148 146.609H434.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' fill='#933' clip-path='url(#clip1)'/>
+<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M87.949 146.609V146.484' fill='#933' clip-path='url(#clip1)'/>
+<path d='M87.949 146.609V146.484' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M85.953 146.484H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M87.949 146.609V146.734' fill='#933' clip-path='url(#clip1)'/>
+<path d='M87.949 146.609V146.734' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M89.941 146.734H85.957' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M146.617 146.609V146.359' fill='#933' clip-path='url(#clip1)'/>
+<path d='M146.617 146.609V146.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M144.625 146.36H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M146.617 146.609V146.859' fill='#933' clip-path='url(#clip1)'/>
+<path d='M146.617 146.609V146.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M148.61 146.86H144.625' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M205.285 146.609V146.297' fill='#933' clip-path='url(#clip1)'/>
+<path d='M205.285 146.609V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M203.293 146.297H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M205.285 146.609V146.922' fill='#933' clip-path='url(#clip1)'/>
+<path d='M205.285 146.609V146.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M207.278 146.922H203.293' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M263.953 146.609V146.422' fill='#933' clip-path='url(#clip1)'/>
+<path d='M263.953 146.609V146.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M261.961 146.422H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M263.953 146.609V146.797' fill='#933' clip-path='url(#clip1)'/>
+<path d='M263.953 146.609V146.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M265.949 146.797H261.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M322.625 146.609V146.168' fill='#933' clip-path='url(#clip1)'/>
+<path d='M322.625 146.609V146.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M320.629 146.168H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M322.625 146.609V147.047' fill='#933' clip-path='url(#clip1)'/>
+<path d='M322.625 146.609V147.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M324.617 147.046H320.633' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M381.293 146.609V145.168' fill='#933' clip-path='url(#clip1)'/>
+<path d='M381.293 146.609V145.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M379.301 145.168H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M381.293 146.609V148.047' fill='#933' clip-path='url(#clip1)'/>
+<path d='M381.293 146.609V148.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M383.285 148.046H379.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M91.559 209.23H94.797V147.172H91.559ZM150.227 209.23H153.465V145.48H150.227ZM208.899 209.23H212.133V146.797H208.899ZM267.567 209.23H270.805V149.051H267.567ZM326.234 209.23H329.473V146.359H326.234ZM384.902 209.23H388.141V132.707H384.902Z' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M91.559 209.23H94.797V147.172H91.559ZM150.227 209.23H153.465V145.48H150.227ZM208.899 209.23H212.133V146.797H208.899ZM267.567 209.23H270.805V149.051H267.567ZM326.234 209.23H329.473V146.359H326.234ZM384.902 209.23H388.141V132.707H384.902Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M93.18 147.172V146.922' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M93.18 147.172V146.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M91.184 146.922H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M93.18 147.172V147.422' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M93.18 147.172V147.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M95.172 147.422H91.187' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M151.848 145.48V145.23' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M151.848 145.48V145.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M149.855 145.23H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M151.848 145.48V145.73' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M151.848 145.48V145.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M153.84 145.73H149.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M210.516 146.797V146.484' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M210.516 146.797V146.484' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M208.523 146.484H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M210.516 146.797V147.109' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M210.516 146.797V147.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M212.508 147.109H208.523' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M269.184 149.051V148.426' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M269.184 149.051V148.426' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M267.191 148.426H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M269.184 149.051V149.676' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M269.184 149.051V149.676' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M271.179 149.676H267.191' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M327.856 146.359V144.164' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M327.856 146.359V144.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M325.859 144.164H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M327.856 146.359V148.551' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M327.856 146.359V148.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M329.847 148.55H325.863' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M386.524 132.707V129.137' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M386.524 132.707V129.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M384.531 129.136H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M386.524 132.707V136.273' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M386.524 132.707V136.273' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M388.515 136.273H384.531' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M96.789 209.23H100.027V146.359H96.789ZM155.457 209.23H158.695V138.781H155.457ZM214.129 209.23H217.363V142.476H214.129ZM272.797 209.23H276.035V135.086H272.797ZM331.465 209.23H334.703V146.922H331.465ZM390.133 209.23H393.371V83.984H390.133Z' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M96.789 209.23H100.027V146.359H96.789ZM155.457 209.23H158.695V138.781H155.457ZM214.129 209.23H217.363V142.476H214.129ZM272.797 209.23H276.035V135.086H272.797ZM331.465 209.23H334.703V146.922H331.465ZM390.133 209.23H393.371V83.984H390.133Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M98.41 146.359V146.043' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M98.41 146.359V146.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M96.414 146.043H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M98.41 146.359V146.672' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M98.41 146.359V146.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M100.402 146.672H96.418' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M157.078 138.781V138.469' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M157.078 138.781V138.469' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M155.086 138.469H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M157.078 138.781V139.094' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M157.078 138.781V139.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M159.071 139.093H155.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M215.746 142.476V142.289' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M215.746 142.476V142.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M213.754 142.289H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M215.746 142.476V142.664' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M215.746 142.476V142.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M217.739 142.664H213.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M274.414 135.086V132.957' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M274.414 135.086V132.957' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M272.422 132.957H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M274.414 135.086V137.215' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M274.414 135.086V137.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M276.41 137.215H272.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M333.086 146.922V145.73' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M333.086 146.922V145.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M331.09 145.73H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M333.086 146.922V148.109' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M333.086 146.922V148.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M335.078 148.109H331.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M102.02 209.23H105.258V142.223H102.02ZM160.688 209.23H163.926V143.851H160.688ZM219.359 209.23H222.594V137.277H219.359ZM278.027 209.23H281.266V131.328H278.027ZM336.695 209.23H339.934V120.934H336.695ZM395.363 209.23H398.602V83.984H395.363Z' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M102.02 209.23H105.258V142.223H102.02ZM160.688 209.23H163.926V143.851H160.688ZM219.359 209.23H222.594V137.277H219.359ZM278.027 209.23H281.266V131.328H278.027ZM336.695 209.23H339.934V120.934H336.695ZM395.363 209.23H398.602V83.984H395.363Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M103.641 142.223V142.098' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M103.641 142.223V142.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M101.644 142.097H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M103.641 142.223V142.351' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M103.641 142.223V142.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M105.633 142.352H101.648' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M162.309 143.851V143.101' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M162.309 143.851V143.101' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M160.316 143.101H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M162.309 143.851V144.605' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M162.309 143.851V144.605' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M164.301 144.605H160.316' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M220.977 137.277V136.902' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M220.977 137.277V136.902' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M218.984 136.903H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M220.977 137.277V137.652' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M220.977 137.277V137.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M222.969 137.652H218.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M279.645 131.328V130.516' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M279.645 131.328V130.516' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M277.652 130.516H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M279.645 131.328V132.141' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M279.645 131.328V132.141' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M281.64 132.14H277.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M338.317 120.934V120.305' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M338.317 120.934V120.305' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M336.32 120.304H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M338.317 120.934V121.559' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M338.317 120.934V121.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M340.308 121.559H336.324' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M396.984 83.984' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M394.992 83.984H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M396.984 83.984' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M394.992 83.984H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M107.25 209.23H110.488V120.367H107.25ZM165.918 209.23H169.156V137.777H165.918ZM224.59 209.23H227.824V111.789H224.59ZM283.258 209.23H286.496V92.187H283.258ZM341.926 209.23H345.164V134.019H341.926ZM400.594 209.23H403.832V118.051H400.594Z' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M107.25 209.23H110.488V120.367H107.25ZM165.918 209.23H169.156V137.777H165.918ZM224.59 209.23H227.824V111.789H224.59ZM283.258 209.23H286.496V92.187H283.258ZM341.926 209.23H345.164V134.019H341.926ZM400.594 209.23H403.832V118.051H400.594Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M108.871 120.367V119.992' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M108.871 120.367V119.992' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M106.875 119.992H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M108.871 120.367V120.746' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M108.871 120.367V120.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M110.864 120.746H106.879' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M167.539 137.777V137.527' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M167.539 137.777V137.527' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M165.547 137.528H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M167.539 137.777V138.027' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M167.539 137.777V138.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M169.532 138.028H165.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M226.207 111.789V111.726' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M226.207 111.789V111.726' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M224.215 111.726H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M226.207 111.789V111.851' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M226.207 111.789V111.851' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M228.2 111.851H224.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M284.875 92.187V90.308' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M284.875 92.187V90.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M282.883 90.309H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M284.875 92.187V94.066' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M284.875 92.187V94.066' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M286.868 94.066H282.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M343.547 134.019V132.894' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M343.547 134.019V132.894' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M341.551 132.895H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M343.547 134.019V135.148' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M343.547 134.019V135.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M345.539 135.148H341.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M402.215 118.051V112.289' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M402.215 118.051V112.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M400.223 112.289H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M402.215 118.051V123.812' fill='#bf80bf' clip-path='url(#clip1)'/>
+<path d='M402.215 118.051V123.812' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M404.207 123.812H400.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M112.481 209.23H115.719V145.918H112.481ZM171.149 209.23H174.387V145.105H171.149ZM229.82 209.23H233.055V147.672H229.82ZM288.488 209.23H291.727V149.176H288.488ZM347.156 209.23H350.395V104.211H347.156ZM405.824 209.23H409.063V115.422H405.824Z' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M112.481 209.23H115.719V145.918H112.481ZM171.149 209.23H174.387V145.105H171.149ZM229.82 209.23H233.055V147.672H229.82ZM288.488 209.23H291.727V149.176H288.488ZM347.156 209.23H350.395V104.211H347.156ZM405.824 209.23H409.063V115.422H405.824Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M114.098 145.918V145.793' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M114.098 145.918V145.793' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M112.105 145.793H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M114.098 145.918V146.043' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M114.098 145.918V146.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M116.094 146.043H112.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M172.77 145.105V144.793' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M172.77 145.105V144.793' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M170.777 144.793H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M172.77 145.105V145.418' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M172.77 145.105V145.418' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M174.762 145.418H170.777' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M231.438 147.672V147.422' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M231.438 147.672V147.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M229.445 147.422H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M231.438 147.672V147.922' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M231.438 147.672V147.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M233.43 147.922H229.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M290.106 149.176V148.738' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M290.106 149.176V148.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M288.113 148.738H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M290.106 149.176V149.613' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M290.106 149.176V149.613' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M292.098 149.613H288.113' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M348.777 104.211V100.582' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M348.777 104.211V100.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M346.781 100.582H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M348.777 104.211V107.844' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M348.777 104.211V107.844' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M350.77 107.843H346.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M407.445 115.422V109.848' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M407.445 115.422V109.848' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M405.453 109.847H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M407.445 115.422V120.996' fill='#c96' clip-path='url(#clip1)'/>
+<path d='M407.445 115.422V120.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M409.437 120.996H405.453' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M117.711 209.23H120.949V143.226H117.711ZM176.379 209.23H179.617V132.266H176.379ZM235.051 209.23H238.285V132.644H235.051ZM293.719 209.23H296.957V110.539H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M117.711 209.23H120.949V143.226H117.711ZM176.379 209.23H179.617V132.266H176.379ZM235.051 209.23H238.285V132.644H235.051ZM293.719 209.23H296.957V110.539H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M119.328 143.226V142.914' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M119.328 143.226V142.914' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M117.336 142.914H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M119.328 143.226V143.539' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M119.328 143.226V143.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M121.325 143.539H117.34' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M178 132.266V131.641' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M178 132.266V131.641' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M176.008 131.64H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M178 132.266V132.894' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M178 132.266V132.894' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M179.993 132.895H176.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M236.668 132.644V132.078' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M236.668 132.644V132.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M234.676 132.079H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M236.668 132.644V133.207' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M236.668 132.644V133.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M238.66 133.207H234.675' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M295.336 110.539V109.785' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M295.336 110.539V109.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M293.344 109.785H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M295.336 110.539V111.289' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M295.336 110.539V111.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M297.328 111.289H293.343' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M122.941 209.23H126.18V136.59H122.941ZM181.609 209.23H184.848V120.242H181.609ZM240.281 209.23H243.516V140.785H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V87.117H357.617ZM416.285 209.23H419.524V83.984H416.285Z' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M122.941 209.23H126.18V136.59H122.941ZM181.609 209.23H184.848V120.242H181.609ZM240.281 209.23H243.516V140.785H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V87.117H357.617ZM416.285 209.23H419.524V83.984H416.285Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M124.559 136.59V136.465' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M124.559 136.59V136.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M122.566 136.465H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M124.559 136.59V136.715' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M124.559 136.59V136.715' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M126.555 136.715H122.57' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M183.231 120.242V119.305' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M183.231 120.242V119.305' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M181.238 119.304H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M183.231 120.242V121.184' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M183.231 120.242V121.184' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M185.223 121.183H181.238' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M241.899 140.785V140.41' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M241.899 140.785V140.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M239.906 140.41H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M241.899 140.785V141.16' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M241.899 140.785V141.16' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M243.891 141.16H239.906' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M359.238 87.117V85.363' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M359.238 87.117V85.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M357.242 85.363H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M359.238 87.117V88.871' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M359.238 87.117V88.871' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M361.231 88.871H357.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip1)'/>
+<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M128.172 209.23H131.41V141.285H128.172ZM186.84 209.23H190.078V131.266H186.84ZM245.512 209.23H248.746V139.781H245.512ZM304.18 209.23H307.418V99.328H304.18ZM362.848 209.23H366.086V105.34H362.848ZM421.516 209.23H424.754V83.984H421.516Z' fill='#399' clip-path='url(#clip1)'/>
+<path d='M128.172 209.23H131.41V141.285H128.172ZM186.84 209.23H190.078V131.266H186.84ZM245.512 209.23H248.746V139.781H245.512ZM304.18 209.23H307.418V99.328H304.18ZM362.848 209.23H366.086V105.34H362.848ZM421.516 209.23H424.754V83.984H421.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M129.789 141.285V141.098' fill='#399' clip-path='url(#clip1)'/>
+<path d='M129.789 141.285V141.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M127.797 141.097H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M129.789 141.285V141.473' fill='#399' clip-path='url(#clip1)'/>
+<path d='M129.789 141.285V141.473' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M131.785 141.473H127.8' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M188.461 131.266V130.891' fill='#399' clip-path='url(#clip1)'/>
+<path d='M188.461 131.266V130.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M186.469 130.891H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M188.461 131.266V131.641' fill='#399' clip-path='url(#clip1)'/>
+<path d='M188.461 131.266V131.641' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M190.453 131.64H186.468' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M247.129 139.781V139.594' fill='#399' clip-path='url(#clip1)'/>
+<path d='M247.129 139.781V139.594' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M245.137 139.593H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M247.129 139.781V139.969' fill='#399' clip-path='url(#clip1)'/>
+<path d='M247.129 139.781V139.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M249.121 139.969H245.136' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M305.797 99.328V98.828' fill='#399' clip-path='url(#clip1)'/>
+<path d='M305.797 99.328V98.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M303.804 98.828H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M305.797 99.328V99.828' fill='#399' clip-path='url(#clip1)'/>
+<path d='M305.797 99.328V99.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M307.789 99.828H303.804' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M364.469 105.34V103.586' fill='#399' clip-path='url(#clip1)'/>
+<path d='M364.469 105.34V103.586' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M362.473 103.586H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M364.469 105.34V107.094' fill='#399' clip-path='url(#clip1)'/>
+<path d='M364.469 105.34V107.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M366.461 107.094H362.476' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M423.137 83.984' fill='#399' clip-path='url(#clip1)'/>
+<path d='M421.144 83.984H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M423.137 83.984' fill='#399' clip-path='url(#clip1)'/>
+<path d='M421.144 83.984H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M133.402 209.23H136.641V138.656H133.402ZM192.07 209.23H195.309V138.531H192.07ZM250.742 209.23H253.977V143.914H250.742ZM309.41 209.23H312.649V123H309.41ZM368.078 209.23H371.317V141.285H368.078ZM426.746 209.23H429.984V83.984H426.746Z' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M133.402 209.23H136.641V138.656H133.402ZM192.07 209.23H195.309V138.531H192.07ZM250.742 209.23H253.977V143.914H250.742ZM309.41 209.23H312.649V123H309.41ZM368.078 209.23H371.317V141.285H368.078ZM426.746 209.23H429.984V83.984H426.746Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M135.02 138.656V138.531' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M135.02 138.656V138.531' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M133.027 138.531H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M135.02 138.656V138.781' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M135.02 138.656V138.781' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M137.016 138.781H133.031' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M193.692 138.531V138.215' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M193.692 138.531V138.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M191.699 138.215H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M193.692 138.531V138.844' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M193.692 138.531V138.844' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M195.684 138.844H191.699' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M252.359 143.914V143.539' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M252.359 143.914V143.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M250.367 143.539H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M252.359 143.914V144.293' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M252.359 143.914V144.293' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M254.352 144.293H250.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M311.027 123V122.75' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M311.027 123V122.75' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M309.035 122.75H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M311.027 123V123.25' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M311.027 123V123.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M313.02 123.25H309.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M369.699 141.285V140.41' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M369.699 141.285V140.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M367.703 140.41H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M369.699 141.285V142.16' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M369.699 141.285V142.16' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M371.692 142.16H367.707' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M428.367 83.984' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M426.375 83.984H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M428.367 83.984' fill='#d9b3b3' clip-path='url(#clip1)'/>
+<path d='M426.375 83.984H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<g transform='matrix(0 -1 1 0 -99.092 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -40.423 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 18.246 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 76.915 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.584 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.253 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -93.862 255.634)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.193 253.943)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.476 255.258)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.145 257.513)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.814 254.82)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.483 241.168)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -88.631 254.82)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.962 247.242)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.707 250.937)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.376 243.548)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.045 255.383)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.714 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-57'/>
+<use x='126.877' y='188.674' xlink:href='#g2-49'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.401 250.687)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.732 252.315)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.937 245.74)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.606 239.79)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.275 229.395)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-52'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.944 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-54'/>
+<use x='126.877' y='188.674' xlink:href='#g2-53'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.17 228.831)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-52'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.501 246.241)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.168 220.252)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.837 200.651)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-56'/>
+<use x='121.25' y='188.674' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.506 242.483)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.175 226.514)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-52'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -72.94 254.382)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.271 253.567)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.398 256.135)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.067 257.638)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.736 212.675)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-54'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.405 223.884)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -67.709 251.689)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.04 240.73)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.629 241.105)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.298 219)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.967 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-49'/>
+<use x='126.877' y='188.674' xlink:href='#g2-57'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.636 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-49'/>
+<use x='126.877' y='188.674' xlink:href='#g2-55'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.479 245.051)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.81 228.706)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-52'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.859 249.246)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.528 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-49'/>
+<use x='122.76' y='188.674' xlink:href='#g2-53'/>
+<use x='125.406' y='188.674' xlink:href='#g2-53'/>
+<use x='128.053' y='188.674' xlink:href='#g2-46'/>
+<use x='129.523' y='188.674' xlink:href='#g2-50'/>
+<use x='132.169' y='188.674' xlink:href='#g2-51'/>
+<use x='134.816' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.197 195.579)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.866 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-55'/>
+<use x='126.877' y='188.674' xlink:href='#g2-57'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.249 249.747)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 1.42 239.728)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 60.089 248.244)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.758 207.79)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-55'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 177.427 213.802)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-54'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 236.096 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-51'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-48'/>
+<use x='126.877' y='188.674' xlink:href='#g2-57'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -52.018 247.117)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.651 246.992)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 65.32 252.378)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 123.989 231.462)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.658 249.747)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 241.327 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-48'/>
+<use x='126.877' y='188.674' xlink:href='#g2-51'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -129.314 316.355)'>
+<use x='114.487' y='188.674' xlink:href='#g1-82'/>
+<use x='120.457' y='188.674' xlink:href='#g1-101'/>
+<use x='124.553' y='188.674' xlink:href='#g1-108'/>
+<use x='126.753' y='188.674' xlink:href='#g1-97'/>
+<use x='131.181' y='188.674' xlink:href='#g1-116'/>
+<use x='134.509' y='188.674' xlink:href='#g1-105'/>
+<use x='136.709' y='188.674' xlink:href='#g1-118'/>
+<use x='140.957' y='188.674' xlink:href='#g1-101'/>
+<use x='148.124' y='188.674' xlink:href='#g1-116'/>
+<use x='151.452' y='188.674' xlink:href='#g1-105'/>
+<use x='153.652' y='188.674' xlink:href='#g1-109'/>
+<use x='160.972' y='188.674' xlink:href='#g1-101'/>
+<use x='168.139' y='188.674' xlink:href='#g3-40'/>
+<use x='171.432' y='188.674' xlink:href='#g3-108'/>
+<use x='173.453' y='188.674' xlink:href='#g3-111'/>
+<use x='177.452' y='188.674' xlink:href='#g3-119'/>
+<use x='183' y='188.674' xlink:href='#g3-101'/>
+<use x='186.764' y='188.674' xlink:href='#g3-114'/>
+<use x='192.479' y='188.674' xlink:href='#g3-105'/>
+<use x='194.499' y='188.674' xlink:href='#g3-115'/>
+<use x='200.568' y='188.674' xlink:href='#g3-98'/>
+<use x='205.176' y='188.674' xlink:href='#g3-101'/>
+<use x='208.94' y='188.674' xlink:href='#g3-116'/>
+<use x='211.998' y='188.674' xlink:href='#g3-116'/>
+<use x='215.056' y='188.674' xlink:href='#g3-101'/>
+<use x='218.819' y='188.674' xlink:href='#g3-114'/>
+<use x='221.711' y='188.674' xlink:href='#g3-41'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.628pt' height='255.741pt' viewBox='106.732 54.993 381.628 255.741'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip2'>
+<path d='M135.949 249.281H487.961V81.519H135.949Z'/>
+</clipPath>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/>
+<use id='g3-49' xlink:href='#g0-49' transform='scale(1.143)'/>
+<use id='g3-54' xlink:href='#g0-54' transform='scale(1.143)'/>
+<use id='g3-56' xlink:href='#g0-56' transform='scale(1.143)'/>
+<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-103' xlink:href='#g0-103' transform='scale(1.143)'/>
+<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/>
+<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/>
+<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/>
+<use id='g2-65' xlink:href='#g0-65' transform='scale(.714)'/>
+<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/>
+<use id='g2-68' xlink:href='#g0-68' transform='scale(.714)'/>
+<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/>
+<use id='g2-77' xlink:href='#g0-77' transform='scale(.714)'/>
+<use id='g2-85' xlink:href='#g0-85' transform='scale(.714)'/>
+<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/>
+<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/>
+<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/>
+<use id='g2-100' xlink:href='#g0-100' transform='scale(.714)'/>
+<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/>
+<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/>
+<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/>
+<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/>
+<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/>
+<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/>
+<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/>
+<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/>
+<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/>
+<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/>
+<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/>
+<use id='g2-117' xlink:href='#g0-117' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/>
+<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/>
+<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/>
+<path id='g0-65' d='M2.803-4.84H2.127L.209 0H.781L1.325-1.381H3.445L3.989 0H4.721L2.803-4.84ZM2.392-4.31L3.271-1.792H1.499L2.392-4.31Z'/>
+<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/>
+<path id='g0-68' d='M.683-4.84V0H2.664C3.919 0 4.931-1.06 4.931-2.378C4.931-3.745 3.912-4.84 2.664-4.84H.683ZM1.367-.411V-4.428H2.476C3.431-4.428 4.247-3.668 4.247-2.385C4.247-1.088 3.396-.411 2.476-.411H1.367Z'/>
+<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/>
+<path id='g0-77' d='M3.884-2.42C3.801-2.211 3.299-.983 3.229-.69H3.222C3.173-.893 2.852-1.695 2.783-1.876L1.583-4.84H.732V0H1.318V-4.282H1.325C1.381-4.038 1.743-3.117 1.778-3.041L2.943-.146H3.494L4.533-2.713C4.533-2.72 5.014-3.905 5.133-4.289H5.14V0H5.726V-4.84H4.868L3.884-2.42Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-85' d='M4.4-4.84H3.794V-1.625C3.794-.69 3.166-.265 2.566-.265S1.381-.697 1.381-1.618V-4.84H.676V-1.632C.676-.607 1.555 .146 2.559 .146C3.557 .146 4.4-.614 4.4-1.632V-4.84Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/>
+<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-117' d='M3.243-3.096H2.636V-1.074C2.636-.516 2.162-.342 1.757-.342C1.241-.342 1.186-.481 1.186-.802V-3.096H.579V-.76C.579-.139 .851 .07 1.339 .07C1.625 .07 2.239 .014 2.657-.321V0H3.243V-3.096Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/>
+</defs>
+<g id='page2'>
+<path d='M194.617 258.141V249.281M253.285 258.141V249.281M311.953 258.141V249.281M370.625 258.141V249.281M429.293 258.141V249.281M194.617 72.66V81.519M253.285 72.66V81.519M311.953 72.66V81.519M370.625 72.66V81.519M429.293 72.66V81.519' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M165.281 253.535V249.281M223.953 253.535V249.281M282.621 253.535V249.281M341.289 253.535V249.281M399.957 253.535V249.281M458.629 253.535V249.281M165.281 77.266V81.519M223.953 77.266V81.519M282.621 77.266V81.519M341.289 77.266V81.519M399.957 77.266V81.519M458.629 77.266V81.519' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M135.949 249.281H140.199M135.949 215.73H140.199M135.949 182.176H140.199M135.949 148.625H140.199M135.949 115.07H140.199M135.949 81.519H140.199M487.961 249.281H483.711M487.961 215.73H483.711M487.961 182.176H483.711M487.961 148.625H483.711M487.961 115.07H483.711M487.961 81.519H483.711' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M135.949 249.281V81.519H487.961V249.281H135.949Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -21.265 74.992)'>
+<use x='168.285' y='188.688' xlink:href='#g3-97'/>
+<use x='172.353' y='188.688' xlink:href='#g3-108'/>
+<use x='174.373' y='188.688' xlink:href='#g3-108'/>
+<use x='176.393' y='188.688' xlink:href='#g3-111'/>
+<use x='180.863' y='188.688' xlink:href='#g3-99'/>
+<use x='184.627' y='188.688' xlink:href='#g3-45'/>
+<use x='187.449' y='188.688' xlink:href='#g3-116'/>
+<use x='190.507' y='188.688' xlink:href='#g3-101'/>
+<use x='194.271' y='188.688' xlink:href='#g3-115'/>
+<use x='197.517' y='188.688' xlink:href='#g3-116'/>
+<use x='200.575' y='188.688' xlink:href='#g3-49'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 74.992)'>
+<use x='168.285' y='188.688' xlink:href='#g3-97'/>
+<use x='172.353' y='188.688' xlink:href='#g3-108'/>
+<use x='174.373' y='188.688' xlink:href='#g3-108'/>
+<use x='176.393' y='188.688' xlink:href='#g3-111'/>
+<use x='180.863' y='188.688' xlink:href='#g3-99'/>
+<use x='184.627' y='188.688' xlink:href='#g3-45'/>
+<use x='187.449' y='188.688' xlink:href='#g3-116'/>
+<use x='190.507' y='188.688' xlink:href='#g3-101'/>
+<use x='194.271' y='188.688' xlink:href='#g3-115'/>
+<use x='197.517' y='188.688' xlink:href='#g3-116'/>
+<use x='200.575' y='188.688' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 74.992)'>
+<use x='168.285' y='188.688' xlink:href='#g3-115'/>
+<use x='171.531' y='188.688' xlink:href='#g3-104'/>
+<use x='175.904' y='188.688' xlink:href='#g3-54'/>
+<use x='180.138' y='188.688' xlink:href='#g3-98'/>
+<use x='184.746' y='188.688' xlink:href='#g3-101'/>
+<use x='188.509' y='188.688' xlink:href='#g3-110'/>
+<use x='192.882' y='188.688' xlink:href='#g3-99'/>
+<use x='196.646' y='188.688' xlink:href='#g3-104'/>
+<use x='201.018' y='188.688' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 74.992)'>
+<use x='168.285' y='188.688' xlink:href='#g3-115'/>
+<use x='171.531' y='188.688' xlink:href='#g3-104'/>
+<use x='175.904' y='188.688' xlink:href='#g3-56'/>
+<use x='180.138' y='188.688' xlink:href='#g3-98'/>
+<use x='184.746' y='188.688' xlink:href='#g3-101'/>
+<use x='188.509' y='188.688' xlink:href='#g3-110'/>
+<use x='192.882' y='188.688' xlink:href='#g3-99'/>
+<use x='196.646' y='188.688' xlink:href='#g3-104'/>
+<use x='201.018' y='188.688' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 74.992)'>
+<use x='168.285' y='188.688' xlink:href='#g3-120'/>
+<use x='172.187' y='188.688' xlink:href='#g3-109'/>
+<use x='178.912' y='188.688' xlink:href='#g3-97'/>
+<use x='182.98' y='188.688' xlink:href='#g3-108'/>
+<use x='185' y='188.688' xlink:href='#g3-108'/>
+<use x='187.02' y='188.688' xlink:href='#g3-111'/>
+<use x='191.49' y='188.688' xlink:href='#g3-99'/>
+<use x='195.254' y='188.688' xlink:href='#g3-45'/>
+<use x='198.076' y='188.688' xlink:href='#g3-116'/>
+<use x='201.134' y='188.688' xlink:href='#g3-101'/>
+<use x='204.898' y='188.688' xlink:href='#g3-115'/>
+<use x='208.144' y='188.688' xlink:href='#g3-116'/>
+<use x='211.202' y='188.688' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 74.992)'>
+<use x='168.285' y='188.688' xlink:href='#g3-99'/>
+<use x='172.049' y='188.688' xlink:href='#g3-97'/>
+<use x='176.117' y='188.688' xlink:href='#g3-99'/>
+<use x='179.88' y='188.688' xlink:href='#g3-104'/>
+<use x='184.253' y='188.688' xlink:href='#g3-101'/>
+<use x='188.017' y='188.688' xlink:href='#g3-45'/>
+<use x='190.839' y='188.688' xlink:href='#g3-115'/>
+<use x='194.086' y='188.688' xlink:href='#g3-99'/>
+<use x='197.849' y='188.688' xlink:href='#g3-114'/>
+<use x='200.741' y='188.688' xlink:href='#g3-97'/>
+<use x='204.81' y='188.688' xlink:href='#g3-116'/>
+<use x='207.868' y='188.688' xlink:href='#g3-99'/>
+<use x='211.631' y='188.688' xlink:href='#g3-104'/>
+<use x='216.004' y='188.688' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 62.23)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.677)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-53'/>
+<use x='175.048' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -4.876)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -38.43)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-53'/>
+<use x='175.048' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.983)'>
+<use x='168.285' y='188.688' xlink:href='#g2-50'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -105.536)'>
+<use x='168.285' y='188.688' xlink:href='#g2-50'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-53'/>
+<use x='175.048' y='188.688' xlink:href='#g2-120'/>
+</g>
+<path d='M135.949 182.176H487.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' fill='#933' clip-path='url(#clip2)'/>
+<path d='M140.125 249.281H143.363V182.176H140.125ZM198.797 249.281H202.035V182.176H198.797ZM257.465 249.281H260.703V182.176H257.465ZM316.133 249.281H319.371V182.176H316.133ZM374.801 249.281H378.039V182.176H374.801ZM433.473 249.281H436.711V182.176H433.473Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M141.746 182.176V181.773' fill='#933' clip-path='url(#clip2)'/>
+<path d='M141.746 182.176V181.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M139.754 181.773H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M141.746 182.176V182.578' fill='#933' clip-path='url(#clip2)'/>
+<path d='M141.746 182.176V182.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M143.738 182.578H139.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M200.414 182.176V181.508' fill='#933' clip-path='url(#clip2)'/>
+<path d='M200.414 182.176V181.508' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M198.422 181.508H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M200.414 182.176V182.848' fill='#933' clip-path='url(#clip2)'/>
+<path d='M200.414 182.176V182.848' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M202.406 182.848H198.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M259.082 182.176' fill='#933' clip-path='url(#clip2)'/>
+<path d='M257.09 182.176H261.074' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M259.082 182.176' fill='#933' clip-path='url(#clip2)'/>
+<path d='M257.09 182.176H261.074' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M317.754 182.176V179.695' fill='#933' clip-path='url(#clip2)'/>
+<path d='M317.754 182.176V179.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M315.758 179.695H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M317.754 182.176V184.66' fill='#933' clip-path='url(#clip2)'/>
+<path d='M317.754 182.176V184.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M319.746 184.66H315.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M376.422 182.176V180.363' fill='#933' clip-path='url(#clip2)'/>
+<path d='M376.422 182.176V180.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M374.43 180.363H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M376.422 182.176V183.988' fill='#933' clip-path='url(#clip2)'/>
+<path d='M376.422 182.176V183.988' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M378.414 183.988H374.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M435.09 182.176V179.629' fill='#933' clip-path='url(#clip2)'/>
+<path d='M435.09 182.176V179.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M433.098 179.629H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M435.09 182.176V184.727' fill='#933' clip-path='url(#clip2)'/>
+<path d='M435.09 182.176V184.727' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M437.082 184.727H433.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M145.356 249.281H148.594V182.312H145.356ZM204.028 249.281H207.266V182.648H204.028ZM262.695 249.281H265.934V167.816H262.695ZM321.363 249.281H324.602V183.922H321.363ZM380.031 249.281H383.27V176.605H380.031ZM438.703 249.281H441.942V180.699H438.703Z' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M145.356 249.281H148.594V182.312H145.356ZM204.028 249.281H207.266V182.648H204.028ZM262.695 249.281H265.934V167.816H262.695ZM321.363 249.281H324.602V183.922H321.363ZM380.031 249.281H383.27V176.605H380.031ZM438.703 249.281H441.942V180.699H438.703Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M146.977 182.312V182.043' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M146.977 182.312V182.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M144.984 182.043H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M146.977 182.312V182.578' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M146.977 182.312V182.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M148.968 182.578H144.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M205.645 182.648V182.379' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M205.645 182.648V182.379' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M203.652 182.379H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M205.645 182.648V182.914' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M205.645 182.648V182.914' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M207.636 182.914H203.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M264.313 167.816V163.051' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M264.313 167.816V163.051' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M262.32 163.051H266.304' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M264.313 167.816V172.582' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M264.313 167.816V172.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M266.308 172.582H262.32' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M322.984 183.922V182.176' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M322.984 183.922V182.176' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M320.988 182.176H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M322.984 183.922V185.668' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M322.984 183.922V185.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M324.976 185.668H320.992' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M381.652 176.605V172.18' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M381.652 176.605V172.18' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M379.66 172.179H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M381.652 176.605V181.035' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M381.652 176.605V181.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M383.644 181.035H379.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M440.32 180.699V177.746' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M440.32 180.699V177.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M438.328 177.746H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M440.32 180.699V183.652' fill='#bf8080' clip-path='url(#clip2)'/>
+<path d='M440.32 180.699V183.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M442.312 183.652H438.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M150.586 249.281H153.824V181.707H150.586ZM209.258 249.281H212.496V180.969H209.258ZM267.926 249.281H271.164V143.859H267.926ZM326.594 249.281H329.832V81.519H326.594ZM385.262 249.281H388.5V81.519H385.262ZM443.934 249.281H447.172V81.519H443.934Z' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M150.586 249.281H153.824V181.707H150.586ZM209.258 249.281H212.496V180.969H209.258ZM267.926 249.281H271.164V143.859H267.926ZM326.594 249.281H329.832V81.519H326.594ZM385.262 249.281H388.5V81.519H385.262ZM443.934 249.281H447.172V81.519H443.934Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M152.207 181.707V181.172' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M152.207 181.707V181.172' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M150.215 181.171H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M152.207 181.707V182.242' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M152.207 181.707V182.242' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M154.2 182.242H150.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M210.875 180.969V179.359' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M210.875 180.969V179.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M208.883 179.36H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M210.875 180.969V182.578' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M210.875 180.969V182.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M212.868 182.578H208.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M269.543 143.859V132.117' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M269.543 143.859V132.117' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M267.551 132.117H271.535' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M269.543 143.859V155.602' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M269.543 143.859V155.602' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M271.539 155.602H267.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M328.215 81.519' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M326.219 81.52H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M328.215 81.519' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M326.219 81.52H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M386.883 81.519' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M384.891 81.52H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M386.883 81.519' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M384.891 81.52H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M445.551 81.519' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M443.559 81.52H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M445.551 81.519' fill='#8080bf' clip-path='url(#clip2)'/>
+<path d='M443.559 81.52H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M155.817 249.281H159.055V176.273H155.817ZM214.488 249.281H217.727V173.988H214.488ZM273.156 249.281H276.395V81.519H273.156ZM331.824 249.281H335.063V81.519H331.824ZM390.492 249.281H393.731V81.519H390.492ZM449.164 249.281H452.402V81.519H449.164Z' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M155.817 249.281H159.055V176.273H155.817ZM214.488 249.281H217.727V173.988H214.488ZM273.156 249.281H276.395V81.519H273.156ZM331.824 249.281H335.063V81.519H331.824ZM390.492 249.281H393.731V81.519H390.492ZM449.164 249.281H452.402V81.519H449.164Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M157.438 176.273V176.137' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M157.438 176.273V176.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M155.445 176.136H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M157.438 176.273V176.406' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M157.438 176.273V176.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M159.43 176.406H155.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M216.106 173.988V172.715' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M216.106 173.988V172.715' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M214.113 172.715H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M216.106 173.988V175.266' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M216.106 173.988V175.266' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M218.098 175.266H214.113' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M274.774 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M272.781 81.52H276.765' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M274.774 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M272.781 81.52H276.765' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M333.445 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M331.449 81.52H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M333.445 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M331.449 81.52H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M392.113 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M390.121 81.52H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M392.113 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M390.121 81.52H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M450.781 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M448.789 81.52H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M450.781 81.519' fill='#ffb733' clip-path='url(#clip2)'/>
+<path d='M448.789 81.52H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M161.047 249.281H164.285V157.48H161.047ZM219.719 249.281H222.957V147.215H219.719ZM278.387 249.281H281.625V81.519H278.387ZM337.055 249.281H340.293V81.519H337.055ZM395.723 249.281H398.961V166.406H395.723ZM454.395 249.281H457.633V182.176H454.395Z' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M161.047 249.281H164.285V157.48H161.047ZM219.719 249.281H222.957V147.215H219.719ZM278.387 249.281H281.625V81.519H278.387ZM337.055 249.281H340.293V81.519H337.055ZM395.723 249.281H398.961V166.406H395.723ZM454.395 249.281H457.633V182.176H454.395Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M162.668 157.48V157.012' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M162.668 157.48V157.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M160.676 157.011H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M162.668 157.48V157.953' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M162.668 157.48V157.953' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M164.661 157.953H160.676' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M221.336 147.215V146.812' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M221.336 147.215V146.812' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M219.344 146.812H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M221.336 147.215V147.617' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M221.336 147.215V147.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M223.329 147.617H219.344' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M280.004 81.519' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M278.012 81.52H281.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M280.004 81.519' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M278.012 81.52H281.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M338.676 81.519' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M336.68 81.52H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M338.676 81.519' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M336.68 81.52H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M397.344 166.406V166.273' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M397.344 166.406V166.273' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M395.352 166.274H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M397.344 166.406V166.543' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M397.344 166.406V166.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M399.336 166.543H395.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M456.012 182.176V179.629' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M456.012 182.176V179.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M454.02 179.629H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M456.012 182.176V184.727' fill='#bf80bf' clip-path='url(#clip2)'/>
+<path d='M456.012 182.176V184.727' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M458.004 184.727H454.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M166.278 249.281H169.516V167.949H166.278ZM224.949 249.281H228.188V176.137H224.949ZM283.617 249.281H286.856V110.305H283.617ZM342.285 249.281H345.524V157.48H342.285ZM400.953 249.281H404.192V186.473H400.953ZM459.625 249.281H462.863V183.652H459.625Z' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M166.278 249.281H169.516V167.949H166.278ZM224.949 249.281H228.188V176.137H224.949ZM283.617 249.281H286.856V110.305H283.617ZM342.285 249.281H345.524V157.48H342.285ZM400.953 249.281H404.192V186.473H400.953ZM459.625 249.281H462.863V183.652H459.625Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M167.899 167.949V167.816' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M167.899 167.949V167.816' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M165.906 167.816H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M167.899 167.949V168.086' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M167.899 167.949V168.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M169.891 168.086H165.906' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M226.567 176.137V175.199' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M226.567 176.137V175.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M224.574 175.199H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M226.567 176.137V177.078' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M226.567 176.137V177.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M228.559 177.078H224.574' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M285.234 110.305V105.543' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M285.234 110.305V105.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M283.242 105.543H287.226' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M285.234 110.305V115.07' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M285.234 110.305V115.07' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M287.23 115.07H283.242' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M343.906 157.48V153.187' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M343.906 157.48V153.187' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M341.91 153.187H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M343.906 157.48V161.777' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M343.906 157.48V161.777' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M345.898 161.778H341.914' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M402.574 186.473V186.269' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M402.574 186.473V186.269' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M400.582 186.27H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M402.574 186.473V186.672' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M402.574 186.473V186.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M404.566 186.672H400.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M461.242 183.652' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M459.25 183.652H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M461.242 183.652' fill='#c96' clip-path='url(#clip2)'/>
+<path d='M459.25 183.652H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M171.508 249.281H174.746V173.789H171.508ZM230.18 249.281H233.414V173.789H230.18ZM288.848 249.281H292.086V81.519H288.848ZM347.516 249.281H350.754V81.519H347.516ZM406.184 249.281H409.422V81.519H406.184ZM464.856 249.281H468.094V81.519H464.856Z' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M171.508 249.281H174.746V173.789H171.508ZM230.18 249.281H233.414V173.789H230.18ZM288.848 249.281H292.086V81.519H288.848ZM347.516 249.281H350.754V81.519H347.516ZM406.184 249.281H409.422V81.519H406.184ZM464.856 249.281H468.094V81.519H464.856Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M173.129 173.789V173.184' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M173.129 173.789V173.184' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M171.137 173.184H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M173.129 173.789V174.394' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M173.129 173.789V174.394' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M175.122 174.395H171.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M231.797 173.789V173.32' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M231.797 173.789V173.32' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M229.805 173.32H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M231.797 173.789V174.258' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M231.797 173.789V174.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M233.79 174.258H229.805' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M290.465 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M288.473 81.52H292.457' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M290.465 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M288.473 81.52H292.457' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M349.137 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M347.141 81.52H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M349.137 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M347.141 81.52H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M407.805 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M405.813 81.52H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M407.805 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M405.813 81.52H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M466.473 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M464.481 81.52H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M466.473 81.519' fill='#80bf80' clip-path='url(#clip2)'/>
+<path d='M464.481 81.52H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M176.738 249.281H179.977V144.664H176.738ZM235.41 249.281H238.645V178.016H235.41ZM294.078 249.281H297.317V81.519H294.078ZM352.746 249.281H355.984V81.519H352.746ZM411.414 249.281H414.652V81.519H411.414ZM470.086 249.281H473.324V183.652H470.086Z' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M176.738 249.281H179.977V144.664H176.738ZM235.41 249.281H238.645V178.016H235.41ZM294.078 249.281H297.317V81.519H294.078ZM352.746 249.281H355.984V81.519H352.746ZM411.414 249.281H414.652V81.519H411.414ZM470.086 249.281H473.324V183.652H470.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M178.36 144.664V142.922' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M178.36 144.664V142.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M176.367 142.922H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M178.36 144.664V146.41' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M178.36 144.664V146.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M180.352 146.41H176.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M237.027 178.016V177.344' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M237.027 178.016V177.344' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M235.035 177.343H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M237.027 178.016V178.687' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M237.027 178.016V178.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M239.02 178.688H235.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M295.695 81.519' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M293.703 81.52H297.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M295.695 81.519' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M293.703 81.52H297.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M354.367 81.519' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M352.371 81.52H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M354.367 81.519' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M352.371 81.52H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M413.035 81.519' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M411.043 81.52H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M413.035 81.519' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M411.043 81.52H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M471.703 183.652' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M469.711 183.652H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M471.703 183.652' fill='#bfbf80' clip-path='url(#clip2)'/>
+<path d='M469.711 183.652H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M181.969 249.281H185.207V165.199H181.969ZM240.641 249.281H243.875V163.387H240.641ZM299.309 249.281H302.547V81.519H299.309ZM357.977 249.281H361.215V81.519H357.977ZM416.645 249.281H419.883V116.613H416.645ZM475.317 249.281H478.555V81.519H475.317Z' fill='#399' clip-path='url(#clip2)'/>
+<path d='M181.969 249.281H185.207V165.199H181.969ZM240.641 249.281H243.875V163.387H240.641ZM299.309 249.281H302.547V81.519H299.309ZM357.977 249.281H361.215V81.519H357.977ZM416.645 249.281H419.883V116.613H416.645ZM475.317 249.281H478.555V81.519H475.317Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M183.59 165.199V164.664' fill='#399' clip-path='url(#clip2)'/>
+<path d='M183.59 165.199V164.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M181.598 164.664H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M183.59 165.199V165.734' fill='#399' clip-path='url(#clip2)'/>
+<path d='M183.59 165.199V165.734' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M185.582 165.734H181.597' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M242.258 163.387V162.852' fill='#399' clip-path='url(#clip2)'/>
+<path d='M242.258 163.387V162.852' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M240.266 162.851H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M242.258 163.387V163.926' fill='#399' clip-path='url(#clip2)'/>
+<path d='M242.258 163.387V163.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M244.25 163.926H240.265' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M300.926 81.519' fill='#399' clip-path='url(#clip2)'/>
+<path d='M298.933 81.52H302.917' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M300.926 81.519' fill='#399' clip-path='url(#clip2)'/>
+<path d='M298.933 81.52H302.917' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M359.598 81.519' fill='#399' clip-path='url(#clip2)'/>
+<path d='M357.602 81.52H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M359.598 81.519' fill='#399' clip-path='url(#clip2)'/>
+<path d='M357.602 81.52H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M418.266 116.613V116.211' fill='#399' clip-path='url(#clip2)'/>
+<path d='M418.266 116.613V116.211' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M416.274 116.211H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M418.266 116.613V117.016' fill='#399' clip-path='url(#clip2)'/>
+<path d='M418.266 116.613V117.016' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M420.257 117.016H416.273' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M476.934 81.519' fill='#399' clip-path='url(#clip2)'/>
+<path d='M474.942 81.52H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M476.934 81.519' fill='#399' clip-path='url(#clip2)'/>
+<path d='M474.942 81.52H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M187.199 249.281H190.438V175.133H187.199ZM245.871 249.281H249.106V171.574H245.871ZM304.539 249.281H307.777V81.519H304.539ZM363.207 249.281H366.445V81.519H363.207ZM421.875 249.281H425.113V170.836H421.875ZM480.547 249.281H483.785V171.707H480.547Z' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M187.199 249.281H190.438V175.133H187.199ZM245.871 249.281H249.106V171.574H245.871ZM304.539 249.281H307.777V81.519H304.539ZM363.207 249.281H366.445V81.519H363.207ZM421.875 249.281H425.113V170.836H421.875ZM480.547 249.281H483.785V171.707H480.547Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M188.82 175.133V174.797' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M188.82 175.133V174.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M186.828 174.797H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M188.82 175.133V175.465' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M188.82 175.133V175.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M190.813 175.464H186.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M247.488 171.574V171.238' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M247.488 171.574V171.238' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M245.496 171.239H249.48' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M247.488 171.574V171.91' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M247.488 171.574V171.91' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M249.481 171.91H245.496' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M306.156 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M304.164 81.52H308.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M306.156 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M304.164 81.52H308.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M364.828 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M362.832 81.52H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M364.828 81.519' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M362.832 81.52H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M423.496 170.836V169.629' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M423.496 170.836V169.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M421.504 169.629H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M423.496 170.836V172.043' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M423.496 170.836V172.043' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M425.488 172.043H421.504' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M482.164 171.707' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M480.172 171.707H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M482.164 171.707' fill='#d9b3b3' clip-path='url(#clip2)'/>
+<path d='M480.172 171.707H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M415.914 310.336H487.762V276.324H415.914Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<g transform='matrix(1 0 0 1 250.949 118.327)'>
+<use x='168.285' y='164.777' xlink:href='#g2-97'/>
+<use x='170.827' y='164.777' xlink:href='#g2-109'/>
+<use x='175.03' y='164.777' xlink:href='#g2-100'/>
+<use x='177.763' y='164.777' xlink:href='#g2-53'/>
+<use x='180.41' y='164.777' xlink:href='#g2-57'/>
+<use x='183.056' y='164.777' xlink:href='#g2-53'/>
+<use x='185.702' y='164.777' xlink:href='#g2-48'/>
+<use x='188.349' y='164.777' xlink:href='#g2-120'/>
+<use x='190.788' y='164.777' xlink:href='#g2-44'/>
+<use x='194.022' y='164.777' xlink:href='#g2-51'/>
+<use x='196.668' y='164.777' xlink:href='#g2-50'/>
+<use x='199.315' y='164.777' xlink:href='#g2-71'/>
+<use x='202.843' y='164.777' xlink:href='#g2-98'/>
+<use x='207.34' y='164.777' xlink:href='#g2-64'/>
+<use x='210.869' y='164.777' xlink:href='#g2-51'/>
+<use x='213.515' y='164.777' xlink:href='#g2-54'/>
+<use x='216.162' y='164.777' xlink:href='#g2-48'/>
+<use x='218.808' y='164.777' xlink:href='#g2-48'/>
+<use x='221.454' y='164.777' xlink:href='#g2-77'/>
+<use x='226.072' y='164.777' xlink:href='#g2-104'/>
+<use x='228.805' y='164.777' xlink:href='#g2-122'/>
+<use x='168.285' y='170.755' xlink:href='#g2-49'/>
+<use x='170.931' y='170.755' xlink:href='#g2-54'/>
+<use x='173.578' y='170.755' xlink:href='#g2-45'/>
+<use x='175.342' y='170.755' xlink:href='#g2-99'/>
+<use x='177.694' y='170.755' xlink:href='#g2-111'/>
+<use x='180.193' y='170.755' xlink:href='#g2-114'/>
+<use x='182.001' y='170.755' xlink:href='#g2-101'/>
+<use x='186.118' y='170.755' xlink:href='#g2-65'/>
+<use x='189.646' y='170.755' xlink:href='#g2-77'/>
+<use x='194.264' y='170.755' xlink:href='#g2-68'/>
+<use x='199.851' y='170.755' xlink:href='#g2-53'/>
+<use x='202.497' y='170.755' xlink:href='#g2-57'/>
+<use x='205.144' y='170.755' xlink:href='#g2-53'/>
+<use x='207.79' y='170.755' xlink:href='#g2-48'/>
+<use x='210.436' y='170.755' xlink:href='#g2-120'/>
+<use x='214.639' y='170.755' xlink:href='#g2-64'/>
+<use x='218.168' y='170.755' xlink:href='#g2-51'/>
+<use x='220.814' y='170.755' xlink:href='#g2-46'/>
+<use x='222.285' y='170.755' xlink:href='#g2-52'/>
+<use x='224.931' y='170.755' xlink:href='#g2-71'/>
+<use x='228.459' y='170.755' xlink:href='#g2-104'/>
+<use x='231.192' y='170.755' xlink:href='#g2-122'/>
+<use x='168.285' y='176.733' xlink:href='#g2-85'/>
+<use x='171.917' y='176.733' xlink:href='#g2-98'/>
+<use x='174.65' y='176.733' xlink:href='#g2-117'/>
+<use x='177.383' y='176.733' xlink:href='#g2-110'/>
+<use x='180.116' y='176.733' xlink:href='#g2-116'/>
+<use x='182.027' y='176.733' xlink:href='#g2-117'/>
+<use x='186.524' y='176.733' xlink:href='#g2-50'/>
+<use x='189.17' y='176.733' xlink:href='#g2-48'/>
+<use x='191.817' y='176.733' xlink:href='#g2-46'/>
+<use x='193.287' y='176.733' xlink:href='#g2-48'/>
+<use x='195.933' y='176.733' xlink:href='#g2-52'/>
+<use x='198.58' y='176.733' xlink:href='#g2-44'/>
+<use x='201.814' y='176.733' xlink:href='#g2-71'/>
+<use x='205.343' y='176.733' xlink:href='#g2-67'/>
+<use x='208.724' y='176.733' xlink:href='#g2-67'/>
+<use x='213.87' y='176.733' xlink:href='#g2-57'/>
+<use x='216.516' y='176.733' xlink:href='#g2-46'/>
+<use x='217.986' y='176.733' xlink:href='#g2-51'/>
+<use x='220.633' y='176.733' xlink:href='#g2-46'/>
+<use x='222.103' y='176.733' xlink:href='#g2-48'/>
+<use x='168.285' y='182.71' xlink:href='#g2-51'/>
+<use x='170.931' y='182.71' xlink:href='#g2-50'/>
+<use x='175.342' y='182.71' xlink:href='#g2-108'/>
+<use x='176.604' y='182.71' xlink:href='#g2-111'/>
+<use x='179.251' y='182.71' xlink:href='#g2-103'/>
+<use x='181.897' y='182.71' xlink:href='#g2-105'/>
+<use x='183.16' y='182.71' xlink:href='#g2-99'/>
+<use x='185.512' y='182.71' xlink:href='#g2-97'/>
+<use x='188.055' y='182.71' xlink:href='#g2-108'/>
+<use x='191.082' y='182.71' xlink:href='#g2-99'/>
+<use x='193.434' y='182.71' xlink:href='#g2-111'/>
+<use x='195.933' y='182.71' xlink:href='#g2-114'/>
+<use x='197.741' y='182.71' xlink:href='#g2-101'/>
+<use x='200.093' y='182.71' xlink:href='#g2-115'/>
+<use x='168.285' y='188.688' xlink:href='#g2-50'/>
+<use x='170.931' y='188.688' xlink:href='#g2-48'/>
+<use x='173.578' y='188.688' xlink:href='#g2-50'/>
+<use x='176.224' y='188.688' xlink:href='#g2-49'/>
+<use x='178.87' y='188.688' xlink:href='#g2-45'/>
+<use x='180.635' y='188.688' xlink:href='#g2-48'/>
+<use x='183.281' y='188.688' xlink:href='#g2-49'/>
+<use x='185.927' y='188.688' xlink:href='#g2-45'/>
+<use x='187.692' y='188.688' xlink:href='#g2-51'/>
+<use x='190.338' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -45.308 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 13.361 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 72.03 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 130.699 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 189.368 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 248.037 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -40.078 344.392)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 18.591 344.728)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-57'/>
+<use x='175.048' y='188.688' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 77.26 329.897)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-50'/>
+<use x='175.048' y='188.688' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.929 346.003)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-57'/>
+<use x='175.048' y='188.688' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.598 338.688)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 253.267 342.782)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -34.847 343.788)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.822 343.05)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.491 305.94)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-53'/>
+<use x='175.048' y='188.688' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 141.16 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-53'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-52'/>
+<use x='183.321' y='188.688' xlink:href='#g2-53'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.829 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-54'/>
+<use x='176.558' y='188.688' xlink:href='#g2-49'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-49'/>
+<use x='183.321' y='188.688' xlink:href='#g2-53'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 258.498 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-50'/>
+<use x='176.558' y='188.688' xlink:href='#g2-50'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-52'/>
+<use x='183.321' y='188.688' xlink:href='#g2-57'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.617 338.353)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 29.052 336.071)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.721 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-50'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-55'/>
+<use x='180.675' y='188.688' xlink:href='#g2-49'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.39 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-50'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-53'/>
+<use x='180.675' y='188.688' xlink:href='#g2-48'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 205.059 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-52'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-48'/>
+<use x='180.675' y='188.688' xlink:href='#g2-56'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 263.728 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-50'/>
+<use x='176.558' y='188.688' xlink:href='#g2-50'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-57'/>
+<use x='183.321' y='188.688' xlink:href='#g2-56'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.386 319.563)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-51'/>
+<use x='175.048' y='188.688' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 34.283 309.296)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-53'/>
+<use x='175.048' y='188.688' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.952 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-56'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-57'/>
+<use x='180.675' y='188.688' xlink:href='#g2-54'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.621 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-51'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-51'/>
+<use x='180.675' y='188.688' xlink:href='#g2-55'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 210.29 328.488)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-50'/>
+<use x='175.048' y='188.688' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 268.959 344.258)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.156 330.031)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-50'/>
+<use x='175.048' y='188.688' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.513 338.218)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 98.182 272.387)'>
+<use x='168.285' y='188.688' xlink:href='#g2-50'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.851 319.563)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-51'/>
+<use x='175.048' y='188.688' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.52 348.553)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-57'/>
+<use x='175.048' y='188.688' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 274.189 345.734)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-57'/>
+<use x='175.048' y='188.688' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 -13.925 335.87)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.744 335.87)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.413 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-50'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-51'/>
+<use x='183.321' y='188.688' xlink:href='#g2-54'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 162.082 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-50'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-57'/>
+<use x='183.321' y='188.688' xlink:href='#g2-51'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.751 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-48'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-52'/>
+<use x='183.321' y='188.688' xlink:href='#g2-50'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 279.42 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-49'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-49'/>
+<use x='183.321' y='188.688' xlink:href='#g2-51'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -8.695 306.746)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-53'/>
+<use x='175.048' y='188.688' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.974 340.097)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-48'/>
+<use x='175.048' y='188.688' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.643 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-54'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-55'/>
+<use x='180.675' y='188.688' xlink:href='#g2-57'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 167.312 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-49'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-49'/>
+<use x='183.321' y='188.688' xlink:href='#g2-52'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.981 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-56'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-52'/>
+<use x='180.675' y='188.688' xlink:href='#g2-50'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 284.65 345.734)'>
+<use x='168.285' y='188.688' xlink:href='#g2-48'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-57'/>
+<use x='175.048' y='188.688' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.465 327.28)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-50'/>
+<use x='175.048' y='188.688' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 55.204 325.468)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-50'/>
+<use x='175.048' y='188.688' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.873 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-49'/>
+<use x='176.558' y='188.688' xlink:href='#g2-56'/>
+<use x='179.205' y='188.688' xlink:href='#g2-46'/>
+<use x='180.675' y='188.688' xlink:href='#g2-52'/>
+<use x='183.321' y='188.688' xlink:href='#g2-51'/>
+<use x='185.968' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.542 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-53'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-55'/>
+<use x='180.675' y='188.688' xlink:href='#g2-56'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 231.211 278.695)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-57'/>
+<use x='175.048' y='188.688' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 289.88 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-52'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-56'/>
+<use x='180.675' y='188.688' xlink:href='#g2-52'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 1.766 337.212)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 60.435 333.655)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 119.104 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-51'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-53'/>
+<use x='180.675' y='188.688' xlink:href='#g2-55'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 177.773 243.599)'>
+<use x='163.396' y='188.688' xlink:href='#g4-1'/>
+<use x='166.901' y='188.688' xlink:href='#g4-1'/>
+<use x='170.407' y='188.688' xlink:href='#g4-1'/>
+<use x='173.912' y='188.688' xlink:href='#g2-50'/>
+<use x='176.558' y='188.688' xlink:href='#g2-46'/>
+<use x='178.029' y='188.688' xlink:href='#g2-53'/>
+<use x='180.675' y='188.688' xlink:href='#g2-53'/>
+<use x='183.321' y='188.688' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 236.442 332.917)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 295.111 333.789)'>
+<use x='168.285' y='188.688' xlink:href='#g2-49'/>
+<use x='170.931' y='188.688' xlink:href='#g2-46'/>
+<use x='172.401' y='188.688' xlink:href='#g2-49'/>
+<use x='175.048' y='188.688' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -75.53 388.945)'>
+<use x='168.285' y='188.688' xlink:href='#g1-82'/>
+<use x='174.255' y='188.688' xlink:href='#g1-101'/>
+<use x='178.351' y='188.688' xlink:href='#g1-108'/>
+<use x='180.551' y='188.688' xlink:href='#g1-97'/>
+<use x='184.979' y='188.688' xlink:href='#g1-116'/>
+<use x='188.307' y='188.688' xlink:href='#g1-105'/>
+<use x='190.507' y='188.688' xlink:href='#g1-118'/>
+<use x='194.755' y='188.688' xlink:href='#g1-101'/>
+<use x='201.922' y='188.688' xlink:href='#g1-116'/>
+<use x='205.25' y='188.688' xlink:href='#g1-105'/>
+<use x='207.45' y='188.688' xlink:href='#g1-109'/>
+<use x='214.77' y='188.688' xlink:href='#g1-101'/>
+<use x='221.937' y='188.688' xlink:href='#g3-40'/>
+<use x='225.231' y='188.688' xlink:href='#g3-108'/>
+<use x='227.251' y='188.688' xlink:href='#g3-111'/>
+<use x='231.25' y='188.688' xlink:href='#g3-119'/>
+<use x='236.799' y='188.688' xlink:href='#g3-101'/>
+<use x='240.562' y='188.688' xlink:href='#g3-114'/>
+<use x='246.277' y='188.688' xlink:href='#g3-105'/>
+<use x='248.297' y='188.688' xlink:href='#g3-115'/>
+<use x='254.366' y='188.688' xlink:href='#g3-98'/>
+<use x='258.974' y='188.688' xlink:href='#g3-101'/>
+<use x='262.738' y='188.688' xlink:href='#g3-116'/>
+<use x='265.796' y='188.688' xlink:href='#g3-116'/>
+<use x='268.854' y='188.688' xlink:href='#g3-101'/>
+<use x='272.618' y='188.688' xlink:href='#g3-114'/>
+<use x='275.51' y='188.688' xlink:href='#g3-41'/>
+</g>
+<path d='M136.149 309.68H346.746V279.68H136.149Z' fill='#fff'/>
+<path d='M136.149 309.68H346.746V279.68H136.149Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' fill='#933'/>
+<path d='M139.336 290.168H142.324V282.199H139.336ZM145.313 290.168H148.301V284.191H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.354 114.479)'>
+<use x='191.843' y='175.681' xlink:href='#g3-120'/>
+<use x='195.745' y='175.681' xlink:href='#g3-109'/>
+<use x='202.47' y='175.681' xlink:href='#g3-105'/>
+<use x='204.49' y='175.681' xlink:href='#g3-58'/>
+<use x='206.843' y='175.681' xlink:href='#g0-57'/>
+<use x='210.548' y='175.681' xlink:href='#g0-50'/>
+</g>
+<path d='M177.086 290.168H180.074V282.199H177.086ZM183.063 290.168H186.055V284.191H183.063Z' fill='#bf8080'/>
+<path d='M177.086 290.168H180.074V282.199H177.086ZM183.063 290.168H186.055V284.191H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -38.403 114.479)'>
+<use x='233.123' y='175.681' xlink:href='#g3-109'/>
+<use x='239.848' y='175.681' xlink:href='#g3-105'/>
+<use x='241.869' y='175.681' xlink:href='#g3-58'/>
+<use x='244.221' y='175.681' xlink:href='#g0-57'/>
+<use x='247.926' y='175.681' xlink:href='#g0-50'/>
+</g>
+<path d='M221.895 290.168H224.883V282.199H221.895ZM227.875 290.168H230.863V284.191H227.875Z' fill='#8080bf'/>
+<path d='M221.895 290.168H224.883V282.199H221.895ZM227.875 290.168H230.863V284.191H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.441 114.036)'>
+<use x='277.134' y='175.681' xlink:href='#g3-116'/>
+<use x='280.192' y='175.681' xlink:href='#g3-99'/>
+<use x='283.956' y='175.681' xlink:href='#g3-58'/>
+<use x='286.308' y='175.681' xlink:href='#g0-54'/>
+<use x='290.013' y='175.681' xlink:href='#g0-49'/>
+</g>
+<path d='M265.109 290.168H268.098V282.199H265.109ZM271.086 290.168H274.074V284.191H271.086Z' fill='#ffb733'/>
+<path d='M265.109 290.168H268.098V282.199H265.109ZM271.086 290.168H274.074V284.191H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.04 114.479)'>
+<use x='319.615' y='175.681' xlink:href='#g3-106'/>
+<use x='321.871' y='175.681' xlink:href='#g3-101'/>
+<use x='325.634' y='175.681' xlink:href='#g3-58'/>
+<use x='327.987' y='175.681' xlink:href='#g0-53'/>
+<use x='331.691' y='175.681' xlink:href='#g0-56'/>
+</g>
+<path d='M306.859 290.168H309.848V282.199H306.859ZM312.836 290.168H315.824V284.191H312.836Z' fill='#bf80bf'/>
+<path d='M306.859 290.168H309.848V282.199H306.859ZM312.836 290.168H315.824V284.191H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -39.932 114.515)'>
+<use x='359.038' y='175.681' xlink:href='#g3-116'/>
+<use x='362.096' y='175.681' xlink:href='#g3-98'/>
+<use x='366.469' y='175.681' xlink:href='#g3-98'/>
+<use x='370.842' y='175.681' xlink:href='#g3-58'/>
+<use x='373.194' y='175.681' xlink:href='#g0-52'/>
+<use x='376.899' y='175.681' xlink:href='#g0-54'/>
+</g>
+<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' fill='#c96'/>
+<path d='M139.336 303.176H142.324V295.207H139.336ZM145.313 303.176H148.301V297.199H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.662 114.036)'>
+<use x='191.843' y='188.688' xlink:href='#g3-114'/>
+<use x='194.735' y='188.688' xlink:href='#g3-112'/>
+<use x='199.108' y='188.688' xlink:href='#g3-58'/>
+<use x='201.46' y='188.688' xlink:href='#g0-55'/>
+<use x='205.165' y='188.688' xlink:href='#g0-56'/>
+</g>
+<path d='M177.086 303.176H180.074V295.207H177.086ZM183.063 303.176H186.055V297.199H183.063Z' fill='#80bf80'/>
+<path d='M177.086 303.176H180.074V295.207H177.086ZM183.063 303.176H186.055V297.199H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.882 114.515)'>
+<use x='233.123' y='188.688' xlink:href='#g3-104'/>
+<use x='237.496' y='188.688' xlink:href='#g3-111'/>
+<use x='241.73' y='188.688' xlink:href='#g3-97'/>
+<use x='245.563' y='188.688' xlink:href='#g3-114'/>
+<use x='248.455' y='188.688' xlink:href='#g3-100'/>
+<use x='252.828' y='188.688' xlink:href='#g3-58'/>
+<use x='255.18' y='188.688' xlink:href='#g0-52'/>
+<use x='258.885' y='188.688' xlink:href='#g0-49'/>
+</g>
+<path d='M221.895 303.176H224.883V295.207H221.895ZM227.875 303.176H230.863V297.199H227.875Z' fill='#bfbf80'/>
+<path d='M221.895 303.176H224.883V295.207H221.895ZM227.875 303.176H230.863V297.199H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.084 114.515)'>
+<use x='277.134' y='188.688' xlink:href='#g3-109'/>
+<use x='283.859' y='188.688' xlink:href='#g3-101'/>
+<use x='287.622' y='188.688' xlink:href='#g3-115'/>
+<use x='290.869' y='188.688' xlink:href='#g3-104'/>
+<use x='295.241' y='188.688' xlink:href='#g3-58'/>
+<use x='297.593' y='188.688' xlink:href='#g0-52'/>
+<use x='301.298' y='188.688' xlink:href='#g0-49'/>
+</g>
+<path d='M265.109 303.176H268.098V295.207H265.109ZM271.086 303.176H274.074V297.199H271.086Z' fill='#399'/>
+<path d='M265.109 303.176H268.098V295.207H265.109ZM271.086 303.176H274.074V297.199H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -42.353 114.515)'>
+<use x='319.615' y='188.688' xlink:href='#g3-103'/>
+<use x='323.849' y='188.688' xlink:href='#g3-108'/>
+<use x='325.869' y='188.688' xlink:href='#g3-105'/>
+<use x='327.89' y='188.688' xlink:href='#g3-98'/>
+<use x='332.498' y='188.688' xlink:href='#g3-99'/>
+<use x='336.261' y='188.688' xlink:href='#g3-58'/>
+<use x='338.614' y='188.688' xlink:href='#g0-51'/>
+<use x='342.318' y='188.688' xlink:href='#g0-57'/>
+</g>
+<path d='M306.859 303.176H309.848V295.207H306.859ZM312.836 303.176H315.824V297.199H312.836Z' fill='#d9b3b3'/>
+<path d='M306.859 303.176H309.848V295.207H306.859ZM312.836 303.176H315.824V297.199H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.026 114.479)'>
+<use x='359.038' y='188.688' xlink:href='#g3-115'/>
+<use x='362.285' y='188.688' xlink:href='#g3-109'/>
+<use x='369.009' y='188.688' xlink:href='#g3-105'/>
+<use x='371.03' y='188.688' xlink:href='#g3-58'/>
+<use x='373.382' y='188.688' xlink:href='#g0-54'/>
+<use x='377.087' y='188.688' xlink:href='#g0-50'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.629pt' height='170.383pt' viewBox='52.934 54.994 381.629 170.383'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip3'>
+<path d='M82.148 209.23H434.164V83.984H82.148Z'/>
+</clipPath>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+</defs>
+<g id='page3'>
+<path d='M140.82 218.086V209.23M199.488 218.086V209.23M258.156 218.086V209.23M316.824 218.086V209.23M375.496 218.086V209.23M140.82 75.129V83.984M199.488 75.129V83.984M258.156 75.129V83.984M316.824 75.129V83.984M375.496 75.129V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M111.484 213.484V209.23M170.152 213.484V209.23M228.824 213.484V209.23M287.492 213.484V209.23M346.16 213.484V209.23M404.828 213.484V209.23M111.484 79.734V83.984M170.152 79.734V83.984M228.824 79.734V83.984M287.492 79.734V83.984M346.16 79.734V83.984M404.828 79.734V83.984' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 209.23H86.402M82.148 177.918H86.402M82.148 146.609H86.402M82.148 115.297H86.402M82.148 83.984H86.402M434.164 209.23H429.91M434.164 177.918H429.91M434.164 146.609H429.91M434.164 115.297H429.91M434.164 83.984H429.91' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 209.23V83.984H434.164V209.23H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -11.54 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-99'/>
+<use x='118.25' y='188.674' xlink:href='#g3-102'/>
+<use x='120.838' y='188.674' xlink:href='#g3-114'/>
+<use x='123.73' y='188.674' xlink:href='#g3-97'/>
+<use x='127.798' y='188.674' xlink:href='#g3-99'/>
+</g>
+<g transform='matrix(1 0 0 1 45.565 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-108'/>
+<use x='116.507' y='188.674' xlink:href='#g3-101'/>
+<use x='120.271' y='188.674' xlink:href='#g3-97'/>
+<use x='124.339' y='188.674' xlink:href='#g3-110'/>
+<use x='128.711' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 106.188 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-114'/>
+<use x='117.379' y='188.674' xlink:href='#g3-101'/>
+<use x='121.142' y='188.674' xlink:href='#g3-100'/>
+<use x='125.515' y='188.674' xlink:href='#g3-105'/>
+<use x='127.535' y='188.674' xlink:href='#g3-115'/>
+</g>
+<g transform='matrix(1 0 0 1 159.716 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-108'/>
+<use x='116.507' y='188.674' xlink:href='#g3-97'/>
+<use x='120.34' y='188.674' xlink:href='#g3-114'/>
+<use x='123.232' y='188.674' xlink:href='#g3-115'/>
+<use x='126.478' y='188.674' xlink:href='#g3-111'/>
+<use x='130.712' y='188.674' xlink:href='#g3-110'/>
+<use x='135.085' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 215.596 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-109'/>
+<use x='121.211' y='188.674' xlink:href='#g3-115'/>
+<use x='124.458' y='188.674' xlink:href='#g3-116'/>
+<use x='127.516' y='188.674' xlink:href='#g3-114'/>
+<use x='130.408' y='188.674' xlink:href='#g3-101'/>
+<use x='134.171' y='188.674' xlink:href='#g3-115'/>
+<use x='137.418' y='188.674' xlink:href='#g3-115'/>
+<use x='140.664' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 277.158 34.954)'>
+<use x='114.487' y='188.674' xlink:href='#g3-114'/>
+<use x='117.379' y='188.674' xlink:href='#g3-112'/>
+<use x='121.751' y='188.674' xlink:href='#g3-116'/>
+<use x='124.809' y='188.674' xlink:href='#g3-101'/>
+<use x='128.573' y='188.674' xlink:href='#g3-115'/>
+<use x='131.819' y='188.674' xlink:href='#g3-116'/>
+<use x='134.877' y='188.674' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 22.192)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -9.12)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -40.431)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.743)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -103.054)'>
+<use x='114.487' y='188.674' xlink:href='#g2-50'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-120'/>
+</g>
+<path d='M82.148 146.609H434.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' fill='#933' clip-path='url(#clip3)'/>
+<path d='M86.328 209.23H89.566V146.609H86.328ZM144.996 209.23H148.234V146.609H144.996ZM203.668 209.23H206.902V146.609H203.668ZM262.336 209.23H265.574V146.609H262.336ZM321.004 209.23H324.242V146.609H321.004ZM379.672 209.23H382.91V146.609H379.672Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M87.949 146.609' fill='#933' clip-path='url(#clip3)'/>
+<path d='M85.953 146.609H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M87.949 146.609' fill='#933' clip-path='url(#clip3)'/>
+<path d='M85.953 146.609H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M146.617 146.609V146.105' fill='#933' clip-path='url(#clip3)'/>
+<path d='M146.617 146.609V146.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M144.625 146.105H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M146.617 146.609V147.109' fill='#933' clip-path='url(#clip3)'/>
+<path d='M146.617 146.609V147.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M148.61 147.109H144.625' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M205.285 146.609V146.359' fill='#933' clip-path='url(#clip3)'/>
+<path d='M205.285 146.609V146.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M203.293 146.36H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M205.285 146.609V146.859' fill='#933' clip-path='url(#clip3)'/>
+<path d='M205.285 146.609V146.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M207.278 146.86H203.293' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M263.953 146.609V145.105' fill='#933' clip-path='url(#clip3)'/>
+<path d='M263.953 146.609V145.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M261.961 145.105H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M263.953 146.609V148.109' fill='#933' clip-path='url(#clip3)'/>
+<path d='M263.953 146.609V148.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M265.949 148.109H261.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M322.625 146.609V144.73' fill='#933' clip-path='url(#clip3)'/>
+<path d='M322.625 146.609V144.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M320.629 144.73H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M322.625 146.609V148.488' fill='#933' clip-path='url(#clip3)'/>
+<path d='M322.625 146.609V148.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M324.617 148.488H320.633' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M381.293 146.609V140.785' fill='#933' clip-path='url(#clip3)'/>
+<path d='M381.293 146.609V140.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M379.301 140.785H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M381.293 146.609V152.434' fill='#933' clip-path='url(#clip3)'/>
+<path d='M381.293 146.609V152.434' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M383.285 152.434H379.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M91.559 209.23H94.797V146.23H91.559ZM150.227 209.23H153.465V146.547H150.227ZM208.899 209.23H212.133V145.293H208.899ZM267.567 209.23H270.805V152.117H267.567ZM326.234 209.23H329.473V140.973H326.234ZM384.902 209.23H388.141V154.562H384.902Z' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M91.559 209.23H94.797V146.23H91.559ZM150.227 209.23H153.465V146.547H150.227ZM208.899 209.23H212.133V145.293H208.899ZM267.567 209.23H270.805V152.117H267.567ZM326.234 209.23H329.473V140.973H326.234ZM384.902 209.23H388.141V154.562H384.902Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M93.18 146.23V146.168' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M93.18 146.23V146.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M91.184 146.168H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M93.18 146.23V146.297' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M93.18 146.23V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M95.172 146.297H91.187' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M151.848 146.547V146.297' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M151.848 146.547V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M149.855 146.297H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M151.848 146.547V146.797' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M151.848 146.547V146.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M153.84 146.797H149.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M210.516 145.293V145.105' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M210.516 145.293V145.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M208.523 145.105H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M210.516 145.293V145.48' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M210.516 145.293V145.48' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M212.508 145.481H208.523' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M269.184 152.117V151.555' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M269.184 152.117V151.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M267.191 151.554H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M269.184 152.117V152.684' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M269.184 152.117V152.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M271.179 152.684H267.191' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M327.856 140.973V137.402' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M327.856 140.973V137.402' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M325.859 137.403H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M327.856 140.973V144.543' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M327.856 140.973V144.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M329.847 144.543H325.863' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M386.524 154.562V147.734' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M386.524 154.562V147.734' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M384.531 147.734H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M386.524 154.562V161.387' fill='#bf8080' clip-path='url(#clip3)'/>
+<path d='M386.524 154.562V161.387' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M388.515 161.387H384.531' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M96.789 209.23H100.027V145.293H96.789ZM155.457 209.23H158.695V143.101H155.457ZM214.129 209.23H217.363V144.668H214.129ZM272.797 209.23H276.035V141.973H272.797ZM331.465 209.23H334.703V143.101H331.465ZM390.133 209.23H393.371V83.984H390.133Z' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M96.789 209.23H100.027V145.293H96.789ZM155.457 209.23H158.695V143.101H155.457ZM214.129 209.23H217.363V144.668H214.129ZM272.797 209.23H276.035V141.973H272.797ZM331.465 209.23H334.703V143.101H331.465ZM390.133 209.23H393.371V83.984H390.133Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M98.41 145.293V145.23' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M98.41 145.293V145.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M96.414 145.23H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M98.41 145.293V145.355' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M98.41 145.293V145.355' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M100.402 145.356H96.418' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M157.078 143.101V142.601' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M157.078 143.101V142.601' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M155.086 142.601H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M157.078 143.101V143.601' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M157.078 143.101V143.601' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M159.071 143.601H155.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M215.746 144.668V144.543' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M215.746 144.668V144.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M213.754 144.543H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M215.746 144.668V144.793' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M215.746 144.668V144.793' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M217.739 144.793H213.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M274.414 141.973V141.535' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M274.414 141.973V141.535' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M272.422 141.536H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M274.414 141.973V142.414' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M274.414 141.973V142.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M276.41 142.414H272.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M333.086 143.101V141.66' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M333.086 143.101V141.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M331.09 141.66H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M333.086 143.101V144.543' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M333.086 143.101V144.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M335.078 144.543H331.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M391.754 83.984' fill='#8080bf' clip-path='url(#clip3)'/>
+<path d='M389.762 83.984H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M102.02 209.23H105.258V143.289H102.02ZM160.688 209.23H163.926V146.484H160.688ZM219.359 209.23H222.594V134.711H219.359ZM278.027 209.23H281.266V139.531H278.027ZM336.695 209.23H339.934V83.984H336.695ZM395.363 209.23H398.602V128.008H395.363Z' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M102.02 209.23H105.258V143.289H102.02ZM160.688 209.23H163.926V146.484H160.688ZM219.359 209.23H222.594V134.711H219.359ZM278.027 209.23H281.266V139.531H278.027ZM336.695 209.23H339.934V83.984H336.695ZM395.363 209.23H398.602V128.008H395.363Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M103.641 143.289' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M101.644 143.289H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M103.641 143.289' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M101.644 143.289H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M162.309 146.484V146.168' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M162.309 146.484V146.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M160.316 146.168H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M162.309 146.484V146.797' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M162.309 146.484V146.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M164.301 146.797H160.316' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M220.977 134.711V134.523' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M220.977 134.711V134.523' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M218.984 134.524H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M220.977 134.711V134.898' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M220.977 134.711V134.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M222.969 134.899H218.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M279.645 139.531V139.469' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M279.645 139.531V139.469' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M277.652 139.469H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M279.645 139.531V139.594' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M279.645 139.531V139.594' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M281.64 139.593H277.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M338.317 83.984' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M336.32 83.984H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M338.317 83.984' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M336.32 83.984H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M396.984 128.008V115.859' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M396.984 128.008V115.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M394.992 115.859H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M396.984 128.008V140.156' fill='#ffb733' clip-path='url(#clip3)'/>
+<path d='M396.984 128.008V140.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M398.976 140.156H394.992' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M107.25 209.23H110.488V127.82H107.25ZM165.918 209.23H169.156V145.105H165.918ZM224.59 209.23H227.824V112.98H224.59ZM283.258 209.23H286.496V115.109H283.258ZM341.926 209.23H345.164V103.961H341.926ZM400.594 209.23H403.832V136.715H400.594Z' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M107.25 209.23H110.488V127.82H107.25ZM165.918 209.23H169.156V145.105H165.918ZM224.59 209.23H227.824V112.98H224.59ZM283.258 209.23H286.496V115.109H283.258ZM341.926 209.23H345.164V103.961H341.926ZM400.594 209.23H403.832V136.715H400.594Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M108.871 127.82V127.758' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M108.871 127.82V127.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M106.875 127.758H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M108.871 127.82V127.883' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M108.871 127.82V127.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M110.864 127.883H106.879' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M167.539 145.105V144.668' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M167.539 145.105V144.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M165.547 144.668H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M167.539 145.105V145.543' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M167.539 145.105V145.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M169.532 145.543H165.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M226.207 112.98V112.73' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M226.207 112.98V112.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M224.215 112.73H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M226.207 112.98V113.23' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M226.207 112.98V113.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M228.2 113.23H224.215' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M284.875 115.109V113.605' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M284.875 115.109V113.605' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M282.883 113.606H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M284.875 115.109V116.613' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M284.875 115.109V116.613' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M286.868 116.614H282.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M343.547 103.961V102.961' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M343.547 103.961V102.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M341.551 102.961H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M343.547 103.961V104.965' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M343.547 103.961V104.965' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M345.539 104.965H341.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M402.215 136.715V130.137' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M402.215 136.715V130.137' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M400.223 130.136H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M402.215 136.715V143.289' fill='#bf80bf' clip-path='url(#clip3)'/>
+<path d='M402.215 136.715V143.289' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M404.207 143.289H400.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M112.481 209.23H115.719V144.918H112.481ZM171.149 209.23H174.387V147.984H171.149ZM229.82 209.23H233.055V134.461H229.82ZM288.488 209.23H291.727V147.734H288.488ZM347.156 209.23H350.395V83.984H347.156ZM405.824 209.23H409.063V123.562H405.824Z' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M112.481 209.23H115.719V144.918H112.481ZM171.149 209.23H174.387V147.984H171.149ZM229.82 209.23H233.055V134.461H229.82ZM288.488 209.23H291.727V147.734H288.488ZM347.156 209.23H350.395V83.984H347.156ZM405.824 209.23H409.063V123.562H405.824Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M114.098 144.918V144.855' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M114.098 144.918V144.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M112.105 144.856H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M114.098 144.918V144.98' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M114.098 144.918V144.98' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M116.094 144.981H112.109' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M172.77 147.984V147.359' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M172.77 147.984V147.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M170.777 147.36H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M172.77 147.984V148.613' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M172.77 147.984V148.613' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M174.762 148.613H170.777' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M231.438 134.461V134.336' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M231.438 134.461V134.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M229.445 134.336H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M231.438 134.461V134.586' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M231.438 134.461V134.586' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M233.43 134.586H229.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M290.106 147.734V146.297' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M290.106 147.734V146.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M288.113 146.297H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M290.106 147.734V149.176' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M290.106 147.734V149.176' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M292.098 149.176H288.113' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M348.777 83.984' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M346.781 83.984H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M348.777 83.984' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M346.781 83.984H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M407.445 123.562V105.965' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M407.445 123.562V105.965' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M405.453 105.965H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M407.445 123.562V141.16' fill='#c96' clip-path='url(#clip3)'/>
+<path d='M407.445 123.562V141.16' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M409.437 141.16H405.453' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M117.711 209.23H120.949V143.601H117.711ZM176.379 209.23H179.617V139.781H176.379ZM235.051 209.23H238.285V126.57H235.051ZM293.719 209.23H296.957V83.984H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M117.711 209.23H120.949V143.601H117.711ZM176.379 209.23H179.617V139.781H176.379ZM235.051 209.23H238.285V126.57H235.051ZM293.719 209.23H296.957V83.984H293.719ZM352.387 209.23H355.625V83.984H352.387ZM411.055 209.23H414.293V83.984H411.055Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M119.328 143.601V143.539' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M119.328 143.601V143.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M117.336 143.539H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M119.328 143.601V143.664' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M119.328 143.601V143.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M121.325 143.664H117.34' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M178 139.781V139.469' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M178 139.781V139.469' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M176.008 139.469H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M178 139.781V140.094' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M178 139.781V140.094' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M179.993 140.093H176.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M236.668 126.57V126.445' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M236.668 126.57V126.445' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M234.676 126.446H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M236.668 126.57V126.695' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M236.668 126.57V126.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M238.66 126.695H234.675' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M295.336 83.984' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M293.344 83.984H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M295.336 83.984' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M293.344 83.984H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M354.008 83.984' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M352.012 83.984H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M412.676 83.984' fill='#80bf80' clip-path='url(#clip3)'/>
+<path d='M410.684 83.984H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M122.941 209.23H126.18V140.094H122.941ZM181.609 209.23H184.848V131.141H181.609ZM240.281 209.23H243.516V136.902H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V83.984H357.617ZM416.285 209.23H419.524V83.984H416.285Z' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M122.941 209.23H126.18V140.094H122.941ZM181.609 209.23H184.848V131.141H181.609ZM240.281 209.23H243.516V136.902H240.281ZM298.949 209.23H302.188V83.984H298.949ZM357.617 209.23H360.856V83.984H357.617ZM416.285 209.23H419.524V83.984H416.285Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M124.559 140.094V140.031' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M124.559 140.094V140.031' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M122.566 140.032H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M124.559 140.094V140.156' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M124.559 140.094V140.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M126.555 140.156H122.57' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M183.231 131.141V130.703' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M183.231 131.141V130.703' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M181.238 130.703H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M183.231 131.141V131.578' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M183.231 131.141V131.578' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M185.223 131.579H181.238' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M241.899 136.902V136.652' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M241.899 136.902V136.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M239.906 136.652H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M241.899 136.902V137.152' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M241.899 136.902V137.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M243.891 137.152H239.906' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M300.567 83.984' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M298.574 83.984H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M359.238 83.984' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M357.242 83.984H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M359.238 83.984' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M357.242 83.984H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M417.906 83.984' fill='#bfbf80' clip-path='url(#clip3)'/>
+<path d='M415.914 83.984H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M128.172 209.23H131.41V141.348H128.172ZM186.84 209.23H190.078V135.273H186.84ZM245.512 209.23H248.746V138.344H245.512ZM304.18 209.23H307.418V113.73H304.18ZM362.848 209.23H366.086V83.984H362.848ZM421.516 209.23H424.754V127.195H421.516Z' fill='#399' clip-path='url(#clip3)'/>
+<path d='M128.172 209.23H131.41V141.348H128.172ZM186.84 209.23H190.078V135.273H186.84ZM245.512 209.23H248.746V138.344H245.512ZM304.18 209.23H307.418V113.73H304.18ZM362.848 209.23H366.086V83.984H362.848ZM421.516 209.23H424.754V127.195H421.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M129.789 141.348V141.285' fill='#399' clip-path='url(#clip3)'/>
+<path d='M129.789 141.348V141.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M127.797 141.285H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M129.789 141.348V141.41' fill='#399' clip-path='url(#clip3)'/>
+<path d='M129.789 141.348V141.41' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M131.785 141.41H127.8' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M188.461 135.273V134.711' fill='#399' clip-path='url(#clip3)'/>
+<path d='M188.461 135.273V134.711' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M186.469 134.711H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M188.461 135.273V135.836' fill='#399' clip-path='url(#clip3)'/>
+<path d='M188.461 135.273V135.836' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M190.453 135.836H186.468' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M247.129 138.344V138.09' fill='#399' clip-path='url(#clip3)'/>
+<path d='M247.129 138.344V138.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M245.137 138.089H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M247.129 138.344V138.594' fill='#399' clip-path='url(#clip3)'/>
+<path d='M247.129 138.344V138.594' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M249.121 138.593H245.136' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M305.797 113.73V112.855' fill='#399' clip-path='url(#clip3)'/>
+<path d='M305.797 113.73V112.855' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M303.804 112.855H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M305.797 113.73V114.609' fill='#399' clip-path='url(#clip3)'/>
+<path d='M305.797 113.73V114.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M307.789 114.61H303.804' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M364.469 83.984' fill='#399' clip-path='url(#clip3)'/>
+<path d='M362.473 83.984H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M364.469 83.984' fill='#399' clip-path='url(#clip3)'/>
+<path d='M362.473 83.984H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M423.137 127.195V122.246' fill='#399' clip-path='url(#clip3)'/>
+<path d='M423.137 127.195V122.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M421.144 122.246H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M423.137 127.195V132.141' fill='#399' clip-path='url(#clip3)'/>
+<path d='M423.137 127.195V132.141' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M425.129 132.14H421.144' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M133.402 209.23H136.641V140.91H133.402ZM192.07 209.23H195.309V145.98H192.07ZM250.742 209.23H253.977V141.098H250.742ZM309.41 209.23H312.649V124.816H309.41ZM368.078 209.23H371.317V83.984H368.078ZM426.746 209.23H429.984V123.937H426.746Z' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M133.402 209.23H136.641V140.91H133.402ZM192.07 209.23H195.309V145.98H192.07ZM250.742 209.23H253.977V141.098H250.742ZM309.41 209.23H312.649V124.816H309.41ZM368.078 209.23H371.317V83.984H368.078ZM426.746 209.23H429.984V123.937H426.746Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M135.02 140.91V140.848' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M135.02 140.91V140.848' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M133.027 140.848H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M135.02 140.91V140.973' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M135.02 140.91V140.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M137.016 140.973H133.031' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M193.692 145.98V144.918' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M193.692 145.98V144.918' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M191.699 144.918H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M193.692 145.98V147.047' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M193.692 145.98V147.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M195.684 147.046H191.699' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M252.359 141.098V140.973' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M252.359 141.098V140.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M250.367 140.973H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M252.359 141.098V141.223' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M252.359 141.098V141.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M254.352 141.223H250.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M311.027 124.816V123.937' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M311.027 124.816V123.937' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M309.035 123.938H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M311.027 124.816V125.691' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M311.027 124.816V125.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M313.02 125.691H309.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M369.699 83.984' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M367.703 83.984H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M369.699 83.984' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M367.703 83.984H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M428.367 123.937V119.867' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M428.367 123.937V119.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M426.375 119.867H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M428.367 123.937V128.008' fill='#d9b3b3' clip-path='url(#clip3)'/>
+<path d='M428.367 123.937V128.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<path d='M430.36 128.008H426.375' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip3)'/>
+<g transform='matrix(0 -1 1 0 -99.092 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -40.423 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 18.246 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 76.915 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.584 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 194.253 255.07)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -93.862 254.695)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.193 255.008)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 23.476 253.755)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 82.145 260.581)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.814 249.434)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 199.483 263.023)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-56'/>
+<use x='121.25' y='188.674' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 -88.631 253.755)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -29.962 251.563)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 28.707 253.129)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 87.376 250.436)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.045 251.563)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 204.714 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-51'/>
+<use x='126.877' y='188.674' xlink:href='#g2-50'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -83.401 251.751)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -24.732 254.945)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 33.937 243.172)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 92.606 247.994)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.275 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-52'/>
+<use x='126.877' y='188.674' xlink:href='#g2-55'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 209.944 236.471)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.17 236.283)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.501 253.567)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.168 221.442)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 97.837 223.571)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.506 212.424)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-54'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 215.175 245.176)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -72.94 253.38)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 -14.271 256.448)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.398 242.922)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.067 256.198)'>
+<use x='114.487' y='188.674' xlink:href='#g2-48'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-57'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 161.736 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-50'/>
+<use x='126.877' y='188.674' xlink:href='#g2-51'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 220.405 232.025)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 -67.709 252.064)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -9.04 248.244)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.629 235.031)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.298 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-53'/>
+<use x='126.877' y='188.674' xlink:href='#g2-54'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 166.967 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-49'/>
+<use x='122.76' y='188.674' xlink:href='#g2-48'/>
+<use x='125.406' y='188.674' xlink:href='#g2-46'/>
+<use x='126.877' y='188.674' xlink:href='#g2-51'/>
+<use x='129.523' y='188.674' xlink:href='#g2-50'/>
+<use x='132.169' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 225.636 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-51'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-48'/>
+<use x='126.877' y='188.674' xlink:href='#g2-56'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.479 248.558)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.81 239.602)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-50'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 54.859 245.364)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.528 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-55'/>
+<use x='125.406' y='188.674' xlink:href='#g2-51'/>
+<use x='128.053' y='188.674' xlink:href='#g2-46'/>
+<use x='129.523' y='188.674' xlink:href='#g2-52'/>
+<use x='132.169' y='188.674' xlink:href='#g2-53'/>
+<use x='134.816' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.197 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-54'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-48'/>
+<use x='126.877' y='188.674' xlink:href='#g2-54'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 230.866 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-50'/>
+<use x='126.877' y='188.674' xlink:href='#g2-52'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -57.249 249.81)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 1.42 243.736)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 60.089 246.804)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-49'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 118.758 222.193)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-53'/>
+<use x='121.25' y='188.674' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 177.427 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-52'/>
+<use x='126.877' y='188.674' xlink:href='#g2-56'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 236.096 235.657)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 -52.018 249.372)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.651 254.444)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 65.32 249.56)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-48'/>
+<use x='121.25' y='188.674' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 123.989 233.278)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.658 192.447)'>
+<use x='109.598' y='188.674' xlink:href='#g4-1'/>
+<use x='113.103' y='188.674' xlink:href='#g4-1'/>
+<use x='116.608' y='188.674' xlink:href='#g4-1'/>
+<use x='120.114' y='188.674' xlink:href='#g2-50'/>
+<use x='122.76' y='188.674' xlink:href='#g2-46'/>
+<use x='124.23' y='188.674' xlink:href='#g2-51'/>
+<use x='126.877' y='188.674' xlink:href='#g2-49'/>
+<use x='129.523' y='188.674' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 241.327 232.401)'>
+<use x='114.487' y='188.674' xlink:href='#g2-49'/>
+<use x='117.133' y='188.674' xlink:href='#g2-46'/>
+<use x='118.603' y='188.674' xlink:href='#g2-51'/>
+<use x='121.25' y='188.674' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -129.314 316.355)'>
+<use x='114.487' y='188.674' xlink:href='#g1-82'/>
+<use x='120.457' y='188.674' xlink:href='#g1-101'/>
+<use x='124.553' y='188.674' xlink:href='#g1-108'/>
+<use x='126.753' y='188.674' xlink:href='#g1-97'/>
+<use x='131.181' y='188.674' xlink:href='#g1-116'/>
+<use x='134.509' y='188.674' xlink:href='#g1-105'/>
+<use x='136.709' y='188.674' xlink:href='#g1-118'/>
+<use x='140.957' y='188.674' xlink:href='#g1-101'/>
+<use x='148.124' y='188.674' xlink:href='#g1-116'/>
+<use x='151.452' y='188.674' xlink:href='#g1-105'/>
+<use x='153.652' y='188.674' xlink:href='#g1-109'/>
+<use x='160.972' y='188.674' xlink:href='#g1-101'/>
+<use x='168.139' y='188.674' xlink:href='#g3-40'/>
+<use x='171.432' y='188.674' xlink:href='#g3-108'/>
+<use x='173.453' y='188.674' xlink:href='#g3-111'/>
+<use x='177.452' y='188.674' xlink:href='#g3-119'/>
+<use x='183' y='188.674' xlink:href='#g3-101'/>
+<use x='186.764' y='188.674' xlink:href='#g3-114'/>
+<use x='192.479' y='188.674' xlink:href='#g3-105'/>
+<use x='194.499' y='188.674' xlink:href='#g3-115'/>
+<use x='200.568' y='188.674' xlink:href='#g3-98'/>
+<use x='205.176' y='188.674' xlink:href='#g3-101'/>
+<use x='208.94' y='188.674' xlink:href='#g3-116'/>
+<use x='211.998' y='188.674' xlink:href='#g3-116'/>
+<use x='215.056' y='188.674' xlink:href='#g3-101'/>
+<use x='218.819' y='188.674' xlink:href='#g3-114'/>
+<use x='221.711' y='188.674' xlink:href='#g3-41'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.627pt' height='259.632pt' viewBox='106.732 54.993 381.627 259.632'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip4'>
+<path d='M135.949 251.93H487.961V84.164H135.949Z'/>
+</clipPath>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/>
+<use id='g3-49' xlink:href='#g0-49' transform='scale(1.143)'/>
+<use id='g3-54' xlink:href='#g0-54' transform='scale(1.143)'/>
+<use id='g3-56' xlink:href='#g0-56' transform='scale(1.143)'/>
+<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-103' xlink:href='#g0-103' transform='scale(1.143)'/>
+<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/>
+<use id='g2-41' xlink:href='#g0-41' transform='scale(.714)'/>
+<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/>
+<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/>
+<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/>
+<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/>
+<use id='g2-73' xlink:href='#g0-73' transform='scale(.714)'/>
+<use id='g2-85' xlink:href='#g0-85' transform='scale(.714)'/>
+<use id='g2-88' xlink:href='#g0-88' transform='scale(.714)'/>
+<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/>
+<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/>
+<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/>
+<use id='g2-100' xlink:href='#g0-100' transform='scale(.714)'/>
+<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/>
+<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/>
+<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/>
+<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/>
+<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/>
+<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/>
+<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/>
+<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/>
+<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/>
+<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/>
+<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/>
+<use id='g2-117' xlink:href='#g0-117' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<path id='g4-2' d='M4.13-2.481C4.184-2.535 4.204-2.57 4.204-2.615C4.204-2.69 4.139-2.755 4.065-2.755C4.01-2.755 3.985-2.73 3.93-2.675L2.7-1.445L1.465-2.68C1.41-2.735 1.375-2.755 1.33-2.755C1.255-2.755 1.191-2.69 1.191-2.615C1.191-2.56 1.215-2.535 1.27-2.481L2.501-1.245L1.27-.01C1.215 .045 1.191 .07 1.191 .125C1.191 .199 1.255 .264 1.33 .264C1.385 .264 1.41 .239 1.46 .189L2.695-1.046L3.97 .229C3.995 .249 4.03 .264 4.065 .264C4.139 .264 4.204 .199 4.204 .125C4.204 .095 4.194 .075 4.184 .05C4.164 .02 3.238-.892 2.894-1.245L4.13-2.481Z'/>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/>
+<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/>
+<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/>
+<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/>
+<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/>
+<path id='g0-73' d='M1.381-4.84H.676V0H1.381V-4.84Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-85' d='M4.4-4.84H3.794V-1.625C3.794-.69 3.166-.265 2.566-.265S1.381-.697 1.381-1.618V-4.84H.676V-1.632C.676-.607 1.555 .146 2.559 .146C3.557 .146 4.4-.614 4.4-1.632V-4.84Z'/>
+<path id='g0-88' d='M2.755-2.552L4.519-4.84H3.759L2.413-3.055L1.039-4.84H.209L2.071-2.552L.105 0H.865L2.413-2.099L3.996 0H4.826L2.755-2.552Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/>
+<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-117' d='M3.243-3.096H2.636V-1.074C2.636-.516 2.162-.342 1.757-.342C1.241-.342 1.186-.481 1.186-.802V-3.096H.579V-.76C.579-.139 .851 .07 1.339 .07C1.625 .07 2.239 .014 2.657-.321V0H3.243V-3.096Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/>
+</defs>
+<g id='page4'>
+<path d='M194.617 260.785V251.93M253.285 260.785V251.93M311.953 260.785V251.93M370.625 260.785V251.93M429.293 260.785V251.93M194.617 75.308V84.164M253.285 75.308V84.164M311.953 75.308V84.164M370.625 75.308V84.164M429.293 75.308V84.164' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M165.281 256.18V251.93M223.953 256.18V251.93M282.621 256.18V251.93M341.289 256.18V251.93M399.957 256.18V251.93M458.629 256.18V251.93M165.281 79.91V84.164M223.953 79.91V84.164M282.621 79.91V84.164M341.289 79.91V84.164M399.957 79.91V84.164M458.629 79.91V84.164' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M135.949 251.93H140.199M135.949 218.375H140.199M135.949 184.824H140.199M135.949 151.269H140.199M135.949 117.719H140.199M135.949 84.164H140.199M487.961 251.93H483.711M487.961 218.375H483.711M487.961 184.824H483.711M487.961 151.269H483.711M487.961 117.719H483.711M487.961 84.164H483.711' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M135.949 251.93V84.164H487.961V251.93H135.949Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -21.265 74.992)'>
+<use x='168.285' y='191.334' xlink:href='#g3-97'/>
+<use x='172.353' y='191.334' xlink:href='#g3-108'/>
+<use x='174.373' y='191.334' xlink:href='#g3-108'/>
+<use x='176.393' y='191.334' xlink:href='#g3-111'/>
+<use x='180.863' y='191.334' xlink:href='#g3-99'/>
+<use x='184.627' y='191.334' xlink:href='#g3-45'/>
+<use x='187.449' y='191.334' xlink:href='#g3-116'/>
+<use x='190.507' y='191.334' xlink:href='#g3-101'/>
+<use x='194.271' y='191.334' xlink:href='#g3-115'/>
+<use x='197.517' y='191.334' xlink:href='#g3-116'/>
+<use x='200.575' y='191.334' xlink:href='#g3-49'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 74.992)'>
+<use x='168.285' y='191.334' xlink:href='#g3-97'/>
+<use x='172.353' y='191.334' xlink:href='#g3-108'/>
+<use x='174.373' y='191.334' xlink:href='#g3-108'/>
+<use x='176.393' y='191.334' xlink:href='#g3-111'/>
+<use x='180.863' y='191.334' xlink:href='#g3-99'/>
+<use x='184.627' y='191.334' xlink:href='#g3-45'/>
+<use x='187.449' y='191.334' xlink:href='#g3-116'/>
+<use x='190.507' y='191.334' xlink:href='#g3-101'/>
+<use x='194.271' y='191.334' xlink:href='#g3-115'/>
+<use x='197.517' y='191.334' xlink:href='#g3-116'/>
+<use x='200.575' y='191.334' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 74.992)'>
+<use x='168.285' y='191.334' xlink:href='#g3-115'/>
+<use x='171.531' y='191.334' xlink:href='#g3-104'/>
+<use x='175.904' y='191.334' xlink:href='#g3-54'/>
+<use x='180.138' y='191.334' xlink:href='#g3-98'/>
+<use x='184.746' y='191.334' xlink:href='#g3-101'/>
+<use x='188.509' y='191.334' xlink:href='#g3-110'/>
+<use x='192.882' y='191.334' xlink:href='#g3-99'/>
+<use x='196.646' y='191.334' xlink:href='#g3-104'/>
+<use x='201.018' y='191.334' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 74.992)'>
+<use x='168.285' y='191.334' xlink:href='#g3-115'/>
+<use x='171.531' y='191.334' xlink:href='#g3-104'/>
+<use x='175.904' y='191.334' xlink:href='#g3-56'/>
+<use x='180.138' y='191.334' xlink:href='#g3-98'/>
+<use x='184.746' y='191.334' xlink:href='#g3-101'/>
+<use x='188.509' y='191.334' xlink:href='#g3-110'/>
+<use x='192.882' y='191.334' xlink:href='#g3-99'/>
+<use x='196.646' y='191.334' xlink:href='#g3-104'/>
+<use x='201.018' y='191.334' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 74.992)'>
+<use x='168.285' y='191.334' xlink:href='#g3-120'/>
+<use x='172.187' y='191.334' xlink:href='#g3-109'/>
+<use x='178.912' y='191.334' xlink:href='#g3-97'/>
+<use x='182.98' y='191.334' xlink:href='#g3-108'/>
+<use x='185' y='191.334' xlink:href='#g3-108'/>
+<use x='187.02' y='191.334' xlink:href='#g3-111'/>
+<use x='191.49' y='191.334' xlink:href='#g3-99'/>
+<use x='195.254' y='191.334' xlink:href='#g3-45'/>
+<use x='198.076' y='191.334' xlink:href='#g3-116'/>
+<use x='201.134' y='191.334' xlink:href='#g3-101'/>
+<use x='204.898' y='191.334' xlink:href='#g3-115'/>
+<use x='208.144' y='191.334' xlink:href='#g3-116'/>
+<use x='211.202' y='191.334' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 74.992)'>
+<use x='168.285' y='191.334' xlink:href='#g3-99'/>
+<use x='172.049' y='191.334' xlink:href='#g3-97'/>
+<use x='176.117' y='191.334' xlink:href='#g3-99'/>
+<use x='179.88' y='191.334' xlink:href='#g3-104'/>
+<use x='184.253' y='191.334' xlink:href='#g3-101'/>
+<use x='188.017' y='191.334' xlink:href='#g3-45'/>
+<use x='190.839' y='191.334' xlink:href='#g3-115'/>
+<use x='194.086' y='191.334' xlink:href='#g3-99'/>
+<use x='197.849' y='191.334' xlink:href='#g3-114'/>
+<use x='200.741' y='191.334' xlink:href='#g3-97'/>
+<use x='204.81' y='191.334' xlink:href='#g3-116'/>
+<use x='207.868' y='191.334' xlink:href='#g3-99'/>
+<use x='211.631' y='191.334' xlink:href='#g3-104'/>
+<use x='216.004' y='191.334' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 62.23)'>
+<use x='168.285' y='191.334' xlink:href='#g2-48'/>
+<use x='170.931' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.677)'>
+<use x='168.285' y='191.334' xlink:href='#g2-48'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-53'/>
+<use x='175.048' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -4.876)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -38.43)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-53'/>
+<use x='175.048' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.983)'>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -105.536)'>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-53'/>
+<use x='175.048' y='191.334' xlink:href='#g2-120'/>
+</g>
+<path d='M135.949 184.824H487.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M140.125 251.93H143.363V184.824H140.125ZM198.797 251.93H202.035V184.824H198.797ZM257.465 251.93H260.703V184.824H257.465ZM316.133 251.93H319.371V184.824H316.133ZM374.801 251.93H378.039V184.824H374.801ZM433.473 251.93H436.711V184.824H433.473Z' fill='#933' clip-path='url(#clip4)'/>
+<path d='M140.125 251.93H143.363V184.824H140.125ZM198.797 251.93H202.035V184.824H198.797ZM257.465 251.93H260.703V184.824H257.465ZM316.133 251.93H319.371V184.824H316.133ZM374.801 251.93H378.039V184.824H374.801ZM433.473 251.93H436.711V184.824H433.473Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M141.746 184.824V184.758' fill='#933' clip-path='url(#clip4)'/>
+<path d='M141.746 184.824V184.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M139.754 184.758H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M141.746 184.824V184.891' fill='#933' clip-path='url(#clip4)'/>
+<path d='M141.746 184.824V184.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M143.738 184.891H139.754' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M200.414 184.824V184.621' fill='#933' clip-path='url(#clip4)'/>
+<path d='M200.414 184.824V184.621' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M198.422 184.621H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M200.414 184.824V185.023' fill='#933' clip-path='url(#clip4)'/>
+<path d='M200.414 184.824V185.023' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M202.406 185.023H198.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M259.082 184.824' fill='#933' clip-path='url(#clip4)'/>
+<path d='M257.09 184.824H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M259.082 184.824' fill='#933' clip-path='url(#clip4)'/>
+<path d='M257.09 184.824H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M317.754 184.824V178.785' fill='#933' clip-path='url(#clip4)'/>
+<path d='M317.754 184.824V178.785' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M315.762 178.785H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M317.754 184.824V190.863' fill='#933' clip-path='url(#clip4)'/>
+<path d='M317.754 184.824V190.863' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M319.746 190.864H315.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M376.422 184.824V184.086' fill='#933' clip-path='url(#clip4)'/>
+<path d='M376.422 184.824V184.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M374.43 184.086H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M376.422 184.824V185.562' fill='#933' clip-path='url(#clip4)'/>
+<path d='M376.422 184.824V185.562' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M378.414 185.562H374.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M435.09 184.824V181.402' fill='#933' clip-path='url(#clip4)'/>
+<path d='M435.09 184.824V181.402' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M433.098 181.403H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M435.09 184.824V188.246' fill='#933' clip-path='url(#clip4)'/>
+<path d='M435.09 184.824V188.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M437.082 188.246H433.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M145.356 251.93H148.594V184.488H145.356ZM204.028 251.93H207.266V184.621H204.028ZM262.695 251.93H265.934V184.824H262.695ZM321.363 251.93H324.602V182.004H321.363ZM380.031 251.93H383.27V178.648H380.031ZM438.703 251.93H441.942V187.238H438.703Z' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M145.356 251.93H148.594V184.488H145.356ZM204.028 251.93H207.266V184.621H204.028ZM262.695 251.93H265.934V184.824H262.695ZM321.363 251.93H324.602V182.004H321.363ZM380.031 251.93H383.27V178.648H380.031ZM438.703 251.93H441.942V187.238H438.703Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M146.977 184.488V184.422' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M146.977 184.488V184.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M144.984 184.421H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M146.977 184.488V184.555' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M146.977 184.488V184.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M148.968 184.555H144.984' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M205.645 184.621V184.555' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M205.645 184.621V184.555' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M203.652 184.555H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M205.645 184.621V184.687' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M205.645 184.621V184.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M207.636 184.688H203.652' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M264.313 184.824' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M262.32 184.824H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M264.313 184.824' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M262.32 184.824H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M322.984 182.004V177.441' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M322.984 182.004V177.441' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M320.992 177.441H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M322.984 182.004V186.566' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M322.984 182.004V186.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M324.976 186.567H320.988' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M381.652 178.648V176.973' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M381.652 178.648V176.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M379.66 176.973H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M381.652 178.648V180.328' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M381.652 178.648V180.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M383.644 180.328H379.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M440.32 187.238V181.402' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M440.32 187.238V181.402' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M438.328 181.403H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M440.32 187.238V193.078' fill='#bf8080' clip-path='url(#clip4)'/>
+<path d='M440.32 187.238V193.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M442.312 193.078H438.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M150.586 251.93H153.824V184.621H150.586ZM209.258 251.93H212.496V171.871H209.258ZM267.926 251.93H271.164V137.312H267.926ZM326.594 251.93H329.832V84.164H326.594ZM385.262 251.93H388.5V84.164H385.262ZM443.934 251.93H447.172V84.164H443.934Z' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M150.586 251.93H153.824V184.621H150.586ZM209.258 251.93H212.496V171.871H209.258ZM267.926 251.93H271.164V137.312H267.926ZM326.594 251.93H329.832V84.164H326.594ZM385.262 251.93H388.5V84.164H385.262ZM443.934 251.93H447.172V84.164H443.934Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M152.207 184.621' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M150.215 184.621H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M152.207 184.621' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M150.215 184.621H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M210.875 171.871V170.461' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M210.875 171.871V170.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M208.883 170.461H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M210.875 171.871V173.281' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M210.875 171.871V173.281' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M212.868 173.281H208.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M269.543 137.312V129.394' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M269.543 137.312V129.394' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M267.551 129.394H271.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M269.543 137.312V145.23' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M269.543 137.312V145.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M271.535 145.23H267.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M328.215 84.164' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M326.223 84.164H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M328.215 84.164' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M326.223 84.164H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M386.883 84.164' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M384.891 84.164H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M386.883 84.164' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M384.891 84.164H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M445.551 84.164' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M443.559 84.164H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M445.551 84.164' fill='#8080bf' clip-path='url(#clip4)'/>
+<path d='M443.559 84.164H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M155.817 251.93H159.055V179.926H155.817ZM214.488 251.93H217.727V180.461H214.488ZM273.156 251.93H276.395V131.676H273.156ZM331.824 251.93H335.063V126.105H331.824ZM390.492 251.93H393.731V84.164H390.492ZM449.164 251.93H452.402V84.164H449.164Z' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M155.817 251.93H159.055V179.926H155.817ZM214.488 251.93H217.727V180.461H214.488ZM273.156 251.93H276.395V131.676H273.156ZM331.824 251.93H335.063V126.105H331.824ZM390.492 251.93H393.731V84.164H390.492ZM449.164 251.93H452.402V84.164H449.164Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M157.438 179.926' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M155.445 179.925H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M157.438 179.926' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M155.445 179.925H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M216.106 180.461' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M214.113 180.461H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M216.106 180.461' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M214.113 180.461H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M274.774 131.676V127.715' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M274.774 131.676V127.715' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M272.781 127.715H276.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M274.774 131.676V135.633' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M274.774 131.676V135.633' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M276.765 135.633H272.781' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M333.445 126.105V120.066' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M333.445 126.105V120.066' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M331.453 120.067H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M333.445 126.105V132.144' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M333.445 126.105V132.144' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M335.437 132.145H331.449' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M392.113 84.164' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M390.121 84.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M392.113 84.164' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M390.121 84.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M450.781 84.164' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M448.789 84.164H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M450.781 84.164' fill='#ffb733' clip-path='url(#clip4)'/>
+<path d='M448.789 84.164H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M161.047 251.93H164.285V162.141H161.047ZM219.719 251.93H222.957V163.418H219.719ZM278.387 251.93H281.625V84.164H278.387ZM337.055 251.93H340.293V112.148H337.055ZM395.723 251.93H398.961V86.848H395.723ZM454.395 251.93H457.633V184.824H454.395Z' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M161.047 251.93H164.285V162.141H161.047ZM219.719 251.93H222.957V163.418H219.719ZM278.387 251.93H281.625V84.164H278.387ZM337.055 251.93H340.293V112.148H337.055ZM395.723 251.93H398.961V86.848H395.723ZM454.395 251.93H457.633V184.824H454.395Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M162.668 162.141V162.074' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M162.668 162.141V162.074' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M160.676 162.074H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M162.668 162.141V162.207' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M162.668 162.141V162.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M164.661 162.207H160.676' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M221.336 163.418V163.348' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M221.336 163.418V163.348' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M219.344 163.348H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M221.336 163.418V163.484' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M221.336 163.418V163.484' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M223.329 163.484H219.344' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M280.004 84.164' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M278.012 84.164H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M280.004 84.164' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M278.012 84.164H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M338.676 112.148' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M336.684 112.148H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M338.676 112.148' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M336.684 112.148H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M397.344 86.848V86.648' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M397.344 86.848V86.648' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M395.352 86.648H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M397.344 86.848V87.051' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M397.344 86.848V87.051' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M399.336 87.051H395.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M456.012 184.824V175.832' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M456.012 184.824V175.832' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M454.02 175.832H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M456.012 184.824V193.816' fill='#bf80bf' clip-path='url(#clip4)'/>
+<path d='M456.012 184.824V193.816' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M458.004 193.816H454.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M166.278 251.93H169.516V171.937H166.278ZM224.949 251.93H228.188V181.066H224.949ZM283.617 251.93H286.856V151.269H283.617ZM342.285 251.93H345.524V162.477H342.285ZM400.953 251.93H404.192V192.34H400.953ZM459.625 251.93H462.863V189.586H459.625Z' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M166.278 251.93H169.516V171.937H166.278ZM224.949 251.93H228.188V181.066H224.949ZM283.617 251.93H286.856V151.269H283.617ZM342.285 251.93H345.524V162.477H342.285ZM400.953 251.93H404.192V192.34H400.953ZM459.625 251.93H462.863V189.586H459.625Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M167.899 171.937' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M165.906 171.938H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M167.899 171.937' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M165.906 171.938H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M226.567 181.066V180.996' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M226.567 181.066V180.996' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M224.574 180.996H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M226.567 181.066V181.133' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M226.567 181.066V181.133' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M228.559 181.133H224.574' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M285.234 151.269' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M283.242 151.27H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M285.234 151.269' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M283.242 151.27H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M343.906 162.477V160.195' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M343.906 162.477V160.195' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M341.914 160.195H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M343.906 162.477V164.758' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M343.906 162.477V164.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M345.898 164.758H341.91' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M402.574 192.34V191.266' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M402.574 192.34V191.266' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M400.582 191.265H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M402.574 192.34V193.414' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M402.574 192.34V193.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M404.566 193.414H400.582' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M461.242 189.586V186.164' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M461.242 189.586V186.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M459.25 186.164H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M461.242 189.586V193.012' fill='#c96' clip-path='url(#clip4)'/>
+<path d='M461.242 189.586V193.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M463.234 193.012H459.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M171.508 251.93H174.746V180.93H171.508ZM230.18 251.93H233.414V179.051H230.18ZM288.848 251.93H292.086V84.164H288.848ZM347.516 251.93H350.754V84.164H347.516ZM406.184 251.93H409.422V84.164H406.184ZM464.856 251.93H468.094V84.164H464.856Z' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M171.508 251.93H174.746V180.93H171.508ZM230.18 251.93H233.414V179.051H230.18ZM288.848 251.93H292.086V84.164H288.848ZM347.516 251.93H350.754V84.164H347.516ZM406.184 251.93H409.422V84.164H406.184ZM464.856 251.93H468.094V84.164H464.856Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M173.129 180.93' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M171.137 180.93H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M173.129 180.93' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M171.137 180.93H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M231.797 179.051V178.852' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M231.797 179.051V178.852' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M229.805 178.852H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M231.797 179.051V179.254' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M231.797 179.051V179.254' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M233.79 179.254H229.805' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M290.465 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M288.473 84.164H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M290.465 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M288.473 84.164H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M349.137 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M347.145 84.164H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M349.137 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M347.145 84.164H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M407.805 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M405.813 84.164H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M407.805 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M405.813 84.164H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M466.473 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M464.481 84.164H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M466.473 84.164' fill='#80bf80' clip-path='url(#clip4)'/>
+<path d='M464.481 84.164H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M176.738 251.93H179.977V154.828H176.738ZM235.41 251.93H238.645V176.168H235.41ZM294.078 251.93H297.317V84.164H294.078ZM352.746 251.93H355.984V84.164H352.746ZM411.414 251.93H414.652V84.164H411.414ZM470.086 251.93H473.324V189.586H470.086Z' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M176.738 251.93H179.977V154.828H176.738ZM235.41 251.93H238.645V176.168H235.41ZM294.078 251.93H297.317V84.164H294.078ZM352.746 251.93H355.984V84.164H352.746ZM411.414 251.93H414.652V84.164H411.414ZM470.086 251.93H473.324V189.586H470.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M178.36 154.828V148.922' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M178.36 154.828V148.922' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M176.367 148.922H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M178.36 154.828V160.73' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M178.36 154.828V160.73' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M180.352 160.731H176.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M237.027 176.168V175.832' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M237.027 176.168V175.832' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M235.035 175.832H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M237.027 176.168V176.5' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M237.027 176.168V176.5' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M239.02 176.5H235.035' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M295.695 84.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M293.703 84.164H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M295.695 84.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M293.703 84.164H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M354.367 84.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M352.375 84.164H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M354.367 84.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M352.375 84.164H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M413.035 84.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M411.043 84.164H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M413.035 84.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M411.043 84.164H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M471.703 189.586V186.164' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M471.703 189.586V186.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M469.711 186.164H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M471.703 189.586V193.012' fill='#bfbf80' clip-path='url(#clip4)'/>
+<path d='M471.703 189.586V193.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M473.695 193.012H469.711' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M181.969 251.93H185.207V167.914H181.969ZM240.641 251.93H243.875V168.984H240.641ZM299.309 251.93H302.547V84.164H299.309ZM357.977 251.93H361.215V84.164H357.977ZM416.645 251.93H419.883V84.164H416.645ZM475.317 251.93H478.555V84.164H475.317Z' fill='#399' clip-path='url(#clip4)'/>
+<path d='M181.969 251.93H185.207V167.914H181.969ZM240.641 251.93H243.875V168.984H240.641ZM299.309 251.93H302.547V84.164H299.309ZM357.977 251.93H361.215V84.164H357.977ZM416.645 251.93H419.883V84.164H416.645ZM475.317 251.93H478.555V84.164H475.317Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M183.59 167.914V167.844' fill='#399' clip-path='url(#clip4)'/>
+<path d='M183.59 167.914V167.844' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M181.598 167.844H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M183.59 167.914V167.98' fill='#399' clip-path='url(#clip4)'/>
+<path d='M183.59 167.914V167.98' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M185.582 167.98H181.597' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M242.258 168.984V168.918' fill='#399' clip-path='url(#clip4)'/>
+<path d='M242.258 168.984V168.918' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M240.266 168.918H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M242.258 168.984V169.055' fill='#399' clip-path='url(#clip4)'/>
+<path d='M242.258 168.984V169.055' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M244.25 169.055H240.265' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M300.926 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M298.933 84.164H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M300.926 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M298.933 84.164H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M359.598 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M357.606 84.164H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M359.598 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M357.606 84.164H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M418.266 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M416.274 84.164H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M418.266 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M416.274 84.164H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M476.934 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M474.942 84.164H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M476.934 84.164' fill='#399' clip-path='url(#clip4)'/>
+<path d='M474.942 84.164H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M187.199 251.93H190.438V175.562H187.199ZM245.871 251.93H249.106V176.168H245.871ZM304.539 251.93H307.777V92.551H304.539ZM363.207 251.93H366.445V126.105H363.207ZM421.875 251.93H425.113V109.461H421.875ZM480.547 251.93H483.785V175.227H480.547Z' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M187.199 251.93H190.438V175.562H187.199ZM245.871 251.93H249.106V176.168H245.871ZM304.539 251.93H307.777V92.551H304.539ZM363.207 251.93H366.445V126.105H363.207ZM421.875 251.93H425.113V109.461H421.875ZM480.547 251.93H483.785V175.227H480.547Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M188.82 175.562V175.43' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M188.82 175.562V175.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M186.828 175.43H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M188.82 175.562V175.695' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M188.82 175.562V175.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M190.813 175.696H186.828' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M247.488 176.168V175.965' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M247.488 176.168V175.965' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M245.496 175.965H249.481' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M247.488 176.168V176.367' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M247.488 176.168V176.367' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M249.481 176.368H245.496' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M306.156 92.551V74.433' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M306.156 92.551V74.433' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M304.164 74.434H308.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M306.156 92.551V110.672' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M306.156 92.551V110.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M308.149 110.672H304.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M364.828 126.105V123.824' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M364.828 126.105V123.824' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M362.836 123.825H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M364.828 126.105V128.387' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M364.828 126.105V128.387' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M366.82 128.387H362.832' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M423.496 109.461V109.262' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M423.496 109.461V109.262' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M421.504 109.262H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M423.496 109.461V109.664' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M423.496 109.461V109.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M425.488 109.664H421.504' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M482.164 175.227V171.805' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M482.164 175.227V171.805' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M480.172 171.804H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M482.164 175.227V178.648' fill='#d9b3b3' clip-path='url(#clip4)'/>
+<path d='M482.164 175.227V178.648' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M484.156 178.648H480.172' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<path d='M369.781 314.227H487.762V278.973H369.781Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip4)'/>
+<g transform='matrix(1 0 0 1 204.818 118.327)'>
+<use x='168.285' y='167.424' xlink:href='#g2-99'/>
+<use x='170.637' y='167.424' xlink:href='#g2-53'/>
+<use x='173.284' y='167.424' xlink:href='#g2-45'/>
+<use x='175.048' y='167.424' xlink:href='#g2-49'/>
+<use x='177.694' y='167.424' xlink:href='#g2-56'/>
+<use x='180.341' y='167.424' xlink:href='#g2-120'/>
+<use x='182.779' y='167.424' xlink:href='#g2-108'/>
+<use x='184.042' y='167.424' xlink:href='#g2-97'/>
+<use x='186.438' y='167.424' xlink:href='#g2-114'/>
+<use x='188.245' y='167.424' xlink:href='#g2-103'/>
+<use x='190.891' y='167.424' xlink:href='#g2-101'/>
+<use x='193.244' y='167.424' xlink:href='#g2-44'/>
+<use x='196.478' y='167.424' xlink:href='#g2-49'/>
+<use x='199.124' y='167.424' xlink:href='#g2-52'/>
+<use x='201.771' y='167.424' xlink:href='#g2-52'/>
+<use x='204.417' y='167.424' xlink:href='#g2-71'/>
+<use x='207.946' y='167.424' xlink:href='#g2-98'/>
+<use x='168.285' y='173.401' xlink:href='#g2-50'/>
+<use x='170.931' y='173.401' xlink:href='#g4-2'/>
+<use x='178.092' y='173.401' xlink:href='#g2-49'/>
+<use x='180.738' y='173.401' xlink:href='#g2-56'/>
+<use x='183.385' y='173.401' xlink:href='#g2-45'/>
+<use x='185.149' y='173.401' xlink:href='#g2-99'/>
+<use x='187.501' y='173.401' xlink:href='#g2-111'/>
+<use x='190.001' y='173.401' xlink:href='#g2-114'/>
+<use x='191.808' y='173.401' xlink:href='#g2-101'/>
+<use x='195.925' y='173.401' xlink:href='#g2-73'/>
+<use x='197.395' y='173.401' xlink:href='#g2-110'/>
+<use x='200.128' y='173.401' xlink:href='#g2-116'/>
+<use x='202.039' y='173.401' xlink:href='#g2-101'/>
+<use x='204.391' y='173.401' xlink:href='#g2-108'/>
+<use x='207.418' y='173.401' xlink:href='#g2-88'/>
+<use x='210.947' y='173.401' xlink:href='#g2-101'/>
+<use x='213.299' y='173.401' xlink:href='#g2-111'/>
+<use x='215.945' y='173.401' xlink:href='#g2-110'/>
+<use x='220.442' y='173.401' xlink:href='#g2-64'/>
+<use x='223.971' y='173.401' xlink:href='#g2-51'/>
+<use x='226.617' y='173.401' xlink:href='#g2-71'/>
+<use x='230.146' y='173.401' xlink:href='#g2-104'/>
+<use x='232.879' y='173.401' xlink:href='#g2-122'/>
+<use x='168.285' y='179.379' xlink:href='#g2-85'/>
+<use x='171.917' y='179.379' xlink:href='#g2-98'/>
+<use x='174.65' y='179.379' xlink:href='#g2-117'/>
+<use x='177.383' y='179.379' xlink:href='#g2-110'/>
+<use x='180.116' y='179.379' xlink:href='#g2-116'/>
+<use x='182.027' y='179.379' xlink:href='#g2-117'/>
+<use x='186.524' y='179.379' xlink:href='#g2-50'/>
+<use x='189.17' y='179.379' xlink:href='#g2-48'/>
+<use x='191.817' y='179.379' xlink:href='#g2-46'/>
+<use x='193.287' y='179.379' xlink:href='#g2-48'/>
+<use x='195.933' y='179.379' xlink:href='#g2-52'/>
+<use x='198.58' y='179.379' xlink:href='#g2-44'/>
+<use x='201.814' y='179.379' xlink:href='#g2-71'/>
+<use x='205.343' y='179.379' xlink:href='#g2-67'/>
+<use x='208.724' y='179.379' xlink:href='#g2-67'/>
+<use x='213.87' y='179.379' xlink:href='#g2-57'/>
+<use x='216.516' y='179.379' xlink:href='#g2-46'/>
+<use x='217.986' y='179.379' xlink:href='#g2-51'/>
+<use x='220.633' y='179.379' xlink:href='#g2-46'/>
+<use x='222.103' y='179.379' xlink:href='#g2-48'/>
+<use x='224.749' y='179.379' xlink:href='#g2-44'/>
+<use x='227.984' y='179.379' xlink:href='#g2-103'/>
+<use x='230.63' y='179.379' xlink:href='#g2-108'/>
+<use x='231.893' y='179.379' xlink:href='#g2-105'/>
+<use x='233.155' y='179.379' xlink:href='#g2-98'/>
+<use x='236.035' y='179.379' xlink:href='#g2-99'/>
+<use x='240.152' y='179.379' xlink:href='#g2-50'/>
+<use x='242.798' y='179.379' xlink:href='#g2-46'/>
+<use x='244.268' y='179.379' xlink:href='#g2-51'/>
+<use x='246.915' y='179.379' xlink:href='#g2-49'/>
+<use x='249.561' y='179.379' xlink:href='#g2-44'/>
+<use x='252.796' y='179.379' xlink:href='#g2-99'/>
+<use x='255.148' y='179.379' xlink:href='#g2-108'/>
+<use x='256.41' y='179.379' xlink:href='#g2-97'/>
+<use x='258.953' y='179.379' xlink:href='#g2-110'/>
+<use x='261.686' y='179.379' xlink:href='#g2-103'/>
+<use x='266.097' y='179.379' xlink:href='#g2-49'/>
+<use x='268.743' y='179.379' xlink:href='#g2-48'/>
+<use x='271.389' y='179.379' xlink:href='#g2-46'/>
+<use x='272.859' y='179.379' xlink:href='#g2-48'/>
+<use x='275.506' y='179.379' xlink:href='#g2-46'/>
+<use x='276.976' y='179.379' xlink:href='#g2-48'/>
+<use x='168.285' y='185.357' xlink:href='#g2-55'/>
+<use x='170.931' y='185.357' xlink:href='#g2-50'/>
+<use x='175.342' y='185.357' xlink:href='#g2-108'/>
+<use x='176.604' y='185.357' xlink:href='#g2-111'/>
+<use x='179.251' y='185.357' xlink:href='#g2-103'/>
+<use x='181.897' y='185.357' xlink:href='#g2-105'/>
+<use x='183.16' y='185.357' xlink:href='#g2-99'/>
+<use x='185.512' y='185.357' xlink:href='#g2-97'/>
+<use x='188.055' y='185.357' xlink:href='#g2-108'/>
+<use x='191.082' y='185.357' xlink:href='#g2-99'/>
+<use x='193.434' y='185.357' xlink:href='#g2-111'/>
+<use x='195.933' y='185.357' xlink:href='#g2-114'/>
+<use x='197.741' y='185.357' xlink:href='#g2-101'/>
+<use x='200.093' y='185.357' xlink:href='#g2-115'/>
+<use x='203.886' y='185.357' xlink:href='#g2-111'/>
+<use x='206.533' y='185.357' xlink:href='#g2-110'/>
+<use x='211.03' y='185.357' xlink:href='#g2-50'/>
+<use x='215.44' y='185.357' xlink:href='#g2-110'/>
+<use x='218.173' y='185.357' xlink:href='#g2-117'/>
+<use x='220.906' y='185.357' xlink:href='#g2-109'/>
+<use x='225.109' y='185.357' xlink:href='#g2-97'/>
+<use x='229.416' y='185.357' xlink:href='#g2-110'/>
+<use x='232.149' y='185.357' xlink:href='#g2-111'/>
+<use x='234.942' y='185.357' xlink:href='#g2-100'/>
+<use x='237.675' y='185.357' xlink:href='#g2-101'/>
+<use x='240.027' y='185.357' xlink:href='#g2-115'/>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-48'/>
+<use x='173.578' y='191.334' xlink:href='#g2-50'/>
+<use x='176.224' y='191.334' xlink:href='#g2-49'/>
+<use x='178.87' y='191.334' xlink:href='#g2-45'/>
+<use x='180.635' y='191.334' xlink:href='#g2-48'/>
+<use x='183.281' y='191.334' xlink:href='#g2-49'/>
+<use x='185.927' y='191.334' xlink:href='#g2-45'/>
+<use x='187.692' y='191.334' xlink:href='#g2-51'/>
+<use x='190.338' y='191.334' xlink:href='#g2-48'/>
+<use x='192.984' y='191.334' xlink:href='#g2-41'/>
+</g>
+<g transform='matrix(0 -1 1 0 -47.954 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 10.715 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 69.384 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 128.053 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 186.722 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 245.391 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -42.724 346.568)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 15.945 346.703)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 74.614 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 133.283 344.086)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 191.952 340.73)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 250.621 349.32)'>
+<use x='168.285' y='191.334' xlink:href='#g2-48'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-57'/>
+<use x='175.048' y='191.334' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -37.493 346.703)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.176 333.952)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 79.845 299.393)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-55'/>
+<use x='175.048' y='191.334' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 138.514 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-49'/>
+<use x='176.558' y='191.334' xlink:href='#g2-53'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-49'/>
+<use x='183.321' y='191.334' xlink:href='#g2-56'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 197.183 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-51'/>
+<use x='176.558' y='191.334' xlink:href='#g2-56'/>
+<use x='179.205' y='191.334' xlink:href='#g2-48'/>
+<use x='181.851' y='191.334' xlink:href='#g2-46'/>
+<use x='183.321' y='191.334' xlink:href='#g2-49'/>
+<use x='185.968' y='191.334' xlink:href='#g2-57'/>
+<use x='188.614' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 255.852 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-49'/>
+<use x='176.558' y='191.334' xlink:href='#g2-55'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-48'/>
+<use x='183.321' y='191.334' xlink:href='#g2-55'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -32.263 342.005)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.406 342.542)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.075 293.756)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-55'/>
+<use x='175.048' y='191.334' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 143.744 288.186)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-56'/>
+<use x='175.048' y='191.334' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.413 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-49'/>
+<use x='176.558' y='191.334' xlink:href='#g2-49'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-54'/>
+<use x='183.321' y='191.334' xlink:href='#g2-55'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 261.082 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-49'/>
+<use x='176.558' y='191.334' xlink:href='#g2-55'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-50'/>
+<use x='183.321' y='191.334' xlink:href='#g2-53'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -27.032 324.222)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-51'/>
+<use x='175.048' y='191.334' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.637 325.497)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-51'/>
+<use x='175.048' y='191.334' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 90.306 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-53'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-50'/>
+<use x='180.675' y='191.334' xlink:href='#g2-57'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 148.975 274.228)'>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 207.644 248.929)'>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-52'/>
+<use x='175.048' y='191.334' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 266.313 346.904)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -21.802 334.02)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.867 343.146)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.536 313.351)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-53'/>
+<use x='175.048' y='191.334' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 154.205 324.558)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-51'/>
+<use x='175.048' y='191.334' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 212.874 354.42)'>
+<use x='168.285' y='191.334' xlink:href='#g2-48'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-56'/>
+<use x='175.048' y='191.334' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 271.543 351.668)'>
+<use x='168.285' y='191.334' xlink:href='#g2-48'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-57'/>
+<use x='175.048' y='191.334' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 -16.571 343.012)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 42.098 341.133)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-48'/>
+<use x='175.048' y='191.334' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.767 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-55'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-50'/>
+<use x='180.675' y='191.334' xlink:href='#g2-53'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 159.436 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-51'/>
+<use x='176.558' y='191.334' xlink:href='#g2-54'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-54'/>
+<use x='183.321' y='191.334' xlink:href='#g2-53'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 218.105 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-51'/>
+<use x='176.558' y='191.334' xlink:href='#g2-56'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-53'/>
+<use x='183.321' y='191.334' xlink:href='#g2-51'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 276.774 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-49'/>
+<use x='176.558' y='191.334' xlink:href='#g2-50'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-56'/>
+<use x='183.321' y='191.334' xlink:href='#g2-50'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -11.341 316.908)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-52'/>
+<use x='175.048' y='191.334' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 47.328 338.247)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 105.997 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-55'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-49'/>
+<use x='180.675' y='191.334' xlink:href='#g2-50'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 164.666 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-55'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-50'/>
+<use x='180.675' y='191.334' xlink:href='#g2-53'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 223.335 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-53'/>
+<use x='176.558' y='191.334' xlink:href='#g2-55'/>
+<use x='179.205' y='191.334' xlink:href='#g2-46'/>
+<use x='180.675' y='191.334' xlink:href='#g2-52'/>
+<use x='183.321' y='191.334' xlink:href='#g2-53'/>
+<use x='185.968' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 282.004 351.668)'>
+<use x='168.285' y='191.334' xlink:href='#g2-48'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-57'/>
+<use x='175.048' y='191.334' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 -6.111 329.993)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-50'/>
+<use x='175.048' y='191.334' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 52.558 331.067)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-50'/>
+<use x='175.048' y='191.334' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 111.227 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-53'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-52'/>
+<use x='180.675' y='191.334' xlink:href='#g2-54'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 169.896 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-52'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-50'/>
+<use x='180.675' y='191.334' xlink:href='#g2-54'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 228.565 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-53'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-53'/>
+<use x='180.675' y='191.334' xlink:href='#g2-54'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 287.234 246.245)'>
+<use x='163.396' y='191.334' xlink:href='#g4-1'/>
+<use x='166.901' y='191.334' xlink:href='#g4-1'/>
+<use x='170.407' y='191.334' xlink:href='#g4-1'/>
+<use x='173.912' y='191.334' xlink:href='#g2-54'/>
+<use x='176.558' y='191.334' xlink:href='#g2-46'/>
+<use x='178.029' y='191.334' xlink:href='#g2-48'/>
+<use x='180.675' y='191.334' xlink:href='#g2-55'/>
+<use x='183.321' y='191.334' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -.88 337.643)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 57.789 338.247)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 116.458 254.633)'>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-51'/>
+<use x='175.048' y='191.334' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 175.127 288.186)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-56'/>
+<use x='175.048' y='191.334' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 233.796 271.544)'>
+<use x='168.285' y='191.334' xlink:href='#g2-50'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 292.465 337.308)'>
+<use x='168.285' y='191.334' xlink:href='#g2-49'/>
+<use x='170.931' y='191.334' xlink:href='#g2-46'/>
+<use x='172.401' y='191.334' xlink:href='#g2-49'/>
+<use x='175.048' y='191.334' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 -78.176 391.591)'>
+<use x='168.285' y='191.334' xlink:href='#g1-82'/>
+<use x='174.255' y='191.334' xlink:href='#g1-101'/>
+<use x='178.351' y='191.334' xlink:href='#g1-108'/>
+<use x='180.551' y='191.334' xlink:href='#g1-97'/>
+<use x='184.979' y='191.334' xlink:href='#g1-116'/>
+<use x='188.307' y='191.334' xlink:href='#g1-105'/>
+<use x='190.507' y='191.334' xlink:href='#g1-118'/>
+<use x='194.755' y='191.334' xlink:href='#g1-101'/>
+<use x='201.922' y='191.334' xlink:href='#g1-116'/>
+<use x='205.25' y='191.334' xlink:href='#g1-105'/>
+<use x='207.45' y='191.334' xlink:href='#g1-109'/>
+<use x='214.77' y='191.334' xlink:href='#g1-101'/>
+<use x='221.937' y='191.334' xlink:href='#g3-40'/>
+<use x='225.231' y='191.334' xlink:href='#g3-108'/>
+<use x='227.251' y='191.334' xlink:href='#g3-111'/>
+<use x='231.25' y='191.334' xlink:href='#g3-119'/>
+<use x='236.799' y='191.334' xlink:href='#g3-101'/>
+<use x='240.562' y='191.334' xlink:href='#g3-114'/>
+<use x='246.277' y='191.334' xlink:href='#g3-105'/>
+<use x='248.297' y='191.334' xlink:href='#g3-115'/>
+<use x='254.366' y='191.334' xlink:href='#g3-98'/>
+<use x='258.974' y='191.334' xlink:href='#g3-101'/>
+<use x='262.738' y='191.334' xlink:href='#g3-116'/>
+<use x='265.796' y='191.334' xlink:href='#g3-116'/>
+<use x='268.854' y='191.334' xlink:href='#g3-101'/>
+<use x='272.618' y='191.334' xlink:href='#g3-114'/>
+<use x='275.51' y='191.334' xlink:href='#g3-41'/>
+</g>
+<path d='M136.149 312.324H346.746V282.324H136.149Z' fill='#fff'/>
+<path d='M136.149 312.324H346.746V282.324H136.149Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' fill='#933'/>
+<path d='M139.336 292.816H142.324V284.844H139.336ZM145.313 292.816H148.301V286.836H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.354 114.479)'>
+<use x='191.843' y='178.327' xlink:href='#g3-120'/>
+<use x='195.745' y='178.327' xlink:href='#g3-109'/>
+<use x='202.47' y='178.327' xlink:href='#g3-105'/>
+<use x='204.49' y='178.327' xlink:href='#g3-58'/>
+<use x='206.843' y='178.327' xlink:href='#g0-57'/>
+<use x='210.548' y='178.327' xlink:href='#g0-52'/>
+</g>
+<path d='M177.086 292.816H180.074V284.844H177.086ZM183.063 292.816H186.055V286.836H183.063Z' fill='#bf8080'/>
+<path d='M177.086 292.816H180.074V284.844H177.086ZM183.063 292.816H186.055V286.836H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -38.403 114.479)'>
+<use x='233.123' y='178.327' xlink:href='#g3-109'/>
+<use x='239.848' y='178.327' xlink:href='#g3-105'/>
+<use x='241.869' y='178.327' xlink:href='#g3-58'/>
+<use x='244.221' y='178.327' xlink:href='#g0-56'/>
+<use x='247.926' y='178.327' xlink:href='#g0-57'/>
+</g>
+<path d='M221.895 292.816H224.883V284.844H221.895ZM227.875 292.816H230.863V286.836H227.875Z' fill='#8080bf'/>
+<path d='M221.895 292.816H224.883V284.844H221.895ZM227.875 292.816H230.863V286.836H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.441 114.036)'>
+<use x='277.134' y='178.327' xlink:href='#g3-116'/>
+<use x='280.192' y='178.327' xlink:href='#g3-99'/>
+<use x='283.956' y='178.327' xlink:href='#g3-58'/>
+<use x='286.308' y='178.327' xlink:href='#g0-53'/>
+<use x='290.013' y='178.327' xlink:href='#g0-56'/>
+</g>
+<path d='M265.109 292.816H268.098V284.844H265.109ZM271.086 292.816H274.074V286.836H271.086Z' fill='#ffb733'/>
+<path d='M265.109 292.816H268.098V284.844H265.109ZM271.086 292.816H274.074V286.836H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.04 114.479)'>
+<use x='319.615' y='178.327' xlink:href='#g3-106'/>
+<use x='321.871' y='178.327' xlink:href='#g3-101'/>
+<use x='325.634' y='178.327' xlink:href='#g3-58'/>
+<use x='327.987' y='178.327' xlink:href='#g0-53'/>
+<use x='331.691' y='178.327' xlink:href='#g0-56'/>
+</g>
+<path d='M306.859 292.816H309.848V284.844H306.859ZM312.836 292.816H315.824V286.836H312.836Z' fill='#bf80bf'/>
+<path d='M306.859 292.816H309.848V284.844H306.859ZM312.836 292.816H315.824V286.836H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -39.932 114.515)'>
+<use x='359.038' y='178.327' xlink:href='#g3-116'/>
+<use x='362.096' y='178.327' xlink:href='#g3-98'/>
+<use x='366.469' y='178.327' xlink:href='#g3-98'/>
+<use x='370.842' y='178.327' xlink:href='#g3-58'/>
+<use x='373.194' y='178.327' xlink:href='#g0-53'/>
+<use x='376.899' y='178.327' xlink:href='#g0-48'/>
+</g>
+<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' fill='#c96'/>
+<path d='M139.336 305.82H142.324V297.852H139.336ZM145.313 305.82H148.301V299.844H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.662 114.036)'>
+<use x='191.843' y='191.334' xlink:href='#g3-114'/>
+<use x='194.735' y='191.334' xlink:href='#g3-112'/>
+<use x='199.108' y='191.334' xlink:href='#g3-58'/>
+<use x='201.46' y='191.334' xlink:href='#g0-55'/>
+<use x='205.165' y='191.334' xlink:href='#g0-53'/>
+</g>
+<path d='M177.086 305.82H180.074V297.852H177.086ZM183.063 305.82H186.055V299.844H183.063Z' fill='#80bf80'/>
+<path d='M177.086 305.82H180.074V297.852H177.086ZM183.063 305.82H186.055V299.844H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.882 114.515)'>
+<use x='233.123' y='191.334' xlink:href='#g3-104'/>
+<use x='237.496' y='191.334' xlink:href='#g3-111'/>
+<use x='241.73' y='191.334' xlink:href='#g3-97'/>
+<use x='245.563' y='191.334' xlink:href='#g3-114'/>
+<use x='248.455' y='191.334' xlink:href='#g3-100'/>
+<use x='252.828' y='191.334' xlink:href='#g3-58'/>
+<use x='255.18' y='191.334' xlink:href='#g0-51'/>
+<use x='258.885' y='191.334' xlink:href='#g0-56'/>
+</g>
+<path d='M221.895 305.82H224.883V297.852H221.895ZM227.875 305.82H230.863V299.844H227.875Z' fill='#bfbf80'/>
+<path d='M221.895 305.82H224.883V297.852H221.895ZM227.875 305.82H230.863V299.844H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.084 114.515)'>
+<use x='277.134' y='191.334' xlink:href='#g3-109'/>
+<use x='283.859' y='191.334' xlink:href='#g3-101'/>
+<use x='287.622' y='191.334' xlink:href='#g3-115'/>
+<use x='290.869' y='191.334' xlink:href='#g3-104'/>
+<use x='295.241' y='191.334' xlink:href='#g3-58'/>
+<use x='297.593' y='191.334' xlink:href='#g0-51'/>
+<use x='301.298' y='191.334' xlink:href='#g0-54'/>
+</g>
+<path d='M265.109 305.82H268.098V297.852H265.109ZM271.086 305.82H274.074V299.844H271.086Z' fill='#399'/>
+<path d='M265.109 305.82H268.098V297.852H265.109ZM271.086 305.82H274.074V299.844H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -42.353 114.515)'>
+<use x='319.615' y='191.334' xlink:href='#g3-103'/>
+<use x='323.849' y='191.334' xlink:href='#g3-108'/>
+<use x='325.869' y='191.334' xlink:href='#g3-105'/>
+<use x='327.89' y='191.334' xlink:href='#g3-98'/>
+<use x='332.498' y='191.334' xlink:href='#g3-99'/>
+<use x='336.261' y='191.334' xlink:href='#g3-58'/>
+<use x='338.614' y='191.334' xlink:href='#g0-52'/>
+<use x='342.318' y='191.334' xlink:href='#g0-54'/>
+</g>
+<path d='M306.859 305.82H309.848V297.852H306.859ZM312.836 305.82H315.824V299.844H312.836Z' fill='#d9b3b3'/>
+<path d='M306.859 305.82H309.848V297.852H306.859ZM312.836 305.82H315.824V299.844H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.026 114.479)'>
+<use x='359.038' y='191.334' xlink:href='#g3-115'/>
+<use x='362.285' y='191.334' xlink:href='#g3-109'/>
+<use x='369.009' y='191.334' xlink:href='#g3-105'/>
+<use x='371.03' y='191.334' xlink:href='#g3-58'/>
+<use x='373.382' y='191.334' xlink:href='#g0-53'/>
+<use x='377.087' y='191.334' xlink:href='#g0-57'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.628pt' height='207.789pt' viewBox='52.934 54.993 381.628 207.789'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip1'>
+<path d='M82.148 246.637H434.164V78.871H82.148Z'/>
+</clipPath>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-114' d='M1.462-1.91C1.462-2.851 2.197-3.425 3.013-3.434V-4.08C2.367-4.071 1.775-3.748 1.408-3.219V-4.035H.744V0H1.462V-1.91Z'/>
+<path id='g1-115' d='M3.165-3.847C2.609-4.098 2.197-4.133 1.829-4.133C1.623-4.133 .305-4.133 .305-2.95C.305-2.52 .565-2.251 .664-2.152C1.004-1.856 1.237-1.811 1.847-1.695C2.134-1.641 2.645-1.542 2.645-1.085C2.645-.502 1.919-.502 1.802-.502C1.273-.502 .762-.681 .377-.95L.26-.296C.798-.009 1.345 .099 1.802 .099C2.385 .099 3.318-.09 3.318-1.157C3.318-1.47 3.192-1.784 2.878-2.053C2.573-2.313 2.304-2.367 1.748-2.475C1.426-2.537 .977-2.618 .977-3.04C.977-3.569 1.614-3.569 1.748-3.569C2.403-3.569 2.789-3.362 3.049-3.219L3.165-3.847Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+</defs>
+<g id='page1'>
+<path d='M140.82 255.492V246.637M199.488 255.492V246.637M258.156 255.492V246.637M316.824 255.492V246.637M375.496 255.492V246.637M140.82 70.016V78.871M199.488 70.016V78.871M258.156 70.016V78.871M316.824 70.016V78.871M375.496 70.016V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M111.484 250.887V246.637M170.152 250.887V246.637M228.824 250.887V246.637M287.492 250.887V246.637M346.16 250.887V246.637M404.828 250.887V246.637M111.484 74.617V78.871M170.152 74.617V78.871M228.824 74.617V78.871M287.492 74.617V78.871M346.16 74.617V78.871M404.828 74.617V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 246.637H86.402M82.148 213.082H86.402M82.148 179.531H86.402M82.148 145.977H86.402M82.148 112.426H86.402M82.148 78.871H86.402M434.164 246.637H429.91M434.164 213.082H429.91M434.164 179.531H429.91M434.164 145.977H429.91M434.164 112.426H429.91M434.164 78.871H429.91' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 246.637V78.871H434.164V246.637H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -11.54 34.954)'>
+<use x='114.487' y='226.079' xlink:href='#g3-99'/>
+<use x='118.25' y='226.079' xlink:href='#g3-102'/>
+<use x='120.838' y='226.079' xlink:href='#g3-114'/>
+<use x='123.73' y='226.079' xlink:href='#g3-97'/>
+<use x='127.798' y='226.079' xlink:href='#g3-99'/>
+</g>
+<g transform='matrix(1 0 0 1 45.565 34.954)'>
+<use x='114.487' y='226.079' xlink:href='#g3-108'/>
+<use x='116.507' y='226.079' xlink:href='#g3-101'/>
+<use x='120.271' y='226.079' xlink:href='#g3-97'/>
+<use x='124.339' y='226.079' xlink:href='#g3-110'/>
+<use x='128.711' y='226.079' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 106.188 34.954)'>
+<use x='114.487' y='226.079' xlink:href='#g3-114'/>
+<use x='117.379' y='226.079' xlink:href='#g3-101'/>
+<use x='121.142' y='226.079' xlink:href='#g3-100'/>
+<use x='125.515' y='226.079' xlink:href='#g3-105'/>
+<use x='127.535' y='226.079' xlink:href='#g3-115'/>
+</g>
+<g transform='matrix(1 0 0 1 159.716 34.954)'>
+<use x='114.487' y='226.079' xlink:href='#g3-108'/>
+<use x='116.507' y='226.079' xlink:href='#g3-97'/>
+<use x='120.34' y='226.079' xlink:href='#g3-114'/>
+<use x='123.232' y='226.079' xlink:href='#g3-115'/>
+<use x='126.478' y='226.079' xlink:href='#g3-111'/>
+<use x='130.712' y='226.079' xlink:href='#g3-110'/>
+<use x='135.085' y='226.079' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 215.596 34.954)'>
+<use x='114.487' y='226.079' xlink:href='#g3-109'/>
+<use x='121.211' y='226.079' xlink:href='#g3-115'/>
+<use x='124.458' y='226.079' xlink:href='#g3-116'/>
+<use x='127.516' y='226.079' xlink:href='#g3-114'/>
+<use x='130.408' y='226.079' xlink:href='#g3-101'/>
+<use x='134.171' y='226.079' xlink:href='#g3-115'/>
+<use x='137.418' y='226.079' xlink:href='#g3-115'/>
+<use x='140.664' y='226.079' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 277.158 34.954)'>
+<use x='114.487' y='226.079' xlink:href='#g3-114'/>
+<use x='117.379' y='226.079' xlink:href='#g3-112'/>
+<use x='121.751' y='226.079' xlink:href='#g3-116'/>
+<use x='124.809' y='226.079' xlink:href='#g3-101'/>
+<use x='128.573' y='226.079' xlink:href='#g3-115'/>
+<use x='131.819' y='226.079' xlink:href='#g3-116'/>
+<use x='134.877' y='226.079' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 22.192)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -11.361)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -44.915)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -78.468)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -112.021)'>
+<use x='114.487' y='226.079' xlink:href='#g2-50'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -145.574)'>
+<use x='114.487' y='226.079' xlink:href='#g2-50'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-120'/>
+</g>
+<path d='M82.148 179.531H434.164' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M86.328 246.637H89.566V179.531H86.328ZM144.996 246.637H148.234V179.531H144.996ZM203.668 246.637H206.902V179.531H203.668ZM262.336 246.637H265.574V179.531H262.336ZM321.004 246.637H324.242V179.531H321.004ZM379.672 246.637H382.91V179.531H379.672Z' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M86.328 246.637H89.566V179.531H86.328ZM144.996 246.637H148.234V179.531H144.996ZM203.668 246.637H206.902V179.531H203.668ZM262.336 246.637H265.574V179.531H262.336ZM321.004 246.637H324.242V179.531H321.004ZM379.672 246.637H382.91V179.531H379.672Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M87.949 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M85.953 179.531H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M87.949 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M85.953 179.531H89.938' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M146.617 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M144.625 179.531H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M146.617 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M144.625 179.531H148.609' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M205.285 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M203.293 179.531H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M205.285 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M203.293 179.531H207.277' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M263.953 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M261.961 179.531H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M263.953 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M261.961 179.531H265.945' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M322.625 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M320.629 179.531H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M322.625 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M320.629 179.531H324.617' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M381.293 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M379.301 179.531H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M381.293 179.531' fill='#fff' clip-path='url(#clip1)'/>
+<path d='M379.301 179.531H383.285' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M91.559 246.637H94.797V180.336H91.559ZM150.227 246.637H153.465V177.449H150.227ZM208.899 246.637H212.133V179.598H208.899ZM267.567 246.637H270.805V186.441H267.567ZM326.234 246.637H329.473V78.871H326.234ZM384.902 246.637H388.141V162.754H384.902Z' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M91.559 246.637H94.797V180.336H91.559ZM150.227 246.637H153.465V177.449H150.227ZM208.899 246.637H212.133V179.598H208.899ZM267.567 246.637H270.805V186.441H267.567ZM326.234 246.637H329.473V78.871H326.234ZM384.902 246.637H388.141V162.754H384.902Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M93.18 180.336' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M91.184 180.336H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M93.18 180.336' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M91.184 180.336H95.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M151.848 177.449' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M149.855 177.45H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M151.848 177.449' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M149.855 177.45H153.84' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M210.516 179.598' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M208.523 179.598H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M210.516 179.598' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M208.523 179.598H212.507' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M269.184 186.441' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M267.191 186.442H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M269.184 186.441' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M267.191 186.442H271.175' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M327.856 78.871' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M325.859 78.871H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M327.856 78.871' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M325.859 78.871H329.847' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M386.524 162.754' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M384.531 162.753H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M386.524 162.754' fill='#f0e0f0' clip-path='url(#clip1)'/>
+<path d='M384.531 162.753H388.515' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M96.789 246.637H100.027V87.73H96.789ZM155.457 246.637H158.695V189.262H155.457ZM214.129 246.637H217.363V161.074H214.129ZM272.797 246.637H276.035V221.738H272.797ZM331.465 246.637H334.703V194.965H331.465ZM390.133 246.637H393.371V212.949H390.133Z' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M96.789 246.637H100.027V87.73H96.789ZM155.457 246.637H158.695V189.262H155.457ZM214.129 246.637H217.363V161.074H214.129ZM272.797 246.637H276.035V221.738H272.797ZM331.465 246.637H334.703V194.965H331.465ZM390.133 246.637H393.371V212.949H390.133Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M98.41 87.73' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M96.414 87.73H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M98.41 87.73' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M96.414 87.73H100.399' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M157.078 189.262' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M155.086 189.261H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M157.078 189.262' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M155.086 189.261H159.071' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M215.746 161.074' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M213.754 161.074H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M215.746 161.074' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M213.754 161.074H217.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M274.414 221.738' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M272.422 221.739H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M274.414 221.738' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M272.422 221.739H276.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M333.086 194.965' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M331.09 194.964H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M333.086 194.965' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M331.09 194.964H335.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M391.754 212.949' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M389.762 212.949H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M391.754 212.949' fill='#e1c2e1' clip-path='url(#clip1)'/>
+<path d='M389.762 212.949H393.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M102.02 246.637H105.258V152.219H102.02ZM160.688 246.637H163.926V180.535H160.688ZM219.359 246.637H222.594V174.766H219.359ZM278.027 246.637H281.266V206.172H278.027ZM336.695 246.637H339.934V192.953H336.695ZM395.363 246.637H398.602V183.223H395.363Z' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M102.02 246.637H105.258V152.219H102.02ZM160.688 246.637H163.926V180.535H160.688ZM219.359 246.637H222.594V174.766H219.359ZM278.027 246.637H281.266V206.172H278.027ZM336.695 246.637H339.934V192.953H336.695ZM395.363 246.637H398.602V183.223H395.363Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M103.641 152.219' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M101.644 152.219H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M103.641 152.219' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M101.644 152.219H105.629' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M162.309 180.535' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M160.316 180.536H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M162.309 180.535' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M160.316 180.536H164.301' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M220.977 174.766' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M218.984 174.765H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M220.977 174.766' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M218.984 174.765H222.969' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M279.645 206.172' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M277.652 206.172H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M279.645 206.172' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M277.652 206.172H281.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M338.317 192.953' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M336.32 192.953H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M338.317 192.953' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M336.32 192.953H340.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M396.984 183.223' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M394.992 183.223H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M396.984 183.223' fill='#d1a3d1' clip-path='url(#clip1)'/>
+<path d='M394.992 183.223H398.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M107.25 246.637H110.488V154.5H107.25ZM165.918 246.637H169.156V169.734H165.918ZM224.59 246.637H227.824V134.703H224.59ZM283.258 246.637H286.496V192.281H283.258ZM341.926 246.637H345.164V197.313H341.926ZM400.594 246.637H403.832V195.703H400.594Z' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M107.25 246.637H110.488V154.5H107.25ZM165.918 246.637H169.156V169.734H165.918ZM224.59 246.637H227.824V134.703H224.59ZM283.258 246.637H286.496V192.281H283.258ZM341.926 246.637H345.164V197.313H341.926ZM400.594 246.637H403.832V195.703H400.594Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M108.871 154.5' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M106.875 154.5H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M108.871 154.5' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M106.875 154.5H110.86' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M167.539 169.734' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M165.547 169.734H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M167.539 169.734' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M165.547 169.734H169.532' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M226.207 134.703' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M224.215 134.703H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M226.207 134.703' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M224.215 134.703H228.2' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M284.875 192.281' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M282.883 192.281H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M284.875 192.281' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M282.883 192.281H286.868' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M343.547 197.313' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M341.551 197.312H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M343.547 197.313' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M341.551 197.312H345.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M402.215 195.703' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M400.223 195.704H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M402.215 195.703' fill='#c285c2' clip-path='url(#clip1)'/>
+<path d='M400.223 195.704H404.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M112.481 246.637H115.719V167.922H112.481ZM171.149 246.637H174.387V172.148H171.149ZM229.82 246.637H233.055V160.07H229.82ZM288.488 246.637H291.727V196.305H288.488ZM347.156 246.637H350.395V78.871H347.156ZM405.824 246.637H409.063V146.379H405.824Z' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M112.481 246.637H115.719V167.922H112.481ZM171.149 246.637H174.387V172.148H171.149ZM229.82 246.637H233.055V160.07H229.82ZM288.488 246.637H291.727V196.305H288.488ZM347.156 246.637H350.395V78.871H347.156ZM405.824 246.637H409.063V146.379H405.824Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M114.098 167.922' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M112.105 167.922H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M114.098 167.922' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M112.105 167.922H116.09' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M172.77 172.148' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M170.777 172.148H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M172.77 172.148' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M170.777 172.148H174.762' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M231.438 160.07' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M229.445 160.07H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M231.438 160.07' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M229.445 160.07H233.43' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M290.106 196.305' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M288.113 196.304H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M290.106 196.305' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M288.113 196.304H292.098' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M348.777 78.871' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M346.781 78.871H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M348.777 78.871' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M346.781 78.871H350.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M407.445 146.379' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M405.453 146.379H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M407.445 146.379' fill='#b366b3' clip-path='url(#clip1)'/>
+<path d='M405.453 146.379H409.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M117.711 246.637H120.949V153.223H117.711ZM176.379 246.637H179.617V169.465H176.379ZM235.051 246.637H238.285V174.633H235.051ZM293.719 246.637H296.957V215.766H293.719ZM352.387 246.637H355.625V78.871H352.387ZM411.055 246.637H414.293V191.742H411.055Z' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M117.711 246.637H120.949V153.223H117.711ZM176.379 246.637H179.617V169.465H176.379ZM235.051 246.637H238.285V174.633H235.051ZM293.719 246.637H296.957V215.766H293.719ZM352.387 246.637H355.625V78.871H352.387ZM411.055 246.637H414.293V191.742H411.055Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M119.328 153.223' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M117.336 153.222H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M119.328 153.223' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M117.336 153.222H121.321' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M178 169.465' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M176.008 169.465H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M178 169.465' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M176.008 169.465H179.993' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M236.668 174.633' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M234.676 174.633H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M236.668 174.633' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M234.676 174.633H238.661' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M295.336 215.766' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M293.344 215.765H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M295.336 215.766' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M293.344 215.765H297.329' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M354.008 78.871' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M352.012 78.871H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M354.008 78.871' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M352.012 78.871H356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M412.676 191.742' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M410.684 191.742H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M412.676 191.742' fill='#a447a4' clip-path='url(#clip1)'/>
+<path d='M410.684 191.742H414.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M122.941 246.637H126.18V177.047H122.941ZM181.609 246.637H184.848V178.457H181.609ZM240.281 246.637H243.516V178.992H240.281ZM298.949 246.637H302.188V221.875H298.949ZM357.617 246.637H360.856V78.871H357.617ZM416.285 246.637H419.524V157.25H416.285Z' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M122.941 246.637H126.18V177.047H122.941ZM181.609 246.637H184.848V178.457H181.609ZM240.281 246.637H243.516V178.992H240.281ZM298.949 246.637H302.188V221.875H298.949ZM357.617 246.637H360.856V78.871H357.617ZM416.285 246.637H419.524V157.25H416.285Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M124.559 177.047' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M122.566 177.047H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M124.559 177.047' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M122.566 177.047H126.551' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M183.231 178.457' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M181.238 178.457H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M183.231 178.457' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M181.238 178.457H185.223' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M241.899 178.992' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M239.906 178.992H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M241.899 178.992' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M239.906 178.992H243.891' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M300.567 221.875' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M298.574 221.875H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M300.567 221.875' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M298.574 221.875H302.559' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M359.238 78.871' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M357.242 78.871H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M359.238 78.871' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M357.242 78.871H361.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M417.906 157.25' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M415.914 157.25H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M417.906 157.25' fill='#942994' clip-path='url(#clip1)'/>
+<path d='M415.914 157.25H419.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M128.172 246.637H131.41V182.414H128.172ZM186.84 246.637H190.078V170.805H186.84ZM245.512 246.637H248.746V179.059H245.512ZM304.18 246.637H307.418V207.176H304.18ZM362.848 246.637H366.086V153.629H362.848ZM421.516 246.637H424.754V207.313H421.516Z' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M128.172 246.637H131.41V182.414H128.172ZM186.84 246.637H190.078V170.805H186.84ZM245.512 246.637H248.746V179.059H245.512ZM304.18 246.637H307.418V207.176H304.18ZM362.848 246.637H366.086V153.629H362.848ZM421.516 246.637H424.754V207.313H421.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M129.789 182.414' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M127.797 182.415H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M129.789 182.414' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M127.797 182.415H131.782' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M188.461 170.805' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M186.469 170.805H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M188.461 170.805' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M186.469 170.805H190.454' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M247.129 179.059' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M245.137 179.058H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M247.129 179.059' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M245.137 179.058H249.122' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M305.797 207.176' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M303.804 207.176H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M305.797 207.176' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M303.804 207.176H307.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M364.469 153.629' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M362.473 153.629H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M364.469 153.629' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M362.473 153.629H366.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M423.137 207.313' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M421.144 207.313H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M423.137 207.313' fill='#850a85' clip-path='url(#clip1)'/>
+<path d='M421.144 207.313H425.128' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M133.402 246.637H136.641V178.055H133.402ZM192.07 246.637H195.309V164.969H192.07ZM250.742 246.637H253.977V175.703H250.742ZM309.41 246.637H312.649V184.027H309.41ZM368.078 246.637H371.317V99.809H368.078ZM426.746 246.637H429.984V143.023H426.746Z' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M133.402 246.637H136.641V178.055H133.402ZM192.07 246.637H195.309V164.969H192.07ZM250.742 246.637H253.977V175.703H250.742ZM309.41 246.637H312.649V184.027H309.41ZM368.078 246.637H371.317V99.809H368.078ZM426.746 246.637H429.984V143.023H426.746Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M135.02 178.055' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M133.027 178.055H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M135.02 178.055' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M133.027 178.055H137.012' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M193.692 164.969' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M191.699 164.969H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M193.692 164.969' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M191.699 164.969H195.684' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M252.359 175.703' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M250.367 175.703H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M252.359 175.703' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M250.367 175.703H254.352' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M311.027 184.027' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M309.035 184.027H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M311.027 184.027' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M309.035 184.027H313.02' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M369.699 99.809' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M367.703 99.809H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M369.699 99.809' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M367.703 99.809H371.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M428.367 143.023' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M426.375 143.023H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M428.367 143.023' fill='#760076' clip-path='url(#clip1)'/>
+<path d='M426.375 143.023H430.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<g transform='matrix(0 -1 1 0 -136.497 287.813)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -77.828 287.813)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.159 287.813)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 39.51 287.813)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 98.179 287.813)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 156.848 287.813)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -131.267 288.618)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-57'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -72.598 285.733)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 -13.929 287.88)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 44.74 294.725)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-57'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 103.409 187.154)'>
+<use x='109.598' y='226.079' xlink:href='#g4-1'/>
+<use x='113.103' y='226.079' xlink:href='#g4-1'/>
+<use x='116.608' y='226.079' xlink:href='#g4-1'/>
+<use x='120.114' y='226.079' xlink:href='#g2-51'/>
+<use x='122.76' y='226.079' xlink:href='#g2-46'/>
+<use x='124.23' y='226.079' xlink:href='#g2-49'/>
+<use x='126.877' y='226.079' xlink:href='#g2-55'/>
+<use x='129.523' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 162.078 271.036)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-50'/>
+<use x='121.25' y='226.079' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -126.036 196.012)'>
+<use x='114.487' y='226.079' xlink:href='#g2-50'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 -67.367 297.543)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-56'/>
+<use x='121.25' y='226.079' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -8.698 269.359)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-50'/>
+<use x='121.25' y='226.079' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 49.971 330.023)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 108.64 303.247)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-55'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 167.309 321.232)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -120.806 260.501)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-52'/>
+<use x='121.25' y='226.079' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 -62.137 288.819)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-57'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -3.468 283.048)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 55.201 314.454)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-54'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 113.87 301.234)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-56'/>
+<use x='121.25' y='226.079' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 172.539 291.504)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-57'/>
+<use x='121.25' y='226.079' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 -115.575 262.782)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 -56.906 278.015)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-49'/>
+<use x='121.25' y='226.079' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 1.763 242.986)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-54'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 60.432 300.563)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-56'/>
+<use x='121.25' y='226.079' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 119.101 305.596)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-55'/>
+<use x='121.25' y='226.079' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 177.77 303.985)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-55'/>
+<use x='121.25' y='226.079' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -110.345 276.204)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-49'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 -51.676 280.431)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-49'/>
+<use x='121.25' y='226.079' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 6.993 268.352)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-50'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 65.662 304.589)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-55'/>
+<use x='121.25' y='226.079' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 124.331 187.154)'>
+<use x='109.598' y='226.079' xlink:href='#g4-1'/>
+<use x='113.103' y='226.079' xlink:href='#g4-1'/>
+<use x='116.608' y='226.079' xlink:href='#g4-1'/>
+<use x='120.114' y='226.079' xlink:href='#g2-53'/>
+<use x='122.76' y='226.079' xlink:href='#g2-46'/>
+<use x='124.23' y='226.079' xlink:href='#g2-51'/>
+<use x='126.877' y='226.079' xlink:href='#g2-50'/>
+<use x='129.523' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 183 254.663)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-52'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -105.114 261.507)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -46.445 277.747)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-49'/>
+<use x='121.25' y='226.079' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 12.224 282.914)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 70.893 324.05)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-52'/>
+<use x='121.25' y='226.079' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 129.562 187.154)'>
+<use x='109.598' y='226.079' xlink:href='#g4-1'/>
+<use x='113.103' y='226.079' xlink:href='#g4-1'/>
+<use x='116.608' y='226.079' xlink:href='#g4-1'/>
+<use x='120.114' y='226.079' xlink:href='#g2-50'/>
+<use x='122.76' y='226.079' xlink:href='#g2-46'/>
+<use x='124.23' y='226.079' xlink:href='#g2-56'/>
+<use x='126.877' y='226.079' xlink:href='#g2-53'/>
+<use x='129.523' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 188.231 300.026)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-56'/>
+<use x='121.25' y='226.079' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -99.884 285.33)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 -41.215 286.739)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 17.454 287.276)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 76.123 330.157)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 134.792 187.154)'>
+<use x='109.598' y='226.079' xlink:href='#g4-1'/>
+<use x='113.103' y='226.079' xlink:href='#g4-1'/>
+<use x='116.608' y='226.079' xlink:href='#g4-1'/>
+<use x='120.114' y='226.079' xlink:href='#g2-52'/>
+<use x='122.76' y='226.079' xlink:href='#g2-46'/>
+<use x='124.23' y='226.079' xlink:href='#g2-50'/>
+<use x='126.877' y='226.079' xlink:href='#g2-51'/>
+<use x='129.523' y='226.079' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 193.461 265.534)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 -94.654 290.698)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-57'/>
+<use x='121.25' y='226.079' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.985 279.089)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-49'/>
+<use x='121.25' y='226.079' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 22.684 287.343)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 81.353 315.461)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 140.022 261.91)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-51'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 198.691 315.595)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -89.423 286.337)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -30.754 273.251)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-50'/>
+<use x='121.25' y='226.079' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 27.915 283.988)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-48'/>
+<use x='121.25' y='226.079' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 86.584 292.309)'>
+<use x='114.487' y='226.079' xlink:href='#g2-48'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-57'/>
+<use x='121.25' y='226.079' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 145.253 208.091)'>
+<use x='114.487' y='226.079' xlink:href='#g2-50'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-49'/>
+<use x='121.25' y='226.079' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 203.922 251.307)'>
+<use x='114.487' y='226.079' xlink:href='#g2-49'/>
+<use x='117.133' y='226.079' xlink:href='#g2-46'/>
+<use x='118.603' y='226.079' xlink:href='#g2-53'/>
+<use x='121.25' y='226.079' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 -166.719 329.135)'>
+<use x='114.487' y='226.079' xlink:href='#g1-82'/>
+<use x='120.457' y='226.079' xlink:href='#g1-101'/>
+<use x='124.553' y='226.079' xlink:href='#g1-108'/>
+<use x='126.753' y='226.079' xlink:href='#g1-97'/>
+<use x='131.181' y='226.079' xlink:href='#g1-116'/>
+<use x='134.509' y='226.079' xlink:href='#g1-105'/>
+<use x='136.709' y='226.079' xlink:href='#g1-118'/>
+<use x='140.957' y='226.079' xlink:href='#g1-101'/>
+<use x='148.124' y='226.079' xlink:href='#g1-114'/>
+<use x='151.272' y='226.079' xlink:href='#g1-115'/>
+<use x='154.805' y='226.079' xlink:href='#g1-115'/>
+<use x='161.409' y='226.079' xlink:href='#g3-40'/>
+<use x='164.702' y='226.079' xlink:href='#g3-108'/>
+<use x='166.722' y='226.079' xlink:href='#g3-111'/>
+<use x='170.721' y='226.079' xlink:href='#g3-119'/>
+<use x='176.27' y='226.079' xlink:href='#g3-101'/>
+<use x='180.034' y='226.079' xlink:href='#g3-114'/>
+<use x='185.749' y='226.079' xlink:href='#g3-105'/>
+<use x='187.769' y='226.079' xlink:href='#g3-115'/>
+<use x='193.838' y='226.079' xlink:href='#g3-98'/>
+<use x='198.446' y='226.079' xlink:href='#g3-101'/>
+<use x='202.209' y='226.079' xlink:href='#g3-116'/>
+<use x='205.267' y='226.079' xlink:href='#g3-116'/>
+<use x='208.325' y='226.079' xlink:href='#g3-101'/>
+<use x='212.089' y='226.079' xlink:href='#g3-114'/>
+<use x='214.981' y='226.079' xlink:href='#g3-41'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='381.627pt' height='254.34pt' viewBox='106.732 54.992 381.627 254.34'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip2'>
+<path d='M135.949 246.637H487.961V78.871H135.949Z'/>
+</clipPath>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-114' d='M1.462-1.91C1.462-2.851 2.197-3.425 3.013-3.434V-4.08C2.367-4.071 1.775-3.748 1.408-3.219V-4.035H.744V0H1.462V-1.91Z'/>
+<path id='g1-115' d='M3.165-3.847C2.609-4.098 2.197-4.133 1.829-4.133C1.623-4.133 .305-4.133 .305-2.95C.305-2.52 .565-2.251 .664-2.152C1.004-1.856 1.237-1.811 1.847-1.695C2.134-1.641 2.645-1.542 2.645-1.085C2.645-.502 1.919-.502 1.802-.502C1.273-.502 .762-.681 .377-.95L.26-.296C.798-.009 1.345 .099 1.802 .099C2.385 .099 3.318-.09 3.318-1.157C3.318-1.47 3.192-1.784 2.878-2.053C2.573-2.313 2.304-2.367 1.748-2.475C1.426-2.537 .977-2.618 .977-3.04C.977-3.569 1.614-3.569 1.748-3.569C2.403-3.569 2.789-3.362 3.049-3.219L3.165-3.847Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/>
+<use id='g3-49' xlink:href='#g0-49' transform='scale(1.143)'/>
+<use id='g3-54' xlink:href='#g0-54' transform='scale(1.143)'/>
+<use id='g3-56' xlink:href='#g0-56' transform='scale(1.143)'/>
+<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-103' xlink:href='#g0-103' transform='scale(1.143)'/>
+<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-112' xlink:href='#g0-112' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/>
+<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/>
+<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/>
+<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/>
+<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/>
+<path id='g0-73' d='M1.381-4.84H.676V0H1.381V-4.84Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-85' d='M4.4-4.84H3.794V-1.625C3.794-.69 3.166-.265 2.566-.265S1.381-.697 1.381-1.618V-4.84H.676V-1.632C.676-.607 1.555 .146 2.559 .146C3.557 .146 4.4-.614 4.4-1.632V-4.84Z'/>
+<path id='g0-88' d='M2.755-2.552L4.519-4.84H3.759L2.413-3.055L1.039-4.84H.209L2.071-2.552L.105 0H.865L2.413-2.099L3.996 0H4.826L2.755-2.552Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/>
+<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-117' d='M3.243-3.096H2.636V-1.074C2.636-.516 2.162-.342 1.757-.342C1.241-.342 1.186-.481 1.186-.802V-3.096H.579V-.76C.579-.139 .851 .07 1.339 .07C1.625 .07 2.239 .014 2.657-.321V0H3.243V-3.096Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<path id='g4-2' d='M4.13-2.481C4.184-2.535 4.204-2.57 4.204-2.615C4.204-2.69 4.139-2.755 4.065-2.755C4.01-2.755 3.985-2.73 3.93-2.675L2.7-1.445L1.465-2.68C1.41-2.735 1.375-2.755 1.33-2.755C1.255-2.755 1.191-2.69 1.191-2.615C1.191-2.56 1.215-2.535 1.27-2.481L2.501-1.245L1.27-.01C1.215 .045 1.191 .07 1.191 .125C1.191 .199 1.255 .264 1.33 .264C1.385 .264 1.41 .239 1.46 .189L2.695-1.046L3.97 .229C3.995 .249 4.03 .264 4.065 .264C4.139 .264 4.204 .199 4.204 .125C4.204 .095 4.194 .075 4.184 .05C4.164 .02 3.238-.892 2.894-1.245L4.13-2.481Z'/>
+<use id='g2-41' xlink:href='#g0-41' transform='scale(.714)'/>
+<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/>
+<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/>
+<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/>
+<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/>
+<use id='g2-73' xlink:href='#g0-73' transform='scale(.714)'/>
+<use id='g2-85' xlink:href='#g0-85' transform='scale(.714)'/>
+<use id='g2-88' xlink:href='#g0-88' transform='scale(.714)'/>
+<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/>
+<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/>
+<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/>
+<use id='g2-100' xlink:href='#g0-100' transform='scale(.714)'/>
+<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/>
+<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/>
+<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/>
+<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/>
+<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/>
+<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/>
+<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/>
+<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/>
+<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/>
+<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/>
+<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/>
+<use id='g2-117' xlink:href='#g0-117' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/>
+</defs>
+<g id='page2'>
+<path d='M194.617 255.492V246.637M253.285 255.492V246.637M311.953 255.492V246.637M370.625 255.492V246.637M429.293 255.492V246.637M194.617 70.016V78.871M253.285 70.016V78.871M311.953 70.016V78.871M370.625 70.016V78.871M429.293 70.016V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M165.281 250.887V246.637M223.953 250.887V246.637M282.621 250.887V246.637M341.289 250.887V246.637M399.957 250.887V246.637M458.629 250.887V246.637M165.281 74.617V78.871M223.953 74.617V78.871M282.621 74.617V78.871M341.289 74.617V78.871M399.957 74.617V78.871M458.629 74.617V78.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M135.949 246.637H140.199M135.949 213.082H140.199M135.949 179.531H140.199M135.949 145.976H140.199M135.949 112.426H140.199M135.949 78.871H140.199M487.961 246.637H483.711M487.961 213.082H483.711M487.961 179.531H483.711M487.961 145.976H483.711M487.961 112.426H483.711M487.961 78.871H483.711' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M135.949 246.637V78.871H487.961V246.637H135.949Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -21.265 74.992)'>
+<use x='168.285' y='186.041' xlink:href='#g3-97'/>
+<use x='172.353' y='186.041' xlink:href='#g3-108'/>
+<use x='174.373' y='186.041' xlink:href='#g3-108'/>
+<use x='176.393' y='186.041' xlink:href='#g3-111'/>
+<use x='180.863' y='186.041' xlink:href='#g3-99'/>
+<use x='184.627' y='186.041' xlink:href='#g3-45'/>
+<use x='187.449' y='186.041' xlink:href='#g3-116'/>
+<use x='190.507' y='186.041' xlink:href='#g3-101'/>
+<use x='194.271' y='186.041' xlink:href='#g3-115'/>
+<use x='197.517' y='186.041' xlink:href='#g3-116'/>
+<use x='200.575' y='186.041' xlink:href='#g3-49'/>
+</g>
+<g transform='matrix(1 0 0 1 36.532 74.992)'>
+<use x='168.285' y='186.041' xlink:href='#g3-97'/>
+<use x='172.353' y='186.041' xlink:href='#g3-108'/>
+<use x='174.373' y='186.041' xlink:href='#g3-108'/>
+<use x='176.393' y='186.041' xlink:href='#g3-111'/>
+<use x='180.863' y='186.041' xlink:href='#g3-99'/>
+<use x='184.627' y='186.041' xlink:href='#g3-45'/>
+<use x='187.449' y='186.041' xlink:href='#g3-116'/>
+<use x='190.507' y='186.041' xlink:href='#g3-101'/>
+<use x='194.271' y='186.041' xlink:href='#g3-115'/>
+<use x='197.517' y='186.041' xlink:href='#g3-116'/>
+<use x='200.575' y='186.041' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 94.98 74.992)'>
+<use x='168.285' y='186.041' xlink:href='#g3-115'/>
+<use x='171.531' y='186.041' xlink:href='#g3-104'/>
+<use x='175.904' y='186.041' xlink:href='#g3-54'/>
+<use x='180.138' y='186.041' xlink:href='#g3-98'/>
+<use x='184.746' y='186.041' xlink:href='#g3-101'/>
+<use x='188.509' y='186.041' xlink:href='#g3-110'/>
+<use x='192.882' y='186.041' xlink:href='#g3-99'/>
+<use x='196.646' y='186.041' xlink:href='#g3-104'/>
+<use x='201.018' y='186.041' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 153.649 74.992)'>
+<use x='168.285' y='186.041' xlink:href='#g3-115'/>
+<use x='171.531' y='186.041' xlink:href='#g3-104'/>
+<use x='175.904' y='186.041' xlink:href='#g3-56'/>
+<use x='180.138' y='186.041' xlink:href='#g3-98'/>
+<use x='184.746' y='186.041' xlink:href='#g3-101'/>
+<use x='188.509' y='186.041' xlink:href='#g3-110'/>
+<use x='192.882' y='186.041' xlink:href='#g3-99'/>
+<use x='196.646' y='186.041' xlink:href='#g3-104'/>
+<use x='201.018' y='186.041' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 207.225 74.992)'>
+<use x='168.285' y='186.041' xlink:href='#g3-120'/>
+<use x='172.187' y='186.041' xlink:href='#g3-109'/>
+<use x='178.912' y='186.041' xlink:href='#g3-97'/>
+<use x='182.98' y='186.041' xlink:href='#g3-108'/>
+<use x='185' y='186.041' xlink:href='#g3-108'/>
+<use x='187.02' y='186.041' xlink:href='#g3-111'/>
+<use x='191.49' y='186.041' xlink:href='#g3-99'/>
+<use x='195.254' y='186.041' xlink:href='#g3-45'/>
+<use x='198.076' y='186.041' xlink:href='#g3-116'/>
+<use x='201.134' y='186.041' xlink:href='#g3-101'/>
+<use x='204.898' y='186.041' xlink:href='#g3-115'/>
+<use x='208.144' y='186.041' xlink:href='#g3-116'/>
+<use x='211.202' y='186.041' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 263.494 74.992)'>
+<use x='168.285' y='186.041' xlink:href='#g3-99'/>
+<use x='172.049' y='186.041' xlink:href='#g3-97'/>
+<use x='176.117' y='186.041' xlink:href='#g3-99'/>
+<use x='179.88' y='186.041' xlink:href='#g3-104'/>
+<use x='184.253' y='186.041' xlink:href='#g3-101'/>
+<use x='188.017' y='186.041' xlink:href='#g3-45'/>
+<use x='190.839' y='186.041' xlink:href='#g3-115'/>
+<use x='194.086' y='186.041' xlink:href='#g3-99'/>
+<use x='197.849' y='186.041' xlink:href='#g3-114'/>
+<use x='200.741' y='186.041' xlink:href='#g3-97'/>
+<use x='204.81' y='186.041' xlink:href='#g3-116'/>
+<use x='207.868' y='186.041' xlink:href='#g3-99'/>
+<use x='211.631' y='186.041' xlink:href='#g3-104'/>
+<use x='216.004' y='186.041' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 62.23)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.677)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -4.876)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -38.43)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -71.983)'>
+<use x='168.285' y='186.041' xlink:href='#g2-50'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -105.536)'>
+<use x='168.285' y='186.041' xlink:href='#g2-50'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-120'/>
+</g>
+<path d='M135.949 179.531H487.961' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M140.125 246.637H143.363V179.531H140.125ZM198.797 246.637H202.035V179.531H198.797ZM257.465 246.637H260.703V179.531H257.465ZM316.133 246.637H319.371V179.531H316.133ZM374.801 246.637H378.039V179.531H374.801ZM433.473 246.637H436.711V179.531H433.473Z' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M140.125 246.637H143.363V179.531H140.125ZM198.797 246.637H202.035V179.531H198.797ZM257.465 246.637H260.703V179.531H257.465ZM316.133 246.637H319.371V179.531H316.133ZM374.801 246.637H378.039V179.531H374.801ZM433.473 246.637H436.711V179.531H433.473Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M141.746 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M139.754 179.531H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M141.746 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M139.754 179.531H143.738' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M200.414 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M198.422 179.531H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M200.414 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M198.422 179.531H202.406' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M259.082 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M257.09 179.531H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M259.082 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M257.09 179.531H261.078' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M317.754 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M315.762 179.531H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M317.754 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M315.762 179.531H319.746' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M376.422 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M374.43 179.531H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M376.422 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M374.43 179.531H378.414' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M435.09 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M433.098 179.531H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M435.09 179.531' fill='#fff' clip-path='url(#clip2)'/>
+<path d='M433.098 179.531H437.082' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M145.356 246.637H148.594V180.066H145.356ZM204.028 246.637H207.266V179.195H204.028ZM262.695 246.637H265.934V181.008H262.695ZM321.363 246.637H324.602V179.934H321.363ZM380.031 246.637H383.27V175.637H380.031ZM438.703 246.637H441.942V179.664H438.703Z' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M145.356 246.637H148.594V180.066H145.356ZM204.028 246.637H207.266V179.195H204.028ZM262.695 246.637H265.934V181.008H262.695ZM321.363 246.637H324.602V179.934H321.363ZM380.031 246.637H383.27V175.637H380.031ZM438.703 246.637H441.942V179.664H438.703Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M146.977 180.066' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M144.984 180.067H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M146.977 180.066' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M144.984 180.067H148.968' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M205.645 179.195' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M203.652 179.196H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M205.645 179.195' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M203.652 179.196H207.636' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M264.313 181.008' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M262.32 181.007H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M264.313 181.008' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M262.32 181.007H266.308' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M322.984 179.934' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M320.992 179.934H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M322.984 179.934' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M320.992 179.934H324.976' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M381.652 175.637' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M379.66 175.637H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M381.652 175.637' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M379.66 175.637H383.644' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M440.32 179.664' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M438.328 179.664H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M440.32 179.664' fill='#f0e0f0' clip-path='url(#clip2)'/>
+<path d='M438.328 179.664H442.312' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M150.586 246.637H153.824V163.426H150.586ZM209.258 246.637H212.496V159.062H209.258ZM267.926 246.637H271.164V184.027H267.926ZM326.594 246.637H329.832V203.687H326.594ZM385.262 246.637H388.5V219.859H385.262ZM443.934 246.637H447.172V139.734H443.934Z' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M150.586 246.637H153.824V163.426H150.586ZM209.258 246.637H212.496V159.062H209.258ZM267.926 246.637H271.164V184.027H267.926ZM326.594 246.637H329.832V203.687H326.594ZM385.262 246.637H388.5V219.859H385.262ZM443.934 246.637H447.172V139.734H443.934Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M152.207 163.426' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M150.215 163.426H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M152.207 163.426' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M150.215 163.426H154.199' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M210.875 159.062' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M208.883 159.063H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M210.875 159.062' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M208.883 159.063H212.867' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M269.543 184.027' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M267.551 184.027H271.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M269.543 184.027' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M267.551 184.027H271.539' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M328.215 203.687' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M326.223 203.687H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M328.215 203.687' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M326.223 203.687H330.207' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M386.883 219.859' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M384.891 219.86H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M386.883 219.859' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M384.891 219.86H388.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M445.551 139.734' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M443.559 139.734H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M445.551 139.734' fill='#e1c2e1' clip-path='url(#clip2)'/>
+<path d='M443.559 139.734H447.543' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M155.817 246.637H159.055V183.824H155.817ZM214.488 246.637H217.727V176.109H214.488ZM273.156 246.637H276.395V181.344H273.156ZM331.824 246.637H335.063V193.086H331.824ZM390.492 246.637H393.731V195.164H390.492ZM449.164 246.637H452.402V144.566H449.164Z' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M155.817 246.637H159.055V183.824H155.817ZM214.488 246.637H217.727V176.109H214.488ZM273.156 246.637H276.395V181.344H273.156ZM331.824 246.637H335.063V193.086H331.824ZM390.492 246.637H393.731V195.164H390.492ZM449.164 246.637H452.402V144.566H449.164Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M157.438 183.824' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M155.445 183.824H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M157.438 183.824' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M155.445 183.824H159.429' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M216.106 176.109' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M214.113 176.11H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M216.106 176.109' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M214.113 176.11H218.097' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M274.774 181.344' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M272.781 181.344H276.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M274.774 181.344' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M272.781 181.344H276.769' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M333.445 193.086' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M331.453 193.085H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M333.445 193.086' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M331.453 193.085H335.437' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M392.113 195.164' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M390.121 195.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M392.113 195.164' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M390.121 195.164H394.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M450.781 144.566' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M448.789 144.567H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M450.781 144.566' fill='#d1a3d1' clip-path='url(#clip2)'/>
+<path d='M448.789 144.567H452.773' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M161.047 246.637H164.285V178.926H161.047ZM219.719 246.637H222.957V169.934H219.719ZM278.387 246.637H281.625V176.644H278.387ZM337.055 246.637H340.293V195.234H337.055ZM395.723 246.637H398.961V182.078H395.723ZM454.395 246.637H457.633V177.652H454.395Z' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M161.047 246.637H164.285V178.926H161.047ZM219.719 246.637H222.957V169.934H219.719ZM278.387 246.637H281.625V176.644H278.387ZM337.055 246.637H340.293V195.234H337.055ZM395.723 246.637H398.961V182.078H395.723ZM454.395 246.637H457.633V177.652H454.395Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M162.668 178.926' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M160.676 178.926H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M162.668 178.926' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M160.676 178.926H164.66' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M221.336 169.934' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M219.344 169.934H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M221.336 169.934' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M219.344 169.934H223.328' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M280.004 176.644' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M278.012 176.644H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M280.004 176.644' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M278.012 176.644H282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M338.676 195.234' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M336.684 195.235H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M338.676 195.234' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M336.684 195.235H340.668' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M397.344 182.078' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M395.352 182.078H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M397.344 182.078' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M395.352 182.078H399.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M456.012 177.652' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M454.02 177.652H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M456.012 177.652' fill='#c285c2' clip-path='url(#clip2)'/>
+<path d='M454.02 177.652H458.004' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M166.278 246.637H169.516V179.598H166.278ZM224.949 246.637H228.188V144.098H224.949ZM283.617 246.637H286.856V172.82H283.617ZM342.285 246.637H345.524V155.91H342.285ZM400.953 246.637H404.192V172.484H400.953ZM459.625 246.637H462.863V172.016H459.625Z' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M166.278 246.637H169.516V179.598H166.278ZM224.949 246.637H228.188V144.098H224.949ZM283.617 246.637H286.856V172.82H283.617ZM342.285 246.637H345.524V155.91H342.285ZM400.953 246.637H404.192V172.484H400.953ZM459.625 246.637H462.863V172.016H459.625Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M167.899 179.598' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M165.906 179.598H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M167.899 179.598' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M165.906 179.598H169.89' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M226.567 144.098' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M224.574 144.098H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M226.567 144.098' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M224.574 144.098H228.558' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M285.234 172.82' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M283.242 172.82H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M285.234 172.82' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M283.242 172.82H287.23' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M343.906 155.91' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M341.914 155.91H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M343.906 155.91' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M341.914 155.91H345.898' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M402.574 172.484' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M400.582 172.484H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M402.574 172.484' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M400.582 172.484H404.566' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M461.242 172.016' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M459.25 172.015H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M461.242 172.016' fill='#b366b3' clip-path='url(#clip2)'/>
+<path d='M459.25 172.015H463.234' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M171.508 246.637H174.746V177.113H171.508ZM230.18 246.637H233.414V179.465H230.18ZM288.848 246.637H292.086V166.176H288.848ZM347.516 246.637H350.754V160.605H347.516ZM406.184 246.637H409.422V78.871H406.184ZM464.856 246.637H468.094V189.797H464.856Z' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M171.508 246.637H174.746V177.113H171.508ZM230.18 246.637H233.414V179.465H230.18ZM288.848 246.637H292.086V166.176H288.848ZM347.516 246.637H350.754V160.605H347.516ZM406.184 246.637H409.422V78.871H406.184ZM464.856 246.637H468.094V189.797H464.856Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M173.129 177.113' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M171.137 177.113H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M173.129 177.113' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M171.137 177.113H175.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M231.797 179.465' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M229.805 179.465H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M231.797 179.465' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M229.805 179.465H233.789' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M290.465 166.176' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M288.473 166.176H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M290.465 166.176' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M288.473 166.176H292.461' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M349.137 160.605' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M347.145 160.605H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M349.137 160.605' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M347.145 160.605H351.129' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M407.805 78.871' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M405.813 78.871H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M407.805 78.871' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M405.813 78.871H409.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M466.473 189.797' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M464.481 189.797H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M466.473 189.797' fill='#a447a4' clip-path='url(#clip2)'/>
+<path d='M464.481 189.797H468.465' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M176.738 246.637H179.977V167.383H176.738ZM235.41 246.637H238.645V78.871H235.41ZM294.078 246.637H297.317V143.09H294.078ZM352.746 246.637H355.984V166.711H352.746ZM411.414 246.637H414.652V219.391H411.414ZM470.086 246.637H473.324V160.336H470.086Z' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M176.738 246.637H179.977V167.383H176.738ZM235.41 246.637H238.645V78.871H235.41ZM294.078 246.637H297.317V143.09H294.078ZM352.746 246.637H355.984V166.711H352.746ZM411.414 246.637H414.652V219.391H411.414ZM470.086 246.637H473.324V160.336H470.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M178.36 167.383' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M176.367 167.383H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M178.36 167.383' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M176.367 167.383H180.351' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M237.027 78.871' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M235.035 78.871H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M237.027 78.871' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M235.035 78.871H239.019' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M295.695 143.09' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M293.703 143.089H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M295.695 143.09' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M293.703 143.089H297.691' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M354.367 166.711' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M352.375 166.711H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M354.367 166.711' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M352.375 166.711H356.359' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M413.035 219.391' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M411.043 219.391H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M413.035 219.391' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M411.043 219.391H415.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M471.703 160.336' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M469.711 160.336H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M471.703 160.336' fill='#942994' clip-path='url(#clip2)'/>
+<path d='M469.711 160.336H473.695' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M181.969 246.637H185.207V176.711H181.969ZM240.641 246.637H243.875V169.062H240.641ZM299.309 246.637H302.547V151.547H299.309ZM357.977 246.637H361.215V113.43H357.977ZM416.645 246.637H419.883V188.387H416.645ZM475.317 246.637H478.555V190.402H475.317Z' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M181.969 246.637H185.207V176.711H181.969ZM240.641 246.637H243.875V169.062H240.641ZM299.309 246.637H302.547V151.547H299.309ZM357.977 246.637H361.215V113.43H357.977ZM416.645 246.637H419.883V188.387H416.645ZM475.317 246.637H478.555V190.402H475.317Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M183.59 176.711' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M181.598 176.711H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M183.59 176.711' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M181.598 176.711H185.583' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M242.258 169.062' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M240.266 169.062H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M242.258 169.062' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M240.266 169.062H244.25' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M300.926 151.547' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M298.933 151.547H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M300.926 151.547' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M298.933 151.547H302.921' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M359.598 113.43' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M357.606 113.43H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M359.598 113.43' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M357.606 113.43H361.59' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M418.266 188.387' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M416.274 188.387H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M418.266 188.387' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M416.274 188.387H420.258' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M476.934 190.402' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M474.942 190.402H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M476.934 190.402' fill='#850a85' clip-path='url(#clip2)'/>
+<path d='M474.942 190.402H478.926' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M187.199 246.637H190.438V179.465H187.199ZM245.871 246.637H249.106V113.094H245.871ZM304.539 246.637H307.777V164.094H304.539ZM363.207 246.637H366.445V156.578H363.207ZM421.875 246.637H425.113V174.496H421.875ZM480.547 246.637H483.785V176.375H480.547Z' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M187.199 246.637H190.438V179.465H187.199ZM245.871 246.637H249.106V113.094H245.871ZM304.539 246.637H307.777V164.094H304.539ZM363.207 246.637H366.445V156.578H363.207ZM421.875 246.637H425.113V174.496H421.875ZM480.547 246.637H483.785V176.375H480.547Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M188.82 179.465' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M186.828 179.465H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M188.82 179.465' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M186.828 179.465H190.813' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M247.488 113.094' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M245.496 113.094H249.481' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M247.488 113.094' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M245.496 113.094H249.481' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M306.156 164.094' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M304.164 164.094H308.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M306.156 164.094' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M304.164 164.094H308.152' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M364.828 156.578' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M362.836 156.578H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M364.828 156.578' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M362.836 156.578H366.82' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M423.496 174.496' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M421.504 174.496H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M423.496 174.496' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M421.504 174.496H425.488' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M482.164 176.375' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M480.172 176.375H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M482.164 176.375' fill='#760076' clip-path='url(#clip2)'/>
+<path d='M480.172 176.375H484.156' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<path d='M369.781 308.934H487.762V273.68H369.781Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip2)'/>
+<g transform='matrix(1 0 0 1 204.818 118.327)'>
+<use x='168.285' y='162.131' xlink:href='#g2-99'/>
+<use x='170.637' y='162.131' xlink:href='#g2-53'/>
+<use x='173.284' y='162.131' xlink:href='#g2-45'/>
+<use x='175.048' y='162.131' xlink:href='#g2-49'/>
+<use x='177.694' y='162.131' xlink:href='#g2-56'/>
+<use x='180.341' y='162.131' xlink:href='#g2-120'/>
+<use x='182.779' y='162.131' xlink:href='#g2-108'/>
+<use x='184.042' y='162.131' xlink:href='#g2-97'/>
+<use x='186.438' y='162.131' xlink:href='#g2-114'/>
+<use x='188.245' y='162.131' xlink:href='#g2-103'/>
+<use x='190.891' y='162.131' xlink:href='#g2-101'/>
+<use x='193.244' y='162.131' xlink:href='#g2-44'/>
+<use x='196.478' y='162.131' xlink:href='#g2-49'/>
+<use x='199.124' y='162.131' xlink:href='#g2-52'/>
+<use x='201.771' y='162.131' xlink:href='#g2-52'/>
+<use x='204.417' y='162.131' xlink:href='#g2-71'/>
+<use x='207.946' y='162.131' xlink:href='#g2-98'/>
+<use x='168.285' y='168.109' xlink:href='#g2-50'/>
+<use x='170.931' y='168.109' xlink:href='#g4-2'/>
+<use x='178.092' y='168.109' xlink:href='#g2-49'/>
+<use x='180.738' y='168.109' xlink:href='#g2-56'/>
+<use x='183.385' y='168.109' xlink:href='#g2-45'/>
+<use x='185.149' y='168.109' xlink:href='#g2-99'/>
+<use x='187.501' y='168.109' xlink:href='#g2-111'/>
+<use x='190.001' y='168.109' xlink:href='#g2-114'/>
+<use x='191.808' y='168.109' xlink:href='#g2-101'/>
+<use x='195.925' y='168.109' xlink:href='#g2-73'/>
+<use x='197.395' y='168.109' xlink:href='#g2-110'/>
+<use x='200.128' y='168.109' xlink:href='#g2-116'/>
+<use x='202.039' y='168.109' xlink:href='#g2-101'/>
+<use x='204.391' y='168.109' xlink:href='#g2-108'/>
+<use x='207.418' y='168.109' xlink:href='#g2-88'/>
+<use x='210.947' y='168.109' xlink:href='#g2-101'/>
+<use x='213.299' y='168.109' xlink:href='#g2-111'/>
+<use x='215.945' y='168.109' xlink:href='#g2-110'/>
+<use x='220.442' y='168.109' xlink:href='#g2-64'/>
+<use x='223.971' y='168.109' xlink:href='#g2-51'/>
+<use x='226.617' y='168.109' xlink:href='#g2-71'/>
+<use x='230.146' y='168.109' xlink:href='#g2-104'/>
+<use x='232.879' y='168.109' xlink:href='#g2-122'/>
+<use x='168.285' y='174.086' xlink:href='#g2-85'/>
+<use x='171.917' y='174.086' xlink:href='#g2-98'/>
+<use x='174.65' y='174.086' xlink:href='#g2-117'/>
+<use x='177.383' y='174.086' xlink:href='#g2-110'/>
+<use x='180.116' y='174.086' xlink:href='#g2-116'/>
+<use x='182.027' y='174.086' xlink:href='#g2-117'/>
+<use x='186.524' y='174.086' xlink:href='#g2-50'/>
+<use x='189.17' y='174.086' xlink:href='#g2-48'/>
+<use x='191.817' y='174.086' xlink:href='#g2-46'/>
+<use x='193.287' y='174.086' xlink:href='#g2-48'/>
+<use x='195.933' y='174.086' xlink:href='#g2-52'/>
+<use x='198.58' y='174.086' xlink:href='#g2-44'/>
+<use x='201.814' y='174.086' xlink:href='#g2-71'/>
+<use x='205.343' y='174.086' xlink:href='#g2-67'/>
+<use x='208.724' y='174.086' xlink:href='#g2-67'/>
+<use x='213.87' y='174.086' xlink:href='#g2-57'/>
+<use x='216.516' y='174.086' xlink:href='#g2-46'/>
+<use x='217.986' y='174.086' xlink:href='#g2-51'/>
+<use x='220.633' y='174.086' xlink:href='#g2-46'/>
+<use x='222.103' y='174.086' xlink:href='#g2-48'/>
+<use x='224.749' y='174.086' xlink:href='#g2-44'/>
+<use x='227.984' y='174.086' xlink:href='#g2-103'/>
+<use x='230.63' y='174.086' xlink:href='#g2-108'/>
+<use x='231.893' y='174.086' xlink:href='#g2-105'/>
+<use x='233.155' y='174.086' xlink:href='#g2-98'/>
+<use x='236.035' y='174.086' xlink:href='#g2-99'/>
+<use x='240.152' y='174.086' xlink:href='#g2-50'/>
+<use x='242.798' y='174.086' xlink:href='#g2-46'/>
+<use x='244.268' y='174.086' xlink:href='#g2-51'/>
+<use x='246.915' y='174.086' xlink:href='#g2-49'/>
+<use x='249.561' y='174.086' xlink:href='#g2-44'/>
+<use x='252.796' y='174.086' xlink:href='#g2-99'/>
+<use x='255.148' y='174.086' xlink:href='#g2-108'/>
+<use x='256.41' y='174.086' xlink:href='#g2-97'/>
+<use x='258.953' y='174.086' xlink:href='#g2-110'/>
+<use x='261.686' y='174.086' xlink:href='#g2-103'/>
+<use x='266.097' y='174.086' xlink:href='#g2-49'/>
+<use x='268.743' y='174.086' xlink:href='#g2-48'/>
+<use x='271.389' y='174.086' xlink:href='#g2-46'/>
+<use x='272.859' y='174.086' xlink:href='#g2-48'/>
+<use x='275.506' y='174.086' xlink:href='#g2-46'/>
+<use x='276.976' y='174.086' xlink:href='#g2-48'/>
+<use x='168.285' y='180.064' xlink:href='#g2-55'/>
+<use x='170.931' y='180.064' xlink:href='#g2-50'/>
+<use x='175.342' y='180.064' xlink:href='#g2-108'/>
+<use x='176.604' y='180.064' xlink:href='#g2-111'/>
+<use x='179.251' y='180.064' xlink:href='#g2-103'/>
+<use x='181.897' y='180.064' xlink:href='#g2-105'/>
+<use x='183.16' y='180.064' xlink:href='#g2-99'/>
+<use x='185.512' y='180.064' xlink:href='#g2-97'/>
+<use x='188.055' y='180.064' xlink:href='#g2-108'/>
+<use x='191.082' y='180.064' xlink:href='#g2-99'/>
+<use x='193.434' y='180.064' xlink:href='#g2-111'/>
+<use x='195.933' y='180.064' xlink:href='#g2-114'/>
+<use x='197.741' y='180.064' xlink:href='#g2-101'/>
+<use x='200.093' y='180.064' xlink:href='#g2-115'/>
+<use x='203.886' y='180.064' xlink:href='#g2-111'/>
+<use x='206.533' y='180.064' xlink:href='#g2-110'/>
+<use x='211.03' y='180.064' xlink:href='#g2-50'/>
+<use x='215.44' y='180.064' xlink:href='#g2-110'/>
+<use x='218.173' y='180.064' xlink:href='#g2-117'/>
+<use x='220.906' y='180.064' xlink:href='#g2-109'/>
+<use x='225.109' y='180.064' xlink:href='#g2-97'/>
+<use x='229.416' y='180.064' xlink:href='#g2-110'/>
+<use x='232.149' y='180.064' xlink:href='#g2-111'/>
+<use x='234.942' y='180.064' xlink:href='#g2-100'/>
+<use x='237.675' y='180.064' xlink:href='#g2-101'/>
+<use x='240.027' y='180.064' xlink:href='#g2-115'/>
+<use x='168.285' y='186.041' xlink:href='#g2-50'/>
+<use x='170.931' y='186.041' xlink:href='#g2-48'/>
+<use x='173.578' y='186.041' xlink:href='#g2-50'/>
+<use x='176.224' y='186.041' xlink:href='#g2-49'/>
+<use x='178.87' y='186.041' xlink:href='#g2-45'/>
+<use x='180.635' y='186.041' xlink:href='#g2-48'/>
+<use x='183.281' y='186.041' xlink:href='#g2-49'/>
+<use x='185.927' y='186.041' xlink:href='#g2-45'/>
+<use x='187.692' y='186.041' xlink:href='#g2-51'/>
+<use x='190.338' y='186.041' xlink:href='#g2-48'/>
+<use x='192.984' y='186.041' xlink:href='#g2-41'/>
+</g>
+<g transform='matrix(0 -1 1 0 -42.661 341.611)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 16.008 341.611)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 74.677 341.611)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 133.346 341.611)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 192.015 341.611)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 250.684 341.611)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -37.431 342.148)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.238 341.275)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 79.907 343.087)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 138.576 342.014)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 197.245 337.719)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 255.914 341.745)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -32.2 325.505)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-50'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.469 321.144)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-51'/>
+<use x='175.048' y='186.041' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 85.138 346.107)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 143.807 365.769)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-54'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 202.476 381.942)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-52'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 261.145 301.817)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -26.97 345.906)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.699 338.189)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 90.368 343.423)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 149.037 355.166)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-56'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 207.706 357.247)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-55'/>
+<use x='175.048' y='186.041' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 266.375 306.649)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 -21.739 341.007)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 36.93 332.015)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 95.599 338.725)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 154.268 357.314)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-55'/>
+<use x='175.048' y='186.041' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 212.937 344.161)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 271.606 339.732)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 -16.509 341.678)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 42.16 306.179)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 100.829 334.9)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 159.498 317.99)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-51'/>
+<use x='175.048' y='186.041' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 218.167 334.565)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 276.836 334.095)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 -11.278 339.195)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 47.391 341.544)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 106.06 328.257)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-50'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 164.729 322.687)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-50'/>
+<use x='175.048' y='186.041' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 223.398 240.952)'>
+<use x='163.396' y='186.041' xlink:href='#g4-1'/>
+<use x='166.901' y='186.041' xlink:href='#g4-1'/>
+<use x='170.407' y='186.041' xlink:href='#g4-1'/>
+<use x='173.912' y='186.041' xlink:href='#g2-57'/>
+<use x='176.558' y='186.041' xlink:href='#g2-46'/>
+<use x='178.029' y='186.041' xlink:href='#g2-54'/>
+<use x='180.675' y='186.041' xlink:href='#g2-56'/>
+<use x='183.321' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 282.067 351.878)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-56'/>
+<use x='175.048' y='186.041' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -6.048 329.465)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 52.621 240.952)'>
+<use x='163.396' y='186.041' xlink:href='#g4-1'/>
+<use x='166.901' y='186.041' xlink:href='#g4-1'/>
+<use x='170.407' y='186.041' xlink:href='#g4-1'/>
+<use x='173.912' y='186.041' xlink:href='#g2-50'/>
+<use x='176.558' y='186.041' xlink:href='#g2-46'/>
+<use x='178.029' y='186.041' xlink:href='#g2-54'/>
+<use x='180.675' y='186.041' xlink:href='#g2-50'/>
+<use x='183.321' y='186.041' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 111.29 305.172)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-53'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 169.959 328.794)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 228.628 381.472)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-52'/>
+<use x='175.048' y='186.041' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 287.297 322.419)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-50'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 -.818 338.793)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 57.851 331.142)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-49'/>
+<use x='175.048' y='186.041' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 116.52 313.628)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-52'/>
+<use x='175.048' y='186.041' xlink:href='#g2-50'/>
+</g>
+<g transform='matrix(0 -1 1 0 175.189 275.511)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 233.858 350.469)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-56'/>
+<use x='175.048' y='186.041' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 292.527 352.482)'>
+<use x='168.285' y='186.041' xlink:href='#g2-48'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-56'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 4.413 341.544)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 63.082 275.176)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-57'/>
+<use x='175.048' y='186.041' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 121.751 326.177)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-50'/>
+<use x='175.048' y='186.041' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 180.42 318.661)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-51'/>
+<use x='175.048' y='186.041' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 239.089 336.578)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 297.758 338.457)'>
+<use x='168.285' y='186.041' xlink:href='#g2-49'/>
+<use x='170.931' y='186.041' xlink:href='#g2-46'/>
+<use x='172.401' y='186.041' xlink:href='#g2-48'/>
+<use x='175.048' y='186.041' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -72.883 382.933)'>
+<use x='168.285' y='186.041' xlink:href='#g1-82'/>
+<use x='174.255' y='186.041' xlink:href='#g1-101'/>
+<use x='178.351' y='186.041' xlink:href='#g1-108'/>
+<use x='180.551' y='186.041' xlink:href='#g1-97'/>
+<use x='184.979' y='186.041' xlink:href='#g1-116'/>
+<use x='188.307' y='186.041' xlink:href='#g1-105'/>
+<use x='190.507' y='186.041' xlink:href='#g1-118'/>
+<use x='194.755' y='186.041' xlink:href='#g1-101'/>
+<use x='201.922' y='186.041' xlink:href='#g1-114'/>
+<use x='205.07' y='186.041' xlink:href='#g1-115'/>
+<use x='208.603' y='186.041' xlink:href='#g1-115'/>
+<use x='215.207' y='186.041' xlink:href='#g3-40'/>
+<use x='218.5' y='186.041' xlink:href='#g3-108'/>
+<use x='220.521' y='186.041' xlink:href='#g3-111'/>
+<use x='224.52' y='186.041' xlink:href='#g3-119'/>
+<use x='230.068' y='186.041' xlink:href='#g3-101'/>
+<use x='233.832' y='186.041' xlink:href='#g3-114'/>
+<use x='239.547' y='186.041' xlink:href='#g3-105'/>
+<use x='241.567' y='186.041' xlink:href='#g3-115'/>
+<use x='247.636' y='186.041' xlink:href='#g3-98'/>
+<use x='252.244' y='186.041' xlink:href='#g3-101'/>
+<use x='256.008' y='186.041' xlink:href='#g3-116'/>
+<use x='259.066' y='186.041' xlink:href='#g3-116'/>
+<use x='262.124' y='186.041' xlink:href='#g3-101'/>
+<use x='265.887' y='186.041' xlink:href='#g3-114'/>
+<use x='268.779' y='186.041' xlink:href='#g3-41'/>
+</g>
+<path d='M136.149 307.031H346.746V277.031H136.149Z' fill='#fff'/>
+<path d='M136.149 307.031H346.746V277.031H136.149Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<path d='M139.336 287.523H142.324V279.551H139.336ZM145.313 287.523H148.301V281.543H145.313Z' fill='#fff'/>
+<path d='M139.336 287.523H142.324V279.551H139.336ZM145.313 287.523H148.301V281.543H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.354 114.479)'>
+<use x='191.843' y='173.035' xlink:href='#g3-120'/>
+<use x='195.745' y='173.035' xlink:href='#g3-109'/>
+<use x='202.47' y='173.035' xlink:href='#g3-105'/>
+<use x='204.49' y='173.035' xlink:href='#g3-58'/>
+<use x='206.843' y='173.035' xlink:href='#g0-54'/>
+<use x='210.548' y='173.035' xlink:href='#g0-56'/>
+</g>
+<path d='M177.086 287.523H180.074V279.551H177.086ZM183.063 287.523H186.055V281.543H183.063Z' fill='#f0e0f0'/>
+<path d='M177.086 287.523H180.074V279.551H177.086ZM183.063 287.523H186.055V281.543H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -38.403 114.479)'>
+<use x='233.123' y='173.035' xlink:href='#g3-109'/>
+<use x='239.848' y='173.035' xlink:href='#g3-105'/>
+<use x='241.869' y='173.035' xlink:href='#g3-58'/>
+<use x='244.221' y='173.035' xlink:href='#g0-54'/>
+<use x='247.926' y='173.035' xlink:href='#g0-56'/>
+</g>
+<path d='M221.895 287.523H224.883V279.551H221.895ZM227.875 287.523H230.863V281.543H227.875Z' fill='#e1c2e1'/>
+<path d='M221.895 287.523H224.883V279.551H221.895ZM227.875 287.523H230.863V281.543H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.441 114.036)'>
+<use x='277.134' y='173.035' xlink:href='#g3-116'/>
+<use x='280.192' y='173.035' xlink:href='#g3-99'/>
+<use x='283.956' y='173.035' xlink:href='#g3-58'/>
+<use x='286.308' y='173.035' xlink:href='#g0-55'/>
+<use x='290.013' y='173.035' xlink:href='#g0-50'/>
+</g>
+<path d='M265.109 287.523H268.098V279.551H265.109ZM271.086 287.523H274.074V281.543H271.086Z' fill='#d1a3d1'/>
+<path d='M265.109 287.523H268.098V279.551H265.109ZM271.086 287.523H274.074V281.543H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.04 114.479)'>
+<use x='319.615' y='173.035' xlink:href='#g3-106'/>
+<use x='321.871' y='173.035' xlink:href='#g3-101'/>
+<use x='325.634' y='173.035' xlink:href='#g3-58'/>
+<use x='327.987' y='173.035' xlink:href='#g0-55'/>
+<use x='331.691' y='173.035' xlink:href='#g0-49'/>
+</g>
+<path d='M306.859 287.523H309.848V279.551H306.859ZM312.836 287.523H315.824V281.543H312.836Z' fill='#c285c2'/>
+<path d='M306.859 287.523H309.848V279.551H306.859ZM312.836 287.523H315.824V281.543H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -39.932 114.515)'>
+<use x='359.038' y='173.035' xlink:href='#g3-116'/>
+<use x='362.096' y='173.035' xlink:href='#g3-98'/>
+<use x='366.469' y='173.035' xlink:href='#g3-98'/>
+<use x='370.842' y='173.035' xlink:href='#g3-58'/>
+<use x='373.194' y='173.035' xlink:href='#g0-54'/>
+<use x='376.899' y='173.035' xlink:href='#g0-51'/>
+</g>
+<path d='M139.336 300.527H142.324V292.559H139.336ZM145.313 300.527H148.301V294.551H145.313Z' fill='#b366b3'/>
+<path d='M139.336 300.527H142.324V292.559H139.336ZM145.313 300.527H148.301V294.551H145.313Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.662 114.036)'>
+<use x='191.843' y='186.041' xlink:href='#g3-114'/>
+<use x='194.735' y='186.041' xlink:href='#g3-112'/>
+<use x='199.108' y='186.041' xlink:href='#g3-58'/>
+<use x='201.46' y='186.041' xlink:href='#g0-52'/>
+<use x='205.165' y='186.041' xlink:href='#g0-50'/>
+</g>
+<path d='M177.086 300.527H180.074V292.559H177.086ZM183.063 300.527H186.055V294.551H183.063Z' fill='#a447a4'/>
+<path d='M177.086 300.527H180.074V292.559H177.086ZM183.063 300.527H186.055V294.551H183.063Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.882 114.515)'>
+<use x='233.123' y='186.041' xlink:href='#g3-104'/>
+<use x='237.496' y='186.041' xlink:href='#g3-111'/>
+<use x='241.73' y='186.041' xlink:href='#g3-97'/>
+<use x='245.563' y='186.041' xlink:href='#g3-114'/>
+<use x='248.455' y='186.041' xlink:href='#g3-100'/>
+<use x='252.828' y='186.041' xlink:href='#g3-58'/>
+<use x='255.18' y='186.041' xlink:href='#g0-53'/>
+<use x='258.885' y='186.041' xlink:href='#g0-51'/>
+</g>
+<path d='M221.895 300.527H224.883V292.559H221.895ZM227.875 300.527H230.863V294.551H227.875Z' fill='#942994'/>
+<path d='M221.895 300.527H224.883V292.559H221.895ZM227.875 300.527H230.863V294.551H227.875Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.084 114.515)'>
+<use x='277.134' y='186.041' xlink:href='#g3-109'/>
+<use x='283.859' y='186.041' xlink:href='#g3-101'/>
+<use x='287.622' y='186.041' xlink:href='#g3-115'/>
+<use x='290.869' y='186.041' xlink:href='#g3-104'/>
+<use x='295.241' y='186.041' xlink:href='#g3-58'/>
+<use x='297.593' y='186.041' xlink:href='#g0-53'/>
+<use x='301.298' y='186.041' xlink:href='#g0-50'/>
+</g>
+<path d='M265.109 300.527H268.098V292.559H265.109ZM271.086 300.527H274.074V294.551H271.086Z' fill='#850a85'/>
+<path d='M265.109 300.527H268.098V292.559H265.109ZM271.086 300.527H274.074V294.551H271.086Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -42.353 114.515)'>
+<use x='319.615' y='186.041' xlink:href='#g3-103'/>
+<use x='323.849' y='186.041' xlink:href='#g3-108'/>
+<use x='325.869' y='186.041' xlink:href='#g3-105'/>
+<use x='327.89' y='186.041' xlink:href='#g3-98'/>
+<use x='332.498' y='186.041' xlink:href='#g3-99'/>
+<use x='336.261' y='186.041' xlink:href='#g3-58'/>
+<use x='338.614' y='186.041' xlink:href='#g0-54'/>
+<use x='342.318' y='186.041' xlink:href='#g0-52'/>
+</g>
+<path d='M306.859 300.527H309.848V292.559H306.859ZM312.836 300.527H315.824V294.551H312.836Z' fill='#760076'/>
+<path d='M306.859 300.527H309.848V292.559H306.859ZM312.836 300.527H315.824V294.551H312.836Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.026 114.479)'>
+<use x='359.038' y='186.041' xlink:href='#g3-115'/>
+<use x='362.285' y='186.041' xlink:href='#g3-109'/>
+<use x='369.009' y='186.041' xlink:href='#g3-105'/>
+<use x='371.03' y='186.041' xlink:href='#g3-58'/>
+<use x='373.382' y='186.041' xlink:href='#g0-52'/>
+<use x='377.087' y='186.041' xlink:href='#g0-51'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.9.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='315.585pt' height='208.604pt' viewBox='52.934 54.994 315.585 208.604'>
+<rect width="1000%" height="1000%" fill="white"/>
+<defs>
+<clipPath id='clip1'>
+<path d='M82.148 203.938H368.121V78.692H82.148Z'/>
+</clipPath>
+<use id='g2-44' xlink:href='#g0-44' transform='scale(.714)'/>
+<use id='g2-45' xlink:href='#g0-45' transform='scale(.714)'/>
+<use id='g2-46' xlink:href='#g0-46' transform='scale(.714)'/>
+<use id='g2-48' xlink:href='#g0-48' transform='scale(.714)'/>
+<use id='g2-49' xlink:href='#g0-49' transform='scale(.714)'/>
+<use id='g2-50' xlink:href='#g0-50' transform='scale(.714)'/>
+<use id='g2-51' xlink:href='#g0-51' transform='scale(.714)'/>
+<use id='g2-52' xlink:href='#g0-52' transform='scale(.714)'/>
+<use id='g2-53' xlink:href='#g0-53' transform='scale(.714)'/>
+<use id='g2-54' xlink:href='#g0-54' transform='scale(.714)'/>
+<use id='g2-55' xlink:href='#g0-55' transform='scale(.714)'/>
+<use id='g2-56' xlink:href='#g0-56' transform='scale(.714)'/>
+<use id='g2-57' xlink:href='#g0-57' transform='scale(.714)'/>
+<use id='g2-64' xlink:href='#g0-64' transform='scale(.714)'/>
+<use id='g2-65' xlink:href='#g0-65' transform='scale(.714)'/>
+<use id='g2-67' xlink:href='#g0-67' transform='scale(.714)'/>
+<use id='g2-71' xlink:href='#g0-71' transform='scale(.714)'/>
+<use id='g2-73' xlink:href='#g0-73' transform='scale(.714)'/>
+<use id='g2-79' xlink:href='#g0-79' transform='scale(.714)'/>
+<use id='g2-83' xlink:href='#g0-83' transform='scale(.714)'/>
+<use id='g2-97' xlink:href='#g0-97' transform='scale(.714)'/>
+<use id='g2-98' xlink:href='#g0-98' transform='scale(.714)'/>
+<use id='g2-99' xlink:href='#g0-99' transform='scale(.714)'/>
+<use id='g2-101' xlink:href='#g0-101' transform='scale(.714)'/>
+<use id='g2-103' xlink:href='#g0-103' transform='scale(.714)'/>
+<use id='g2-104' xlink:href='#g0-104' transform='scale(.714)'/>
+<use id='g2-105' xlink:href='#g0-105' transform='scale(.714)'/>
+<use id='g2-108' xlink:href='#g0-108' transform='scale(.714)'/>
+<use id='g2-109' xlink:href='#g0-109' transform='scale(.714)'/>
+<use id='g2-110' xlink:href='#g0-110' transform='scale(.714)'/>
+<use id='g2-111' xlink:href='#g0-111' transform='scale(.714)'/>
+<use id='g2-112' xlink:href='#g0-112' transform='scale(.714)'/>
+<use id='g2-114' xlink:href='#g0-114' transform='scale(.714)'/>
+<use id='g2-115' xlink:href='#g0-115' transform='scale(.714)'/>
+<use id='g2-116' xlink:href='#g0-116' transform='scale(.714)'/>
+<use id='g2-120' xlink:href='#g0-120' transform='scale(.714)'/>
+<use id='g2-122' xlink:href='#g0-122' transform='scale(.714)'/>
+<use id='g3-40' xlink:href='#g0-40' transform='scale(1.143)'/>
+<use id='g3-41' xlink:href='#g0-41' transform='scale(1.143)'/>
+<use id='g3-45' xlink:href='#g0-45' transform='scale(1.143)'/>
+<use id='g3-58' xlink:href='#g0-58' transform='scale(1.143)'/>
+<use id='g3-78' xlink:href='#g0-78' transform='scale(1.143)'/>
+<use id='g3-97' xlink:href='#g0-97' transform='scale(1.143)'/>
+<use id='g3-98' xlink:href='#g0-98' transform='scale(1.143)'/>
+<use id='g3-99' xlink:href='#g0-99' transform='scale(1.143)'/>
+<use id='g3-100' xlink:href='#g0-100' transform='scale(1.143)'/>
+<use id='g3-101' xlink:href='#g0-101' transform='scale(1.143)'/>
+<use id='g3-102' xlink:href='#g0-102' transform='scale(1.143)'/>
+<use id='g3-104' xlink:href='#g0-104' transform='scale(1.143)'/>
+<use id='g3-105' xlink:href='#g0-105' transform='scale(1.143)'/>
+<use id='g3-106' xlink:href='#g0-106' transform='scale(1.143)'/>
+<use id='g3-108' xlink:href='#g0-108' transform='scale(1.143)'/>
+<use id='g3-109' xlink:href='#g0-109' transform='scale(1.143)'/>
+<use id='g3-110' xlink:href='#g0-110' transform='scale(1.143)'/>
+<use id='g3-111' xlink:href='#g0-111' transform='scale(1.143)'/>
+<use id='g3-114' xlink:href='#g0-114' transform='scale(1.143)'/>
+<use id='g3-115' xlink:href='#g0-115' transform='scale(1.143)'/>
+<use id='g3-116' xlink:href='#g0-116' transform='scale(1.143)'/>
+<use id='g3-119' xlink:href='#g0-119' transform='scale(1.143)'/>
+<use id='g3-120' xlink:href='#g0-120' transform='scale(1.143)'/>
+<use id='g3-121' xlink:href='#g0-121' transform='scale(1.143)'/>
+<path id='g4-1' d='M1.445-1.245C1.445-1.41 1.305-1.549 1.141-1.549S.837-1.41 .837-1.245S.976-.941 1.141-.941S1.445-1.081 1.445-1.245Z'/>
+<path id='g1-82' d='M3.891-2.914C4.806-3.165 5.452-3.811 5.452-4.546C5.452-5.469 4.411-6.223 3.129-6.223H.87V0H1.704V-2.824H3.138L4.842 0H5.703L3.891-2.914ZM1.704-3.407V-5.694H3.022C4.062-5.694 4.671-5.192 4.671-4.546C4.671-3.963 4.125-3.407 3.022-3.407H1.704Z'/>
+<path id='g1-97' d='M3.694-2.591C3.694-3.479 3.04-4.133 2.152-4.133C1.569-4.133 1.139-3.981 .708-3.739L.762-3.102C1.21-3.434 1.65-3.569 2.143-3.569C2.645-3.569 2.95-3.165 2.95-2.582V-2.206C1.408-2.17 .395-1.766 .395-1.04C.395-.619 .672 .099 1.453 .099C1.632 .099 2.412 .081 2.977-.341V0H3.694V-2.591ZM2.95-1.255C2.95-1.067 2.95-.843 2.627-.655C2.403-.52 2.107-.484 1.928-.484C1.47-.484 1.085-.699 1.085-1.058C1.085-1.695 2.833-1.722 2.95-1.722V-1.255Z'/>
+<path id='g1-101' d='M3.829-1.964C3.829-2.242 3.82-2.923 3.47-3.461C3.093-4.026 2.52-4.133 2.179-4.133C1.139-4.133 .314-3.174 .314-2.026C.314-.843 1.193 .099 2.313 .099C2.744 .099 3.264-.009 3.784-.341L3.73-.959C3.165-.556 2.636-.484 2.322-.484C1.578-.484 1.004-1.139 .977-1.964H3.829ZM1.031-2.493C1.175-3.067 1.614-3.551 2.179-3.551C2.511-3.551 3.12-3.398 3.291-2.493H1.031Z'/>
+<path id='g1-105' d='M1.524-6.133H.664V-5.272H1.524V-6.133ZM1.453-3.981H.735V0H1.453V-3.981Z'/>
+<path id='g1-108' d='M1.453-6.223H.735V0H1.453V-6.223Z'/>
+<path id='g1-109' d='M6.581-2.663C6.581-3.327 6.402-4.08 5.317-4.08C4.564-4.08 4.142-3.622 3.927-3.344C3.865-3.524 3.676-4.08 2.762-4.08C2.053-4.08 1.623-3.667 1.417-3.398V-4.035H.726V0H1.47V-2.188C1.47-2.78 1.704-3.497 2.385-3.497C3.282-3.497 3.282-2.86 3.282-2.6V0H4.026V-2.188C4.026-2.78 4.259-3.497 4.94-3.497C5.837-3.497 5.837-2.86 5.837-2.6V0H6.581V-2.663Z'/>
+<path id='g1-116' d='M1.623-3.425H2.914V-3.981H1.623V-5.12H.959V-3.981H.17V-3.425H.933V-1.13C.933-.601 1.049 .099 1.704 .099C2.098 .099 2.564 .018 3.067-.233L2.914-.798C2.681-.619 2.367-.511 2.089-.511C1.739-.511 1.623-.825 1.623-1.291V-3.425Z'/>
+<path id='g1-118' d='M4.116-3.981H3.407L2.699-2.161C2.52-1.695 2.188-.825 2.143-.493H2.125C2.107-.646 2.08-.816 1.587-2.107C1.318-2.833 .879-3.927 .861-3.981H.126L1.704 0H2.537L4.116-3.981Z'/>
+<path id='g0-40' d='M2.127-5.23C2.008-5.23 1.995-5.23 1.911-5.154C1.032-4.387 .586-3.145 .586-1.743C.586-.425 .983 .844 1.904 1.653C1.995 1.743 2.008 1.743 2.127 1.743H2.462C2.441 1.73 1.764 1.151 1.444 .063C1.276-.481 1.193-1.053 1.193-1.743C1.193-4.156 2.322-5.112 2.462-5.23H2.127Z'/>
+<path id='g0-41' d='M.746 1.743C.865 1.743 .879 1.743 .962 1.667C1.841 .9 2.287-.342 2.287-1.743C2.287-3.062 1.89-4.331 .969-5.14C.879-5.23 .865-5.23 .746-5.23H.411C.432-5.216 1.109-4.638 1.43-3.55C1.597-3.006 1.681-2.434 1.681-1.743C1.681 .669 .551 1.625 .411 1.743H.746Z'/>
+<path id='g0-44' d='M1.339-.007V-.628H.711V0H.907L.704 .893H1.018L1.339-.007Z'/>
+<path id='g0-45' d='M2.05-1.332V-1.771H.084V-1.332H2.05Z'/>
+<path id='g0-46' d='M1.339-.628H.711V0H1.339V-.628Z'/>
+<path id='g0-48' d='M3.403-2.267C3.403-2.601 3.403-3.417 3.075-3.989C2.72-4.617 2.183-4.721 1.848-4.721C1.534-4.721 .99-4.624 .642-4.024C.307-3.466 .293-2.706 .293-2.267C.293-1.75 .321-1.116 .614-.586C.921-.021 1.437 .146 1.848 .146C2.545 .146 2.929-.258 3.138-.697C3.382-1.193 3.403-1.834 3.403-2.267ZM1.848-.314C1.555-.314 1.22-.481 1.046-.983C.907-1.409 .9-1.848 .9-2.357C.9-2.999 .9-4.261 1.848-4.261S2.797-2.999 2.797-2.357C2.797-1.897 2.797-1.374 2.629-.928C2.434-.425 2.078-.314 1.848-.314Z'/>
+<path id='g0-49' d='M2.239-4.721H2.085C1.632-4.303 1.06-4.275 .642-4.261V-3.822C.914-3.829 1.262-3.843 1.611-3.982V-.439H.683V0H3.166V-.439H2.239V-4.721Z'/>
+<path id='g0-50' d='M1.974-.537C1.89-.537 1.806-.53 1.723-.53H.928L2.008-1.485C2.134-1.597 2.476-1.855 2.608-1.967C2.915-2.246 3.327-2.608 3.327-3.215C3.327-4.003 2.741-4.721 1.743-4.721C1.004-4.721 .544-4.324 .307-3.612L.635-3.201C.795-3.787 1.039-4.24 1.646-4.24C2.232-4.24 2.678-3.829 2.678-3.201C2.678-2.622 2.336-2.294 1.918-1.897C1.778-1.757 1.402-1.444 1.255-1.304C1.053-1.123 .572-.656 .37-.481V0H3.327V-.537H1.974Z'/>
+<path id='g0-51' d='M.697-3.578C.983-4.135 1.485-4.289 1.82-4.289C2.232-4.289 2.538-4.052 2.538-3.654C2.538-3.285 2.287-2.831 1.757-2.741C1.723-2.734 1.695-2.734 1.234-2.699V-2.239H1.778C2.441-2.239 2.685-1.716 2.685-1.276C2.685-.732 2.35-.314 1.806-.314C1.311-.314 .746-.551 .398-.997L.307-.544C.711-.091 1.276 .146 1.82 .146C2.734 .146 3.389-.537 3.389-1.269C3.389-1.841 2.929-2.301 2.378-2.462C2.908-2.734 3.18-3.201 3.18-3.654C3.18-4.247 2.573-4.721 1.827-4.721C1.213-4.721 .704-4.4 .411-3.982L.697-3.578Z'/>
+<path id='g0-52' d='M2.762-1.165H3.487V-1.625H2.762V-4.575H2.071L.209-1.625V-1.165H2.162V0H2.762V-1.165ZM.802-1.625C1.011-1.953 2.211-3.815 2.211-4.233V-1.625H.802Z'/>
+<path id='g0-53' d='M1.144-4.094H3.075V-4.575H.586V-1.967H1.095C1.262-2.343 1.59-2.511 1.904-2.511C2.19-2.511 2.622-2.315 2.622-1.43C2.622-.516 2.043-.314 1.688-.314C1.227-.314 .781-.558 .544-.955L.279-.537C.621-.112 1.137 .146 1.688 .146C2.608 .146 3.327-.565 3.327-1.416C3.327-2.28 2.685-2.971 1.918-2.971C1.618-2.971 1.353-2.866 1.144-2.692V-4.094Z'/>
+<path id='g0-54' d='M3.062-4.582C2.685-4.721 2.42-4.721 2.287-4.721C1.227-4.721 .307-3.724 .307-2.253C.307-.363 1.158 .146 1.862 .146C2.427 .146 2.72-.119 2.936-.342C3.382-.816 3.389-1.311 3.389-1.555C3.389-2.469 2.894-3.229 2.218-3.229C1.534-3.229 1.165-2.873 .962-2.671C1.053-3.626 1.541-4.289 2.294-4.289C2.434-4.289 2.713-4.275 3.062-4.142V-4.582ZM.969-1.534C.969-1.576 .969-1.681 .976-1.716C.976-2.19 1.276-2.769 1.897-2.769C2.748-2.769 2.748-1.792 2.748-1.555C2.748-1.29 2.748-.997 2.559-.704C2.392-.453 2.183-.314 1.862-.314C1.123-.314 1.004-1.227 .969-1.534Z'/>
+<path id='g0-55' d='M1.723-4.038C1.806-4.038 1.89-4.045 1.974-4.045H2.852C1.792-3.006 1.116-1.548 1.116 .07H1.771C1.771-1.967 2.762-3.431 3.389-4.087V-4.575H.307V-4.038H1.723Z'/>
+<path id='g0-56' d='M2.385-2.469C2.845-2.615 3.285-2.985 3.285-3.501C3.285-4.135 2.678-4.721 1.848-4.721S.411-4.135 .411-3.501C.411-2.978 .865-2.608 1.311-2.469C.697-2.28 .307-1.806 .307-1.269C.307-.523 .969 .146 1.848 .146S3.389-.523 3.389-1.269C3.389-1.806 2.992-2.28 2.385-2.469ZM1.848-2.699C1.353-2.699 .948-2.985 .948-3.494C.948-3.94 1.262-4.289 1.848-4.289C2.427-4.289 2.748-3.94 2.748-3.494C2.748-2.999 2.357-2.699 1.848-2.699ZM1.848-.314C1.367-.314 .941-.621 .941-1.276C.941-1.904 1.346-2.239 1.848-2.239S2.755-1.897 2.755-1.276C2.755-.621 2.322-.314 1.848-.314Z'/>
+<path id='g0-57' d='M.537-.174C.879 .077 1.193 .146 1.52 .146C2.497 .146 3.389-.837 3.389-2.336C3.389-4.24 2.545-4.721 1.876-4.721C1.255-4.721 .969-4.428 .767-4.226C.321-3.773 .307-3.292 .307-3.02C.307-2.12 .795-1.346 1.478-1.346C2.267-1.346 2.699-1.869 2.734-1.911C2.636-.802 2.092-.314 1.52-.314C1.158-.314 .934-.446 .774-.579L.537-.174ZM2.713-3.027C2.72-2.985 2.72-2.915 2.72-2.873C2.72-2.357 2.406-1.806 1.799-1.806C1.534-1.806 1.325-1.883 1.144-2.169C.962-2.441 .948-2.706 .948-3.02C.948-3.292 .948-3.605 1.165-3.912C1.311-4.122 1.52-4.289 1.869-4.289C2.545-4.289 2.692-3.473 2.713-3.027Z'/>
+<path id='g0-58' d='M1.339-3.096H.711V-2.469H1.339V-3.096ZM.711-.628V0H1.339V-.628H.711Z'/>
+<path id='g0-64' d='M4.142-.614C4.038-.614 4.024-.614 3.968-.586C3.626-.467 3.271-.391 2.901-.391C1.778-.391 .976-1.339 .976-2.42C.976-3.592 1.883-4.449 2.859-4.449C3.055-4.449 3.515-4.4 3.745-3.843C3.55-3.954 3.333-4.003 3.152-4.003C2.406-4.003 1.778-3.306 1.778-2.42C1.778-1.513 2.427-.837 3.145-.837C3.689-.837 4.519-1.276 4.519-2.518C4.519-3.222 4.47-4.91 2.866-4.91C1.541-4.91 .411-3.815 .411-2.42C.411-1.039 1.527 .07 2.873 .07C3.515 .07 4.115-.195 4.519-.614H4.142ZM3.152-1.297C2.72-1.297 2.343-1.778 2.343-2.42C2.343-3.082 2.734-3.543 3.145-3.543C3.578-3.543 3.954-3.062 3.954-2.42C3.954-1.757 3.564-1.297 3.152-1.297Z'/>
+<path id='g0-65' d='M2.803-4.84H2.127L.209 0H.781L1.325-1.381H3.445L3.989 0H4.721L2.803-4.84ZM2.392-4.31L3.271-1.792H1.499L2.392-4.31Z'/>
+<path id='g0-67' d='M4.317-.851C3.829-.551 3.605-.418 2.908-.418C1.827-.418 1.172-1.43 1.172-2.434C1.172-3.466 1.89-4.435 2.908-4.435C3.368-4.435 3.843-4.289 4.163-4.045L4.275-4.679C3.787-4.861 3.396-4.917 2.887-4.917C1.506-4.917 .474-3.773 .474-2.427C.474-.99 1.569 .07 2.929 .07C3.612 .07 3.898-.07 4.359-.321L4.317-.851Z'/>
+<path id='g0-71' d='M4.442-2.085H2.88V-1.625H3.829V-.558C3.522-.481 3.222-.418 2.908-.418C1.834-.418 1.172-1.43 1.172-2.427C1.172-3.382 1.82-4.435 2.873-4.435C3.515-4.435 3.919-4.24 4.268-3.947L4.38-4.582C3.898-4.812 3.473-4.924 2.943-4.924C1.534-4.924 .474-3.822 .474-2.427C.474-1.067 1.527 .07 2.901 .07C3.403 .07 3.996-.042 4.442-.272V-2.085Z'/>
+<path id='g0-73' d='M1.381-4.84H.676V0H1.381V-4.84Z'/>
+<path id='g0-78' d='M1.646-4.84H.697V0H1.283V-4.289H1.29L3.578 0H4.526V-4.84H3.94V-.551H3.933L1.646-4.84Z'/>
+<path id='g0-79' d='M5.056-2.399C5.056-3.843 3.996-4.986 2.734-4.986S.411-3.843 .411-2.399S1.485 .146 2.734 .146C3.989 .146 5.056-.962 5.056-2.399ZM2.734-.349C1.89-.349 1.116-1.193 1.116-2.511C1.116-3.745 1.897-4.505 2.734-4.505S4.352-3.745 4.352-2.511C4.352-1.186 3.578-.349 2.734-.349Z'/>
+<path id='g0-83' d='M3.445-4.645C2.999-4.875 2.601-4.986 2.085-4.986C1.032-4.986 .411-4.275 .411-3.605C.411-3.32 .502-2.985 .844-2.664C1.151-2.378 1.471-2.308 1.904-2.204C2.49-2.064 2.65-2.029 2.852-1.82C2.985-1.688 3.096-1.492 3.096-1.255C3.096-.823 2.706-.377 2.029-.377C1.632-.377 .99-.495 .439-.962L.328-.335C.676-.133 1.255 .146 2.036 .146C3.006 .146 3.696-.558 3.696-1.339C3.696-1.904 3.368-2.225 3.229-2.371C2.936-2.657 2.615-2.734 2.078-2.859C1.653-2.957 1.43-3.013 1.262-3.173C1.172-3.264 1.011-3.424 1.011-3.689C1.011-4.08 1.402-4.484 2.078-4.484C2.608-4.484 2.978-4.317 3.333-4.017L3.445-4.645Z'/>
+<path id='g0-97' d='M2.971-2.008C2.971-2.72 2.427-3.201 1.736-3.201C1.297-3.201 .962-3.11 .572-2.901L.614-2.392C.844-2.545 1.186-2.755 1.736-2.755C2.043-2.755 2.364-2.525 2.364-2.001V-1.723C1.332-1.688 .314-1.471 .314-.823C.314-.474 .551 .07 1.165 .07C1.465 .07 2.015 .007 2.385-.265V0H2.971V-2.008ZM2.364-.99C2.364-.851 2.364-.669 2.12-.523C1.897-.398 1.625-.391 1.548-.391C1.165-.391 .872-.565 .872-.83C.872-1.276 2.05-1.318 2.364-1.332V-.99Z'/>
+<path id='g0-98' d='M1.179-4.84H.593V0H1.2V-.328C1.353-.195 1.688 .07 2.197 .07C2.957 .07 3.571-.642 3.571-1.555C3.571-2.399 3.089-3.166 2.392-3.166C1.953-3.166 1.527-3.027 1.179-2.769V-4.84ZM1.2-2.197C1.2-2.308 1.2-2.392 1.444-2.552C1.548-2.615 1.736-2.706 1.974-2.706C2.441-2.706 2.964-2.392 2.964-1.555C2.964-.704 2.385-.391 1.897-.391C1.639-.391 1.395-.509 1.2-.823V-2.197Z'/>
+<path id='g0-99' d='M3.034-.76C2.685-.537 2.308-.411 1.876-.411C1.234-.411 .858-.928 .858-1.555C.858-2.092 1.137-2.72 1.897-2.72C2.371-2.72 2.594-2.622 2.95-2.399L3.041-2.901C2.622-3.11 2.441-3.201 1.897-3.201C.851-3.201 .251-2.357 .251-1.548C.251-.697 .921 .07 1.869 .07C2.357 .07 2.776-.077 3.075-.251L3.034-.76Z'/>
+<path id='g0-100' d='M3.229-4.84H2.643V-2.797C2.197-3.124 1.743-3.166 1.541-3.166C.809-3.166 .251-2.434 .251-1.548S.802 .07 1.52 .07C1.953 .07 2.357-.126 2.622-.363V0H3.229V-4.84ZM2.622-.865C2.448-.579 2.183-.391 1.848-.391C1.36-.391 .858-.732 .858-1.541C.858-2.413 1.451-2.706 1.925-2.706C2.204-2.706 2.441-2.587 2.622-2.35V-.865Z'/>
+<path id='g0-101' d='M2.999-.76C2.608-.481 2.169-.391 1.869-.391C1.262-.391 .802-.886 .781-1.527H3.068C3.068-1.848 3.034-2.315 2.762-2.713C2.511-3.068 2.092-3.201 1.75-3.201C.9-3.201 .244-2.455 .244-1.569C.244-.676 .941 .07 1.862 .07C2.267 .07 2.685-.049 3.041-.265L2.999-.76ZM.83-1.946C.99-2.504 1.402-2.741 1.75-2.741C2.057-2.741 2.511-2.594 2.643-1.946H.83Z'/>
+<path id='g0-102' d='M1.325-2.657H2.12V-3.096H1.304V-3.898C1.304-4.38 1.743-4.449 1.974-4.449C2.12-4.449 2.308-4.428 2.566-4.331V-4.84C2.385-4.882 2.169-4.91 1.981-4.91C1.262-4.91 .739-4.394 .739-3.703V-3.096H.202V-2.657H.739V0H1.325V-2.657Z'/>
+<path id='g0-103' d='M3.508-3.166C3.354-3.166 2.887-3.159 2.357-2.957L2.343-2.95C2.092-3.117 1.848-3.166 1.646-3.166C.962-3.166 .453-2.629 .453-2.029C.453-1.785 .537-1.534 .697-1.339C.6-1.22 .495-1.025 .495-.76C.495-.488 .607-.314 .669-.23C.286-.007 .209 .314 .209 .481C.209 1.011 .941 1.43 1.848 1.43C2.762 1.43 3.487 1.011 3.487 .481C3.487-.502 2.267-.502 1.967-.502H1.318C1.206-.502 .907-.502 .907-.865C.907-1.004 .955-1.074 .962-1.088C1.206-.934 1.451-.886 1.639-.886C2.322-.886 2.831-1.423 2.831-2.022C2.831-2.246 2.769-2.448 2.643-2.636C2.615-2.678 2.615-2.685 2.615-2.692C2.615-2.72 3.034-2.72 3.068-2.72C3.075-2.72 3.34-2.72 3.592-2.692L3.508-3.166ZM1.646-1.318C1.269-1.318 .99-1.555 .99-2.022C.99-2.566 1.339-2.734 1.639-2.734C2.015-2.734 2.294-2.497 2.294-2.029C2.294-1.485 1.946-1.318 1.646-1.318ZM1.974 .042C2.134 .042 2.957 .042 2.957 .488C2.957 .788 2.434 .997 1.848 .997S.739 .788 .739 .488C.739 .453 .739 .042 1.304 .042H1.974Z'/>
+<path id='g0-104' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.625-3.166 1.304-2.817 1.165-2.671V-4.84H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-105' d='M1.227-4.784H.523V-4.08H1.227V-4.784ZM1.172-3.096H.586V0H1.172V-3.096Z'/>
+<path id='g0-106' d='M1.381-4.784H.676V-4.08H1.381V-4.784ZM-.453 1.186C-.133 1.36 .181 1.423 .446 1.423C.928 1.423 1.381 1.053 1.381 .411V-3.096H.795V.46C.795 .586 .795 .697 .649 .816C.488 .934 .293 .934 .23 .934C-.063 .934-.244 .802-.328 .725L-.453 1.186Z'/>
+<path id='g0-108' d='M1.172-4.84H.586V0H1.172V-4.84Z'/>
+<path id='g0-109' d='M5.3-2.064C5.3-2.608 5.14-3.166 4.282-3.166C3.696-3.166 3.333-2.824 3.166-2.601C3.096-2.79 2.922-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-1.695C3.243-2.155 3.438-2.706 3.975-2.706C4.693-2.706 4.693-2.218 4.693-2.015V0H5.3V-2.064Z'/>
+<path id='g0-110' d='M3.243-2.064C3.243-2.608 3.082-3.166 2.225-3.166C1.827-3.166 1.444-3.006 1.137-2.636V-3.145H.579V0H1.186V-1.695C1.186-2.155 1.381-2.706 1.918-2.706C2.636-2.706 2.636-2.218 2.636-2.015V0H3.243V-2.064Z'/>
+<path id='g0-111' d='M3.487-1.527C3.487-2.448 2.755-3.201 1.848-3.201S.209-2.441 .209-1.527C.209-.642 .948 .07 1.848 .07C2.755 .07 3.487-.642 3.487-1.527ZM1.848-.411C1.297-.411 .816-.816 .816-1.604S1.332-2.741 1.848-2.741C2.371-2.741 2.88-2.378 2.88-1.604C2.88-.809 2.385-.411 1.848-.411Z'/>
+<path id='g0-112' d='M1.2-.328C1.569 .007 1.967 .07 2.204 .07C2.943 .07 3.571-.635 3.571-1.555C3.571-2.392 3.11-3.166 2.42-3.166C2.106-3.166 1.583-3.075 1.179-2.762V-3.096H.593V1.353H1.2V-.328ZM1.2-2.315C1.36-2.511 1.632-2.685 1.967-2.685C2.525-2.685 2.964-2.169 2.964-1.555C2.964-.865 2.441-.391 1.897-.391C1.792-.391 1.618-.404 1.437-.551C1.227-.711 1.2-.816 1.2-.948V-2.315Z'/>
+<path id='g0-114' d='M1.179-1.485C1.179-2.239 1.806-2.643 2.42-2.65V-3.166C1.834-3.159 1.409-2.873 1.13-2.504V-3.145H.593V0H1.179V-1.485Z'/>
+<path id='g0-115' d='M2.545-2.985C2.071-3.18 1.723-3.201 1.471-3.201C1.297-3.201 .244-3.201 .244-2.273C.244-1.946 .425-1.764 .516-1.681C.76-1.437 1.053-1.381 1.423-1.311C1.75-1.248 2.127-1.179 2.127-.844C2.127-.404 1.548-.404 1.451-.404C1.004-.404 .586-.565 .307-.76L.209-.237C.446-.119 .872 .07 1.451 .07C1.764 .07 2.071 .021 2.329-.167C2.587-.363 2.671-.669 2.671-.907C2.671-1.032 2.657-1.304 2.364-1.569C2.106-1.799 1.855-1.848 1.52-1.911C1.109-1.988 .788-2.05 .788-2.357C.788-2.755 1.297-2.755 1.402-2.755C1.799-2.755 2.106-2.671 2.455-2.49L2.545-2.985Z'/>
+<path id='g0-116' d='M1.311-2.657H2.343V-3.096H1.311V-3.982H.774V-3.096H.139V-2.657H.753V-.893C.753-.425 .872 .07 1.374 .07S2.26-.091 2.469-.188L2.35-.635C2.12-.467 1.876-.411 1.681-.411C1.388-.411 1.311-.697 1.311-1.018V-2.657Z'/>
+<path id='g0-119' d='M4.951-3.096H4.407C4.345-2.901 3.954-1.723 3.738-.997C3.682-.795 3.612-.572 3.592-.411H3.585C3.543-.697 3.299-1.451 3.285-1.499L2.769-3.096H2.239C2.036-2.497 1.513-.934 1.458-.425H1.451C1.395-.921 .879-2.462 .767-2.797C.711-2.964 .711-2.978 .676-3.096H.105L1.123 0H1.709C1.716-.028 1.904-.579 2.148-1.353C2.253-1.695 2.462-2.364 2.497-2.671L2.504-2.678C2.518-2.532 2.559-2.378 2.608-2.204S2.706-1.841 2.755-1.681L3.292 0H3.933L4.951-3.096Z'/>
+<path id='g0-120' d='M1.932-1.597L3.285-3.096H2.671L1.681-1.953L.669-3.096H.042L1.437-1.597L0 0H.621L1.681-1.311L2.783 0H3.41L1.932-1.597Z'/>
+<path id='g0-121' d='M3.306-3.096H2.741C2.176-1.764 1.785-.865 1.757-.439C1.743-.635 1.618-.983 1.492-1.311C1.381-1.59 1.269-1.869 1.144-2.141L.704-3.096H.105L1.548 0C1.465 .202 1.325 .523 1.283 .614C1.137 .907 1.039 1.004 .851 1.004C.823 1.004 .565 1.004 .265 .879L.307 1.367C.37 1.381 .628 1.423 .844 1.423C1.123 1.423 1.374 1.318 1.667 .649L3.306-3.096Z'/>
+<path id='g0-122' d='M2.957-2.803V-3.096H.307V-2.65H1.332C1.416-2.65 1.499-2.657 1.583-2.657H2.127L.209-.307V0H2.978V-.467H1.897C1.813-.467 1.73-.46 1.646-.46H1.039L2.957-2.803Z'/>
+</defs>
+<g id='page1'>
+<path d='M139.344 212.797V203.938M196.539 212.797V203.938M253.734 212.797V203.938M310.926 212.797V203.938M139.344 69.836V78.692M196.539 69.836V78.692M253.734 69.836V78.692M310.926 69.836V78.692' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M110.746 208.192V203.938M167.941 208.192V203.938M225.137 208.192V203.938M282.332 208.192V203.938M339.524 208.192V203.938M110.746 74.442V78.692M167.941 74.442V78.692M225.137 74.442V78.692M282.332 74.442V78.692M339.524 74.442V78.692' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 203.938H86.402M82.148 172.629H86.402M82.148 141.317H86.402M82.148 110.004H86.402M82.148 78.692H86.402M368.121 203.938H363.871M368.121 172.629H363.871M368.121 141.317H363.871M368.121 110.004H363.871M368.121 78.692H363.871' stroke='#808080' fill='none' stroke-width='.199' stroke-miterlimit='10'/>
+<path d='M82.148 203.938V78.692H368.121V203.938H82.148Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -12.278 72.902)'>
+<use x='114.487' y='145.434' xlink:href='#g3-99'/>
+<use x='118.25' y='145.434' xlink:href='#g3-102'/>
+<use x='120.838' y='145.434' xlink:href='#g3-114'/>
+<use x='123.73' y='145.434' xlink:href='#g3-97'/>
+<use x='127.798' y='145.434' xlink:href='#g3-99'/>
+</g>
+<g transform='matrix(1 0 0 1 43.353 72.902)'>
+<use x='114.487' y='145.434' xlink:href='#g3-108'/>
+<use x='116.507' y='145.434' xlink:href='#g3-101'/>
+<use x='120.271' y='145.434' xlink:href='#g3-97'/>
+<use x='124.339' y='145.434' xlink:href='#g3-110'/>
+<use x='128.711' y='145.434' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 97.361 72.902)'>
+<use x='114.487' y='145.434' xlink:href='#g3-108'/>
+<use x='116.507' y='145.434' xlink:href='#g3-97'/>
+<use x='120.34' y='145.434' xlink:href='#g3-114'/>
+<use x='123.232' y='145.434' xlink:href='#g3-115'/>
+<use x='126.478' y='145.434' xlink:href='#g3-111'/>
+<use x='130.712' y='145.434' xlink:href='#g3-110'/>
+<use x='135.085' y='145.434' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 151.766 72.902)'>
+<use x='114.487' y='145.434' xlink:href='#g3-109'/>
+<use x='121.211' y='145.434' xlink:href='#g3-115'/>
+<use x='124.458' y='145.434' xlink:href='#g3-116'/>
+<use x='127.516' y='145.434' xlink:href='#g3-114'/>
+<use x='130.408' y='145.434' xlink:href='#g3-101'/>
+<use x='134.171' y='145.434' xlink:href='#g3-115'/>
+<use x='137.418' y='145.434' xlink:href='#g3-115'/>
+<use x='140.664' y='145.434' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 200.59 72.902)'>
+<use x='114.487' y='145.434' xlink:href='#g3-120'/>
+<use x='118.389' y='145.434' xlink:href='#g3-109'/>
+<use x='125.114' y='145.434' xlink:href='#g3-97'/>
+<use x='129.182' y='145.434' xlink:href='#g3-108'/>
+<use x='131.202' y='145.434' xlink:href='#g3-108'/>
+<use x='133.222' y='145.434' xlink:href='#g3-111'/>
+<use x='137.692' y='145.434' xlink:href='#g3-99'/>
+<use x='141.455' y='145.434' xlink:href='#g3-45'/>
+<use x='144.278' y='145.434' xlink:href='#g3-116'/>
+<use x='147.336' y='145.434' xlink:href='#g3-101'/>
+<use x='151.1' y='145.434' xlink:href='#g3-115'/>
+<use x='154.346' y='145.434' xlink:href='#g3-116'/>
+<use x='157.404' y='145.434' xlink:href='#g3-78'/>
+</g>
+<g transform='matrix(1 0 0 1 -40.942 60.139)'>
+<use x='114.487' y='145.434' xlink:href='#g2-48'/>
+<use x='117.133' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 28.828)'>
+<use x='114.487' y='145.434' xlink:href='#g2-48'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-53'/>
+<use x='121.25' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -2.484)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -33.795)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-53'/>
+<use x='121.25' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(1 0 0 1 -45.059 -65.107)'>
+<use x='114.487' y='145.434' xlink:href='#g2-50'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-120'/>
+</g>
+<path d='M82.148 141.317H368.121' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M96.051 203.938H99.289V141.317H96.051ZM153.246 203.938H156.484V141.317H153.246ZM210.442 203.938H213.68V141.317H210.442ZM267.637 203.938H270.875V141.317H267.637ZM324.828 203.938H328.067V141.317H324.828Z' fill='#933' clip-path='url(#clip1)'/>
+<path d='M96.051 203.938H99.289V141.317H96.051ZM153.246 203.938H156.484V141.317H153.246ZM210.442 203.938H213.68V141.317H210.442ZM267.637 203.938H270.875V141.317H267.637ZM324.828 203.938H328.067V141.317H324.828Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M97.672 141.317' fill='#933' clip-path='url(#clip1)'/>
+<path d='M95.68 141.317H99.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M97.672 141.317' fill='#933' clip-path='url(#clip1)'/>
+<path d='M95.68 141.317H99.664' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M154.867 141.317V141.067' fill='#933' clip-path='url(#clip1)'/>
+<path d='M154.867 141.317V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M152.871 141.066H156.859' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M154.867 141.317V141.567' fill='#933' clip-path='url(#clip1)'/>
+<path d='M154.867 141.317V141.567' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M156.86 141.566H152.875' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M212.059 141.317V141.067' fill='#933' clip-path='url(#clip1)'/>
+<path d='M212.059 141.317V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M210.066 141.066H214.05' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M212.059 141.317V141.567' fill='#933' clip-path='url(#clip1)'/>
+<path d='M212.059 141.317V141.567' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M214.054 141.566H210.066' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M269.254 141.317V141.254' fill='#933' clip-path='url(#clip1)'/>
+<path d='M269.254 141.317V141.254' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M267.262 141.254H271.246' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M269.254 141.317V141.379' fill='#933' clip-path='url(#clip1)'/>
+<path d='M269.254 141.317V141.379' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M271.246 141.379H267.262' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M326.449 141.317V141.067' fill='#933' clip-path='url(#clip1)'/>
+<path d='M326.449 141.317V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M324.457 141.066H328.441' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M326.449 141.317V141.567' fill='#933' clip-path='url(#clip1)'/>
+<path d='M326.449 141.317V141.567' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M328.441 141.566H324.457' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M101.281 203.938H104.52V142.067H101.281ZM158.477 203.938H161.715V140.817H158.477ZM215.672 203.938H218.91V143.696H215.672ZM272.867 203.938H276.106V141.442H272.867ZM330.059 203.938H333.297V138.122H330.059Z' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M101.281 203.938H104.52V142.067H101.281ZM158.477 203.938H161.715V140.817H158.477ZM215.672 203.938H218.91V143.696H215.672ZM272.867 203.938H276.106V141.442H272.867ZM330.059 203.938H333.297V138.122H330.059Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M102.902 142.067' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M100.91 142.066H104.895' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M102.902 142.067' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M100.91 142.066H104.895' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M160.098 140.817V140.563' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M160.098 140.817V140.563' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M158.101 140.562H162.089' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M160.098 140.817V141.067' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M160.098 140.817V141.067' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M162.09 141.066H158.105' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M217.289 143.696V143.508' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M217.289 143.696V143.508' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M215.297 143.507H219.282' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M217.289 143.696V143.883' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M217.289 143.696V143.883' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M219.285 143.883H215.297' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M274.484 141.442' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M272.492 141.442H276.476' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M274.484 141.442' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M272.492 141.442H276.476' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M331.68 138.122V138.059' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M331.68 138.122V138.059' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M329.688 138.058H333.672' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M331.68 138.122V138.184' fill='#bf8080' clip-path='url(#clip1)'/>
+<path d='M331.68 138.122V138.184' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M333.671 138.183H329.687' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M106.512 203.938H109.75V122.028H106.512ZM163.707 203.938H166.945V128.918H163.707ZM220.902 203.938H224.141V119.961H220.902ZM278.098 203.938H281.336V139.375H278.098ZM335.289 203.938H338.527V78.692H335.289Z' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M106.512 203.938H109.75V122.028H106.512ZM163.707 203.938H166.945V128.918H163.707ZM220.902 203.938H224.141V119.961H220.902ZM278.098 203.938H281.336V139.375H278.098ZM335.289 203.938H338.527V78.692H335.289Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M108.133 122.028' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M106.14 122.028H110.125' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M108.133 122.028' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M106.14 122.028H110.125' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M165.328 128.918V128.856' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M165.328 128.918V128.856' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M163.332 128.856H167.317' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M165.328 128.918V128.981' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M165.328 128.918V128.981' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M167.321 128.981H163.336' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M222.52 119.961V119.836' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M222.52 119.961V119.836' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M220.527 119.836H224.512' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M222.52 119.961V120.086' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M222.52 119.961V120.086' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M224.512 120.086H220.527' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M279.715 139.375V139.125' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M279.715 139.375V139.125' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M277.723 139.125H281.707' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M279.715 139.375V139.625' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M279.715 139.375V139.625' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M281.708 139.625H277.723' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M336.91 78.692' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M334.918 78.691H338.902' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M336.91 78.692' fill='#8080bf' clip-path='url(#clip1)'/>
+<path d='M334.918 78.691H338.902' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M111.742 203.938H114.981V120.086H111.742ZM168.938 203.938H172.176V136.43H168.938ZM226.133 203.938H229.371V136.809H226.133ZM283.328 203.938H286.567V78.692H283.328ZM340.52 203.938H343.758V112.571H340.52Z' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M111.742 203.938H114.981V120.086H111.742ZM168.938 203.938H172.176V136.43H168.938ZM226.133 203.938H229.371V136.809H226.133ZM283.328 203.938H286.567V78.692H283.328ZM340.52 203.938H343.758V112.571H340.52Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M113.363 120.086V119.899' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M113.363 120.086V119.899' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M111.371 119.899H115.356' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M113.363 120.086V120.274' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M113.363 120.086V120.274' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M115.356 120.273H111.371' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M170.559 136.43' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M168.562 136.43H172.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M170.559 136.43' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M168.562 136.43H172.547' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M227.75 136.809' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M225.758 136.809H229.743' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M227.75 136.809' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M225.758 136.809H229.743' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M284.945 78.692' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M282.953 78.691H286.937' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M284.945 78.692' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M282.953 78.691H286.937' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M342.141 112.571V112.383' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M342.141 112.571V112.383' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M340.149 112.383H344.133' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M342.141 112.571V112.758' fill='#ffb733' clip-path='url(#clip1)'/>
+<path d='M342.141 112.571V112.758' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M344.132 112.757H340.148' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M116.973 203.938H120.211V137.059H116.973ZM174.168 203.938H177.406V131.235H174.168ZM231.363 203.938H234.602V78.692H231.363ZM288.559 203.938H291.797V79.696H288.559ZM345.75 203.938H348.988V78.692H345.75Z' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M116.973 203.938H120.211V137.059H116.973ZM174.168 203.938H177.406V131.235H174.168ZM231.363 203.938H234.602V78.692H231.363ZM288.559 203.938H291.797V79.696H288.559ZM345.75 203.938H348.988V78.692H345.75Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M118.594 137.059V136.809' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M118.594 137.059V136.809' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M116.601 136.809H120.586' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M118.594 137.059V137.309' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M118.594 137.059V137.309' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M120.586 137.309H116.601' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M175.789 131.235V131.047' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M175.789 131.235V131.047' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M173.793 131.046H177.778' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M175.789 131.235V131.422' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M175.789 131.235V131.422' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M177.782 131.422H173.797' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M232.981 78.692' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M230.988 78.691H234.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M232.981 78.692' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M230.988 78.691H234.973' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M290.176 79.696V79.383' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M290.176 79.696V79.383' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M288.184 79.383H292.168' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M290.176 79.696V80.008' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M290.176 79.696V80.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M292.168 80.008H288.183' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M347.371 78.692' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M345.379 78.691H349.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M347.371 78.692' fill='#80bf80' clip-path='url(#clip1)'/>
+<path d='M345.379 78.691H349.363' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M122.203 203.938H125.441V78.692H122.203ZM179.399 203.938H182.637V93.286H179.399ZM236.594 203.938H239.832V78.692H236.594ZM293.789 203.938H297.024V78.692H293.789ZM350.981 203.938H354.219V78.692H350.981Z' fill='#399' clip-path='url(#clip1)'/>
+<path d='M122.203 203.938H125.441V78.692H122.203ZM179.399 203.938H182.637V93.286H179.399ZM236.594 203.938H239.832V78.692H236.594ZM293.789 203.938H297.024V78.692H293.789ZM350.981 203.938H354.219V78.692H350.981Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M123.824 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M121.832 78.691H125.817' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M123.824 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M121.832 78.691H125.817' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M181.02 93.286V93.161' fill='#399' clip-path='url(#clip1)'/>
+<path d='M181.02 93.286V93.161' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M179.023 93.16H183.008' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M181.02 93.286V93.411' fill='#399' clip-path='url(#clip1)'/>
+<path d='M181.02 93.286V93.411' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M183.012 93.41H179.027' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M238.211 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M236.219 78.691H240.204' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M238.211 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M236.219 78.691H240.204' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M295.406 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M293.414 78.691H297.398' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M295.406 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M293.414 78.691H297.398' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M352.602 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M350.609 78.691H354.593' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M352.602 78.692' fill='#399' clip-path='url(#clip1)'/>
+<path d='M350.609 78.691H354.593' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<path d='M263.02 263.2H367.922V229.188H263.02Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10' clip-path='url(#clip1)'/>
+<g transform='matrix(1 0 0 1 151.853 114.444)'>
+<use x='114.487' y='121.524' xlink:href='#g2-109'/>
+<use x='118.69' y='121.524' xlink:href='#g2-97'/>
+<use x='121.232' y='121.524' xlink:href='#g2-99'/>
+<use x='125.349' y='121.524' xlink:href='#g2-109'/>
+<use x='129.552' y='121.524' xlink:href='#g2-105'/>
+<use x='130.814' y='121.524' xlink:href='#g2-110'/>
+<use x='133.547' y='121.524' xlink:href='#g2-105'/>
+<use x='134.81' y='121.524' xlink:href='#g2-44'/>
+<use x='138.044' y='121.524' xlink:href='#g2-49'/>
+<use x='140.691' y='121.524' xlink:href='#g2-54'/>
+<use x='143.337' y='121.524' xlink:href='#g2-71'/>
+<use x='146.866' y='121.524' xlink:href='#g2-98'/>
+<use x='114.487' y='127.501' xlink:href='#g2-52'/>
+<use x='117.133' y='127.501' xlink:href='#g2-45'/>
+<use x='118.897' y='127.501' xlink:href='#g2-99'/>
+<use x='121.25' y='127.501' xlink:href='#g2-111'/>
+<use x='123.749' y='127.501' xlink:href='#g2-114'/>
+<use x='125.556' y='127.501' xlink:href='#g2-101'/>
+<use x='129.673' y='127.501' xlink:href='#g2-73'/>
+<use x='131.143' y='127.501' xlink:href='#g2-110'/>
+<use x='133.876' y='127.501' xlink:href='#g2-116'/>
+<use x='135.787' y='127.501' xlink:href='#g2-101'/>
+<use x='138.14' y='127.501' xlink:href='#g2-108'/>
+<use x='141.166' y='127.501' xlink:href='#g2-105'/>
+<use x='142.429' y='127.501' xlink:href='#g2-51'/>
+<use x='146.84' y='127.501' xlink:href='#g2-64'/>
+<use x='150.368' y='127.501' xlink:href='#g2-51'/>
+<use x='153.015' y='127.501' xlink:href='#g2-46'/>
+<use x='154.485' y='127.501' xlink:href='#g2-54'/>
+<use x='157.131' y='127.501' xlink:href='#g2-71'/>
+<use x='160.66' y='127.501' xlink:href='#g2-104'/>
+<use x='163.392' y='127.501' xlink:href='#g2-122'/>
+<use x='114.487' y='133.479' xlink:href='#g2-109'/>
+<use x='118.69' y='133.479' xlink:href='#g2-97'/>
+<use x='121.232' y='133.479' xlink:href='#g2-99'/>
+<use x='123.585' y='133.479' xlink:href='#g2-79'/>
+<use x='127.494' y='133.479' xlink:href='#g2-83'/>
+<use x='132.198' y='133.479' xlink:href='#g2-67'/>
+<use x='135.58' y='133.479' xlink:href='#g2-97'/>
+<use x='138.122' y='133.479' xlink:href='#g2-116'/>
+<use x='140.034' y='133.479' xlink:href='#g2-97'/>
+<use x='142.576' y='133.479' xlink:href='#g2-108'/>
+<use x='143.839' y='133.479' xlink:href='#g2-105'/>
+<use x='145.101' y='133.479' xlink:href='#g2-110'/>
+<use x='147.834' y='133.479' xlink:href='#g2-97'/>
+<use x='152.141' y='133.479' xlink:href='#g2-49'/>
+<use x='154.787' y='133.479' xlink:href='#g2-48'/>
+<use x='157.434' y='133.479' xlink:href='#g2-46'/>
+<use x='158.904' y='133.479' xlink:href='#g2-49'/>
+<use x='161.55' y='133.479' xlink:href='#g2-53'/>
+<use x='164.197' y='133.479' xlink:href='#g2-46'/>
+<use x='165.667' y='133.479' xlink:href='#g2-55'/>
+<use x='168.313' y='133.479' xlink:href='#g2-44'/>
+<use x='171.548' y='133.479' xlink:href='#g2-65'/>
+<use x='175.076' y='133.479' xlink:href='#g2-112'/>
+<use x='177.809' y='133.479' xlink:href='#g2-112'/>
+<use x='180.542' y='133.479' xlink:href='#g2-108'/>
+<use x='181.805' y='133.479' xlink:href='#g2-101'/>
+<use x='185.921' y='133.479' xlink:href='#g2-99'/>
+<use x='188.273' y='133.479' xlink:href='#g2-108'/>
+<use x='189.536' y='133.479' xlink:href='#g2-97'/>
+<use x='192.079' y='133.479' xlink:href='#g2-110'/>
+<use x='194.812' y='133.479' xlink:href='#g2-103'/>
+<use x='199.222' y='133.479' xlink:href='#g2-49'/>
+<use x='201.868' y='133.479' xlink:href='#g2-49'/>
+<use x='204.515' y='133.479' xlink:href='#g2-46'/>
+<use x='205.985' y='133.479' xlink:href='#g2-48'/>
+<use x='208.631' y='133.479' xlink:href='#g2-46'/>
+<use x='210.102' y='133.479' xlink:href='#g2-51'/>
+<use x='114.487' y='139.456' xlink:href='#g2-56'/>
+<use x='118.897' y='139.456' xlink:href='#g2-108'/>
+<use x='120.16' y='139.456' xlink:href='#g2-111'/>
+<use x='122.806' y='139.456' xlink:href='#g2-103'/>
+<use x='125.453' y='139.456' xlink:href='#g2-105'/>
+<use x='126.715' y='139.456' xlink:href='#g2-99'/>
+<use x='129.068' y='139.456' xlink:href='#g2-97'/>
+<use x='131.61' y='139.456' xlink:href='#g2-108'/>
+<use x='134.637' y='139.456' xlink:href='#g2-99'/>
+<use x='136.989' y='139.456' xlink:href='#g2-111'/>
+<use x='139.489' y='139.456' xlink:href='#g2-114'/>
+<use x='141.296' y='139.456' xlink:href='#g2-101'/>
+<use x='143.648' y='139.456' xlink:href='#g2-115'/>
+<use x='114.487' y='145.434' xlink:href='#g2-50'/>
+<use x='117.133' y='145.434' xlink:href='#g2-48'/>
+<use x='119.779' y='145.434' xlink:href='#g2-50'/>
+<use x='122.426' y='145.434' xlink:href='#g2-49'/>
+<use x='125.072' y='145.434' xlink:href='#g2-45'/>
+<use x='126.836' y='145.434' xlink:href='#g2-48'/>
+<use x='129.483' y='145.434' xlink:href='#g2-49'/>
+<use x='132.129' y='145.434' xlink:href='#g2-45'/>
+<use x='133.893' y='145.434' xlink:href='#g2-51'/>
+<use x='136.54' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -46.129 249.778)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 11.066 249.778)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 68.26 249.778)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 125.455 249.778)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 182.649 249.778)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 -40.898 250.529)'>
+<use x='114.487' y='145.434' xlink:href='#g2-48'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-57'/>
+<use x='121.25' y='145.434' xlink:href='#g2-57'/>
+</g>
+<g transform='matrix(0 -1 1 0 16.296 249.277)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 73.491 252.158)'>
+<use x='114.487' y='145.434' xlink:href='#g2-48'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-57'/>
+<use x='121.25' y='145.434' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 130.685 249.903)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 187.88 246.584)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-53'/>
+</g>
+<g transform='matrix(0 -1 1 0 -35.668 230.49)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-51'/>
+<use x='121.25' y='145.434' xlink:href='#g2-49'/>
+</g>
+<g transform='matrix(0 -1 1 0 21.527 237.378)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-50'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 78.721 228.423)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-51'/>
+<use x='121.25' y='145.434' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 135.916 247.837)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-51'/>
+</g>
+<g transform='matrix(0 -1 1 0 193.11 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-53'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-52'/>
+<use x='126.877' y='145.434' xlink:href='#g2-55'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -30.437 228.549)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-51'/>
+<use x='121.25' y='145.434' xlink:href='#g2-52'/>
+</g>
+<g transform='matrix(0 -1 1 0 26.757 244.893)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 83.952 245.269)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 141.146 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-51'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-50'/>
+<use x='126.877' y='145.434' xlink:href='#g2-49'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 198.34 221.034)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-52'/>
+<use x='121.25' y='145.434' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 -25.207 245.519)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-48'/>
+<use x='121.25' y='145.434' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 31.988 239.696)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-49'/>
+<use x='121.25' y='145.434' xlink:href='#g2-54'/>
+</g>
+<g transform='matrix(0 -1 1 0 89.182 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-50'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-49'/>
+<use x='126.877' y='145.434' xlink:href='#g2-52'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 146.376 188.157)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-57'/>
+<use x='121.25' y='145.434' xlink:href='#g2-56'/>
+</g>
+<g transform='matrix(0 -1 1 0 203.571 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-52'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-52'/>
+<use x='126.877' y='145.434' xlink:href='#g2-57'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -19.976 187.155)'>
+<use x='114.487' y='145.434' xlink:href='#g2-50'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-50'/>
+<use x='121.25' y='145.434' xlink:href='#g2-48'/>
+</g>
+<g transform='matrix(0 -1 1 0 37.218 201.746)'>
+<use x='114.487' y='145.434' xlink:href='#g2-49'/>
+<use x='117.133' y='145.434' xlink:href='#g2-46'/>
+<use x='118.603' y='145.434' xlink:href='#g2-55'/>
+<use x='121.25' y='145.434' xlink:href='#g2-55'/>
+</g>
+<g transform='matrix(0 -1 1 0 94.413 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-56'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-48'/>
+<use x='126.877' y='145.434' xlink:href='#g2-52'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 151.607 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-50'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-55'/>
+<use x='126.877' y='145.434' xlink:href='#g2-56'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 208.801 187.155)'>
+<use x='109.598' y='145.434' xlink:href='#g4-1'/>
+<use x='113.103' y='145.434' xlink:href='#g4-1'/>
+<use x='116.608' y='145.434' xlink:href='#g4-1'/>
+<use x='120.114' y='145.434' xlink:href='#g2-56'/>
+<use x='122.76' y='145.434' xlink:href='#g2-46'/>
+<use x='124.23' y='145.434' xlink:href='#g2-54'/>
+<use x='126.877' y='145.434' xlink:href='#g2-49'/>
+<use x='129.523' y='145.434' xlink:href='#g2-120'/>
+</g>
+<g transform='matrix(0 -1 1 0 -86.074 311.062)'>
+<use x='114.487' y='145.434' xlink:href='#g1-82'/>
+<use x='120.457' y='145.434' xlink:href='#g1-101'/>
+<use x='124.553' y='145.434' xlink:href='#g1-108'/>
+<use x='126.753' y='145.434' xlink:href='#g1-97'/>
+<use x='131.181' y='145.434' xlink:href='#g1-116'/>
+<use x='134.509' y='145.434' xlink:href='#g1-105'/>
+<use x='136.709' y='145.434' xlink:href='#g1-118'/>
+<use x='140.957' y='145.434' xlink:href='#g1-101'/>
+<use x='148.124' y='145.434' xlink:href='#g1-116'/>
+<use x='151.452' y='145.434' xlink:href='#g1-105'/>
+<use x='153.652' y='145.434' xlink:href='#g1-109'/>
+<use x='160.972' y='145.434' xlink:href='#g1-101'/>
+<use x='168.139' y='145.434' xlink:href='#g3-40'/>
+<use x='171.432' y='145.434' xlink:href='#g3-108'/>
+<use x='173.453' y='145.434' xlink:href='#g3-111'/>
+<use x='177.452' y='145.434' xlink:href='#g3-119'/>
+<use x='183' y='145.434' xlink:href='#g3-101'/>
+<use x='186.764' y='145.434' xlink:href='#g3-114'/>
+<use x='192.479' y='145.434' xlink:href='#g3-105'/>
+<use x='194.499' y='145.434' xlink:href='#g3-115'/>
+<use x='200.568' y='145.434' xlink:href='#g3-98'/>
+<use x='205.176' y='145.434' xlink:href='#g3-101'/>
+<use x='208.94' y='145.434' xlink:href='#g3-116'/>
+<use x='211.998' y='145.434' xlink:href='#g3-116'/>
+<use x='215.056' y='145.434' xlink:href='#g3-101'/>
+<use x='218.819' y='145.434' xlink:href='#g3-114'/>
+<use x='221.711' y='145.434' xlink:href='#g3-41'/>
+</g>
+<path d='M82.348 262.243H231.688V232.317H82.348Z' fill='#fff'/>
+<path d='M82.348 262.243H231.688V232.317H82.348Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<path d='M85.535 242.77H88.523V234.801H85.535ZM91.516 242.77H94.504V236.793H91.516Z' fill='#933'/>
+<path d='M85.535 242.77H88.523V234.801H85.535ZM91.516 242.77H94.504V236.793H91.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -40.354 110.298)'>
+<use x='141.573' y='132.464' xlink:href='#g3-120'/>
+<use x='145.475' y='132.464' xlink:href='#g3-109'/>
+<use x='152.2' y='132.464' xlink:href='#g3-105'/>
+<use x='154.221' y='132.464' xlink:href='#g3-58'/>
+<use x='156.573' y='132.464' xlink:href='#g0-57'/>
+<use x='160.278' y='132.464' xlink:href='#g0-48'/>
+</g>
+<path d='M130.344 242.77H133.336V234.801H130.344ZM136.324 242.77H139.313V236.793H136.324Z' fill='#bf8080'/>
+<path d='M130.344 242.77H133.336V234.801H130.344ZM136.324 242.77H139.313V236.793H136.324Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -38.403 110.298)'>
+<use x='181.727' y='132.464' xlink:href='#g3-109'/>
+<use x='188.452' y='132.464' xlink:href='#g3-105'/>
+<use x='190.472' y='132.464' xlink:href='#g3-58'/>
+<use x='192.825' y='132.464' xlink:href='#g0-57'/>
+<use x='196.53' y='132.464' xlink:href='#g0-51'/>
+</g>
+<path d='M165.844 242.77H168.832V234.801H165.844ZM171.82 242.77H174.813V236.793H171.82Z' fill='#8080bf'/>
+<path d='M165.844 242.77H168.832V234.801H165.844ZM171.82 242.77H174.813V236.793H171.82Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.441 109.855)'>
+<use x='215.44' y='132.464' xlink:href='#g3-116'/>
+<use x='218.498' y='132.464' xlink:href='#g3-99'/>
+<use x='222.262' y='132.464' xlink:href='#g3-58'/>
+<use x='224.614' y='132.464' xlink:href='#g0-53'/>
+<use x='228.319' y='132.464' xlink:href='#g0-48'/>
+</g>
+<path d='M197.77 242.77H200.758V234.801H197.77ZM203.75 242.77H206.738V236.793H203.75Z' fill='#ffb733'/>
+<path d='M197.77 242.77H200.758V234.801H197.77ZM203.75 242.77H206.738V236.793H203.75Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -37.04 110.298)'>
+<use x='246.965' y='132.464' xlink:href='#g3-106'/>
+<use x='249.221' y='132.464' xlink:href='#g3-101'/>
+<use x='252.984' y='132.464' xlink:href='#g3-58'/>
+<use x='255.337' y='132.464' xlink:href='#g0-53'/>
+<use x='259.041' y='132.464' xlink:href='#g0-51'/>
+</g>
+<path d='M85.535 255.742H88.523V247.77H85.535ZM91.516 255.742H94.504V249.762H91.516Z' fill='#80bf80'/>
+<path d='M85.535 255.742H88.523V247.77H85.535ZM91.516 255.742H94.504V249.762H91.516Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -43.882 110.334)'>
+<use x='141.573' y='145.434' xlink:href='#g3-104'/>
+<use x='145.946' y='145.434' xlink:href='#g3-111'/>
+<use x='150.18' y='145.434' xlink:href='#g3-97'/>
+<use x='154.013' y='145.434' xlink:href='#g3-114'/>
+<use x='156.905' y='145.434' xlink:href='#g3-100'/>
+<use x='161.278' y='145.434' xlink:href='#g3-58'/>
+<use x='163.63' y='145.434' xlink:href='#g0-53'/>
+<use x='167.335' y='145.434' xlink:href='#g0-51'/>
+</g>
+<path d='M130.344 255.742H133.336V247.77H130.344ZM136.324 255.742H139.313V249.762H136.324Z' fill='#399'/>
+<path d='M130.344 255.742H133.336V247.77H130.344ZM136.324 255.742H139.313V249.762H136.324Z' stroke='#000' fill='none' stroke-width='.399' stroke-miterlimit='10'/>
+<g transform='matrix(1 0 0 1 -39.227 109.855)'>
+<use x='181.727' y='145.434' xlink:href='#g3-115'/>
+<use x='184.974' y='145.434' xlink:href='#g3-121'/>
+<use x='188.876' y='145.434' xlink:href='#g3-115'/>
+<use x='192.122' y='145.434' xlink:href='#g3-58'/>
+<use x='194.474' y='145.434' xlink:href='#g0-50'/>
+<use x='198.179' y='145.434' xlink:href='#g0-51'/>
+</g>
+</g>
+</svg>
\ No newline at end of file
--- /dev/null
+# Doxyfile 1.9.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the configuration
+# file that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = mi-malloc
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER = 1.7/2.0
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO = mimalloc-logo.svg
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ..
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all generated output in the proper direction.
+# Possible values are: None, LTR, RTL and Context.
+# The default value is: None.
+
+OUTPUT_TEXT_DIRECTION = None
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
+# such as
+# /***************
+# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
+# Javadoc-style will behave just like regular comments and it will not be
+# interpreted by doxygen.
+# The default value is: NO.
+
+JAVADOC_BANNER = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# By default Python docstrings are displayed as preformatted text and doxygen's
+# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
+# doxygen's special commands can be used and the contents of the docstring
+# documentation blocks is shown as doxygen documentation.
+# The default value is: YES.
+
+PYTHON_DOCSTRING = YES
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 2
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines (in the resulting output). You can put ^^ in the value part of an
+# alias to insert a newline as if a physical newline was in the original file.
+# When you need a literal { or } or , in the value part of an alias you have to
+# escape them by means of a backslash (\), this can lead to conflicts with the
+# commands \{ and \} for these it is advised to use the version @{ and @} or use
+# a double escape (\\{ and \\})
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
+# sources only. Doxygen will then generate output that is more tailored for that
+# language. For instance, namespaces will be presented as modules, types will be
+# separated into more groups, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_SLICE = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
+# tries to guess whether the code is fixed or free formatted code, this is the
+# default for Fortran type files). For instance to make doxygen treat .inc files
+# as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen. When specifying no_extension you should add
+# * to the FILE_PATTERNS.
+#
+# Note see also the list of default file extension mappings.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 5.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = YES
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = YES
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
+# during processing. When set to 0 doxygen will based this on the number of
+# cores available in the system. You can set it explicitly to a value larger
+# than 0 to get more control over the balance between CPU load and processing
+# speed. At this moment only the input processing can be done using multiple
+# threads. Since this is still an experimental feature the default is set to 1,
+# which efficively disables parallel processing. Please report any issues you
+# encounter. Generating dot graphs in parallel is controlled by the
+# DOT_NUM_THREADS setting.
+# Minimum value: 0, maximum value: 32, default value: 1.
+
+NUM_PROC_THREADS = 1
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
+# methods of a class will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIV_VIRTUAL = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If this flag is set to YES, the name of an unnamed parameter in a declaration
+# will be determined by the corresponding definition. By default unnamed
+# parameters remain unnamed in the output.
+# The default value is: YES.
+
+RESOLVE_UNNAMED_PARAMS = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# declarations. If set to NO, these declarations will be included in the
+# documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
+# able to match the capabilities of the underlying filesystem. In case the
+# filesystem is case sensitive (i.e. it supports files in the same directory
+# whose names only differ in casing), the option must be set to YES to properly
+# deal with such files in case they appear in the input. For filesystems that
+# are not case sensitive the option should be be set to NO to properly deal with
+# output files written for symbols that only differ in casing, such as for two
+# classes, one named CLASS and the other named Class, and to also support
+# references to files without having to specify the exact matching casing. On
+# Windows (including Cygwin) and MacOS, users should typically set this option
+# to NO, whereas on Linux or other Unix flavors it should typically be set to
+# YES.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 0
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation. If
+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
+# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
+# at the end of the doxygen process doxygen will return with a non-zero status.
+# Possible values are: NO, YES and FAIL_ON_WARNINGS.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = mimalloc-doc.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see:
+# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# Note the list of default checked file patterns might differ from the list of
+# default file extension mappings.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
+# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
+# *.ucf, *.qsf and *.ice.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.pyw \
+ *.f90 \
+ *.f95 \
+ *.f03 \
+ *.f08 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# entity all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see https://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see:
+# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
+# performance. This can be particularly helpful with template rich C++ code for
+# which doxygen's built-in parser lacks the necessary type information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse_libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to
+# YES then doxygen will add the directory of each input to the include path.
+# The default value is: YES.
+
+CLANG_ADD_INC_PATHS = YES
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+# If clang assisted parsing is enabled you can provide the clang parser with the
+# path to the directory containing a file called compile_commands.json. This
+# file is the compilation database (see:
+# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
+# options used when the source files were built. This is equivalent to
+# specifying the -p option to a clang tool, such as clang-check. These options
+# will then be passed to the parser. Any options specified with CLANG_OPTIONS
+# will be added as well.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse_libclang=ON option for CMake.
+
+CLANG_DATABASE_PATH =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = docs
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET = mimalloc-doxygen.css
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 189
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 12
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 240
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via JavaScript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have JavaScript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see:
+# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
+# create a documentation set, doxygen will generate a Makefile in the HTML
+# output directory. Running make will produce the docset in that directory and
+# running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
+# genXcode/_index.html for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see:
+# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the main .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location (absolute path
+# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
+# run qhelpgenerator on the generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 180
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
+# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
+# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
+# the HTML output. These images will generally look nicer at scaled resolutions.
+# Possible values are: png (the default) and svg (looks nicer but requires the
+# pdf2svg or inkscape tool).
+# The default value is: png.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FORMULA_FORMAT = png
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
+# to create new LaTeX commands to be used in formulas as building blocks. See
+# the section "Including formulas" for details.
+
+FORMULA_MACROFILE =
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# https://www.mathjax.org) which uses client side JavaScript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see:
+# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using JavaScript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see:
+# https://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see:
+# https://xapian.org/). See the section "External Indexing and Searching" for
+# details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when not enabling USE_PDFLATEX the default is latex when enabling
+# USE_PDFLATEX the default is pdflatex and when in the later case latex is
+# chosen this is overwritten by pdflatex. For specific output languages the
+# default can have been set differently, this depends on the implementation of
+# the output language.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# Note: This tag is used in the Makefile / make.bat.
+# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
+# (.tex).
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
+# generate index for LaTeX. In case there is no backslash (\) as first character
+# it will be automatically added in the LaTeX code.
+# Note: This tag is used in the generated output file (.tex).
+# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
+# The default value is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_MAKEINDEX_CMD = \makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
+# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
+# files. Set this option to YES, to get a higher quality PDF documentation.
+#
+# See also section LATEX_CMD_NAME for selecting the engine.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
+# path from which the emoji images will be read. If a relative path is entered,
+# it will be relative to the LATEX_OUTPUT directory. If left blank the
+# LATEX_OUTPUT directory will be used.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EMOJI_DIRECTORY =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# configuration file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's configuration file. A template extensions file can be
+# generated using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
+# namespace members in file scope as well, matching the HTML output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_NS_MEMB_FILE_SCOPE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
+# the structure of the code including all documentation. Note that this feature
+# is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to Sqlite3 output
+#---------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag UML_LOOK is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
+# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
+# tag is set to YES, doxygen will add type and arguments for attributes and
+# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
+# will not generate fields with class member information in the UML graphs. The
+# class diagrams will look similar to the default class diagrams but using UML
+# notation for the relationships.
+# Possible values are: NO, YES and NONE.
+# The default value is: NO.
+# This tag requires that the tag UML_LOOK is set to YES.
+
+DOT_UML_DETAILS = NO
+
+# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
+# to display on a single line. If the actual line length exceeds this threshold
+# significantly it will wrapped across multiple lines. Some heuristics are apply
+# to avoid ugly line breaks.
+# Minimum value: 0, maximum value: 1000, default value: 17.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_WRAP_THRESHOLD = 17
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
+# files that are used to generate the various graphs.
+#
+# Note: This setting is not only used for dot files but also for msc and
+# plantuml temporary files.
+# The default value is: YES.
+
+DOT_CLEANUP = YES
--- /dev/null
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+
+#error "documentation file only!"
+
+
+/*! \mainpage
+
+This is the API documentation of the
+[mimalloc](https://github.com/microsoft/mimalloc) allocator
+(pronounced "me-malloc") -- a
+general purpose allocator with excellent [performance](bench.html)
+characteristics. Initially
+developed by Daan Leijen for the run-time systems of the
+[Koka](https://github.com/koka-lang/koka) and [Lean](https://github.com/leanprover/lean) languages.
+
+It is a drop-in replacement for `malloc` and can be used in other programs
+without code changes, for example, on Unix you can use it as:
+```
+> LD_PRELOAD=/usr/bin/libmimalloc.so myprogram
+```
+
+Notable aspects of the design include:
+
+- __small and consistent__: the library is about 8k LOC using simple and
+ consistent data structures. This makes it very suitable
+ to integrate and adapt in other projects. For runtime systems it
+ provides hooks for a monotonic _heartbeat_ and deferred freeing (for
+ bounded worst-case times with reference counting).
+- __free list sharding__: instead of one big free list (per size class) we have
+ many smaller lists per "mimalloc page" which reduces fragmentation and
+ increases locality --
+ things that are allocated close in time get allocated close in memory.
+ (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system).
+- __free list multi-sharding__: the big idea! Not only do we shard the free list
+ per mimalloc page, but for each page we have multiple free lists. In particular, there
+ is one list for thread-local `free` operations, and another one for concurrent `free`
+ operations. Free-ing from another thread can now be a single CAS without needing
+ sophisticated coordination between threads. Since there will be
+ thousands of separate free lists, contention is naturally distributed over the heap,
+ and the chance of contending on a single location will be low -- this is quite
+ similar to randomized algorithms like skip lists where adding
+ a random oracle removes the need for a more complex algorithm.
+- __eager page reset__: when a "page" becomes empty (with increased chance
+ due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged")
+ reducing (real) memory pressure and fragmentation, especially in long running
+ programs.
+- __secure__: _mimalloc_ can be build in secure mode, adding guard pages,
+ randomized allocation, encrypted free lists, etc. to protect against various
+ heap vulnerabilities. The performance penalty is only around 5% on average
+ over our benchmarks.
+- __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions.
+ A heap can be destroyed at once instead of deallocating each object separately.
+- __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation
+ times (_wcat_), bounded space overhead (~0.2% meta-data, with at most 12.5% waste in allocation sizes),
+ and has no internal points of contention using only atomic operations.
+- __fast__: In our benchmarks (see [below](#performance)),
+ _mimalloc_ outperforms all other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc),
+ and usually uses less memory (up to 25% more in the worst case). A nice property
+ is that it does consistently well over a wide range of benchmarks.
+
+You can read more on the design of _mimalloc_ in the
+[technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action)
+which also has detailed benchmark results.
+
+
+Further information:
+
+- \ref build
+- \ref using
+- \ref environment
+- \ref overrides
+- \ref bench
+- \ref malloc
+- \ref extended
+- \ref aligned
+- \ref heap
+- \ref typed
+- \ref analysis
+- \ref options
+- \ref posix
+- \ref cpp
+
+*/
+
+
+/// \defgroup malloc Basic Allocation
+/// The basic allocation interface.
+/// \{
+
+
+/// Free previously allocated memory.
+/// The pointer `p` must have been allocated before (or be \a NULL).
+/// @param p pointer to free, or \a NULL.
+void mi_free(void* p);
+
+/// Allocate \a size bytes.
+/// @param size number of bytes to allocate.
+/// @returns pointer to the allocated memory or \a NULL if out of memory.
+/// Returns a unique pointer if called with \a size 0.
+void* mi_malloc(size_t size);
+
+/// Allocate zero-initialized `size` bytes.
+/// @param size The size in bytes.
+/// @returns Pointer to newly allocated zero initialized memory,
+/// or \a NULL if out of memory.
+void* mi_zalloc(size_t size);
+
+/// Allocate zero-initialized \a count elements of \a size bytes.
+/// @param count number of elements.
+/// @param size size of each element.
+/// @returns pointer to the allocated memory
+/// of \a size*\a count bytes, or \a NULL if either out of memory
+/// or when `count*size` overflows.
+///
+/// Returns a unique pointer if called with either \a size or \a count of 0.
+/// @see mi_zalloc()
+void* mi_calloc(size_t count, size_t size);
+
+/// Re-allocate memory to \a newsize bytes.
+/// @param p pointer to previously allocated memory (or \a NULL).
+/// @param newsize the new required size in bytes.
+/// @returns pointer to the re-allocated memory
+/// of \a newsize bytes, or \a NULL if out of memory.
+/// If \a NULL is returned, the pointer \a p is not freed.
+/// Otherwise the original pointer is either freed or returned
+/// as the reallocated result (in case it fits in-place with the
+/// new size). If the pointer \a p is \a NULL, it behaves as
+/// \a mi_malloc(\a newsize). If \a newsize is larger than the
+/// original \a size allocated for \a p, the bytes after \a size
+/// are uninitialized.
+void* mi_realloc(void* p, size_t newsize);
+
+/// Re-allocate memory to \a count elements of \a size bytes, with extra memory initialized to zero.
+/// @param p Pointer to a previously allocated block (or \a NULL).
+/// @param count The number of elements.
+/// @param size The size of each element.
+/// @returns A pointer to a re-allocated block of \a count * \a size bytes, or \a NULL
+/// if out of memory or if \a count * \a size overflows.
+///
+/// If there is no overflow, it behaves exactly like `mi_rezalloc(p,count*size)`.
+/// @see mi_reallocn()
+/// @see [recallocarray()](http://man.openbsd.org/reallocarray) (on BSD).
+void* mi_recalloc(void* p, size_t count, size_t size);
+
+/// Try to re-allocate memory to \a newsize bytes _in place_.
+/// @param p pointer to previously allocated memory (or \a NULL).
+/// @param newsize the new required size in bytes.
+/// @returns pointer to the re-allocated memory
+/// of \a newsize bytes (always equal to \a p),
+/// or \a NULL if either out of memory or if
+/// the memory could not be expanded in place.
+/// If \a NULL is returned, the pointer \a p is not freed.
+/// Otherwise the original pointer is returned
+/// as the reallocated result since it fits in-place with the
+/// new size. If \a newsize is larger than the
+/// original \a size allocated for \a p, the bytes after \a size
+/// are uninitialized.
+void* mi_expand(void* p, size_t newsize);
+
+/// Allocate \a count elements of \a size bytes.
+/// @param count The number of elements.
+/// @param size The size of each element.
+/// @returns A pointer to a block of \a count * \a size bytes, or \a NULL
+/// if out of memory or if \a count * \a size overflows.
+///
+/// If there is no overflow, it behaves exactly like `mi_malloc(p,count*size)`.
+/// @see mi_calloc()
+/// @see mi_zallocn()
+void* mi_mallocn(size_t count, size_t size);
+
+/// Re-allocate memory to \a count elements of \a size bytes.
+/// @param p Pointer to a previously allocated block (or \a NULL).
+/// @param count The number of elements.
+/// @param size The size of each element.
+/// @returns A pointer to a re-allocated block of \a count * \a size bytes, or \a NULL
+/// if out of memory or if \a count * \a size overflows.
+///
+/// If there is no overflow, it behaves exactly like `mi_realloc(p,count*size)`.
+/// @see [reallocarray()](<http://man.openbsd.org/reallocarray>) (on BSD)
+void* mi_reallocn(void* p, size_t count, size_t size);
+
+/// Re-allocate memory to \a newsize bytes,
+/// @param p pointer to previously allocated memory (or \a NULL).
+/// @param newsize the new required size in bytes.
+/// @returns pointer to the re-allocated memory
+/// of \a newsize bytes, or \a NULL if out of memory.
+///
+/// In contrast to mi_realloc(), if \a NULL is returned, the original pointer
+/// \a p is freed (if it was not \a NULL itself).
+/// Otherwise the original pointer is either freed or returned
+/// as the reallocated result (in case it fits in-place with the
+/// new size). If the pointer \a p is \a NULL, it behaves as
+/// \a mi_malloc(\a newsize). If \a newsize is larger than the
+/// original \a size allocated for \a p, the bytes after \a size
+/// are uninitialized.
+///
+/// @see [reallocf](https://www.freebsd.org/cgi/man.cgi?query=reallocf) (on BSD)
+void* mi_reallocf(void* p, size_t newsize);
+
+
+/// Allocate and duplicate a string.
+/// @param s string to duplicate (or \a NULL).
+/// @returns a pointer to newly allocated memory initialized
+/// to string \a s, or \a NULL if either out of memory or if
+/// \a s is \a NULL.
+///
+/// Replacement for the standard [strdup()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html)
+/// such that mi_free() can be used on the returned result.
+char* mi_strdup(const char* s);
+
+/// Allocate and duplicate a string up to \a n bytes.
+/// @param s string to duplicate (or \a NULL).
+/// @param n maximum number of bytes to copy (excluding the terminating zero).
+/// @returns a pointer to newly allocated memory initialized
+/// to string \a s up to the first \a n bytes (and always zero terminated),
+/// or \a NULL if either out of memory or if \a s is \a NULL.
+///
+/// Replacement for the standard [strndup()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html)
+/// such that mi_free() can be used on the returned result.
+char* mi_strndup(const char* s, size_t n);
+
+/// Resolve a file path name.
+/// @param fname File name.
+/// @param resolved_name Should be \a NULL (but can also point to a buffer
+/// of at least \a PATH_MAX bytes).
+/// @returns If successful a pointer to the resolved absolute file name, or
+/// \a NULL on failure (with \a errno set to the error code).
+///
+/// If \a resolved_name was \a NULL, the returned result should be freed with
+/// mi_free().
+///
+/// Replacement for the standard [realpath()](http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html)
+/// such that mi_free() can be used on the returned result (if \a resolved_name was \a NULL).
+char* mi_realpath(const char* fname, char* resolved_name);
+
+/// \}
+
+// ------------------------------------------------------
+// Extended functionality
+// ------------------------------------------------------
+
+/// \defgroup extended Extended Functions
+/// Extended functionality.
+/// \{
+
+/// Maximum size allowed for small allocations in
+/// #mi_malloc_small and #mi_zalloc_small (usually `128*sizeof(void*)` (= 1KB on 64-bit systems))
+#define MI_SMALL_SIZE_MAX (128*sizeof(void*))
+
+/// Allocate a small object.
+/// @param size The size in bytes, can be at most #MI_SMALL_SIZE_MAX.
+/// @returns a pointer to newly allocated memory of at least \a size
+/// bytes, or \a NULL if out of memory.
+/// This function is meant for use in run-time systems for best
+/// performance and does not check if \a size was indeed small -- use
+/// with care!
+void* mi_malloc_small(size_t size);
+
+/// Allocate a zero initialized small object.
+/// @param size The size in bytes, can be at most #MI_SMALL_SIZE_MAX.
+/// @returns a pointer to newly allocated zero-initialized memory of at
+/// least \a size bytes, or \a NULL if out of memory.
+/// This function is meant for use in run-time systems for best
+/// performance and does not check if \a size was indeed small -- use
+/// with care!
+void* mi_zalloc_small(size_t size);
+
+/// Return the available bytes in a memory block.
+/// @param p Pointer to previously allocated memory (or \a NULL)
+/// @returns Returns the available bytes in the memory block, or
+/// 0 if \a p was \a NULL.
+///
+/// The returned size can be
+/// used to call \a mi_expand successfully.
+/// The returned size is always at least equal to the
+/// allocated size of \a p, and, in the current design,
+/// should be less than 16.7% more.
+///
+/// @see [_msize](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/msize?view=vs-2017) (Windows)
+/// @see [malloc_usable_size](http://man7.org/linux/man-pages/man3/malloc_usable_size.3.html) (Linux)
+/// @see mi_good_size()
+size_t mi_usable_size(void* p);
+
+/// Return the used allocation size.
+/// @param size The minimal required size in bytes.
+/// @returns the size `n` that will be allocated, where `n >= size`.
+///
+/// Generally, `mi_usable_size(mi_malloc(size)) == mi_good_size(size)`.
+/// This can be used to reduce internal wasted space when
+/// allocating buffers for example.
+///
+/// @see mi_usable_size()
+size_t mi_good_size(size_t size);
+
+/// Eagerly free memory.
+/// @param force If \a true, aggressively return memory to the OS (can be expensive!)
+///
+/// Regular code should not have to call this function. It can be beneficial
+/// in very narrow circumstances; in particular, when a long running thread
+/// allocates a lot of blocks that are freed by other threads it may improve
+/// resource usage by calling this every once in a while.
+void mi_collect(bool force);
+
+/// Deprecated
+/// @param out Ignored, outputs to the registered output function or stderr by default.
+///
+/// Most detailed when using a debug build.
+void mi_stats_print(void* out);
+
+/// Print the main statistics.
+/// @param out An output function or \a NULL for the default.
+/// @param arg Optional argument passed to \a out (if not \a NULL)
+///
+/// Most detailed when using a debug build.
+void mi_stats_print_out(mi_output_fun* out, void* arg);
+
+/// Reset statistics.
+void mi_stats_reset(void);
+
+/// Merge thread local statistics with the main statistics and reset.
+void mi_stats_merge(void);
+
+/// Initialize mimalloc on a thread.
+/// Should not be used as on most systems (pthreads, windows) this is done
+/// automatically.
+void mi_thread_init(void);
+
+/// Uninitialize mimalloc on a thread.
+/// Should not be used as on most systems (pthreads, windows) this is done
+/// automatically. Ensures that any memory that is not freed yet (but will
+/// be freed by other threads in the future) is properly handled.
+void mi_thread_done(void);
+
+/// Print out heap statistics for this thread.
+/// @param out An output function or \a NULL for the default.
+/// @param arg Optional argument passed to \a out (if not \a NULL)
+///
+/// Most detailed when using a debug build.
+void mi_thread_stats_print_out(mi_output_fun* out, void* arg);
+
+/// Type of deferred free functions.
+/// @param force If \a true all outstanding items should be freed.
+/// @param heartbeat A monotonically increasing count.
+/// @param arg Argument that was passed at registration to hold extra state.
+///
+/// @see mi_register_deferred_free
+typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg);
+
+/// Register a deferred free function.
+/// @param deferred_free Address of a deferred free-ing function or \a NULL to unregister.
+/// @param arg Argument that will be passed on to the deferred free function.
+///
+/// Some runtime systems use deferred free-ing, for example when using
+/// reference counting to limit the worst case free time.
+/// Such systems can register (re-entrant) deferred free function
+/// to free more memory on demand. When the \a force parameter is
+/// \a true all possible memory should be freed.
+/// The per-thread \a heartbeat parameter is monotonically increasing
+/// and guaranteed to be deterministic if the program allocates
+/// deterministically. The \a deferred_free function is guaranteed
+/// to be called deterministically after some number of allocations
+/// (regardless of freeing or available free memory).
+/// At most one \a deferred_free function can be active.
+void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg);
+
+/// Type of output functions.
+/// @param msg Message to output.
+/// @param arg Argument that was passed at registration to hold extra state.
+///
+/// @see mi_register_output()
+typedef void (mi_output_fun)(const char* msg, void* arg);
+
+/// Register an output function.
+/// @param out The output function, use `NULL` to output to stderr.
+/// @param arg Argument that will be passed on to the output function.
+///
+/// The `out` function is called to output any information from mimalloc,
+/// like verbose or warning messages.
+void mi_register_output(mi_output_fun* out, void* arg);
+
+/// Type of error callback functions.
+/// @param err Error code (see mi_register_error() for a complete list).
+/// @param arg Argument that was passed at registration to hold extra state.
+///
+/// @see mi_register_error()
+typedef void (mi_error_fun)(int err, void* arg);
+
+/// Register an error callback function.
+/// @param errfun The error function that is called on an error (use \a NULL for default)
+/// @param arg Extra argument that will be passed on to the error function.
+///
+/// The \a errfun function is called on an error in mimalloc after emitting
+/// an error message (through the output function). It as always legal to just
+/// return from the \a errfun function in which case allocation functions generally
+/// return \a NULL or ignore the condition. The default function only calls abort()
+/// when compiled in secure mode with an \a EFAULT error. The possible error
+/// codes are:
+/// * \a EAGAIN: Double free was detected (only in debug and secure mode).
+/// * \a EFAULT: Corrupted free list or meta-data was detected (only in debug and secure mode).
+/// * \a ENOMEM: Not enough memory available to satisfy the request.
+/// * \a EOVERFLOW: Too large a request, for example in mi_calloc(), the \a count and \a size parameters are too large.
+/// * \a EINVAL: Trying to free or re-allocate an invalid pointer.
+void mi_register_error(mi_error_fun* errfun, void* arg);
+
+/// Is a pointer part of our heap?
+/// @param p The pointer to check.
+/// @returns \a true if this is a pointer into our heap.
+/// This function is relatively fast.
+bool mi_is_in_heap_region(const void* p);
+
+/// Reserve OS memory for use by mimalloc. Reserved areas are used
+/// before allocating from the OS again. By reserving a large area upfront,
+/// allocation can be more efficient, and can be better managed on systems
+/// without `mmap`/`VirtualAlloc` (like WASM for example).
+/// @param size The size to reserve.
+/// @param commit Commit the memory upfront.
+/// @param allow_large Allow large OS pages (2MiB) to be used?
+/// @return \a 0 if successful, and an error code otherwise (e.g. `ENOMEM`).
+int mi_reserve_os_memory(size_t size, bool commit, bool allow_large);
+
+/// Manage a particular memory area for use by mimalloc.
+/// This is just like `mi_reserve_os_memory` except that the area should already be
+/// allocated in some manner and available for use my mimalloc.
+/// @param start Start of the memory area
+/// @param size The size of the memory area.
+/// @param commit Is the area already committed?
+/// @param is_large Does it consist of large OS pages? Set this to \a true as well for memory
+/// that should not be decommitted or protected (like rdma etc.)
+/// @param is_zero Does the area consists of zero's?
+/// @param numa_node Possible associated numa node or `-1`.
+/// @return \a true if successful, and \a false on error.
+bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node);
+
+/// Reserve \a pages of huge OS pages (1GiB) evenly divided over \a numa_nodes nodes,
+/// but stops after at most `timeout_msecs` seconds.
+/// @param pages The number of 1GiB pages to reserve.
+/// @param numa_nodes The number of nodes do evenly divide the pages over, or 0 for using the actual number of NUMA nodes.
+/// @param timeout_msecs Maximum number of milli-seconds to try reserving, or 0 for no timeout.
+/// @returns 0 if successfull, \a ENOMEM if running out of memory, or \a ETIMEDOUT if timed out.
+///
+/// The reserved memory is used by mimalloc to satisfy allocations.
+/// May quit before \a timeout_msecs are expired if it estimates it will take more than
+/// 1.5 times \a timeout_msecs. The time limit is needed because on some operating systems
+/// it can take a long time to reserve contiguous memory if the physical memory is
+/// fragmented.
+int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs);
+
+/// Reserve \a pages of huge OS pages (1GiB) at a specific \a numa_node,
+/// but stops after at most `timeout_msecs` seconds.
+/// @param pages The number of 1GiB pages to reserve.
+/// @param numa_node The NUMA node where the memory is reserved (start at 0).
+/// @param timeout_msecs Maximum number of milli-seconds to try reserving, or 0 for no timeout.
+/// @returns 0 if successfull, \a ENOMEM if running out of memory, or \a ETIMEDOUT if timed out.
+///
+/// The reserved memory is used by mimalloc to satisfy allocations.
+/// May quit before \a timeout_msecs are expired if it estimates it will take more than
+/// 1.5 times \a timeout_msecs. The time limit is needed because on some operating systems
+/// it can take a long time to reserve contiguous memory if the physical memory is
+/// fragmented.
+int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs);
+
+
+/// Is the C runtime \a malloc API redirected?
+/// @returns \a true if all malloc API calls are redirected to mimalloc.
+///
+/// Currenty only used on Windows.
+bool mi_is_redirected();
+
+/// Return process information (time and memory usage).
+/// @param elapsed_msecs Optional. Elapsed wall-clock time of the process in milli-seconds.
+/// @param user_msecs Optional. User time in milli-seconds (as the sum over all threads).
+/// @param system_msecs Optional. System time in milli-seconds.
+/// @param current_rss Optional. Current working set size (touched pages).
+/// @param peak_rss Optional. Peak working set size (touched pages).
+/// @param current_commit Optional. Current committed memory (backed by the page file).
+/// @param peak_commit Optional. Peak committed memory (backed by the page file).
+/// @param page_faults Optional. Count of hard page faults.
+///
+/// The \a current_rss is precise on Windows and MacOSX; other systems estimate
+/// this using \a current_commit. The \a commit is precise on Windows but estimated
+/// on other systems as the amount of read/write accessible memory reserved by mimalloc.
+void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults);
+
+/// \}
+
+// ------------------------------------------------------
+// Aligned allocation
+// ------------------------------------------------------
+
+/// \defgroup aligned Aligned Allocation
+///
+/// Allocating aligned memory blocks.
+///
+/// \{
+
+/// The maximum supported alignment size (currently 1MiB).
+#define MI_ALIGNMENT_MAX (1024*1024UL)
+
+/// Allocate \a size bytes aligned by \a alignment.
+/// @param size number of bytes to allocate.
+/// @param alignment the minimal alignment of the allocated memory. Must be less than #MI_ALIGNMENT_MAX.
+/// @returns pointer to the allocated memory or \a NULL if out of memory.
+/// The returned pointer is aligned by \a alignment, i.e.
+/// `(uintptr_t)p % alignment == 0`.
+///
+/// Returns a unique pointer if called with \a size 0.
+/// @see [_aligned_malloc](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc?view=vs-2017) (on Windows)
+/// @see [aligned_alloc](http://man.openbsd.org/reallocarray) (on BSD, with switched arguments!)
+/// @see [posix_memalign](https://linux.die.net/man/3/posix_memalign) (on Posix, with switched arguments!)
+/// @see [memalign](https://linux.die.net/man/3/posix_memalign) (on Linux, with switched arguments!)
+void* mi_malloc_aligned(size_t size, size_t alignment);
+void* mi_zalloc_aligned(size_t size, size_t alignment);
+void* mi_calloc_aligned(size_t count, size_t size, size_t alignment);
+void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment);
+
+/// Allocate \a size bytes aligned by \a alignment at a specified \a offset.
+/// @param size number of bytes to allocate.
+/// @param alignment the minimal alignment of the allocated memory at \a offset.
+/// @param offset the offset that should be aligned.
+/// @returns pointer to the allocated memory or \a NULL if out of memory.
+/// The returned pointer is aligned by \a alignment at \a offset, i.e.
+/// `((uintptr_t)p + offset) % alignment == 0`.
+///
+/// Returns a unique pointer if called with \a size 0.
+/// @see [_aligned_offset_malloc](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-offset-malloc?view=vs-2017) (on Windows)
+void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset);
+void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset);
+void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset);
+void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
+
+/// \}
+
+/// \defgroup heap Heap Allocation
+///
+/// First-class heaps that can be destroyed in one go.
+///
+/// \{
+
+/// Type of first-class heaps.
+/// A heap can only be used for allocation in
+/// the thread that created this heap! Any allocated
+/// blocks can be freed or reallocated by any other thread though.
+struct mi_heap_s;
+
+/// Type of first-class heaps.
+/// A heap can only be used for (re)allocation in
+/// the thread that created this heap! Any allocated
+/// blocks can be freed by any other thread though.
+typedef struct mi_heap_s mi_heap_t;
+
+/// Create a new heap that can be used for allocation.
+mi_heap_t* mi_heap_new();
+
+/// Delete a previously allocated heap.
+/// This will release resources and migrate any
+/// still allocated blocks in this heap (efficienty)
+/// to the default heap.
+///
+/// If \a heap is the default heap, the default
+/// heap is set to the backing heap.
+void mi_heap_delete(mi_heap_t* heap);
+
+/// Destroy a heap, freeing all its still allocated blocks.
+/// Use with care as this will free all blocks still
+/// allocated in the heap. However, this can be a very
+/// efficient way to free all heap memory in one go.
+///
+/// If \a heap is the default heap, the default
+/// heap is set to the backing heap.
+void mi_heap_destroy(mi_heap_t* heap);
+
+/// Set the default heap to use for mi_malloc() et al.
+/// @param heap The new default heap.
+/// @returns The previous default heap.
+mi_heap_t* mi_heap_set_default(mi_heap_t* heap);
+
+/// Get the default heap that is used for mi_malloc() et al.
+/// @returns The current default heap.
+mi_heap_t* mi_heap_get_default();
+
+/// Get the backing heap.
+/// The _backing_ heap is the initial default heap for
+/// a thread and always available for allocations.
+/// It cannot be destroyed or deleted
+/// except by exiting the thread.
+mi_heap_t* mi_heap_get_backing();
+
+/// Release outstanding resources in a specific heap.
+void mi_heap_collect(mi_heap_t* heap, bool force);
+
+/// Allocate in a specific heap.
+/// @see mi_malloc()
+void* mi_heap_malloc(mi_heap_t* heap, size_t size);
+
+/// Allocate a small object in a specific heap.
+/// \a size must be smaller or equal to MI_SMALL_SIZE_MAX().
+/// @see mi_malloc()
+void* mi_heap_malloc_small(mi_heap_t* heap, size_t size);
+
+/// Allocate zero-initialized in a specific heap.
+/// @see mi_zalloc()
+void* mi_heap_zalloc(mi_heap_t* heap, size_t size);
+
+/// Allocate \a count zero-initialized elements in a specific heap.
+/// @see mi_calloc()
+void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size);
+
+/// Allocate \a count elements in a specific heap.
+/// @see mi_mallocn()
+void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size);
+
+/// Duplicate a string in a specific heap.
+/// @see mi_strdup()
+char* mi_heap_strdup(mi_heap_t* heap, const char* s);
+
+/// Duplicate a string of at most length \a n in a specific heap.
+/// @see mi_strndup()
+char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n);
+
+/// Resolve a file path name using a specific \a heap to allocate the result.
+/// @see mi_realpath()
+char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name);
+
+void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize);
+void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size);
+void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize);
+
+void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
+void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
+void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
+void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
+void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment);
+void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset);
+void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
+void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
+
+/// \}
+
+
+/// \defgroup zeroinit Zero initialized re-allocation
+///
+/// The zero-initialized re-allocations are only valid on memory that was
+/// originally allocated with zero initialization too.
+/// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc.
+/// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992>
+///
+/// \{
+
+void* mi_rezalloc(void* p, size_t newsize);
+void* mi_recalloc(void* p, size_t newcount, size_t size) ;
+
+void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment);
+void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
+void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment);
+void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset);
+
+void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize);
+void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size);
+
+void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
+void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
+void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment);
+void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset);
+
+/// \}
+
+/// \defgroup typed Typed Macros
+///
+/// Typed allocation macros. For example:
+/// ```
+/// int* p = mi_malloc_tp(int)
+/// ```
+///
+/// \{
+
+/// Allocate a block of type \a tp.
+/// @param tp The type of the block to allocate.
+/// @returns A pointer to an object of type \a tp, or
+/// \a NULL if out of memory.
+///
+/// **Example:**
+/// ```
+/// int* p = mi_malloc_tp(int)
+/// ```
+///
+/// @see mi_malloc()
+#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp)))
+
+/// Allocate a zero-initialized block of type \a tp.
+#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp)))
+
+/// Allocate \a count zero-initialized blocks of type \a tp.
+#define mi_calloc_tp(tp,count) ((tp*)mi_calloc(count,sizeof(tp)))
+
+/// Allocate \a count blocks of type \a tp.
+#define mi_mallocn_tp(tp,count) ((tp*)mi_mallocn(count,sizeof(tp)))
+
+/// Re-allocate to \a count blocks of type \a tp.
+#define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp)))
+
+/// Allocate a block of type \a tp in a heap \a hp.
+#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))
+
+/// Allocate a zero-initialized block of type \a tp in a heap \a hp.
+#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))
+
+/// Allocate \a count zero-initialized blocks of type \a tp in a heap \a hp.
+#define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp)))
+
+/// Allocate \a count blocks of type \a tp in a heap \a hp.
+#define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp)))
+
+/// Re-allocate to \a count blocks of type \a tp in a heap \a hp.
+#define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp)))
+
+/// Re-allocate to \a count zero initialized blocks of type \a tp in a heap \a hp.
+#define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp)))
+
+/// \}
+
+/// \defgroup analysis Heap Introspection
+///
+/// Inspect the heap at runtime.
+///
+/// \{
+
+/// Does a heap contain a pointer to a previously allocated block?
+/// @param heap The heap.
+/// @param p Pointer to a previously allocated block (in any heap)-- cannot be some
+/// random pointer!
+/// @returns \a true if the block pointed to by \a p is in the \a heap.
+/// @see mi_heap_check_owned()
+bool mi_heap_contains_block(mi_heap_t* heap, const void* p);
+
+/// Check safely if any pointer is part of a heap.
+/// @param heap The heap.
+/// @param p Any pointer -- not required to be previously allocated by us.
+/// @returns \a true if \a p points to a block in \a heap.
+///
+/// Note: expensive function, linear in the pages in the heap.
+/// @see mi_heap_contains_block()
+/// @see mi_heap_get_default()
+bool mi_heap_check_owned(mi_heap_t* heap, const void* p);
+
+/// Check safely if any pointer is part of the default heap of this thread.
+/// @param p Any pointer -- not required to be previously allocated by us.
+/// @returns \a true if \a p points to a block in default heap of this thread.
+///
+/// Note: expensive function, linear in the pages in the heap.
+/// @see mi_heap_contains_block()
+/// @see mi_heap_get_default()
+bool mi_check_owned(const void* p);
+
+/// An area of heap space contains blocks of a single size.
+/// The bytes in freed blocks are `committed - used`.
+typedef struct mi_heap_area_s {
+ void* blocks; ///< start of the area containing heap blocks
+ size_t reserved; ///< bytes reserved for this area
+ size_t committed; ///< current committed bytes of this area
+ size_t used; ///< bytes in use by allocated blocks
+ size_t block_size; ///< size in bytes of one block
+} mi_heap_area_t;
+
+/// Visitor function passed to mi_heap_visit_blocks()
+/// @returns \a true if ok, \a false to stop visiting (i.e. break)
+///
+/// This function is always first called for every \a area
+/// with \a block as a \a NULL pointer. If \a visit_all_blocks
+/// was \a true, the function is then called for every allocated
+/// block in that area.
+typedef bool (mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);
+
+/// Visit all areas and blocks in a heap.
+/// @param heap The heap to visit.
+/// @param visit_all_blocks If \a true visits all allocated blocks, otherwise
+/// \a visitor is only called for every heap area.
+/// @param visitor This function is called for every area in the heap
+/// (with \a block as \a NULL). If \a visit_all_blocks is
+/// \a true, \a visitor is also called for every allocated
+/// block in every area (with `block!=NULL`).
+/// return \a false from this function to stop visiting early.
+/// @param arg Extra argument passed to \a visitor.
+/// @returns \a true if all areas and blocks were visited.
+bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg);
+
+/// \}
+
+/// \defgroup options Runtime Options
+///
+/// Set runtime behavior.
+///
+/// \{
+
+/// Runtime options.
+typedef enum mi_option_e {
+ // stable options
+ mi_option_show_errors, ///< Print error messages to `stderr`.
+ mi_option_show_stats, ///< Print statistics to `stderr` when the program is done.
+ mi_option_verbose, ///< Print verbose messages to `stderr`.
+
+ // the following options are experimental
+ mi_option_eager_commit, ///< Eagerly commit segments (4MiB) (enabled by default).
+ mi_option_large_os_pages, ///< Use large OS pages (2MiB in size) if possible
+ mi_option_reserve_huge_os_pages, ///< The number of huge OS pages (1GiB in size) to reserve at the start of the program.
+ mi_option_reserve_huge_os_pages_at, ///< Reserve huge OS pages at node N.
+ mi_option_reserve_os_memory, ///< Reserve specified amount of OS memory at startup, e.g. "1g" or "512m".
+ mi_option_segment_cache, ///< The number of segments per thread to keep cached (0).
+ mi_option_page_reset, ///< Reset page memory after \a mi_option_reset_delay milliseconds when it becomes free.
+ mi_option_abandoned_page_reset, //< Reset free page memory when a thread terminates.
+ mi_option_use_numa_nodes, ///< Pretend there are at most N NUMA nodes; Use 0 to use the actual detected NUMA nodes at runtime.
+ mi_option_eager_commit_delay, ///< the first N segments per thread are not eagerly committed (=1).
+ mi_option_os_tag, ///< OS tag to assign to mimalloc'd memory
+ mi_option_limit_os_alloc, ///< If set to 1, do not use OS memory for allocation (but only pre-reserved arenas)
+
+ // v1.x specific options
+ mi_option_eager_region_commit, ///< Eagerly commit large (256MiB) memory regions (enabled by default, except on Windows)
+ mi_option_segment_reset, ///< Experimental
+ mi_option_reset_delay, ///< Delay in milli-seconds before resetting a page (100ms by default)
+ mi_option_reset_decommits, ///< Experimental
+
+ // v2.x specific options
+ mi_option_allow_decommit, ///< Enable decommitting memory (=on)
+ mi_option_decommit_delay, ///< Decommit page memory after N milli-seconds delay (25ms).
+ mi_option_segment_decommit_delay, ///< Decommit large segment memory after N milli-seconds delay (500ms).
+
+ _mi_option_last
+} mi_option_t;
+
+
+bool mi_option_is_enabled(mi_option_t option);
+void mi_option_enable(mi_option_t option);
+void mi_option_disable(mi_option_t option);
+void mi_option_set_enabled(mi_option_t option, bool enable);
+void mi_option_set_enabled_default(mi_option_t option, bool enable);
+
+long mi_option_get(mi_option_t option);
+void mi_option_set(mi_option_t option, long value);
+void mi_option_set_default(mi_option_t option, long value);
+
+
+/// \}
+
+/// \defgroup posix Posix
+///
+/// `mi_` prefixed implementations of various Posix, Unix, and C++ allocation functions.
+/// Defined for convenience as all redirect to the regular mimalloc API.
+///
+/// \{
+
+void* mi_recalloc(void* p, size_t count, size_t size);
+size_t mi_malloc_size(const void* p);
+size_t mi_malloc_usable_size(const void *p);
+
+/// Just as `free` but also checks if the pointer `p` belongs to our heap.
+void mi_cfree(void* p);
+
+int mi_posix_memalign(void** p, size_t alignment, size_t size);
+int mi__posix_memalign(void** p, size_t alignment, size_t size);
+void* mi_memalign(size_t alignment, size_t size);
+void* mi_valloc(size_t size);
+
+void* mi_pvalloc(size_t size);
+void* mi_aligned_alloc(size_t alignment, size_t size);
+
+/// Correspond s to [reallocarray](https://www.freebsd.org/cgi/man.cgi?query=reallocarray&sektion=3&manpath=freebsd-release-ports)
+/// in FreeBSD.
+void* mi_reallocarray(void* p, size_t count, size_t size);
+
+/// Corresponds to [reallocarr](https://man.netbsd.org/reallocarr.3) in NetBSD.
+int mi_reallocarr(void* p, size_t count, size_t size);
+
+void mi_free_size(void* p, size_t size);
+void mi_free_size_aligned(void* p, size_t size, size_t alignment);
+void mi_free_aligned(void* p, size_t alignment);
+
+/// \}
+
+/// \defgroup cpp C++ wrappers
+///
+/// `mi_` prefixed implementations of various allocation functions
+/// that use C++ semantics on out-of-memory, generally calling
+/// `std::get_new_handler` and raising a `std::bad_alloc` exception on failure.
+///
+/// Note: use the `mimalloc-new-delete.h` header to override the \a new
+/// and \a delete operators globally. The wrappers here are mostly
+/// for convience for library writers that need to interface with
+/// mimalloc from C++.
+///
+/// \{
+
+/// like mi_malloc(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure.
+void* mi_new(std::size_t n) noexcept(false);
+
+/// like mi_mallocn(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure.
+void* mi_new_n(size_t count, size_t size) noexcept(false);
+
+/// like mi_malloc_aligned(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure.
+void* mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false);
+
+/// like `mi_malloc`, but when out of memory, use `std::get_new_handler` but return \a NULL on failure.
+void* mi_new_nothrow(size_t n);
+
+/// like `mi_malloc_aligned`, but when out of memory, use `std::get_new_handler` but return \a NULL on failure.
+void* mi_new_aligned_nothrow(size_t n, size_t alignment);
+
+/// like mi_realloc(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure.
+void* mi_new_realloc(void* p, size_t newsize);
+
+/// like mi_reallocn(), but when out of memory, use `std::get_new_handler` and raise `std::bad_alloc` exception on failure.
+void* mi_new_reallocn(void* p, size_t newcount, size_t size);
+
+/// \a std::allocator implementation for mimalloc for use in STL containers.
+/// For example:
+/// ```
+/// std::vector<int, mi_stl_allocator<int> > vec;
+/// vec.push_back(1);
+/// vec.pop_back();
+/// ```
+template<class T> struct mi_stl_allocator { }
+
+/// \}
+
+/*! \page build Building
+
+Checkout the sources from Github:
+```
+git clone https://github.com/microsoft/mimalloc
+```
+
+## Windows
+
+Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build (or `ide/vs2017/mimalloc.sln`).
+The `mimalloc` project builds a static library (in `out/msvc-x64`), while the
+`mimalloc-override` project builds a DLL for overriding malloc
+in the entire program.
+
+## macOS, Linux, BSD, etc.
+
+We use [`cmake`](https://cmake.org)<sup>1</sup> as the build system:
+
+```
+> mkdir -p out/release
+> cd out/release
+> cmake ../..
+> make
+```
+This builds the library as a shared (dynamic)
+library (`.so` or `.dylib`), a static library (`.a`), and
+as a single object file (`.o`).
+
+`> sudo make install` (install the library and header files in `/usr/local/lib` and `/usr/local/include`)
+
+You can build the debug version which does many internal checks and
+maintains detailed statistics as:
+
+```
+> mkdir -p out/debug
+> cd out/debug
+> cmake -DCMAKE_BUILD_TYPE=Debug ../..
+> make
+```
+This will name the shared library as `libmimalloc-debug.so`.
+
+Finally, you can build a _secure_ version that uses guard pages, encrypted
+free lists, etc, as:
+```
+> mkdir -p out/secure
+> cd out/secure
+> cmake -DMI_SECURE=ON ../..
+> make
+```
+This will name the shared library as `libmimalloc-secure.so`.
+Use `ccmake`<sup>2</sup> instead of `cmake`
+to see and customize all the available build options.
+
+Notes:
+1. Install CMake: `sudo apt-get install cmake`
+2. Install CCMake: `sudo apt-get install cmake-curses-gui`
+
+*/
+
+/*! \page using Using the library
+
+### Build
+
+The preferred usage is including `<mimalloc.h>`, linking with
+the shared- or static library, and using the `mi_malloc` API exclusively for allocation. For example,
+```
+gcc -o myprogram -lmimalloc myfile.c
+```
+
+mimalloc uses only safe OS calls (`mmap` and `VirtualAlloc`) and can co-exist
+with other allocators linked to the same program.
+If you use `cmake`, you can simply use:
+```
+find_package(mimalloc 1.0 REQUIRED)
+```
+in your `CMakeLists.txt` to find a locally installed mimalloc. Then use either:
+```
+target_link_libraries(myapp PUBLIC mimalloc)
+```
+to link with the shared (dynamic) library, or:
+```
+target_link_libraries(myapp PUBLIC mimalloc-static)
+```
+to link with the static library. See `test\CMakeLists.txt` for an example.
+
+### C++
+For best performance in C++ programs, it is also recommended to override the
+global `new` and `delete` operators. For convience, mimalloc provides
+[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) which does this for you -- just include it in a single(!) source file in your project.
+
+In C++, mimalloc also provides the `mi_stl_allocator` struct which implements the `std::allocator`
+interface. For example:
+```
+std::vector<some_struct, mi_stl_allocator<some_struct>> vec;
+vec.push_back(some_struct());
+```
+
+### Statistics
+
+You can pass environment variables to print verbose messages (`MIMALLOC_VERBOSE=1`)
+and statistics (`MIMALLOC_SHOW_STATS=1`) (in the debug version):
+```
+> env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363
+
+175451865205073170563711388363 = 374456281610909315237213 * 468551
+
+heap stats: peak total freed unit
+normal 2: 16.4 kb 17.5 mb 17.5 mb 16 b ok
+normal 3: 16.3 kb 15.2 mb 15.2 mb 24 b ok
+normal 4: 64 b 4.6 kb 4.6 kb 32 b ok
+normal 5: 80 b 118.4 kb 118.4 kb 40 b ok
+normal 6: 48 b 48 b 48 b 48 b ok
+normal 17: 960 b 960 b 960 b 320 b ok
+
+heap stats: peak total freed unit
+ normal: 33.9 kb 32.8 mb 32.8 mb 1 b ok
+ huge: 0 b 0 b 0 b 1 b ok
+ total: 33.9 kb 32.8 mb 32.8 mb 1 b ok
+malloc requested: 32.8 mb
+
+ committed: 58.2 kb 58.2 kb 58.2 kb 1 b ok
+ reserved: 2.0 mb 2.0 mb 2.0 mb 1 b ok
+ reset: 0 b 0 b 0 b 1 b ok
+ segments: 1 1 1
+-abandoned: 0
+ pages: 6 6 6
+-abandoned: 0
+ mmaps: 3
+ mmap fast: 0
+ mmap slow: 1
+ threads: 0
+ elapsed: 2.022s
+ process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb
+```
+
+The above model of using the `mi_` prefixed API is not always possible
+though in existing programs that already use the standard malloc interface,
+and another option is to override the standard malloc interface
+completely and redirect all calls to the _mimalloc_ library instead.
+
+See \ref overrides for more info.
+
+*/
+
+/*! \page environment Environment Options
+
+You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)),
+or via environment variables.
+
+- `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates.
+- `MIMALLOC_VERBOSE=1`: show verbose messages.
+- `MIMALLOC_SHOW_ERRORS=1`: show error and warning messages.
+- `MIMALLOC_PAGE_RESET=0`: by default, mimalloc will reset (or purge) OS pages when not in use to signal to the OS
+ that the underlying physical memory can be reused. This can reduce memory fragmentation in long running (server)
+ programs. By setting it to `0` no such page resets will be done which can improve performance for programs that are not long
+ running. As an alternative, the `MIMALLOC_DECOMMIT_DELAY=`<msecs> can be set higher (100ms by default) to make the page
+ reset occur less frequently instead of turning it off completely.
+- `MIMALLOC_LARGE_OS_PAGES=1`: use large OS pages (2MiB) when available; for some workloads this can significantly
+ improve performance. Use `MIMALLOC_VERBOSE` to check if the large OS pages are enabled -- usually one needs
+ to explicitly allow large OS pages (as on [Windows][windows-huge] and [Linux][linux-huge]). However, sometimes
+ the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that
+ can have fragmented memory (for that reason, we generally recommend to use `MIMALLOC_RESERVE_HUGE_OS_PAGES` instead when possible).
+- `MIMALLOC_RESERVE_HUGE_OS_PAGES=N`: where N is the number of 1GiB _huge_ OS pages. This reserves the huge pages at
+ startup and sometimes this can give a large (latency) performance improvement on big workloads.
+ Usually it is better to not use
+ `MIMALLOC_LARGE_OS_PAGES` in combination with this setting. Just like large OS pages, use with care as reserving
+ contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at
+ startup only once).
+ Note that we usually need to explicitly enable huge OS pages (as on [Windows][windows-huge] and [Linux][linux-huge])). With huge OS pages, it may be beneficial to set the setting
+ `MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB)
+ of a thread to not allocate in the huge OS pages; this prevents threads that are short lived
+ and allocate just a little to take up space in the huge OS page area (which cannot be reset).
+- `MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N`: where N is the numa node. This reserves the huge pages at a specific numa node.
+ (`N` is -1 by default to reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected))
+
+Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write
+for all pages in the original process including the huge OS pages. When any memory is now written in that area, the
+OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in big increments.
+
+[linux-huge]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5
+[windows-huge]: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017
+
+*/
+
+/*! \page overrides Overriding Malloc
+
+Overriding the standard `malloc` can be done either _dynamically_ or _statically_.
+
+## Dynamic override
+
+This is the recommended way to override the standard malloc interface.
+
+
+### Linux, BSD
+
+On these systems we preload the mimalloc shared
+library so all calls to the standard `malloc` interface are
+resolved to the _mimalloc_ library.
+
+- `env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram`
+
+You can set extra environment variables to check that mimalloc is running,
+like:
+```
+env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram
+```
+or run with the debug version to get detailed statistics:
+```
+env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram
+```
+
+### MacOS
+
+On macOS we can also preload the mimalloc shared
+library so all calls to the standard `malloc` interface are
+resolved to the _mimalloc_ library.
+
+- `env DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram`
+
+Note that certain security restrictions may apply when doing this from
+the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash).
+
+(Note: macOS support for dynamic overriding is recent, please report any issues.)
+
+
+### Windows
+
+Overriding on Windows is robust and has the
+particular advantage to be able to redirect all malloc/free calls that go through
+the (dynamic) C runtime allocator, including those from other DLL's or libraries.
+
+The overriding on Windows requires that you link your program explicitly with
+the mimalloc DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch).
+Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be available
+in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency).
+The redirection DLL ensures that all calls to the C runtime malloc API get redirected to
+mimalloc (in `mimalloc-override.dll`).
+
+To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some
+call to the mimalloc API in the `main` function, like `mi_version()`
+(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project
+for an example on how to use this. For best performance on Windows with C++, it
+is also recommended to also override the `new`/`delete` operations (by including
+[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) a single(!) source file in your project).
+
+The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic
+overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc was successfully redirected.
+
+(Note: in principle, it is possible to even patch existing executables without any recompilation
+if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `mimalloc-override.dll`
+into the import table (and put `mimalloc-redirect.dll` in the same folder)
+Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388)).
+
+
+## Static override
+
+On Unix systems, you can also statically link with _mimalloc_ to override the standard
+malloc interface. The recommended way is to link the final program with the
+_mimalloc_ single object file (`mimalloc-override.o`). We use
+an object file instead of a library file as linkers give preference to
+that over archives to resolve symbols. To ensure that the standard
+malloc interface resolves to the _mimalloc_ library, link it as the first
+object file. For example:
+
+```
+gcc -o myprogram mimalloc-override.o myfile1.c ...
+```
+
+## List of Overrides:
+
+The specific functions that get redirected to the _mimalloc_ library are:
+
+```
+// C
+void* malloc(size_t size);
+void* calloc(size_t size, size_t n);
+void* realloc(void* p, size_t newsize);
+void free(void* p);
+
+void* aligned_alloc(size_t alignment, size_t size);
+char* strdup(const char* s);
+char* strndup(const char* s, size_t n);
+char* realpath(const char* fname, char* resolved_name);
+
+
+// C++
+void operator delete(void* p);
+void operator delete[](void* p);
+
+void* operator new(std::size_t n) noexcept(false);
+void* operator new[](std::size_t n) noexcept(false);
+void* operator new( std::size_t n, std::align_val_t align) noexcept(false);
+void* operator new[]( std::size_t n, std::align_val_t align) noexcept(false);
+
+void* operator new ( std::size_t count, const std::nothrow_t& tag);
+void* operator new[]( std::size_t count, const std::nothrow_t& tag);
+void* operator new ( std::size_t count, std::align_val_t al, const std::nothrow_t&);
+void* operator new[]( std::size_t count, std::align_val_t al, const std::nothrow_t&);
+
+// Posix
+int posix_memalign(void** p, size_t alignment, size_t size);
+
+// Linux
+void* memalign(size_t alignment, size_t size);
+void* valloc(size_t size);
+void* pvalloc(size_t size);
+size_t malloc_usable_size(void *p);
+void* reallocf(void* p, size_t newsize);
+
+// macOS
+void vfree(void* p);
+size_t malloc_size(const void* p);
+size_t malloc_good_size(size_t size);
+
+// BSD
+void* reallocarray( void* p, size_t count, size_t size );
+void* reallocf(void* p, size_t newsize);
+void cfree(void* p);
+
+// NetBSD
+int reallocarr(void* p, size_t count, size_t size);
+
+// Windows
+void* _expand(void* p, size_t newsize);
+size_t _msize(void* p);
+
+void* _malloc_dbg(size_t size, int block_type, const char* fname, int line);
+void* _realloc_dbg(void* p, size_t newsize, int block_type, const char* fname, int line);
+void* _calloc_dbg(size_t count, size_t size, int block_type, const char* fname, int line);
+void* _expand_dbg(void* p, size_t size, int block_type, const char* fname, int line);
+size_t _msize_dbg(void* p, int block_type);
+void _free_dbg(void* p, int block_type);
+```
+
+*/
+
+/*! \page bench Performance
+
+We tested _mimalloc_ against many other top allocators over a wide
+range of benchmarks, ranging from various real world programs to
+synthetic benchmarks that see how the allocator behaves under more
+extreme circumstances.
+
+In our benchmarks, _mimalloc_ always outperforms all other leading
+allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc) (Jan 2021),
+and usually uses less memory (up to 25% more in the worst case).
+A nice property is that it does *consistently* well over the wide
+range of benchmarks.
+
+See the [Performance](https://github.com/microsoft/mimalloc#Performance)
+section in the _mimalloc_ repository for benchmark results,
+or the the technical report for detailed benchmark results.
+
+*/
--- /dev/null
+#projectlogo img {
+ padding: 1ex;
+}
+tt, code, kbd, samp, div.memproto, div.fragment, div.line, table.memname {
+ font-family: Consolas, Monaco, Inconsolata, "Courier New", monospace;
+}
+.image img, .textblock img {
+ max-width: 99%;
+ max-height: 350px;
+}
+table.memname, .memname{
+ font-weight: bold;
+}
+code {
+ background-color: #EEE;
+ padding: 0ex 0.25ex;
+}
+body {
+ margin: 1ex 1ex 0ex 1ex;
+ border: 1px solid black;
+}
+.contents table, .contents div, .contents p, .contents dl {
+ font-size: 16px;
+ line-height: 1.44;
+}
+body #nav-tree .label {
+ font-size: 14px;
+}
+a{
+ text-decoration: underline;
+}
+#side-nav {
+ margin-left: 1ex;
+ border-left: 1px solid black;
+}
+#nav-tree {
+ padding-left: 1ex;
+}
+#nav-path {
+ display: none;
+}
+div.fragment {
+ background-color: #EEE;
+ padding: 0.25ex 0.5ex;
+ border-color: black;
+}
+#nav-sync img {
+ display: none;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="20mm"
+ height="20mm"
+ viewBox="0 0 10 10"
+ version="1.1"
+ id="svg8"
+ sodipodi:docname="mimalloc-logo.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <defs
+ id="defs2">
+ <linearGradient
+ id="linearGradient6471"
+ osb:paint="solid">
+ <stop
+ style="stop-color:#008da3;stop-opacity:1;"
+ offset="0"
+ id="stop6469" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="23.706667"
+ inkscape:cx="24.864771"
+ inkscape:cy="35.79485"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="3840"
+ inkscape:window-height="2050"
+ inkscape:window-x="-12"
+ inkscape:window-y="-12"
+ inkscape:window-maximized="1"
+ inkscape:snap-object-midpoints="false"
+ inkscape:snap-bbox="false"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:bbox-nodes="false"
+ inkscape:bbox-paths="false"
+ inkscape:snap-bbox-edge-midpoints="false"
+ showguides="false"
+ showborder="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid815"
+ units="mm"
+ spacingx="0.99999997"
+ spacingy="0.99999997" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-287)">
+ <circle
+ id="path840"
+ cx="5"
+ cy="292"
+ style="fill:#0d8ca4;fill-opacity:0.64444448;fill-rule:nonzero;stroke:#000000;stroke-width:0.56603777;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ r="4.7169809" />
+ <ellipse
+ id="path4522"
+ style="fill:none;stroke:#000000;stroke-width:0.6;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ cx="5.171"
+ cy="292"
+ r="4.8711185" />
+ <g
+ aria-label="malloc"
+ transform="matrix(0.9031136,0,0,0.80782132,0.58122269,37.023319)"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28599727"
+ id="text6501">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 1.7799307,318.87079 c 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.70159 c 0.013406,-0.0223 0.031281,-0.0469 0.05139,-0.0693 0.017875,-0.0223 0.049156,-0.0447 0.089374,-0.0693 0.040218,-0.0223 0.082671,-0.0358 0.1273581,-0.0358 0.040218,0 0.078202,0.0179 0.1117177,0.0536 0.031281,0.0358 0.049156,0.0827 0.049156,0.143 v 0.67924 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.67924 -0.0223 c 0.0067,-0.0112 0.01564,-0.0223 0.024578,-0.0358 0.00894,-0.0134 0.022344,-0.0268 0.040218,-0.0447 0.017875,-0.0179 0.03575,-0.0335 0.053624,-0.0469 0.017875,-0.0134 0.042453,-0.0246 0.069265,-0.0335 0.026812,-0.009 0.053625,-0.0134 0.080437,-0.0134 0.040218,0 0.078202,0.0179 0.1117177,0.0536 0.031281,0.0358 0.049156,0.0827 0.049156,0.143 v 0.67924 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.67924 c 0,-0.11396 -0.037984,-0.21003 -0.1094833,-0.29047 -0.073734,-0.0804 -0.1631078,-0.12066 -0.2658881,-0.12066 -0.073734,0 -0.1407643,0.0156 -0.1988575,0.0425 -0.058093,0.0268 -0.1094833,0.0626 -0.1541704,0.10725 -0.075968,-0.0983 -0.1720452,-0.14971 -0.290466,-0.14971 -0.1027802,0 -0.1943887,0.029 -0.2748255,0.0849 -0.00894,-0.0179 -0.022343,-0.0335 -0.040218,-0.0469 -0.017875,-0.0134 -0.037984,-0.0201 -0.060328,-0.0201 -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 0.96524 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6515" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 4.2824069,317.69105 c -0.01564,0 -0.029047,0.004 -0.042453,0.009 -0.013406,0.007 -0.026812,0.0156 -0.03575,0.0246 -0.00894,0.0112 -0.017875,0.0223 -0.022344,0.0335 -0.078202,-0.0559 -0.1631079,-0.0849 -0.2569507,-0.0849 -0.145233,0 -0.2658881,0.0626 -0.359731,0.18322 -0.093843,0.12066 -0.1407642,0.26366 -0.1407642,0.42453 0,0.16311 0.046921,0.30611 0.1407642,0.42676 0.093843,0.12066 0.214498,0.18098 0.359731,0.18098 0.093843,0 0.1787483,-0.0268 0.2569507,-0.0849 0.00894,0.0201 0.022344,0.0358 0.040218,0.0491 0.017875,0.0134 0.037984,0.0179 0.060328,0.0179 0.029047,0 0.053625,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.96524 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z m -0.107249,0.77979 c -0.017875,0.0424 -0.040218,0.0782 -0.067031,0.10948 -0.026812,0.0313 -0.055859,0.0559 -0.08714,0.0715 -0.031281,0.0156 -0.064796,0.0224 -0.096077,0.0224 -0.073734,0 -0.1407643,-0.0358 -0.1988575,-0.10949 -0.058093,-0.0737 -0.08714,-0.16757 -0.08714,-0.28376 0,-0.11395 0.029047,-0.2078 0.08714,-0.28153 0.058093,-0.0737 0.1251238,-0.11172 0.1988575,-0.11172 0.049156,0 0.098312,0.0179 0.1429986,0.0536 0.044687,0.0358 0.080437,0.0871 0.107249,0.1497 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6517" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 4.7471525,317.2263 c -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 1.21549 c 0,0.10502 0.0067,0.18545 0.022343,0.24131 0.00447,0.0268 0.017875,0.0469 0.037984,0.0603 0.017875,0.0134 0.040218,0.0201 0.064796,0.0201 0.00894,0 0.017875,0 0.026812,-0.002 0.00447,-0.002 0.011172,-0.004 0.017875,-0.009 0.0067,-0.002 0.013406,-0.004 0.017875,-0.009 0.00447,-0.004 0.011172,-0.009 0.01564,-0.0134 0.00447,-0.004 0.0067,-0.0112 0.011172,-0.0156 0.00447,-0.004 0.0067,-0.0112 0.00894,-0.0179 0.00223,-0.007 0.00447,-0.0134 0.0067,-0.0201 0,-0.007 0.00223,-0.0134 0.00223,-0.0201 v -0.007 c 0,-0.002 -0.00223,-0.004 -0.00223,-0.007 0,-0.002 0,-0.004 0,-0.009 -0.011172,-0.0447 -0.01564,-0.10725 -0.01564,-0.19216 v -1.21549 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6519" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 5.2655226,317.2263 c -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 1.21549 c 0,0.10502 0.0067,0.18545 0.022344,0.24131 0.00447,0.0268 0.017875,0.0469 0.037984,0.0603 0.017875,0.0134 0.040218,0.0201 0.064796,0.0201 0.00894,0 0.017875,0 0.026812,-0.002 0.00447,-0.002 0.011172,-0.004 0.017875,-0.009 0.0067,-0.002 0.013406,-0.004 0.017875,-0.009 0.00447,-0.004 0.011172,-0.009 0.01564,-0.0134 0.00447,-0.004 0.0067,-0.0112 0.011172,-0.0156 0.00447,-0.004 0.0067,-0.0112 0.00894,-0.0179 0.00223,-0.007 0.00447,-0.0134 0.0067,-0.0201 0,-0.007 0.00223,-0.0134 0.00223,-0.0201 v -0.007 c 0,-0.002 -0.00223,-0.004 -0.00223,-0.007 0,-0.002 0,-0.004 0,-0.009 -0.011172,-0.0447 -0.01564,-0.10725 -0.01564,-0.19216 v -1.21549 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6521" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 6.6061344,318.28092 c 0,-0.16087 -0.049156,-0.30387 -0.1429986,-0.42453 -0.093843,-0.12065 -0.2144979,-0.18322 -0.3574966,-0.18322 -0.145233,0 -0.2658881,0.0626 -0.3597309,0.18322 -0.093843,0.12066 -0.1407643,0.26366 -0.1407643,0.42453 0,0.16311 0.046921,0.30611 0.1407643,0.42676 0.093843,0.12066 0.2144979,0.18098 0.3597309,0.18098 0.1429987,0 0.2636538,-0.0603 0.3574966,-0.18098 0.093843,-0.12065 0.1429986,-0.26365 0.1429986,-0.42676 z m -0.2144979,0 c 0,0.11619 -0.031281,0.21003 -0.089374,0.28376 -0.058093,0.0737 -0.1251238,0.10949 -0.1966231,0.10949 -0.073734,0 -0.1407643,-0.0358 -0.1988575,-0.10949 -0.058093,-0.0737 -0.08714,-0.16757 -0.08714,-0.28376 0,-0.11395 0.029047,-0.2078 0.08714,-0.28153 0.058093,-0.0737 0.1251238,-0.11172 0.1988575,-0.11172 0.071499,0 0.1385299,0.038 0.1966231,0.11172 0.058093,0.0737 0.089374,0.16758 0.089374,0.28153 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6523" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 7.6406407,318.47754 c -0.00894,-0.004 -0.01564,-0.007 -0.024578,-0.009 -0.00894,-0.002 -0.017875,-0.004 -0.026812,-0.004 -0.044687,0 -0.075968,0.0201 -0.093843,0.0559 -0.026812,0.0514 -0.060328,0.0894 -0.098312,0.11618 -0.040218,0.0268 -0.080437,0.038 -0.1206551,0.038 -0.071499,0 -0.1340612,-0.0358 -0.1921544,-0.10949 -0.058093,-0.0737 -0.084905,-0.16757 -0.084905,-0.28376 0,-0.11395 0.026812,-0.2078 0.084905,-0.28153 0.058093,-0.0737 0.1206551,-0.11172 0.1921544,-0.11172 0.080437,0 0.1474674,0.0447 0.2055606,0.1296 0.020109,0.0335 0.049156,0.0491 0.089374,0.0491 0.022343,0 0.040218,-0.004 0.058093,-0.0179 0.0067,-0.004 0.013406,-0.009 0.020109,-0.0156 0.0067,-0.007 0.011172,-0.0134 0.01564,-0.0224 0.00447,-0.009 0.0067,-0.0156 0.00894,-0.0246 0.00223,-0.009 0.00447,-0.0179 0.00447,-0.0268 0,-0.004 -0.00223,-0.0112 -0.00223,-0.0156 0,-0.004 -0.00223,-0.009 -0.00223,-0.0134 -0.00223,-0.004 -0.00447,-0.0112 -0.0067,-0.0156 -0.00223,-0.004 -0.00447,-0.009 -0.0067,-0.0134 -0.031281,-0.0447 -0.064796,-0.0827 -0.1027803,-0.11619 -0.037984,-0.0335 -0.080437,-0.0603 -0.1295925,-0.0804 -0.049156,-0.0201 -0.1005459,-0.0313 -0.1519361,-0.0313 -0.1429986,0 -0.2614194,0.0626 -0.3530279,0.18322 -0.093843,0.12066 -0.1385299,0.26366 -0.1385299,0.42453 0,0.16311 0.044687,0.30611 0.1385299,0.42676 0.091608,0.12066 0.2100293,0.18098 0.3530279,0.18098 0.084905,0 0.1631078,-0.0246 0.2346072,-0.0737 0.071499,-0.0492 0.1273581,-0.11172 0.1720452,-0.19215 0.0067,-0.0134 0.011172,-0.0313 0.013406,-0.0514 0,-0.0425 -0.020109,-0.0737 -0.055859,-0.0939 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6525" />
+ </g>
+ <g
+ aria-label="m"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3694315px;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578"
+ id="text848">
+ <path
+ d="m 2.3718985,293.17081 c 0.080862,0 0.1492836,-0.0249 0.211485,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.95313 c 0.037321,-0.0622 0.087082,-0.13062 0.1430634,-0.19282 0.049761,-0.0622 0.1368433,-0.1244 0.2488059,-0.19283 0.1119627,-0.0622 0.2301455,-0.0995 0.3545485,-0.0995 0.1119626,0 0.2177051,0.0498 0.3110074,0.14929 0.087082,0.0995 0.1368432,0.23014 0.1368432,0.39808 v 1.89093 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.89093 -0.0622 c 0.018661,-0.0311 0.043541,-0.0622 0.068422,-0.0995 0.024881,-0.0373 0.062201,-0.0746 0.1119626,-0.1244 0.049761,-0.0498 0.099522,-0.0933 0.1492836,-0.13063 0.049761,-0.0373 0.1181828,-0.0684 0.1928246,-0.0933 0.074642,-0.0249 0.1492835,-0.0373 0.2239253,-0.0373 0.1119626,0 0.2177052,0.0498 0.3110074,0.14929 0.087082,0.0995 0.1368432,0.23014 0.1368432,0.39808 v 1.89093 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.89093 c 0,-0.31722 -0.1057425,-0.58469 -0.3047872,-0.80861 -0.2052649,-0.22393 -0.4540708,-0.33589 -0.7401976,-0.33589 -0.2052649,0 -0.3918693,0.0435 -0.5535932,0.11818 -0.1617238,0.0746 -0.3047872,0.17416 -0.4291902,0.29857 -0.211485,-0.27369 -0.4789514,-0.41675 -0.8086192,-0.41675 -0.2861268,0 -0.5411529,0.0809 -0.7650782,0.23636 -0.024881,-0.0498 -0.062202,-0.0933 -0.1119627,-0.13062 -0.049761,-0.0373 -0.1057425,-0.056 -0.167944,-0.056 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.087082,0.13062 -0.087082,0.21149 v 2.6871 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.1244029,0.0871 0.211485,0.0871 z"
+ style="stroke-width:0.15923578"
+ id="path834" />
+ </g>
+ <g
+ id="g28"
+ transform="translate(-0.23995531,0.02790178)">
+ <g
+ id="g835">
+ <g
+ transform="matrix(1.0000001,0,0,0.98554676,-7.6075554e-7,4.2369817)"
+ id="g25">
+ <path
+ d="m 7.426334,293.15097 c 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21149 v -2.6871 c 0,-0.0809 -0.031101,-0.14928 -0.087082,-0.21149 -0.062201,-0.056 -0.1306232,-0.0871 -0.2114851,-0.0871 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.087082,0.13063 -0.087082,0.21149 v 2.6871 c 0,0.0871 0.024881,0.15551 0.087082,0.21149 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578"
+ id="path896"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 7.4249389,289.61754 c 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.086228,-0.1244 0.087082,-0.21149 l 0.0014,-0.14231 c 7.93e-4,-0.0809 -0.031101,-0.14929 -0.087082,-0.21149 -0.062201,-0.056 -0.1306232,-0.0871 -0.2114851,-0.0871 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.086289,0.13062 -0.087082,0.21149 l -0.0014,0.14231 c -8.538e-4,0.0871 0.024881,0.15551 0.087082,0.21149 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578"
+ id="path898"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="scsscscsscs" />
+ </g>
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ height="706.71118"
+ width="746.71118"
+ viewBox="-150.3282 -273.04775 810.70706 1447.2442"
+ version="1.1"
+ id="svg34"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs24">
+ <clipPath
+ id="a"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ d="M 0,1024 H 1024 V 0 H 0 Z"
+ id="path21" />
+ </clipPath>
+ </defs>
+ <rect
+ style="fill:#b2b2b2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.04786;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect121"
+ width="1300.7299"
+ height="1264.0651"
+ x="-391.91745"
+ y="-186.69598"
+ rx="154.79872"
+ ry="154.79872" />
+ <path
+ d="m 693.86447,863.90527 v -94.746 h -35.855 v 122.747 h 120.26 v -28 z"
+ id="path26" />
+ <g
+ clip-path="url(#a)"
+ transform="matrix(1.33333,0,0,-1.33333,-408.39652,1133.2393)"
+ id="g32">
+ <path
+ d="m 498.837,117.958 h 20.085 c 0.498,-5.295 -1.063,-7.971 -5.392,-8.386 -4.293,-0.411 -8.612,-0.76 -12.92,-0.77 -17.903,-0.044 -19.822,2.052 -18.737,19.932 0.02,0.333 0.03,0.666 0.063,0.997 0.67,6.667 3.126,9.189 9.81,9.499 5.15,0.238 10.316,0.089 15.476,0.132 5.373,0.044 10.5,-0.337 11.806,-6.626 h 13.198 c 1.86,10.558 -1.6,16.306 -11.74,16.9 -13.059,0.767 -26.228,0.648 -39.293,-0.086 -8.782,-0.493 -13.292,-5.67 -13.804,-14.27 -0.444,-7.454 -0.42,-14.975 -0.007,-22.434 0.441,-7.953 4.16,-11.928 11.938,-13.918 2.87,-0.734 5.785,-1.29 8.68,-1.928 h 26 c 2.091,0.444 4.177,0.913 6.274,1.328 5.615,1.11 11.135,2.918 12.264,9.28 1.114,6.278 1.061,12.763 1.546,19.515 h -35.247 z m -103.4,63.438 v 91.393 h -26.424 v -69.795 l -54.236,70.22 H 273.38 V 181.28 h 26.308 v 68.354 l 1.226,0.31 53.645,-68.547 z m 47.577,45.635 v 26.323 c 12.208,0 24.12,0.002 36.033,-0.003 1.662,0 3.323,-0.048 4.985,-0.059 14.801,-0.1 16.353,-4.42 14.866,-18.979 -0.484,-4.738 -4.073,-7.103 -8.306,-7.175 -15.731,-0.268 -31.469,-0.107 -47.578,-0.107 m 56.443,-33.406 c 0.357,-4.063 0.548,-8.14 0.82,-12.3 h 26.391 c 0,5.758 0.219,11.061 -0.045,16.34 -0.581,11.61 -2.289,16.735 -13.599,18.696 -0.592,0.103 -1.114,0.614 -2.506,1.42 11.369,2.53 15.442,10.208 15.981,20.201 0.267,4.96 0.176,10.017 -0.484,14.932 -1.604,11.95 -5.993,16.673 -17.761,18.885 a 101.743,101.743 0 0 1 -17.843,1.741 c -22.818,0.197 -45.638,0.09 -68.458,0.066 -1.78,-0.002 -3.559,-0.22 -5.646,-0.36 v -91.884 h 26.535 v 25.35 c 6.04,0 11.509,0.111 16.972,-0.025 9.644,-0.24 19.344,-0.086 28.908,-1.129 7.832,-0.854 10.041,-4.046 10.735,-11.933 m 73.129,24.754 h 68.786 v 18.565 h -68.899 v 16.585 h 72.852 v 19.517 h -99.79 v -91.744 h 101.018 v 20.193 h -73.967 z m -319.109,52.037 c 0.004,0.918 -0.563,1.84 -0.847,2.708 h -26.34 c 0,-16.299 0.052,-32.104 -0.036,-47.909 -0.025,-4.314 -0.31,-8.644 -0.772,-12.935 -0.665,-6.161 -4.552,-10.04 -10.412,-10.334 -12.098,-0.61 -24.283,-1.056 -36.347,-0.266 -9.717,0.635 -12.873,4.996 -12.984,14.895 -0.19,16.997 -0.103,33.998 -0.188,50.997 -0.009,1.895 -0.385,3.789 -0.59,5.67 h -26.32 c 0,-22.846 -0.788,-45.02 0.27,-67.106 0.734,-15.35 7.1,-21.4 22.59,-23.992 22.481,-3.765 45.194,-3.61 67.677,-0.266 17.168,2.553 22.995,8.927 23.753,26.069 0.92,20.79 0.464,41.644 0.546,62.47 m 447.926,-53.371 19.515,38.362 19.723,-38.362 z m 2.8,56.306 -49.975,-92.133 h 28.863 l 8.345,15.905 h 59.333 l 8.375,-15.847 h 29.165 l -50.248,92.075 z m -264.917,-161.351 -1.233,-0.292 a 532757.74,532757.74 0 0 1 -30.02,38.7 h -23.4 v -51.93 h 14.433 v 37.887 l 1.47,0.522 30.288,-38.488 h 23.367 v 51.89 h -14.904 z m 187.996,-0.026 -1.193,-0.31 c -9.93,12.813 -19.858,25.627 -29.476,38.039 H 573.309 V 98.583 h 14.777 v 39.2 l 30.889,-39.43 h 23.009 v 51.189 h -14.702 z m -295.244,7.284 h 39.176 v 10.717 H 332.04 v 9.647 h 41.322 V 150.45 H 317.11 V 98.519 h 57.303 v 11.039 h -42.375 z m 338.914,0.018 h 38.455 v 10.44 H 671.1 v 9.635 h 40.57 v 10.3 H 655.83 V 98.556 h 56.742 v 10.952 h -41.62 z M 545.666,98.416 h 14.301 v 51.189 H 545.666 Z M 312.554,585.913 c 0,0 -10.463,51.999 44.874,114.973 55.342,62.972 96.863,85.871 141.707,97.799 l -0.078,-0.046 0.17,0.046 c 0,0 -35.227,-20.517 -35.227,-51.522 0,-9 1.435,-15.184 3.423,-19.315 2.638,-5.488 6.816,-7.354 10.567,-7.372 3.16,-0.018 5.01,1.281 9.01,2.834 V 555.386 c 0,0 0.433,-2.707 2.863,-5.915 3.5,-4.613 9,-10.243 19.335,-10.3 17.629,0.113 39.802,20.026 39.802,20.026 v 135.964 c 0,13.832 -9.9,30.53 -20.39,36.259 0,0 1.43,0.09 3.744,0.089 6.926,0.002 21.784,-0.79 30.063,-7.115 2.3,2.665 39.418,44.665 105.466,57.589 l -0.032,-0.037 0.18,0.037 c 0,0 -36.531,-43.016 -47.981,-64.348 -2.035,-0.121 -2.332,-40.471 -1.993,-80.79 0.329,-38.92 1.253,-77.818 1.789,-80.509 0,0 3.898,-5.794 13.824,-5.844 11.196,-0.057 30.063,7.195 59.643,38.288 l -10e-4,-10e-4 v 10e-4 c 0,0 -0.78,-1.771 -2.35,-4.908 -8.476,-16.938 -39.974,-73.721 -95.924,-106.725 l -0.003,0.003 -0.005,-0.003 -36.29,30.693 -0.927,0.774 -39.58,-41.967 -0.06,0.006 -0.005,-0.006 c 0,0 -90.232,7.633 -127.92,62.015 l 0.179,-0.065 -0.047,0.065 c 0,0 5.707,-2.221 12.148,-2.342 7.547,-0.138 15.472,2.619 15.472,15.229 v 127.85 c 0,6.529 -4.495,13.853 -14.362,13.825 -8.874,-0.023 -21.614,-5.994 -39.01,-23.843 -36.734,-37.685 -51.99,-73.468 -51.99,-73.468 l -0.025,0.136 -0.06,-0.136 M 513,369.156 c 70.386,0 136.56,27.41 186.33,77.18 49.77,49.771 77.18,115.944 77.18,186.33 0,70.386 -27.41,136.559 -77.18,186.33 -49.77,49.77 -115.944,77.18 -186.33,77.18 -70.386,0 -136.56,-27.41 -186.33,-77.18 -49.77,-49.771 -77.18,-115.944 -77.18,-186.33 0,-70.386 27.41,-136.559 77.18,-186.33 49.77,-49.77 115.944,-77.18 186.33,-77.18"
+ id="path28" />
+ <path
+ d="m 513,908.307 c 152.232,0 275.641,-123.409 275.641,-275.64 0,-152.233 -123.409,-275.642 -275.641,-275.642 -152.232,0 -275.641,123.41 -275.641,275.641 0,152.232 123.409,275.641 275.641,275.641 m 0,-559.119 c 75.72,0 146.907,29.487 200.449,83.03 53.542,53.541 83.028,124.728 83.028,200.448 0,75.72 -29.486,146.907 -83.028,200.45 -53.542,53.54 -124.729,83.026 -200.449,83.026 -75.72,0 -146.907,-29.486 -200.449,-83.028 -53.542,-53.542 -83.028,-124.73 -83.028,-200.449 0,-75.72 29.486,-146.907 83.028,-200.449 C 366.093,378.674 437.28,349.188 513,349.188"
+ id="path30" />
+ </g>
+</svg>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Data Structures</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('annotated.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">Data Structures</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here are the data structures with brief descriptions:</div><div class="directory">
+<table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="group__analysis.html#structmi__heap__area__t" target="_self">mi_heap_area_t</a></td><td class="desc">An area of heap space contains blocks of a single size </td></tr>
+<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="group__cpp.html#structmi__stl__allocator" target="_self">mi_stl_allocator</a></td><td class="desc"><em>std::allocator</em> implementation for mimalloc for use in STL containers </td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var annotated_dup =
+[
+ [ "mi_heap_area_t", "group__analysis.html#structmi__heap__area__t", "group__analysis_structmi__heap__area__t" ],
+ [ "mi_stl_allocator", "group__cpp.html#structmi__stl__allocator", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Performance</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('bench.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="PageDoc"><div class="header">
+ <div class="headertitle">
+<div class="title">Performance </div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>We tested <em>mimalloc</em> against many other top allocators over a wide range of benchmarks, ranging from various real world programs to synthetic benchmarks that see how the allocator behaves under more extreme circumstances.</p>
+<p>In our benchmarks, <em>mimalloc</em> always outperforms all other leading allocators (<em>jemalloc</em>, <em>tcmalloc</em>, <em>Hoard</em>, etc) (Jan 2021), and usually uses less memory (up to 25% more in the worst case). A nice property is that it does <em>consistently</em> well over the wide range of benchmarks.</p>
+<p>See the <a href="https://github.com/microsoft/mimalloc#Performance">Performance</a> section in the <em>mimalloc</em> repository for benchmark results, or the the technical report for detailed benchmark results. </p>
+</div></div><!-- contents -->
+</div><!-- PageDoc -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Building</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('build.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="PageDoc"><div class="header">
+ <div class="headertitle">
+<div class="title">Building </div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>Checkout the sources from Github: </p><div class="fragment"><div class="line">git clone https:<span class="comment">//github.com/microsoft/mimalloc</span></div>
+</div><!-- fragment --><h2>Windows</h2>
+<p>Open <code>ide/vs2019/mimalloc.sln</code> in Visual Studio 2019 and build (or <code>ide/vs2017/mimalloc.sln</code>). The <code>mimalloc</code> project builds a static library (in <code>out/msvc-x64</code>), while the <code>mimalloc-override</code> project builds a DLL for overriding malloc in the entire program.</p>
+<h2>macOS, Linux, BSD, etc.</h2>
+<p>We use <a href="https://cmake.org"><code>cmake</code></a><sup>1</sup> as the build system:</p>
+<div class="fragment"><div class="line">> mkdir -p out/release</div>
+<div class="line">> cd out/release</div>
+<div class="line">> cmake ../..</div>
+<div class="line">> make</div>
+</div><!-- fragment --><p> This builds the library as a shared (dynamic) library (<code>.so</code> or <code>.dylib</code>), a static library (<code>.a</code>), and as a single object file (<code>.o</code>).</p>
+<p><code>> sudo make install</code> (install the library and header files in <code>/usr/local/lib</code> and <code>/usr/local/include</code>)</p>
+<p>You can build the debug version which does many internal checks and maintains detailed statistics as:</p>
+<div class="fragment"><div class="line">> mkdir -p out/debug</div>
+<div class="line">> cd out/debug</div>
+<div class="line">> cmake -DCMAKE_BUILD_TYPE=Debug ../..</div>
+<div class="line">> make</div>
+</div><!-- fragment --><p> This will name the shared library as <code>libmimalloc-debug.so</code>.</p>
+<p>Finally, you can build a <em>secure</em> version that uses guard pages, encrypted free lists, etc, as: </p><div class="fragment"><div class="line">> mkdir -p out/secure</div>
+<div class="line">> cd out/secure</div>
+<div class="line">> cmake -DMI_SECURE=ON ../..</div>
+<div class="line">> make</div>
+</div><!-- fragment --><p> This will name the shared library as <code>libmimalloc-secure.so</code>. Use <code>ccmake</code><sup>2</sup> instead of <code>cmake</code> to see and customize all the available build options.</p>
+<p>Notes:</p><ol type="1">
+<li>Install CMake: <code>sudo apt-get install cmake</code></li>
+<li>Install CCMake: <code>sudo apt-get install cmake-curses-gui</code> </li>
+</ol>
+</div></div><!-- contents -->
+</div><!-- PageDoc -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Data Structure Index</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('classes.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">Data Structure Index</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="qindex"><a class="qindex" href="#letter_M">M</a></div>
+<div class="classindex">
+<dl class="classindex even">
+<dt class="alphachar"><a name="letter_M">M</a></dt>
+<dd><a class="el" href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a></dd><dd><a class="el" href="group__cpp.html#structmi__stl__allocator">mi_stl_allocator</a></dd></dl>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+/* The standard CSS for doxygen 1.9.1 */
+
+body, table, div, p, dl {
+ font: 400 14px/22px Roboto,sans-serif;
+}
+
+p.reference, p.definition {
+ font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+ font-size: 150%;
+}
+
+.title {
+ font: 400 14px/28px Roboto,sans-serif;
+ font-size: 150%;
+ font-weight: bold;
+ margin: 10px 2px;
+}
+
+h2.groupheader {
+ border-bottom: 1px solid #474D4E;
+ color: #0A0B0B;
+ font-size: 150%;
+ font-weight: normal;
+ margin-top: 1.75em;
+ padding-top: 8px;
+ padding-bottom: 4px;
+ width: 100%;
+}
+
+h3.groupheader {
+ font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ -webkit-transition: text-shadow 0.5s linear;
+ -moz-transition: text-shadow 0.5s linear;
+ -ms-transition: text-shadow 0.5s linear;
+ -o-transition: text-shadow 0.5s linear;
+ transition: text-shadow 0.5s linear;
+ margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+ text-shadow: 0 0 15px cyan;
+}
+
+dt {
+ font-weight: bold;
+}
+
+ul.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+ column-count: 3;
+}
+
+p.startli, p.startdd {
+ margin-top: 2px;
+}
+
+th p.starttd, th p.intertd, th p.endtd {
+ font-size: 100%;
+ font-weight: 700;
+}
+
+p.starttd {
+ margin-top: 0px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+p.interli {
+}
+
+p.interdd {
+}
+
+p.intertd {
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.navtab {
+ border-right: 1px solid #636C6D;
+ padding-right: 15px;
+ text-align: right;
+ line-height: 110%;
+}
+
+div.navtab table {
+ border-spacing: 0;
+}
+
+td.navtab {
+ padding-right: 6px;
+ padding-left: 6px;
+}
+td.navtabHL {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ padding-right: 6px;
+ padding-left: 6px;
+}
+
+td.navtabHL a, td.navtabHL a:visited {
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+a.navtab {
+ font-weight: bold;
+}
+
+div.qindex{
+ text-align: center;
+ width: 100%;
+ line-height: 140%;
+ font-size: 130%;
+ color: #A0A0A0;
+}
+
+dt.alphachar{
+ font-size: 180%;
+ font-weight: bold;
+}
+
+.alphachar a{
+ color: black;
+}
+
+.alphachar a:hover, .alphachar a:visited{
+ text-decoration: none;
+}
+
+.classindex dl {
+ padding: 25px;
+ column-count:1
+}
+
+.classindex dd {
+ display:inline-block;
+ margin-left: 50px;
+ width: 90%;
+ line-height: 1.15em;
+}
+
+.classindex dl.odd {
+ background-color: #F0F1F1;
+}
+
+@media(min-width: 1120px) {
+ .classindex dl {
+ column-count:2
+ }
+}
+
+@media(min-width: 1320px) {
+ .classindex dl {
+ column-count:3
+ }
+}
+
+
+/* @group Link Styling */
+
+a {
+ color: #0F1010;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #171919;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+.contents a.qindexHL:visited {
+ color: #FFFFFF;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+ color: #171919;
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+ color: #171919;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+ul {
+ overflow: hidden; /*Fixed: list item bullets overlap floating elements*/
+}
+
+#side-nav ul {
+ overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */
+}
+
+#main-nav ul {
+ overflow: visible; /* reset ul rule for the navigation bar drop down lists */
+}
+
+.fragment {
+ text-align: left;
+ direction: ltr;
+ overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/
+ overflow-y: hidden;
+}
+
+pre.fragment {
+ border: 1px solid #90989A;
+ background-color: #F7F8F8;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+div.fragment {
+ padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/
+ margin: 4px 8px 4px 2px;
+ background-color: #F7F8F8;
+ border: 1px solid #90989A;
+}
+
+div.line {
+ font-family: monospace, fixed;
+ font-size: 13px;
+ min-height: 13px;
+ line-height: 1.0;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ text-indent: -53px;
+ padding-left: 53px;
+ padding-bottom: 0px;
+ margin: 0px;
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+div.line:after {
+ content:"\000A";
+ white-space: pre;
+}
+
+div.line.glow {
+ background-color: cyan;
+ box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+ padding-right: 4px;
+ text-align: right;
+ border-right: 2px solid #0F0;
+ background-color: #E8E8E8;
+ white-space: pre;
+}
+span.lineno a {
+ background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+ background-color: #C8C8C8;
+}
+
+.lineno {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+div.ah, span.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #FFFFFF;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%);
+}
+
+div.classindex ul {
+ list-style: none;
+ padding-left: 0;
+}
+
+div.classindex span.ai {
+ display: inline-block;
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background-color: white;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 12px;
+ margin-right: 8px;
+}
+
+td.indexkey {
+ background-color: #D6D9D9;
+ font-weight: bold;
+ border: 1px solid #90989A;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: #D6D9D9;
+ border: 1px solid #90989A;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #DADDDE;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl, img.inline {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+blockquote {
+ background-color: #EDEFEF;
+ border-left: 2px solid #5B6364;
+ margin: 0 24px 0 4px;
+ padding: 0 12px 0 16px;
+}
+
+blockquote.DocNodeRTL {
+ border-left: 0;
+ border-right: 2px solid #5B6364;
+ margin: 0 4px 0 24px;
+ padding: 0 16px 0 12px;
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #636C6D;
+}
+
+th.dirtab {
+ background: #D6D9D9;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #1A1D1D;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+ background-color: cyan;
+ box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #F2F3F3;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memSeparator {
+ border-bottom: 1px solid #BBC0C1;
+ line-height: 1px;
+ margin: 0px;
+ padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight, .memTemplItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: #171919;
+ white-space: nowrap;
+ font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtitle {
+ padding: 8px;
+ border-top: 1px solid #697273;
+ border-left: 1px solid #697273;
+ border-right: 1px solid #697273;
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ margin-bottom: -1px;
+ background-image: url('nav_f.png');
+ background-repeat: repeat-x;
+ background-color: #C4C8C9;
+ line-height: 1.25;
+ font-weight: 300;
+ float:left;
+}
+
+.permalink
+{
+ font-size: 65%;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.memtemplate {
+ font-size: 80%;
+ color: #171919;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: #D6D9D9;
+ border: 1px solid #636C6D;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+ -webkit-transition: box-shadow 0.5s linear;
+ -moz-transition: box-shadow 0.5s linear;
+ -ms-transition: box-shadow 0.5s linear;
+ -o-transition: box-shadow 0.5s linear;
+ transition: box-shadow 0.5s linear;
+ display: table !important;
+ width: 100%;
+}
+
+.memitem.glow {
+ box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+ font-weight: 400;
+ margin-left: 6px;
+}
+
+.memname td {
+ vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid #697273;
+ border-left: 1px solid #697273;
+ border-right: 1px solid #697273;
+ padding: 6px 0px 6px 0px;
+ color: #030303;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ background-color: #BDC2C3;
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 4px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 4px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 4px;
+
+}
+
+.overload {
+ font-family: "courier new",courier,monospace;
+ font-size: 65%;
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid #697273;
+ border-left: 1px solid #697273;
+ border-right: 1px solid #697273;
+ padding: 6px 10px 2px 10px;
+ background-color: #F7F8F8;
+ border-top-width: 0;
+ background-image:url('nav_g.png');
+ background-repeat:repeat-x;
+ background-color: #FFFFFF;
+ /* opera specific markup */
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+.paramname code {
+ line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype, .tparams .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir, .tparams .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+table.mlabels {
+ border-spacing: 0px;
+}
+
+td.mlabels-left {
+ width: 100%;
+ padding: 0px;
+}
+
+td.mlabels-right {
+ vertical-align: bottom;
+ padding: 0px;
+ white-space: nowrap;
+}
+
+span.mlabels {
+ margin-left: 8px;
+}
+
+span.mlabel {
+ background-color: #353A3B;
+ border-top:1px solid #212425;
+ border-left:1px solid #212425;
+ border-right:1px solid #90989A;
+ border-bottom:1px solid #90989A;
+ text-shadow: none;
+ color: white;
+ margin-right: 4px;
+ padding: 2px 3px;
+ border-radius: 3px;
+ font-size: 7pt;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+ margin: 10px 0px;
+ border-top: 1px solid #5B6364;
+ border-bottom: 1px solid #5B6364;
+ width: 100%;
+}
+
+.directory table {
+ border-collapse:collapse;
+}
+
+.directory td {
+ margin: 0px;
+ padding: 0px;
+ vertical-align: top;
+}
+
+.directory td.entry {
+ white-space: nowrap;
+ padding-right: 6px;
+ padding-top: 3px;
+}
+
+.directory td.entry a {
+ outline:none;
+}
+
+.directory td.entry a img {
+ border: none;
+}
+
+.directory td.desc {
+ width: 100%;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 3px;
+ border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+ padding-left: 6px;
+ background-color: #EDEFEF;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+.directory .levels {
+ white-space: nowrap;
+ width: 100%;
+ text-align: right;
+ font-size: 9pt;
+}
+
+.directory .levels span {
+ cursor: pointer;
+ padding-left: 2px;
+ padding-right: 2px;
+ color: #0F1010;
+}
+
+.arrow {
+ color: #5B6364;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ font-size: 80%;
+ display: inline-block;
+ width: 16px;
+ height: 22px;
+}
+
+.icon {
+ font-family: Arial, Helvetica;
+ font-weight: bold;
+ font-size: 12px;
+ height: 14px;
+ width: 16px;
+ display: inline-block;
+ background-color: #353A3B;
+ color: white;
+ text-align: center;
+ border-radius: 4px;
+ margin-left: 2px;
+ margin-right: 2px;
+}
+
+.icona {
+ width: 24px;
+ height: 22px;
+ display: inline-block;
+}
+
+.iconfopen {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('folderopen.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.iconfclosed {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('folderclosed.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+.icondoc {
+ width: 24px;
+ height: 18px;
+ margin-bottom: 4px;
+ background-image:url('doc.png');
+ background-position: 0px -4px;
+ background-repeat: repeat-y;
+ vertical-align:top;
+ display: inline-block;
+}
+
+table.directory {
+ font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+ margin-top: 8px;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+address {
+ font-style: normal;
+ color: #050505;
+}
+
+table.doxtable caption {
+ caption-side: top;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #060606;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #0B0C0C;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+table.fieldtable {
+ /*width: 100%;*/
+ margin-bottom: 10px;
+ border: 1px solid #697273;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid #697273;
+ border-bottom: 1px solid #697273;
+ vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+ padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid #697273;
+ /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+ margin-top: 0px;
+}
+
+.fieldtable td.fielddoc p:last-child {
+ margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #C4C8C9;
+ font-size: 90%;
+ color: #030303;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ font-weight: 400;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid #697273;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ background-position: 0 -5px;
+ height:30px;
+ line-height:30px;
+ color:#494F50;
+ border:solid 1px #8C9596;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#0A0B0B;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+ color: #040404;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:#2E3233;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#0A0B0B;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+table.classindex
+{
+ margin: 10px;
+ white-space: nowrap;
+ margin-left: 3%;
+ margin-right: 3%;
+ width: 94%;
+ border: 0;
+ border-spacing: 0;
+ padding: 0;
+}
+
+div.ingroups
+{
+ font-size: 8pt;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F2F3F3;
+ margin: 0px;
+ border-bottom: 1px solid #90989A;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 10px;
+}
+
+.PageDocRTL-title div.headertitle {
+ text-align: right;
+ direction: rtl;
+}
+
+dl {
+ padding: 0 0 0 0;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */
+dl.section {
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+dl.section.DocNodeRTL {
+ margin-right: 0px;
+ padding-right: 0px;
+}
+
+dl.note {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #D0C000;
+}
+
+dl.note.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #FF0000;
+}
+
+dl.warning.DocNodeRTL, dl.attention.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #00D000;
+}
+
+dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #00D000;
+}
+
+dl.deprecated {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #505050;
+}
+
+dl.deprecated.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #505050;
+}
+
+dl.todo {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #00C0E0;
+}
+
+dl.todo.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #3030E0;
+}
+
+dl.test.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #C08050;
+}
+
+dl.bug.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #C08050;
+}
+
+dl.section dd {
+ margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectalign
+{
+ vertical-align: middle;
+}
+
+#projectname
+{
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 120% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 50% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid #212425;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.plantumlgraph
+{
+ text-align: center;
+}
+
+.diagraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid #4F5657;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:#080909;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+ text-align:right;
+ width:52px;
+}
+
+dl.citelist dd {
+ margin:2px 0 2px 72px;
+ padding:5px 0;
+}
+
+div.toc {
+ padding: 14px 25px;
+ background-color: #E8EAEA;
+ border: 1px solid #B1B7B8;
+ border-radius: 7px 7px 7px 7px;
+ float: right;
+ height: auto;
+ margin: 0 8px 10px 10px;
+ width: 200px;
+}
+
+.PageDocRTL-title div.toc {
+ float: left !important;
+ text-align: right;
+}
+
+div.toc li {
+ background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+ font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+ margin-top: 5px;
+ padding-left: 10px;
+ padding-top: 2px;
+}
+
+.PageDocRTL-title div.toc li {
+ background-position-x: right !important;
+ padding-left: 0 !important;
+ padding-right: 10px;
+}
+
+div.toc h3 {
+ font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+ color: #171919;
+ border-bottom: 0 none;
+ margin: 0;
+}
+
+div.toc ul {
+ list-style: none outside none;
+ border: medium none;
+ padding: 0px;
+}
+
+div.toc li.level1 {
+ margin-left: 0px;
+}
+
+div.toc li.level2 {
+ margin-left: 15px;
+}
+
+div.toc li.level3 {
+ margin-left: 30px;
+}
+
+div.toc li.level4 {
+ margin-left: 45px;
+}
+
+span.emoji {
+ /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html
+ * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort;
+ */
+}
+
+.PageDocRTL-title div.toc li.level1 {
+ margin-left: 0 !important;
+ margin-right: 0;
+}
+
+.PageDocRTL-title div.toc li.level2 {
+ margin-left: 0 !important;
+ margin-right: 15px;
+}
+
+.PageDocRTL-title div.toc li.level3 {
+ margin-left: 0 !important;
+ margin-right: 30px;
+}
+
+.PageDocRTL-title div.toc li.level4 {
+ margin-left: 0 !important;
+ margin-right: 45px;
+}
+
+.inherit_header {
+ font-weight: bold;
+ color: gray;
+ cursor: pointer;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.inherit_header td {
+ padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+ display: none;
+}
+
+tr.heading h2 {
+ margin-top: 12px;
+ margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+ position: absolute;
+ display: none;
+}
+
+#powerTip {
+ cursor: default;
+ white-space: nowrap;
+ background-color: white;
+ border: 1px solid gray;
+ border-radius: 4px 4px 4px 4px;
+ box-shadow: 1px 1px 7px gray;
+ display: none;
+ font-size: smaller;
+ max-width: 80%;
+ opacity: 0.9;
+ padding: 1ex 1em 1em;
+ position: absolute;
+ z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+ color: grey;
+ font-style: italic;
+}
+
+#powerTip div.ttname a {
+ font-weight: bold;
+}
+
+#powerTip div.ttname {
+ font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+ color: #006318;
+}
+
+#powerTip div {
+ margin: 0px;
+ padding: 0px;
+ font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+ content: "";
+ position: absolute;
+ margin: 0px;
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.w:after, #powerTip.w:before,
+#powerTip.e:after, #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+}
+
+#powerTip.n:after, #powerTip.s:after,
+#powerTip.w:after, #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+ border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before, #powerTip.s:before,
+#powerTip.w:before, #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+ border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+ top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+ border-top-color: #FFFFFF;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+#powerTip.n:before {
+ border-top-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+ left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+ right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+ left: 14px;
+}
+
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+ border-bottom-color: #FFFFFF;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+ border-bottom-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+ left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+ right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+ left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+ left: 100%;
+}
+#powerTip.e:after {
+ border-left-color: #FFFFFF;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.e:before {
+ border-left-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+ right: 100%;
+}
+#powerTip.w:after {
+ border-right-color: #FFFFFF;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.w:before {
+ border-right-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+@media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+}
+
+/* @group Markdown */
+
+table.markdownTable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.markdownTable td, table.markdownTable th {
+ border: 1px solid #060606;
+ padding: 3px 7px 2px;
+}
+
+table.markdownTable tr {
+}
+
+th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone {
+ background-color: #0B0C0C;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+th.markdownTableHeadLeft, td.markdownTableBodyLeft {
+ text-align: left
+}
+
+th.markdownTableHeadRight, td.markdownTableBodyRight {
+ text-align: right
+}
+
+th.markdownTableHeadCenter, td.markdownTableBodyCenter {
+ text-align: center
+}
+
+.DocNodeRTL {
+ text-align: right;
+ direction: rtl;
+}
+
+.DocNodeLTR {
+ text-align: left;
+ direction: ltr;
+}
+
+table.DocNodeRTL {
+ width: auto;
+ margin-right: 0;
+ margin-left: auto;
+}
+
+table.DocNodeLTR {
+ width: auto;
+ margin-right: auto;
+ margin-left: 0;
+}
+
+tt, code, kbd, samp
+{
+ display: inline-block;
+ direction:ltr;
+}
+/* @end */
+
+u {
+ text-decoration: underline;
+}
+
--- /dev/null
+/*
+ @licstart The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend The above is the entire license notice for the JavaScript code in this file
+ */
+function toggleVisibility(linkObj)
+{
+ var base = $(linkObj).attr('id');
+ var summary = $('#'+base+'-summary');
+ var content = $('#'+base+'-content');
+ var trigger = $('#'+base+'-trigger');
+ var src=$(trigger).attr('src');
+ if (content.is(':visible')===true) {
+ content.hide();
+ summary.show();
+ $(linkObj).addClass('closed').removeClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ content.show();
+ summary.hide();
+ $(linkObj).removeClass('closed').addClass('opened');
+ $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+ return false;
+}
+
+function updateStripes()
+{
+ $('table.directory tr').
+ removeClass('even').filter(':visible:even').addClass('even');
+}
+
+function toggleLevel(level)
+{
+ $('table.directory tr').each(function() {
+ var l = this.id.split('_').length-1;
+ var i = $('#img'+this.id.substring(3));
+ var a = $('#arr'+this.id.substring(3));
+ if (l<level+1) {
+ i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
+ a.html('▼');
+ $(this).show();
+ } else if (l==level+1) {
+ i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
+ a.html('►');
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+ updateStripes();
+}
+
+function toggleFolder(id)
+{
+ // the clicked row
+ var currentRow = $('#row_'+id);
+
+ // all rows after the clicked row
+ var rows = currentRow.nextAll("tr");
+
+ var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
+
+ // only match elements AFTER this one (can't hide elements before)
+ var childRows = rows.filter(function() { return this.id.match(re); });
+
+ // first row is visible we are HIDING
+ if (childRows.filter(':first').is(':visible')===true) {
+ // replace down arrow by right arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ currentRowSpans.filter(".arrow").html('►');
+ rows.filter("[id^=row_"+id+"]").hide(); // hide all children
+ } else { // we are SHOWING
+ // replace right arrow by down arrow for current row
+ var currentRowSpans = currentRow.find("span");
+ currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
+ currentRowSpans.filter(".arrow").html('▼');
+ // replace down arrows by right arrows for child rows
+ var childRowsSpans = childRows.find("span");
+ childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+ childRowsSpans.filter(".arrow").html('►');
+ childRows.show(); //show all children
+ }
+ updateStripes();
+}
+
+
+function toggleInherit(id)
+{
+ var rows = $('tr.inherit.'+id);
+ var img = $('tr.inherit_header.'+id+' img');
+ var src = $(img).attr('src');
+ if (rows.filter(':first').is(':visible')===true) {
+ rows.css('display','none');
+ $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+ rows.css('display','table-row'); // using show() causes jump in firefox
+ $(img).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+}
+/* @license-end */
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Environment Options</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('environment.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="PageDoc"><div class="header">
+ <div class="headertitle">
+<div class="title">Environment Options </div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>You can set further options either programmatically (using <a href="https://microsoft.github.io/mimalloc/group__options.html"><code>mi_option_set</code></a>), or via environment variables.</p>
+<ul>
+<li><code>MIMALLOC_SHOW_STATS=1</code>: show statistics when the program terminates.</li>
+<li><code>MIMALLOC_VERBOSE=1</code>: show verbose messages.</li>
+<li><code>MIMALLOC_SHOW_ERRORS=1</code>: show error and warning messages.</li>
+<li><code>MIMALLOC_PAGE_RESET=0</code>: by default, mimalloc will reset (or purge) OS pages when not in use to signal to the OS that the underlying physical memory can be reused. This can reduce memory fragmentation in long running (server) programs. By setting it to <code>0</code> no such page resets will be done which can improve performance for programs that are not long running. As an alternative, the <code>MIMALLOC_RESET_DELAY=</code><msecs> can be set higher (100ms by default) to make the page reset occur less frequently instead of turning it off completely.</li>
+<li><code>MIMALLOC_LARGE_OS_PAGES=1</code>: use large OS pages (2MiB) when available; for some workloads this can significantly improve performance. Use <code>MIMALLOC_VERBOSE</code> to check if the large OS pages are enabled – usually one needs to explicitly allow large OS pages (as on <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017">Windows</a> and <a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5">Linux</a>). However, sometimes the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that can have fragmented memory (for that reason, we generally recommend to use <code>MIMALLOC_RESERVE_HUGE_OS_PAGES</code> instead when possible).</li>
+<li><code>MIMALLOC_RESERVE_HUGE_OS_PAGES=N</code>: where N is the number of 1GiB <em>huge</em> OS pages. This reserves the huge pages at startup and sometimes this can give a large (latency) performance improvement on big workloads. Usually it is better to not use <code>MIMALLOC_LARGE_OS_PAGES</code> in combination with this setting. Just like large OS pages, use with care as reserving contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at startup only once). Note that we usually need to explicitly enable huge OS pages (as on <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017">Windows</a> and <a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5">Linux</a>)). With huge OS pages, it may be beneficial to set the setting <code>MIMALLOC_EAGER_COMMIT_DELAY=N</code> (<code>N</code> is 1 by default) to delay the initial <code>N</code> segments (of 4MiB) of a thread to not allocate in the huge OS pages; this prevents threads that are short lived and allocate just a little to take up space in the huge OS page area (which cannot be reset).</li>
+<li><code>MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N</code>: where N is the numa node. This reserves the huge pages at a specific numa node. (<code>N</code> is -1 by default to reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected))</li>
+</ul>
+<p>Use caution when using <code>fork</code> in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write for all pages in the original process including the huge OS pages. When any memory is now written in that area, the OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in big increments. </p>
+</div></div><!-- contents -->
+</div><!-- PageDoc -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('functions.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+<div class="textblock">Here is a list of all struct and union fields with links to the structures/unions they belong to:</div><ul>
+<li>block_size
+: <a class="el" href="group__analysis.html#a332a6c14d736a99699d5453a1cb04b41">mi_heap_area_t</a>
+</li>
+<li>blocks
+: <a class="el" href="group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8">mi_heap_area_t</a>
+</li>
+<li>committed
+: <a class="el" href="group__analysis.html#ab47526df656d8837ec3e97f11b83f835">mi_heap_area_t</a>
+</li>
+<li>reserved
+: <a class="el" href="group__analysis.html#ae848a3e6840414891035423948ca0383">mi_heap_area_t</a>
+</li>
+<li>used
+: <a class="el" href="group__analysis.html#ab820302c5cd0df133eb8e51650a008b4">mi_heap_area_t</a>
+</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Data Fields - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('functions_vars.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+ <ul>
+<li>block_size
+: <a class="el" href="group__analysis.html#a332a6c14d736a99699d5453a1cb04b41">mi_heap_area_t</a>
+</li>
+<li>blocks
+: <a class="el" href="group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8">mi_heap_area_t</a>
+</li>
+<li>committed
+: <a class="el" href="group__analysis.html#ab47526df656d8837ec3e97f11b83f835">mi_heap_area_t</a>
+</li>
+<li>reserved
+: <a class="el" href="group__analysis.html#ae848a3e6840414891035423948ca0383">mi_heap_area_t</a>
+</li>
+<li>used
+: <a class="el" href="group__analysis.html#ab820302c5cd0df133eb8e51650a008b4">mi_heap_area_t</a>
+</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Aligned Allocation</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__aligned.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#define-members">Macros</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Aligned Allocation</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>Allocating aligned memory blocks.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
+Macros</h2></td></tr>
+<tr class="memitem:ga83c03016066b438f51a8095e9140be06"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga83c03016066b438f51a8095e9140be06">MI_ALIGNMENT_MAX</a></td></tr>
+<tr class="memdesc:ga83c03016066b438f51a8095e9140be06"><td class="mdescLeft"> </td><td class="mdescRight">The maximum supported alignment size (currently 1MiB). <a href="group__aligned.html#ga83c03016066b438f51a8095e9140be06">More...</a><br /></td></tr>
+<tr class="separator:ga83c03016066b438f51a8095e9140be06"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:ga68930196751fa2cca9e1fd0d71bade56"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56">mi_malloc_aligned</a> (size_t size, size_t alignment)</td></tr>
+<tr class="memdesc:ga68930196751fa2cca9e1fd0d71bade56"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>size</em> bytes aligned by <em>alignment</em>. <a href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56">More...</a><br /></td></tr>
+<tr class="separator:ga68930196751fa2cca9e1fd0d71bade56"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga0cadbcf5b89a7b6fb171bc8df8734819"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819">mi_zalloc_aligned</a> (size_t size, size_t alignment)</td></tr>
+<tr class="separator:ga0cadbcf5b89a7b6fb171bc8df8734819"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga53dddb4724042a90315b94bc268fb4c9"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9">mi_calloc_aligned</a> (size_t count, size_t size, size_t alignment)</td></tr>
+<tr class="separator:ga53dddb4724042a90315b94bc268fb4c9"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga4028d1cf4aa4c87c880747044a8322ae"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae">mi_realloc_aligned</a> (void *p, size_t newsize, size_t alignment)</td></tr>
+<tr class="separator:ga4028d1cf4aa4c87c880747044a8322ae"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga5850da130c936bd77db039dcfbc8295d"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga5850da130c936bd77db039dcfbc8295d">mi_malloc_aligned_at</a> (size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="memdesc:ga5850da130c936bd77db039dcfbc8295d"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>size</em> bytes aligned by <em>alignment</em> at a specified <em>offset</em>. <a href="group__aligned.html#ga5850da130c936bd77db039dcfbc8295d">More...</a><br /></td></tr>
+<tr class="separator:ga5850da130c936bd77db039dcfbc8295d"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga5f8c2353766db522565e642fafd8a3f8"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8">mi_zalloc_aligned_at</a> (size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga5f8c2353766db522565e642fafd8a3f8"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga08647c4593f3b2eef24a919a73eba3a3"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3">mi_calloc_aligned_at</a> (size_t count, size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga08647c4593f3b2eef24a919a73eba3a3"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaf66a9ae6c6f08bd6be6fb6ea771faffb"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb">mi_realloc_aligned_at</a> (void *p, size_t newsize, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:gaf66a9ae6c6f08bd6be6fb6ea771faffb"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>Allocating aligned memory blocks. </p>
+<h2 class="groupheader">Macro Definition Documentation</h2>
+<a id="ga83c03016066b438f51a8095e9140be06"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga83c03016066b438f51a8095e9140be06">◆ </a></span>MI_ALIGNMENT_MAX</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define MI_ALIGNMENT_MAX</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>The maximum supported alignment size (currently 1MiB). </p>
+
+</div>
+</div>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="ga53dddb4724042a90315b94bc268fb4c9"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga53dddb4724042a90315b94bc268fb4c9">◆ </a></span>mi_calloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_calloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga08647c4593f3b2eef24a919a73eba3a3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga08647c4593f3b2eef24a919a73eba3a3">◆ </a></span>mi_calloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_calloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga68930196751fa2cca9e1fd0d71bade56"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga68930196751fa2cca9e1fd0d71bade56">◆ </a></span>mi_malloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_malloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>size</em> bytes aligned by <em>alignment</em>. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>number of bytes to allocate. </td></tr>
+ <tr><td class="paramname">alignment</td><td>the minimal alignment of the allocated memory. Must be less than <a class="el" href="group__aligned.html#ga83c03016066b438f51a8095e9140be06" title="The maximum supported alignment size (currently 1MiB).">MI_ALIGNMENT_MAX</a>. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the allocated memory or <em>NULL</em> if out of memory. The returned pointer is aligned by <em>alignment</em>, i.e. <code>(uintptr_t)p % alignment == 0</code>.</dd></dl>
+<p>Returns a unique pointer if called with <em>size</em> 0. </p><dl class="section see"><dt>See also</dt><dd><a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc?view=vs-2017">_aligned_malloc</a> (on Windows) </dd>
+<dd>
+<a href="http://man.openbsd.org/reallocarray">aligned_alloc</a> (on BSD, with switched arguments!) </dd>
+<dd>
+<a href="https://linux.die.net/man/3/posix_memalign">posix_memalign</a> (on Posix, with switched arguments!) </dd>
+<dd>
+<a href="https://linux.die.net/man/3/posix_memalign">memalign</a> (on Linux, with switched arguments!) </dd></dl>
+
+</div>
+</div>
+<a id="ga5850da130c936bd77db039dcfbc8295d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga5850da130c936bd77db039dcfbc8295d">◆ </a></span>mi_malloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_malloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>size</em> bytes aligned by <em>alignment</em> at a specified <em>offset</em>. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>number of bytes to allocate. </td></tr>
+ <tr><td class="paramname">alignment</td><td>the minimal alignment of the allocated memory at <em>offset</em>. </td></tr>
+ <tr><td class="paramname">offset</td><td>the offset that should be aligned. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the allocated memory or <em>NULL</em> if out of memory. The returned pointer is aligned by <em>alignment</em> at <em>offset</em>, i.e. <code>((uintptr_t)p + offset) % alignment == 0</code>.</dd></dl>
+<p>Returns a unique pointer if called with <em>size</em> 0. </p><dl class="section see"><dt>See also</dt><dd><a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-offset-malloc?view=vs-2017">_aligned_offset_malloc</a> (on Windows) </dd></dl>
+
+</div>
+</div>
+<a id="ga4028d1cf4aa4c87c880747044a8322ae"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4028d1cf4aa4c87c880747044a8322ae">◆ </a></span>mi_realloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_realloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gaf66a9ae6c6f08bd6be6fb6ea771faffb"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf66a9ae6c6f08bd6be6fb6ea771faffb">◆ </a></span>mi_realloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_realloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga0cadbcf5b89a7b6fb171bc8df8734819"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga0cadbcf5b89a7b6fb171bc8df8734819">◆ </a></span>mi_zalloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_zalloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga5f8c2353766db522565e642fafd8a3f8"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga5f8c2353766db522565e642fafd8a3f8">◆ </a></span>mi_zalloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_zalloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__aligned =
+[
+ [ "MI_ALIGNMENT_MAX", "group__aligned.html#ga83c03016066b438f51a8095e9140be06", null ],
+ [ "mi_calloc_aligned", "group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9", null ],
+ [ "mi_calloc_aligned_at", "group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3", null ],
+ [ "mi_malloc_aligned", "group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56", null ],
+ [ "mi_malloc_aligned_at", "group__aligned.html#ga5850da130c936bd77db039dcfbc8295d", null ],
+ [ "mi_realloc_aligned", "group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae", null ],
+ [ "mi_realloc_aligned_at", "group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb", null ],
+ [ "mi_zalloc_aligned", "group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819", null ],
+ [ "mi_zalloc_aligned_at", "group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Heap Introspection</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__analysis.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> |
+<a href="#typedef-members">Typedefs</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Heap Introspection</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>Inspect the heap at runtime.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr class="memitem:structmi__heap__area__t"><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a></td></tr>
+<tr class="memdesc:structmi__heap__area__t"><td class="mdescLeft"> </td><td class="mdescRight">An area of heap space contains blocks of a single size. <a href="group__analysis.html#structmi__heap__area__t">More...</a><br /></td></tr>
+<tr class="separator:structmi__heap__area__t"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr class="memitem:gadfa01e2900f0e5d515ad5506b26f6d65"><td class="memItemLeft" align="right" valign="top">typedef bool() </td><td class="memItemRight" valign="bottom"><a class="el" href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">mi_block_visit_fun</a>(const <a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const <a class="el" href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a> *area, void *block, size_t block_size, void *arg)</td></tr>
+<tr class="memdesc:gadfa01e2900f0e5d515ad5506b26f6d65"><td class="mdescLeft"> </td><td class="mdescRight">Visitor function passed to <a class="el" href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed" title="Visit all areas and blocks in a heap.">mi_heap_visit_blocks()</a> <a href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">More...</a><br /></td></tr>
+<tr class="separator:gadfa01e2900f0e5d515ad5506b26f6d65"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:gaa862aa8ed8d57d84cae41fc1022d71af"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af">mi_heap_contains_block</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const void *p)</td></tr>
+<tr class="memdesc:gaa862aa8ed8d57d84cae41fc1022d71af"><td class="mdescLeft"> </td><td class="mdescRight">Does a heap contain a pointer to a previously allocated block? <a href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af">More...</a><br /></td></tr>
+<tr class="separator:gaa862aa8ed8d57d84cae41fc1022d71af"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga0d67c1789faaa15ff366c024fcaf6377"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377">mi_heap_check_owned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const void *p)</td></tr>
+<tr class="memdesc:ga0d67c1789faaa15ff366c024fcaf6377"><td class="mdescLeft"> </td><td class="mdescRight">Check safely if any pointer is part of a heap. <a href="group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377">More...</a><br /></td></tr>
+<tr class="separator:ga0d67c1789faaa15ff366c024fcaf6377"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga628c237489c2679af84a4d0d143b3dd5"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5">mi_check_owned</a> (const void *p)</td></tr>
+<tr class="memdesc:ga628c237489c2679af84a4d0d143b3dd5"><td class="mdescLeft"> </td><td class="mdescRight">Check safely if any pointer is part of the default heap of this thread. <a href="group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5">More...</a><br /></td></tr>
+<tr class="separator:ga628c237489c2679af84a4d0d143b3dd5"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga70c46687dc6e9dc98b232b02646f8bed"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed">mi_heap_visit_blocks</a> (const <a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, bool visit_all_blocks, <a class="el" href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">mi_block_visit_fun</a> *visitor, void *arg)</td></tr>
+<tr class="memdesc:ga70c46687dc6e9dc98b232b02646f8bed"><td class="mdescLeft"> </td><td class="mdescRight">Visit all areas and blocks in a heap. <a href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed">More...</a><br /></td></tr>
+<tr class="separator:ga70c46687dc6e9dc98b232b02646f8bed"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>Inspect the heap at runtime. </p>
+<hr/><h2 class="groupheader">Data Structure Documentation</h2>
+<a name="structmi__heap__area__t" id="structmi__heap__area__t"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#structmi__heap__area__t">◆ </a></span>mi_heap_area_t</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct mi_heap_area_t</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+<div class="textblock"><p>An area of heap space contains blocks of a single size. </p>
+<p>The bytes in freed blocks are <code>committed - used</code>. </p>
+</div><table class="fieldtable">
+<tr><th colspan="3">Data Fields</th></tr>
+<tr><td class="fieldtype">
+<a id="a332a6c14d736a99699d5453a1cb04b41"></a>size_t</td>
+<td class="fieldname">
+block_size</td>
+<td class="fielddoc">
+size in bytes of one block </td></tr>
+<tr><td class="fieldtype">
+<a id="ae0085e6e1cf059a4eb7767e30e9991b8"></a>void *</td>
+<td class="fieldname">
+blocks</td>
+<td class="fielddoc">
+start of the area containing heap blocks </td></tr>
+<tr><td class="fieldtype">
+<a id="ab47526df656d8837ec3e97f11b83f835"></a>size_t</td>
+<td class="fieldname">
+committed</td>
+<td class="fielddoc">
+current committed bytes of this area </td></tr>
+<tr><td class="fieldtype">
+<a id="ae848a3e6840414891035423948ca0383"></a>size_t</td>
+<td class="fieldname">
+reserved</td>
+<td class="fielddoc">
+bytes reserved for this area </td></tr>
+<tr><td class="fieldtype">
+<a id="ab820302c5cd0df133eb8e51650a008b4"></a>size_t</td>
+<td class="fieldname">
+used</td>
+<td class="fielddoc">
+bytes in use by allocated blocks </td></tr>
+</table>
+
+</div>
+</div>
+<h2 class="groupheader">Typedef Documentation</h2>
+<a id="gadfa01e2900f0e5d515ad5506b26f6d65"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gadfa01e2900f0e5d515ad5506b26f6d65">◆ </a></span>mi_block_visit_fun</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef bool() mi_block_visit_fun(const <a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const <a class="el" href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a> *area, void *block, size_t block_size, void *arg)</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Visitor function passed to <a class="el" href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed" title="Visit all areas and blocks in a heap.">mi_heap_visit_blocks()</a> </p>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if ok, <em>false</em> to stop visiting (i.e. break)</dd></dl>
+<p>This function is always first called for every <em>area</em> with <em>block</em> as a <em>NULL</em> pointer. If <em>visit_all_blocks</em> was <em>true</em>, the function is then called for every allocated block in that area. </p>
+
+</div>
+</div>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="ga628c237489c2679af84a4d0d143b3dd5"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga628c237489c2679af84a4d0d143b3dd5">◆ </a></span>mi_check_owned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_check_owned </td>
+ <td>(</td>
+ <td class="paramtype">const void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Check safely if any pointer is part of the default heap of this thread. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>Any pointer – not required to be previously allocated by us. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if <em>p</em> points to a block in default heap of this thread.</dd></dl>
+<p>Note: expensive function, linear in the pages in the heap. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af" title="Does a heap contain a pointer to a previously allocated block?">mi_heap_contains_block()</a> </dd>
+<dd>
+<a class="el" href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05" title="Get the default heap that is used for mi_malloc() et al.">mi_heap_get_default()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga0d67c1789faaa15ff366c024fcaf6377"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga0d67c1789faaa15ff366c024fcaf6377">◆ </a></span>mi_heap_check_owned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_heap_check_owned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">const void * </td>
+ <td class="paramname"><em>p</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Check safely if any pointer is part of a heap. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">heap</td><td>The heap. </td></tr>
+ <tr><td class="paramname">p</td><td>Any pointer – not required to be previously allocated by us. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if <em>p</em> points to a block in <em>heap</em>.</dd></dl>
+<p>Note: expensive function, linear in the pages in the heap. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af" title="Does a heap contain a pointer to a previously allocated block?">mi_heap_contains_block()</a> </dd>
+<dd>
+<a class="el" href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05" title="Get the default heap that is used for mi_malloc() et al.">mi_heap_get_default()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gaa862aa8ed8d57d84cae41fc1022d71af"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaa862aa8ed8d57d84cae41fc1022d71af">◆ </a></span>mi_heap_contains_block()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_heap_contains_block </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">const void * </td>
+ <td class="paramname"><em>p</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Does a heap contain a pointer to a previously allocated block? </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">heap</td><td>The heap. </td></tr>
+ <tr><td class="paramname">p</td><td>Pointer to a previously allocated block (in any heap)– cannot be some random pointer! </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if the block pointed to by <em>p</em> is in the <em>heap</em>. </dd></dl>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377" title="Check safely if any pointer is part of a heap.">mi_heap_check_owned()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga70c46687dc6e9dc98b232b02646f8bed"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga70c46687dc6e9dc98b232b02646f8bed">◆ </a></span>mi_heap_visit_blocks()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_heap_visit_blocks </td>
+ <td>(</td>
+ <td class="paramtype">const <a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>visit_all_blocks</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"><a class="el" href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">mi_block_visit_fun</a> * </td>
+ <td class="paramname"><em>visitor</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>arg</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Visit all areas and blocks in a heap. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">heap</td><td>The heap to visit. </td></tr>
+ <tr><td class="paramname">visit_all_blocks</td><td>If <em>true</em> visits all allocated blocks, otherwise <em>visitor</em> is only called for every heap area. </td></tr>
+ <tr><td class="paramname">visitor</td><td>This function is called for every area in the heap (with <em>block</em> as <em>NULL</em>). If <em>visit_all_blocks</em> is <em>true</em>, <em>visitor</em> is also called for every allocated block in every area (with <code>block!=NULL</code>). return <em>false</em> from this function to stop visiting early. </td></tr>
+ <tr><td class="paramname">arg</td><td>Extra argument passed to <em>visitor</em>. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if all areas and blocks were visited. </dd></dl>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__analysis =
+[
+ [ "mi_heap_area_t", "group__analysis.html#structmi__heap__area__t", [
+ [ "block_size", "group__analysis.html#a332a6c14d736a99699d5453a1cb04b41", null ],
+ [ "blocks", "group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8", null ],
+ [ "committed", "group__analysis.html#ab47526df656d8837ec3e97f11b83f835", null ],
+ [ "reserved", "group__analysis.html#ae848a3e6840414891035423948ca0383", null ],
+ [ "used", "group__analysis.html#ab820302c5cd0df133eb8e51650a008b4", null ]
+ ] ],
+ [ "mi_block_visit_fun", "group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65", null ],
+ [ "mi_check_owned", "group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5", null ],
+ [ "mi_heap_check_owned", "group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377", null ],
+ [ "mi_heap_contains_block", "group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af", null ],
+ [ "mi_heap_visit_blocks", "group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed", null ]
+];
\ No newline at end of file
--- /dev/null
+var group__analysis_structmi__heap__area__t =
+[
+ [ "block_size", "group__analysis.html#a332a6c14d736a99699d5453a1cb04b41", null ],
+ [ "blocks", "group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8", null ],
+ [ "committed", "group__analysis.html#ab47526df656d8837ec3e97f11b83f835", null ],
+ [ "reserved", "group__analysis.html#ae848a3e6840414891035423948ca0383", null ],
+ [ "used", "group__analysis.html#ab820302c5cd0df133eb8e51650a008b4", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: C++ wrappers</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__cpp.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#nested-classes">Data Structures</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">C++ wrappers</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><code>mi_</code> prefixed implementations of various allocation functions that use C++ semantics on out-of-memory, generally calling <code>std::get_new_handler</code> and raising a <code>std::bad_alloc</code> exception on failure.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
+Data Structures</h2></td></tr>
+<tr class="memitem:structmi__stl__allocator"><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#structmi__stl__allocator">mi_stl_allocator< T ></a></td></tr>
+<tr class="memdesc:structmi__stl__allocator"><td class="mdescLeft"> </td><td class="mdescRight"><em>std::allocator</em> implementation for mimalloc for use in STL containers. <a href="group__cpp.html#structmi__stl__allocator">More...</a><br /></td></tr>
+<tr class="separator:structmi__stl__allocator"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:gaad048a9fce3d02c5909cd05c6ec24545"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545">mi_new</a> (std::size_t n) noexcept(false)</td></tr>
+<tr class="memdesc:gaad048a9fce3d02c5909cd05c6ec24545"><td class="mdescLeft"> </td><td class="mdescRight">like <a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. <a href="group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545">More...</a><br /></td></tr>
+<tr class="separator:gaad048a9fce3d02c5909cd05c6ec24545"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gae7bc4f56cd57ed3359060ff4f38bda81"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81">mi_new_n</a> (size_t count, size_t size) noexcept(false)</td></tr>
+<tr class="memdesc:gae7bc4f56cd57ed3359060ff4f38bda81"><td class="mdescLeft"> </td><td class="mdescRight">like <a class="el" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6" title="Allocate count elements of size bytes.">mi_mallocn()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. <a href="group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81">More...</a><br /></td></tr>
+<tr class="separator:gae7bc4f56cd57ed3359060ff4f38bda81"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaef2c2bdb4f70857902d3c8903ac095f3"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3">mi_new_aligned</a> (std::size_t n, std::align_val_t alignment) noexcept(false)</td></tr>
+<tr class="memdesc:gaef2c2bdb4f70857902d3c8903ac095f3"><td class="mdescLeft"> </td><td class="mdescRight">like <a class="el" href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56" title="Allocate size bytes aligned by alignment.">mi_malloc_aligned()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. <a href="group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3">More...</a><br /></td></tr>
+<tr class="separator:gaef2c2bdb4f70857902d3c8903ac095f3"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaeaded64eda71ed6b1d569d3e723abc4a"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a">mi_new_nothrow</a> (size_t n)</td></tr>
+<tr class="memdesc:gaeaded64eda71ed6b1d569d3e723abc4a"><td class="mdescLeft"> </td><td class="mdescRight">like <code>mi_malloc</code>, but when out of memory, use <code>std::get_new_handler</code> but return <em>NULL</em> on failure. <a href="group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a">More...</a><br /></td></tr>
+<tr class="separator:gaeaded64eda71ed6b1d569d3e723abc4a"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gab5e29558926d934c3f1cae8c815f942c"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#gab5e29558926d934c3f1cae8c815f942c">mi_new_aligned_nothrow</a> (size_t n, size_t alignment)</td></tr>
+<tr class="memdesc:gab5e29558926d934c3f1cae8c815f942c"><td class="mdescLeft"> </td><td class="mdescRight">like <code>mi_malloc_aligned</code>, but when out of memory, use <code>std::get_new_handler</code> but return <em>NULL</em> on failure. <a href="group__cpp.html#gab5e29558926d934c3f1cae8c815f942c">More...</a><br /></td></tr>
+<tr class="separator:gab5e29558926d934c3f1cae8c815f942c"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaab78a32f55149e9fbf432d5288e38e1e"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e">mi_new_realloc</a> (void *p, size_t newsize)</td></tr>
+<tr class="memdesc:gaab78a32f55149e9fbf432d5288e38e1e"><td class="mdescLeft"> </td><td class="mdescRight">like <a class="el" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6" title="Re-allocate memory to newsize bytes.">mi_realloc()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. <a href="group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e">More...</a><br /></td></tr>
+<tr class="separator:gaab78a32f55149e9fbf432d5288e38e1e"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga756f4b2bc6a7ecd0a90baea8e90c7907"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907">mi_new_reallocn</a> (void *p, size_t newcount, size_t size)</td></tr>
+<tr class="memdesc:ga756f4b2bc6a7ecd0a90baea8e90c7907"><td class="mdescLeft"> </td><td class="mdescRight">like <a class="el" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853" title="Re-allocate memory to count elements of size bytes.">mi_reallocn()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. <a href="group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907">More...</a><br /></td></tr>
+<tr class="separator:ga756f4b2bc6a7ecd0a90baea8e90c7907"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p><code>mi_</code> prefixed implementations of various allocation functions that use C++ semantics on out-of-memory, generally calling <code>std::get_new_handler</code> and raising a <code>std::bad_alloc</code> exception on failure. </p>
+<p>Note: use the <code>mimalloc-new-delete.h</code> header to override the <em>new</em> and <em>delete</em> operators globally. The wrappers here are mostly for convience for library writers that need to interface with mimalloc from C++. </p>
+<hr/><h2 class="groupheader">Data Structure Documentation</h2>
+<a name="structmi__stl__allocator" id="structmi__stl__allocator"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#structmi__stl__allocator">◆ </a></span>mi_stl_allocator</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">struct mi_stl_allocator</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+<div class="textblock"><h3>template<class T><br />
+struct mi_stl_allocator< T ></h3>
+
+<p><em>std::allocator</em> implementation for mimalloc for use in STL containers. </p>
+<p>For example: </p><div class="fragment"><div class="line">std::vector<int, mi_stl_allocator<int> > vec;</div>
+<div class="line">vec.push_back(1);</div>
+<div class="line">vec.pop_back();</div>
+</div><!-- fragment --> </div>
+</div>
+</div>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="gaad048a9fce3d02c5909cd05c6ec24545"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaad048a9fce3d02c5909cd05c6ec24545">◆ </a></span>mi_new()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+ <tr>
+ <td class="mlabels-left">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new </td>
+ <td>(</td>
+ <td class="paramtype">std::size_t </td>
+ <td class="paramname"><em>n</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+ </td>
+ <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">noexcept</span></span> </td>
+ </tr>
+</table>
+</div><div class="memdoc">
+
+<p>like <a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. </p>
+
+</div>
+</div>
+<a id="gaef2c2bdb4f70857902d3c8903ac095f3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaef2c2bdb4f70857902d3c8903ac095f3">◆ </a></span>mi_new_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+ <tr>
+ <td class="mlabels-left">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new_aligned </td>
+ <td>(</td>
+ <td class="paramtype">std::size_t </td>
+ <td class="paramname"><em>n</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">std::align_val_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+ </td>
+ <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">noexcept</span></span> </td>
+ </tr>
+</table>
+</div><div class="memdoc">
+
+<p>like <a class="el" href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56" title="Allocate size bytes aligned by alignment.">mi_malloc_aligned()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. </p>
+
+</div>
+</div>
+<a id="gab5e29558926d934c3f1cae8c815f942c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gab5e29558926d934c3f1cae8c815f942c">◆ </a></span>mi_new_aligned_nothrow()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new_aligned_nothrow </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>n</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>like <code>mi_malloc_aligned</code>, but when out of memory, use <code>std::get_new_handler</code> but return <em>NULL</em> on failure. </p>
+
+</div>
+</div>
+<a id="gae7bc4f56cd57ed3359060ff4f38bda81"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gae7bc4f56cd57ed3359060ff4f38bda81">◆ </a></span>mi_new_n()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+ <tr>
+ <td class="mlabels-left">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new_n </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+ </td>
+ <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">noexcept</span></span> </td>
+ </tr>
+</table>
+</div><div class="memdoc">
+
+<p>like <a class="el" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6" title="Allocate count elements of size bytes.">mi_mallocn()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. </p>
+
+</div>
+</div>
+<a id="gaeaded64eda71ed6b1d569d3e723abc4a"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaeaded64eda71ed6b1d569d3e723abc4a">◆ </a></span>mi_new_nothrow()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new_nothrow </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>n</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>like <code>mi_malloc</code>, but when out of memory, use <code>std::get_new_handler</code> but return <em>NULL</em> on failure. </p>
+
+</div>
+</div>
+<a id="gaab78a32f55149e9fbf432d5288e38e1e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaab78a32f55149e9fbf432d5288e38e1e">◆ </a></span>mi_new_realloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new_realloc </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>like <a class="el" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6" title="Re-allocate memory to newsize bytes.">mi_realloc()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. </p>
+
+</div>
+</div>
+<a id="ga756f4b2bc6a7ecd0a90baea8e90c7907"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga756f4b2bc6a7ecd0a90baea8e90c7907">◆ </a></span>mi_new_reallocn()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_new_reallocn </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newcount</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>like <a class="el" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853" title="Re-allocate memory to count elements of size bytes.">mi_reallocn()</a>, but when out of memory, use <code>std::get_new_handler</code> and raise <code>std::bad_alloc</code> exception on failure. </p>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__cpp =
+[
+ [ "mi_stl_allocator", "group__cpp.html#structmi__stl__allocator", null ],
+ [ "mi_new", "group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545", null ],
+ [ "mi_new_aligned", "group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3", null ],
+ [ "mi_new_aligned_nothrow", "group__cpp.html#gab5e29558926d934c3f1cae8c815f942c", null ],
+ [ "mi_new_n", "group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81", null ],
+ [ "mi_new_nothrow", "group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a", null ],
+ [ "mi_new_realloc", "group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e", null ],
+ [ "mi_new_reallocn", "group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Extended Functions</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__extended.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#define-members">Macros</a> |
+<a href="#typedef-members">Typedefs</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Extended Functions</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>Extended functionality.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
+Macros</h2></td></tr>
+<tr class="memitem:ga1ea64283508718d9d645c38efc2f4305"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga1ea64283508718d9d645c38efc2f4305">MI_SMALL_SIZE_MAX</a></td></tr>
+<tr class="memdesc:ga1ea64283508718d9d645c38efc2f4305"><td class="mdescLeft"> </td><td class="mdescRight">Maximum size allowed for small allocations in <a class="el" href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99" title="Allocate a small object.">mi_malloc_small</a> and <a class="el" href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152" title="Allocate a zero initialized small object.">mi_zalloc_small</a> (usually <code>128*sizeof(void*)</code> (= 1KB on 64-bit systems)) <a href="group__extended.html#ga1ea64283508718d9d645c38efc2f4305">More...</a><br /></td></tr>
+<tr class="separator:ga1ea64283508718d9d645c38efc2f4305"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr class="memitem:ga299dae78d25ce112e384a98b7309c5be"><td class="memItemLeft" align="right" valign="top">typedef void() </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">mi_deferred_free_fun</a>(bool force, unsigned long long heartbeat, void *arg)</td></tr>
+<tr class="memdesc:ga299dae78d25ce112e384a98b7309c5be"><td class="mdescLeft"> </td><td class="mdescRight">Type of deferred free functions. <a href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">More...</a><br /></td></tr>
+<tr class="separator:ga299dae78d25ce112e384a98b7309c5be"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gad823d23444a4b77a40f66bf075a98a0c"><td class="memItemLeft" align="right" valign="top">typedef void() </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a>(const char *msg, void *arg)</td></tr>
+<tr class="memdesc:gad823d23444a4b77a40f66bf075a98a0c"><td class="mdescLeft"> </td><td class="mdescRight">Type of output functions. <a href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">More...</a><br /></td></tr>
+<tr class="separator:gad823d23444a4b77a40f66bf075a98a0c"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga251d369cda3f1c2a955c555486ed90e5"><td class="memItemLeft" align="right" valign="top">typedef void() </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">mi_error_fun</a>(int err, void *arg)</td></tr>
+<tr class="memdesc:ga251d369cda3f1c2a955c555486ed90e5"><td class="mdescLeft"> </td><td class="mdescRight">Type of error callback functions. <a href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">More...</a><br /></td></tr>
+<tr class="separator:ga251d369cda3f1c2a955c555486ed90e5"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:ga7136c2e55cb22c98ecf95d08d6debb99"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99">mi_malloc_small</a> (size_t size)</td></tr>
+<tr class="memdesc:ga7136c2e55cb22c98ecf95d08d6debb99"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a small object. <a href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99">More...</a><br /></td></tr>
+<tr class="separator:ga7136c2e55cb22c98ecf95d08d6debb99"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga220f29f40a44404b0061c15bc1c31152"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152">mi_zalloc_small</a> (size_t size)</td></tr>
+<tr class="memdesc:ga220f29f40a44404b0061c15bc1c31152"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a zero initialized small object. <a href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152">More...</a><br /></td></tr>
+<tr class="separator:ga220f29f40a44404b0061c15bc1c31152"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga089c859d9eddc5f9b4bd946cd53cebee"><td class="memItemLeft" align="right" valign="top">size_t </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee">mi_usable_size</a> (void *p)</td></tr>
+<tr class="memdesc:ga089c859d9eddc5f9b4bd946cd53cebee"><td class="mdescLeft"> </td><td class="mdescRight">Return the available bytes in a memory block. <a href="group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee">More...</a><br /></td></tr>
+<tr class="separator:ga089c859d9eddc5f9b4bd946cd53cebee"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gac057927cd06c854b45fe7847e921bd47"><td class="memItemLeft" align="right" valign="top">size_t </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gac057927cd06c854b45fe7847e921bd47">mi_good_size</a> (size_t size)</td></tr>
+<tr class="memdesc:gac057927cd06c854b45fe7847e921bd47"><td class="mdescLeft"> </td><td class="mdescRight">Return the used allocation size. <a href="group__extended.html#gac057927cd06c854b45fe7847e921bd47">More...</a><br /></td></tr>
+<tr class="separator:gac057927cd06c854b45fe7847e921bd47"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga421430e2226d7d468529cec457396756"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga421430e2226d7d468529cec457396756">mi_collect</a> (bool force)</td></tr>
+<tr class="memdesc:ga421430e2226d7d468529cec457396756"><td class="mdescLeft"> </td><td class="mdescRight">Eagerly free memory. <a href="group__extended.html#ga421430e2226d7d468529cec457396756">More...</a><br /></td></tr>
+<tr class="separator:ga421430e2226d7d468529cec457396756"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga2d126e5c62d3badc35445e5d84166df2"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga2d126e5c62d3badc35445e5d84166df2">mi_stats_print</a> (void *out)</td></tr>
+<tr class="memdesc:ga2d126e5c62d3badc35445e5d84166df2"><td class="mdescLeft"> </td><td class="mdescRight">Deprecated. <a href="group__extended.html#ga2d126e5c62d3badc35445e5d84166df2">More...</a><br /></td></tr>
+<tr class="separator:ga2d126e5c62d3badc35445e5d84166df2"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga537f13b299ddf801e49a5a94fde02c79"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga537f13b299ddf801e49a5a94fde02c79">mi_stats_print_out</a> (<a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a> *out, void *arg)</td></tr>
+<tr class="memdesc:ga537f13b299ddf801e49a5a94fde02c79"><td class="mdescLeft"> </td><td class="mdescRight">Print the main statistics. <a href="group__extended.html#ga537f13b299ddf801e49a5a94fde02c79">More...</a><br /></td></tr>
+<tr class="separator:ga537f13b299ddf801e49a5a94fde02c79"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga3bb8468b8cfcc6e2a61d98aee85c5f99"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99">mi_stats_reset</a> (void)</td></tr>
+<tr class="memdesc:ga3bb8468b8cfcc6e2a61d98aee85c5f99"><td class="mdescLeft"> </td><td class="mdescRight">Reset statistics. <a href="group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99">More...</a><br /></td></tr>
+<tr class="separator:ga3bb8468b8cfcc6e2a61d98aee85c5f99"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga854b1de8cb067c7316286c28b2fcd3d1"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1">mi_stats_merge</a> (void)</td></tr>
+<tr class="memdesc:ga854b1de8cb067c7316286c28b2fcd3d1"><td class="mdescLeft"> </td><td class="mdescRight">Merge thread local statistics with the main statistics and reset. <a href="group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1">More...</a><br /></td></tr>
+<tr class="separator:ga854b1de8cb067c7316286c28b2fcd3d1"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaf8e73efc2cbca9ebfdfb166983a04c17"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17">mi_thread_init</a> (void)</td></tr>
+<tr class="memdesc:gaf8e73efc2cbca9ebfdfb166983a04c17"><td class="mdescLeft"> </td><td class="mdescRight">Initialize mimalloc on a thread. <a href="group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17">More...</a><br /></td></tr>
+<tr class="separator:gaf8e73efc2cbca9ebfdfb166983a04c17"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga0ae4581e85453456a0d658b2b98bf7bf"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf">mi_thread_done</a> (void)</td></tr>
+<tr class="memdesc:ga0ae4581e85453456a0d658b2b98bf7bf"><td class="mdescLeft"> </td><td class="mdescRight">Uninitialize mimalloc on a thread. <a href="group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf">More...</a><br /></td></tr>
+<tr class="separator:ga0ae4581e85453456a0d658b2b98bf7bf"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gab1dac8476c46cb9eecab767eb40c1525"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gab1dac8476c46cb9eecab767eb40c1525">mi_thread_stats_print_out</a> (<a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a> *out, void *arg)</td></tr>
+<tr class="memdesc:gab1dac8476c46cb9eecab767eb40c1525"><td class="mdescLeft"> </td><td class="mdescRight">Print out heap statistics for this thread. <a href="group__extended.html#gab1dac8476c46cb9eecab767eb40c1525">More...</a><br /></td></tr>
+<tr class="separator:gab1dac8476c46cb9eecab767eb40c1525"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga3460a6ca91af97be4058f523d3cb8ece"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece">mi_register_deferred_free</a> (<a class="el" href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">mi_deferred_free_fun</a> *deferred_free, void *arg)</td></tr>
+<tr class="memdesc:ga3460a6ca91af97be4058f523d3cb8ece"><td class="mdescLeft"> </td><td class="mdescRight">Register a deferred free function. <a href="group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece">More...</a><br /></td></tr>
+<tr class="separator:ga3460a6ca91af97be4058f523d3cb8ece"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gae5b17ff027cd2150b43a33040250cf3f"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gae5b17ff027cd2150b43a33040250cf3f">mi_register_output</a> (<a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a> *out, void *arg)</td></tr>
+<tr class="memdesc:gae5b17ff027cd2150b43a33040250cf3f"><td class="mdescLeft"> </td><td class="mdescRight">Register an output function. <a href="group__extended.html#gae5b17ff027cd2150b43a33040250cf3f">More...</a><br /></td></tr>
+<tr class="separator:gae5b17ff027cd2150b43a33040250cf3f"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaa1d55e0e894be240827e5d87ec3a1f45"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45">mi_register_error</a> (<a class="el" href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">mi_error_fun</a> *errfun, void *arg)</td></tr>
+<tr class="memdesc:gaa1d55e0e894be240827e5d87ec3a1f45"><td class="mdescLeft"> </td><td class="mdescRight">Register an error callback function. <a href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45">More...</a><br /></td></tr>
+<tr class="separator:gaa1d55e0e894be240827e5d87ec3a1f45"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga5f071b10d4df1c3658e04e7fd67a94e6"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6">mi_is_in_heap_region</a> (const void *p)</td></tr>
+<tr class="memdesc:ga5f071b10d4df1c3658e04e7fd67a94e6"><td class="mdescLeft"> </td><td class="mdescRight">Is a pointer part of our heap? <a href="group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6">More...</a><br /></td></tr>
+<tr class="separator:ga5f071b10d4df1c3658e04e7fd67a94e6"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga00ec3324b6b2591c7fe3677baa30a767"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767">mi_reserve_os_memory</a> (size_t size, bool commit, bool allow_large)</td></tr>
+<tr class="memdesc:ga00ec3324b6b2591c7fe3677baa30a767"><td class="mdescLeft"> </td><td class="mdescRight">Reserve OS memory for use by mimalloc. <a href="group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767">More...</a><br /></td></tr>
+<tr class="separator:ga00ec3324b6b2591c7fe3677baa30a767"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga4c6486a1fdcd7a423b5f25fe4be8e0cf"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf">mi_manage_os_memory</a> (void *start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node)</td></tr>
+<tr class="memdesc:ga4c6486a1fdcd7a423b5f25fe4be8e0cf"><td class="mdescLeft"> </td><td class="mdescRight">Manage a particular memory area for use by mimalloc. <a href="group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf">More...</a><br /></td></tr>
+<tr class="separator:ga4c6486a1fdcd7a423b5f25fe4be8e0cf"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga3132f521fb756fc0e8ec0b74fb58df50"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50">mi_reserve_huge_os_pages_interleave</a> (size_t pages, size_t numa_nodes, size_t timeout_msecs)</td></tr>
+<tr class="memdesc:ga3132f521fb756fc0e8ec0b74fb58df50"><td class="mdescLeft"> </td><td class="mdescRight">Reserve <em>pages</em> of huge OS pages (1GiB) evenly divided over <em>numa_nodes</em> nodes, but stops after at most <code>timeout_msecs</code> seconds. <a href="group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50">More...</a><br /></td></tr>
+<tr class="separator:ga3132f521fb756fc0e8ec0b74fb58df50"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga7795a13d20087447281858d2c771cca1"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga7795a13d20087447281858d2c771cca1">mi_reserve_huge_os_pages_at</a> (size_t pages, int numa_node, size_t timeout_msecs)</td></tr>
+<tr class="memdesc:ga7795a13d20087447281858d2c771cca1"><td class="mdescLeft"> </td><td class="mdescRight">Reserve <em>pages</em> of huge OS pages (1GiB) at a specific <em>numa_node</em>, but stops after at most <code>timeout_msecs</code> seconds. <a href="group__extended.html#ga7795a13d20087447281858d2c771cca1">More...</a><br /></td></tr>
+<tr class="separator:ga7795a13d20087447281858d2c771cca1"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaad25050b19f30cd79397b227e0157a3f"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#gaad25050b19f30cd79397b227e0157a3f">mi_is_redirected</a> ()</td></tr>
+<tr class="memdesc:gaad25050b19f30cd79397b227e0157a3f"><td class="mdescLeft"> </td><td class="mdescRight">Is the C runtime <em>malloc</em> API redirected? <a href="group__extended.html#gaad25050b19f30cd79397b227e0157a3f">More...</a><br /></td></tr>
+<tr class="separator:gaad25050b19f30cd79397b227e0157a3f"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga7d862c2affd5790381da14eb102a364d"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__extended.html#ga7d862c2affd5790381da14eb102a364d">mi_process_info</a> (size_t *elapsed_msecs, size_t *user_msecs, size_t *system_msecs, size_t *current_rss, size_t *peak_rss, size_t *current_commit, size_t *peak_commit, size_t *page_faults)</td></tr>
+<tr class="memdesc:ga7d862c2affd5790381da14eb102a364d"><td class="mdescLeft"> </td><td class="mdescRight">Return process information (time and memory usage). <a href="group__extended.html#ga7d862c2affd5790381da14eb102a364d">More...</a><br /></td></tr>
+<tr class="separator:ga7d862c2affd5790381da14eb102a364d"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>Extended functionality. </p>
+<h2 class="groupheader">Macro Definition Documentation</h2>
+<a id="ga1ea64283508718d9d645c38efc2f4305"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga1ea64283508718d9d645c38efc2f4305">◆ </a></span>MI_SMALL_SIZE_MAX</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define MI_SMALL_SIZE_MAX</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Maximum size allowed for small allocations in <a class="el" href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99" title="Allocate a small object.">mi_malloc_small</a> and <a class="el" href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152" title="Allocate a zero initialized small object.">mi_zalloc_small</a> (usually <code>128*sizeof(void*)</code> (= 1KB on 64-bit systems)) </p>
+
+</div>
+</div>
+<h2 class="groupheader">Typedef Documentation</h2>
+<a id="ga299dae78d25ce112e384a98b7309c5be"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga299dae78d25ce112e384a98b7309c5be">◆ </a></span>mi_deferred_free_fun</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef void() mi_deferred_free_fun(bool force, unsigned long long heartbeat, void *arg)</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Type of deferred free functions. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">force</td><td>If <em>true</em> all outstanding items should be freed. </td></tr>
+ <tr><td class="paramname">heartbeat</td><td>A monotonically increasing count. </td></tr>
+ <tr><td class="paramname">arg</td><td>Argument that was passed at registration to hold extra state.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece" title="Register a deferred free function.">mi_register_deferred_free</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga251d369cda3f1c2a955c555486ed90e5"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga251d369cda3f1c2a955c555486ed90e5">◆ </a></span>mi_error_fun</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef void() mi_error_fun(int err, void *arg)</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Type of error callback functions. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">err</td><td>Error code (see <a class="el" href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45" title="Register an error callback function.">mi_register_error()</a> for a complete list). </td></tr>
+ <tr><td class="paramname">arg</td><td>Argument that was passed at registration to hold extra state.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45" title="Register an error callback function.">mi_register_error()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gad823d23444a4b77a40f66bf075a98a0c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gad823d23444a4b77a40f66bf075a98a0c">◆ </a></span>mi_output_fun</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef void() mi_output_fun(const char *msg, void *arg)</td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Type of output functions. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">msg</td><td>Message to output. </td></tr>
+ <tr><td class="paramname">arg</td><td>Argument that was passed at registration to hold extra state.</td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__extended.html#gae5b17ff027cd2150b43a33040250cf3f" title="Register an output function.">mi_register_output()</a> </dd></dl>
+
+</div>
+</div>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="ga421430e2226d7d468529cec457396756"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga421430e2226d7d468529cec457396756">◆ </a></span>mi_collect()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_collect </td>
+ <td>(</td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>force</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Eagerly free memory. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">force</td><td>If <em>true</em>, aggressively return memory to the OS (can be expensive!)</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>Regular code should not have to call this function. It can be beneficial in very narrow circumstances; in particular, when a long running thread allocates a lot of blocks that are freed by other threads it may improve resource usage by calling this every once in a while. </p>
+
+</div>
+</div>
+<a id="gac057927cd06c854b45fe7847e921bd47"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gac057927cd06c854b45fe7847e921bd47">◆ </a></span>mi_good_size()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t mi_good_size </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Return the used allocation size. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>The minimal required size in bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>the size <code>n</code> that will be allocated, where <code>n >= size</code>.</dd></dl>
+<p>Generally, <code>mi_usable_size(mi_malloc(size)) == mi_good_size(size)</code>. This can be used to reduce internal wasted space when allocating buffers for example.</p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee" title="Return the available bytes in a memory block.">mi_usable_size()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga5f071b10d4df1c3658e04e7fd67a94e6"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga5f071b10d4df1c3658e04e7fd67a94e6">◆ </a></span>mi_is_in_heap_region()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_is_in_heap_region </td>
+ <td>(</td>
+ <td class="paramtype">const void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Is a pointer part of our heap? </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>The pointer to check. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if this is a pointer into our heap. This function is relatively fast. </dd></dl>
+
+</div>
+</div>
+<a id="gaad25050b19f30cd79397b227e0157a3f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaad25050b19f30cd79397b227e0157a3f">◆ </a></span>mi_is_redirected()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_is_redirected </td>
+ <td>(</td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Is the C runtime <em>malloc</em> API redirected? </p>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if all malloc API calls are redirected to mimalloc.</dd></dl>
+<p>Currenty only used on Windows. </p>
+
+</div>
+</div>
+<a id="ga7136c2e55cb22c98ecf95d08d6debb99"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7136c2e55cb22c98ecf95d08d6debb99">◆ </a></span>mi_malloc_small()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_malloc_small </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a small object. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>The size in bytes, can be at most <a class="el" href="group__extended.html#ga1ea64283508718d9d645c38efc2f4305" title="Maximum size allowed for small allocations in mi_malloc_small and mi_zalloc_small (usually 128*sizeof...">MI_SMALL_SIZE_MAX</a>. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>a pointer to newly allocated memory of at least <em>size</em> bytes, or <em>NULL</em> if out of memory. This function is meant for use in run-time systems for best performance and does not check if <em>size</em> was indeed small – use with care! </dd></dl>
+
+</div>
+</div>
+<a id="ga4c6486a1fdcd7a423b5f25fe4be8e0cf"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4c6486a1fdcd7a423b5f25fe4be8e0cf">◆ </a></span>mi_manage_os_memory()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_manage_os_memory </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>start</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>is_committed</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>is_large</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>is_zero</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int </td>
+ <td class="paramname"><em>numa_node</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Manage a particular memory area for use by mimalloc. </p>
+<p>This is just like <code>mi_reserve_os_memory</code> except that the area should already be allocated in some manner and available for use my mimalloc. </p><dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">start</td><td>Start of the memory area </td></tr>
+ <tr><td class="paramname">size</td><td>The size of the memory area. </td></tr>
+ <tr><td class="paramname">commit</td><td>Is the area already committed? </td></tr>
+ <tr><td class="paramname">is_large</td><td>Does it consist of large OS pages? Set this to <em>true</em> as well for memory that should not be decommitted or protected (like rdma etc.) </td></tr>
+ <tr><td class="paramname">is_zero</td><td>Does the area consists of zero's? </td></tr>
+ <tr><td class="paramname">numa_node</td><td>Possible associated numa node or <code>-1</code>. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>true</em> if successful, and <em>false</em> on error. </dd></dl>
+
+</div>
+</div>
+<a id="ga7d862c2affd5790381da14eb102a364d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7d862c2affd5790381da14eb102a364d">◆ </a></span>mi_process_info()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_process_info </td>
+ <td>(</td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>elapsed_msecs</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>user_msecs</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>system_msecs</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>current_rss</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>peak_rss</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>current_commit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>peak_commit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t * </td>
+ <td class="paramname"><em>page_faults</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Return process information (time and memory usage). </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">elapsed_msecs</td><td>Optional. Elapsed wall-clock time of the process in milli-seconds. </td></tr>
+ <tr><td class="paramname">user_msecs</td><td>Optional. User time in milli-seconds (as the sum over all threads). </td></tr>
+ <tr><td class="paramname">system_msecs</td><td>Optional. System time in milli-seconds. </td></tr>
+ <tr><td class="paramname">current_rss</td><td>Optional. Current working set size (touched pages). </td></tr>
+ <tr><td class="paramname">peak_rss</td><td>Optional. Peak working set size (touched pages). </td></tr>
+ <tr><td class="paramname">current_commit</td><td>Optional. Current committed memory (backed by the page file). </td></tr>
+ <tr><td class="paramname">peak_commit</td><td>Optional. Peak committed memory (backed by the page file). </td></tr>
+ <tr><td class="paramname">page_faults</td><td>Optional. Count of hard page faults.</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>The <em>current_rss</em> is precise on Windows and MacOSX; other systems estimate this using <em>current_commit</em>. The <em>commit</em> is precise on Windows but estimated on other systems as the amount of read/write accessible memory reserved by mimalloc. </p>
+
+</div>
+</div>
+<a id="ga3460a6ca91af97be4058f523d3cb8ece"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga3460a6ca91af97be4058f523d3cb8ece">◆ </a></span>mi_register_deferred_free()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_register_deferred_free </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">mi_deferred_free_fun</a> * </td>
+ <td class="paramname"><em>deferred_free</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>arg</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Register a deferred free function. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">deferred_free</td><td>Address of a deferred free-ing function or <em>NULL</em> to unregister. </td></tr>
+ <tr><td class="paramname">arg</td><td>Argument that will be passed on to the deferred free function.</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>Some runtime systems use deferred free-ing, for example when using reference counting to limit the worst case free time. Such systems can register (re-entrant) deferred free function to free more memory on demand. When the <em>force</em> parameter is <em>true</em> all possible memory should be freed. The per-thread <em>heartbeat</em> parameter is monotonically increasing and guaranteed to be deterministic if the program allocates deterministically. The <em>deferred_free</em> function is guaranteed to be called deterministically after some number of allocations (regardless of freeing or available free memory). At most one <em>deferred_free</em> function can be active. </p>
+
+</div>
+</div>
+<a id="gaa1d55e0e894be240827e5d87ec3a1f45"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaa1d55e0e894be240827e5d87ec3a1f45">◆ </a></span>mi_register_error()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_register_error </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">mi_error_fun</a> * </td>
+ <td class="paramname"><em>errfun</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>arg</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Register an error callback function. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">errfun</td><td>The error function that is called on an error (use <em>NULL</em> for default) </td></tr>
+ <tr><td class="paramname">arg</td><td>Extra argument that will be passed on to the error function.</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>The <em>errfun</em> function is called on an error in mimalloc after emitting an error message (through the output function). It as always legal to just return from the <em>errfun</em> function in which case allocation functions generally return <em>NULL</em> or ignore the condition. The default function only calls abort() when compiled in secure mode with an <em>EFAULT</em> error. The possible error codes are:</p><ul>
+<li><em>EAGAIN:</em> Double free was detected (only in debug and secure mode).</li>
+<li><em>EFAULT:</em> Corrupted free list or meta-data was detected (only in debug and secure mode).</li>
+<li><em>ENOMEM:</em> Not enough memory available to satisfy the request.</li>
+<li><em>EOVERFLOW:</em> Too large a request, for example in <a class="el" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d" title="Allocate zero-initialized count elements of size bytes.">mi_calloc()</a>, the <em>count</em> and <em>size</em> parameters are too large.</li>
+<li><em>EINVAL:</em> Trying to free or re-allocate an invalid pointer. </li>
+</ul>
+
+</div>
+</div>
+<a id="gae5b17ff027cd2150b43a33040250cf3f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gae5b17ff027cd2150b43a33040250cf3f">◆ </a></span>mi_register_output()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_register_output </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a> * </td>
+ <td class="paramname"><em>out</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>arg</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Register an output function. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">out</td><td>The output function, use <code>NULL</code> to output to stderr. </td></tr>
+ <tr><td class="paramname">arg</td><td>Argument that will be passed on to the output function.</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>The <code>out</code> function is called to output any information from mimalloc, like verbose or warning messages. </p>
+
+</div>
+</div>
+<a id="ga7795a13d20087447281858d2c771cca1"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7795a13d20087447281858d2c771cca1">◆ </a></span>mi_reserve_huge_os_pages_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int mi_reserve_huge_os_pages_at </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>pages</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int </td>
+ <td class="paramname"><em>numa_node</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>timeout_msecs</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Reserve <em>pages</em> of huge OS pages (1GiB) at a specific <em>numa_node</em>, but stops after at most <code>timeout_msecs</code> seconds. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">pages</td><td>The number of 1GiB pages to reserve. </td></tr>
+ <tr><td class="paramname">numa_node</td><td>The NUMA node where the memory is reserved (start at 0). </td></tr>
+ <tr><td class="paramname">timeout_msecs</td><td>Maximum number of milli-seconds to try reserving, or 0 for no timeout. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successfull, <em>ENOMEM</em> if running out of memory, or <em>ETIMEDOUT</em> if timed out.</dd></dl>
+<p>The reserved memory is used by mimalloc to satisfy allocations. May quit before <em>timeout_msecs</em> are expired if it estimates it will take more than 1.5 times <em>timeout_msecs</em>. The time limit is needed because on some operating systems it can take a long time to reserve contiguous memory if the physical memory is fragmented. </p>
+
+</div>
+</div>
+<a id="ga3132f521fb756fc0e8ec0b74fb58df50"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga3132f521fb756fc0e8ec0b74fb58df50">◆ </a></span>mi_reserve_huge_os_pages_interleave()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int mi_reserve_huge_os_pages_interleave </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>pages</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>numa_nodes</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>timeout_msecs</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Reserve <em>pages</em> of huge OS pages (1GiB) evenly divided over <em>numa_nodes</em> nodes, but stops after at most <code>timeout_msecs</code> seconds. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">pages</td><td>The number of 1GiB pages to reserve. </td></tr>
+ <tr><td class="paramname">numa_nodes</td><td>The number of nodes do evenly divide the pages over, or 0 for using the actual number of NUMA nodes. </td></tr>
+ <tr><td class="paramname">timeout_msecs</td><td>Maximum number of milli-seconds to try reserving, or 0 for no timeout. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successfull, <em>ENOMEM</em> if running out of memory, or <em>ETIMEDOUT</em> if timed out.</dd></dl>
+<p>The reserved memory is used by mimalloc to satisfy allocations. May quit before <em>timeout_msecs</em> are expired if it estimates it will take more than 1.5 times <em>timeout_msecs</em>. The time limit is needed because on some operating systems it can take a long time to reserve contiguous memory if the physical memory is fragmented. </p>
+
+</div>
+</div>
+<a id="ga00ec3324b6b2591c7fe3677baa30a767"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga00ec3324b6b2591c7fe3677baa30a767">◆ </a></span>mi_reserve_os_memory()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int mi_reserve_os_memory </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>commit</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>allow_large</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Reserve OS memory for use by mimalloc. </p>
+<p>Reserved areas are used before allocating from the OS again. By reserving a large area upfront, allocation can be more efficient, and can be better managed on systems without <code>mmap</code>/<code>VirtualAlloc</code> (like WASM for example). </p><dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>The size to reserve. </td></tr>
+ <tr><td class="paramname">commit</td><td>Commit the memory upfront. </td></tr>
+ <tr><td class="paramname">allow_large</td><td>Allow large OS pages (2MiB) to be used? </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd><em>0</em> if successful, and an error code otherwise (e.g. <code>ENOMEM</code>). </dd></dl>
+
+</div>
+</div>
+<a id="ga854b1de8cb067c7316286c28b2fcd3d1"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga854b1de8cb067c7316286c28b2fcd3d1">◆ </a></span>mi_stats_merge()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_stats_merge </td>
+ <td>(</td>
+ <td class="paramtype">void </td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Merge thread local statistics with the main statistics and reset. </p>
+
+</div>
+</div>
+<a id="ga2d126e5c62d3badc35445e5d84166df2"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga2d126e5c62d3badc35445e5d84166df2">◆ </a></span>mi_stats_print()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_stats_print </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>out</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Deprecated. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">out</td><td>Ignored, outputs to the registered output function or stderr by default.</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>Most detailed when using a debug build. </p>
+
+</div>
+</div>
+<a id="ga537f13b299ddf801e49a5a94fde02c79"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga537f13b299ddf801e49a5a94fde02c79">◆ </a></span>mi_stats_print_out()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_stats_print_out </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a> * </td>
+ <td class="paramname"><em>out</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>arg</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Print the main statistics. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">out</td><td>An output function or <em>NULL</em> for the default. </td></tr>
+ <tr><td class="paramname">arg</td><td>Optional argument passed to <em>out</em> (if not <em>NULL</em>)</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>Most detailed when using a debug build. </p>
+
+</div>
+</div>
+<a id="ga3bb8468b8cfcc6e2a61d98aee85c5f99"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga3bb8468b8cfcc6e2a61d98aee85c5f99">◆ </a></span>mi_stats_reset()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_stats_reset </td>
+ <td>(</td>
+ <td class="paramtype">void </td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Reset statistics. </p>
+
+</div>
+</div>
+<a id="ga0ae4581e85453456a0d658b2b98bf7bf"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga0ae4581e85453456a0d658b2b98bf7bf">◆ </a></span>mi_thread_done()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_thread_done </td>
+ <td>(</td>
+ <td class="paramtype">void </td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Uninitialize mimalloc on a thread. </p>
+<p>Should not be used as on most systems (pthreads, windows) this is done automatically. Ensures that any memory that is not freed yet (but will be freed by other threads in the future) is properly handled. </p>
+
+</div>
+</div>
+<a id="gaf8e73efc2cbca9ebfdfb166983a04c17"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf8e73efc2cbca9ebfdfb166983a04c17">◆ </a></span>mi_thread_init()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_thread_init </td>
+ <td>(</td>
+ <td class="paramtype">void </td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Initialize mimalloc on a thread. </p>
+<p>Should not be used as on most systems (pthreads, windows) this is done automatically. </p>
+
+</div>
+</div>
+<a id="gab1dac8476c46cb9eecab767eb40c1525"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gab1dac8476c46cb9eecab767eb40c1525">◆ </a></span>mi_thread_stats_print_out()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_thread_stats_print_out </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a> * </td>
+ <td class="paramname"><em>out</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>arg</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Print out heap statistics for this thread. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">out</td><td>An output function or <em>NULL</em> for the default. </td></tr>
+ <tr><td class="paramname">arg</td><td>Optional argument passed to <em>out</em> (if not <em>NULL</em>)</td></tr>
+ </table>
+ </dd>
+</dl>
+<p>Most detailed when using a debug build. </p>
+
+</div>
+</div>
+<a id="ga089c859d9eddc5f9b4bd946cd53cebee"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga089c859d9eddc5f9b4bd946cd53cebee">◆ </a></span>mi_usable_size()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t mi_usable_size </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Return the available bytes in a memory block. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>Pointer to previously allocated memory (or <em>NULL</em>) </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>Returns the available bytes in the memory block, or 0 if <em>p</em> was <em>NULL</em>.</dd></dl>
+<p>The returned size can be used to call <em>mi_expand</em> successfully. The returned size is always at least equal to the allocated size of <em>p</em>, and, in the current design, should be less than 16.7% more.</p>
+<dl class="section see"><dt>See also</dt><dd><a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/msize?view=vs-2017">_msize</a> (Windows) </dd>
+<dd>
+<a href="http://man7.org/linux/man-pages/man3/malloc_usable_size.3.html">malloc_usable_size</a> (Linux) </dd>
+<dd>
+<a class="el" href="group__extended.html#gac057927cd06c854b45fe7847e921bd47" title="Return the used allocation size.">mi_good_size()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga220f29f40a44404b0061c15bc1c31152"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga220f29f40a44404b0061c15bc1c31152">◆ </a></span>mi_zalloc_small()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_zalloc_small </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a zero initialized small object. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>The size in bytes, can be at most <a class="el" href="group__extended.html#ga1ea64283508718d9d645c38efc2f4305" title="Maximum size allowed for small allocations in mi_malloc_small and mi_zalloc_small (usually 128*sizeof...">MI_SMALL_SIZE_MAX</a>. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>a pointer to newly allocated zero-initialized memory of at least <em>size</em> bytes, or <em>NULL</em> if out of memory. This function is meant for use in run-time systems for best performance and does not check if <em>size</em> was indeed small – use with care! </dd></dl>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__extended =
+[
+ [ "MI_SMALL_SIZE_MAX", "group__extended.html#ga1ea64283508718d9d645c38efc2f4305", null ],
+ [ "mi_deferred_free_fun", "group__extended.html#ga299dae78d25ce112e384a98b7309c5be", null ],
+ [ "mi_error_fun", "group__extended.html#ga251d369cda3f1c2a955c555486ed90e5", null ],
+ [ "mi_output_fun", "group__extended.html#gad823d23444a4b77a40f66bf075a98a0c", null ],
+ [ "mi_collect", "group__extended.html#ga421430e2226d7d468529cec457396756", null ],
+ [ "mi_good_size", "group__extended.html#gac057927cd06c854b45fe7847e921bd47", null ],
+ [ "mi_is_in_heap_region", "group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6", null ],
+ [ "mi_is_redirected", "group__extended.html#gaad25050b19f30cd79397b227e0157a3f", null ],
+ [ "mi_malloc_small", "group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99", null ],
+ [ "mi_manage_os_memory", "group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf", null ],
+ [ "mi_process_info", "group__extended.html#ga7d862c2affd5790381da14eb102a364d", null ],
+ [ "mi_register_deferred_free", "group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece", null ],
+ [ "mi_register_error", "group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45", null ],
+ [ "mi_register_output", "group__extended.html#gae5b17ff027cd2150b43a33040250cf3f", null ],
+ [ "mi_reserve_huge_os_pages_at", "group__extended.html#ga7795a13d20087447281858d2c771cca1", null ],
+ [ "mi_reserve_huge_os_pages_interleave", "group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50", null ],
+ [ "mi_reserve_os_memory", "group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767", null ],
+ [ "mi_stats_merge", "group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1", null ],
+ [ "mi_stats_print", "group__extended.html#ga2d126e5c62d3badc35445e5d84166df2", null ],
+ [ "mi_stats_print_out", "group__extended.html#ga537f13b299ddf801e49a5a94fde02c79", null ],
+ [ "mi_stats_reset", "group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99", null ],
+ [ "mi_thread_done", "group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf", null ],
+ [ "mi_thread_init", "group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17", null ],
+ [ "mi_thread_stats_print_out", "group__extended.html#gab1dac8476c46cb9eecab767eb40c1525", null ],
+ [ "mi_usable_size", "group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee", null ],
+ [ "mi_zalloc_small", "group__extended.html#ga220f29f40a44404b0061c15bc1c31152", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Heap Allocation</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__heap.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#typedef-members">Typedefs</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Heap Allocation</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>First-class heaps that can be destroyed in one go.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
+Typedefs</h2></td></tr>
+<tr class="memitem:ga34a47cde5a5b38c29f1aa3c5e76943c2"><td class="memItemLeft" align="right" valign="top">typedef struct mi_heap_s </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a></td></tr>
+<tr class="memdesc:ga34a47cde5a5b38c29f1aa3c5e76943c2"><td class="mdescLeft"> </td><td class="mdescRight">Type of first-class heaps. <a href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">More...</a><br /></td></tr>
+<tr class="separator:ga34a47cde5a5b38c29f1aa3c5e76943c2"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:ga766f672ba56f2fbfeb9d9dbb0b7f6b11"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11">mi_heap_new</a> ()</td></tr>
+<tr class="memdesc:ga766f672ba56f2fbfeb9d9dbb0b7f6b11"><td class="mdescLeft"> </td><td class="mdescRight">Create a new heap that can be used for allocation. <a href="group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11">More...</a><br /></td></tr>
+<tr class="separator:ga766f672ba56f2fbfeb9d9dbb0b7f6b11"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga2ab1af8d438819b55319c7ef51d1e409"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409">mi_heap_delete</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap)</td></tr>
+<tr class="memdesc:ga2ab1af8d438819b55319c7ef51d1e409"><td class="mdescLeft"> </td><td class="mdescRight">Delete a previously allocated heap. <a href="group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409">More...</a><br /></td></tr>
+<tr class="separator:ga2ab1af8d438819b55319c7ef51d1e409"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga9f9c0844edb9717f4feacd79116b8e0d"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d">mi_heap_destroy</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap)</td></tr>
+<tr class="memdesc:ga9f9c0844edb9717f4feacd79116b8e0d"><td class="mdescLeft"> </td><td class="mdescRight">Destroy a heap, freeing all its still allocated blocks. <a href="group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d">More...</a><br /></td></tr>
+<tr class="separator:ga9f9c0844edb9717f4feacd79116b8e0d"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gab8631ec88c8d26641b68b5d25dcd4422"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422">mi_heap_set_default</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap)</td></tr>
+<tr class="memdesc:gab8631ec88c8d26641b68b5d25dcd4422"><td class="mdescLeft"> </td><td class="mdescRight">Set the default heap to use for <a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> et al. <a href="group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422">More...</a><br /></td></tr>
+<tr class="separator:gab8631ec88c8d26641b68b5d25dcd4422"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga8db4cbb87314a989a9a187464d6b5e05"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05">mi_heap_get_default</a> ()</td></tr>
+<tr class="memdesc:ga8db4cbb87314a989a9a187464d6b5e05"><td class="mdescLeft"> </td><td class="mdescRight">Get the default heap that is used for <a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> et al. <a href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05">More...</a><br /></td></tr>
+<tr class="separator:ga8db4cbb87314a989a9a187464d6b5e05"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga5d03fbe062ffcf38f0f417fd968357fc"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc">mi_heap_get_backing</a> ()</td></tr>
+<tr class="memdesc:ga5d03fbe062ffcf38f0f417fd968357fc"><td class="mdescLeft"> </td><td class="mdescRight">Get the backing heap. <a href="group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc">More...</a><br /></td></tr>
+<tr class="separator:ga5d03fbe062ffcf38f0f417fd968357fc"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga7922f7495cde30b1984d0e6072419298"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga7922f7495cde30b1984d0e6072419298">mi_heap_collect</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, bool force)</td></tr>
+<tr class="memdesc:ga7922f7495cde30b1984d0e6072419298"><td class="mdescLeft"> </td><td class="mdescRight">Release outstanding resources in a specific heap. <a href="group__heap.html#ga7922f7495cde30b1984d0e6072419298">More...</a><br /></td></tr>
+<tr class="separator:ga7922f7495cde30b1984d0e6072419298"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga9cbed01e42c0647907295de92c3fa296"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga9cbed01e42c0647907295de92c3fa296">mi_heap_malloc</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size)</td></tr>
+<tr class="memdesc:ga9cbed01e42c0647907295de92c3fa296"><td class="mdescLeft"> </td><td class="mdescRight">Allocate in a specific heap. <a href="group__heap.html#ga9cbed01e42c0647907295de92c3fa296">More...</a><br /></td></tr>
+<tr class="separator:ga9cbed01e42c0647907295de92c3fa296"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaa1a1c7a1f4da6826b5a25b70ef878368"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368">mi_heap_malloc_small</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size)</td></tr>
+<tr class="memdesc:gaa1a1c7a1f4da6826b5a25b70ef878368"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a small object in a specific heap. <a href="group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368">More...</a><br /></td></tr>
+<tr class="separator:gaa1a1c7a1f4da6826b5a25b70ef878368"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga903104592c8ed53417a3762da6241133"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga903104592c8ed53417a3762da6241133">mi_heap_zalloc</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size)</td></tr>
+<tr class="memdesc:ga903104592c8ed53417a3762da6241133"><td class="mdescLeft"> </td><td class="mdescRight">Allocate zero-initialized in a specific heap. <a href="group__heap.html#ga903104592c8ed53417a3762da6241133">More...</a><br /></td></tr>
+<tr class="separator:ga903104592c8ed53417a3762da6241133"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaa6702b3c48e9e53e50e81b36f5011d55"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55">mi_heap_calloc</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t count, size_t size)</td></tr>
+<tr class="memdesc:gaa6702b3c48e9e53e50e81b36f5011d55"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> zero-initialized elements in a specific heap. <a href="group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55">More...</a><br /></td></tr>
+<tr class="separator:gaa6702b3c48e9e53e50e81b36f5011d55"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga851da6c43fe0b71c1376cee8aef90db0"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0">mi_heap_mallocn</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga851da6c43fe0b71c1376cee8aef90db0"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> elements in a specific heap. <a href="group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0">More...</a><br /></td></tr>
+<tr class="separator:ga851da6c43fe0b71c1376cee8aef90db0"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga139d6b09dbf50c3c2523d0f4d1cfdeb5"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5">mi_heap_strdup</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const char *s)</td></tr>
+<tr class="memdesc:ga139d6b09dbf50c3c2523d0f4d1cfdeb5"><td class="mdescLeft"> </td><td class="mdescRight">Duplicate a string in a specific heap. <a href="group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5">More...</a><br /></td></tr>
+<tr class="separator:ga139d6b09dbf50c3c2523d0f4d1cfdeb5"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga8e3dbd46650dd26573cf307a2c8f1f5a"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a">mi_heap_strndup</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const char *s, size_t n)</td></tr>
+<tr class="memdesc:ga8e3dbd46650dd26573cf307a2c8f1f5a"><td class="mdescLeft"> </td><td class="mdescRight">Duplicate a string of at most length <em>n</em> in a specific heap. <a href="group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a">More...</a><br /></td></tr>
+<tr class="separator:ga8e3dbd46650dd26573cf307a2c8f1f5a"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga00e95ba1e01acac3cfd95bb7a357a6f0"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0">mi_heap_realpath</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, const char *fname, char *resolved_name)</td></tr>
+<tr class="memdesc:ga00e95ba1e01acac3cfd95bb7a357a6f0"><td class="mdescLeft"> </td><td class="mdescRight">Resolve a file path name using a specific <em>heap</em> to allocate the result. <a href="group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0">More...</a><br /></td></tr>
+<tr class="separator:ga00e95ba1e01acac3cfd95bb7a357a6f0"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaaef3395f66be48f37bdc8322509c5d81"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gaaef3395f66be48f37bdc8322509c5d81">mi_heap_realloc</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize)</td></tr>
+<tr class="separator:gaaef3395f66be48f37bdc8322509c5d81"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gac74e94ad9b0c9b57c1c4d88b8825b7a8"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8">mi_heap_reallocn</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t count, size_t size)</td></tr>
+<tr class="separator:gac74e94ad9b0c9b57c1c4d88b8825b7a8"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga4a21070eb4e7cce018133c8d5f4b0527"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527">mi_heap_reallocf</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize)</td></tr>
+<tr class="separator:ga4a21070eb4e7cce018133c8d5f4b0527"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gab5b87e1805306f70df38789fcfcf6653"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gab5b87e1805306f70df38789fcfcf6653">mi_heap_malloc_aligned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size, size_t alignment)</td></tr>
+<tr class="separator:gab5b87e1805306f70df38789fcfcf6653"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga23acd7680fb0976dde3783254c6c874b"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga23acd7680fb0976dde3783254c6c874b">mi_heap_malloc_aligned_at</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga23acd7680fb0976dde3783254c6c874b"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaa450a59c6c7ae5fdbd1c2b80a8329ef0"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0">mi_heap_zalloc_aligned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size, size_t alignment)</td></tr>
+<tr class="separator:gaa450a59c6c7ae5fdbd1c2b80a8329ef0"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga45fb43a62776fbebbdf1edd99b527954"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga45fb43a62776fbebbdf1edd99b527954">mi_heap_zalloc_aligned_at</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga45fb43a62776fbebbdf1edd99b527954"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga4af03a6e2b93fae77424d93f889705c3"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga4af03a6e2b93fae77424d93f889705c3">mi_heap_calloc_aligned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t count, size_t size, size_t alignment)</td></tr>
+<tr class="separator:ga4af03a6e2b93fae77424d93f889705c3"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga08ca6419a5c057a4d965868998eef487"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#ga08ca6419a5c057a4d965868998eef487">mi_heap_calloc_aligned_at</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, size_t count, size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga08ca6419a5c057a4d965868998eef487"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gafc603b696bd14cae6da28658f950d98c"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gafc603b696bd14cae6da28658f950d98c">mi_heap_realloc_aligned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize, size_t alignment)</td></tr>
+<tr class="separator:gafc603b696bd14cae6da28658f950d98c"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaf96c788a1bf553fe2d371de9365e047c"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__heap.html#gaf96c788a1bf553fe2d371de9365e047c">mi_heap_realloc_aligned_at</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:gaf96c788a1bf553fe2d371de9365e047c"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>First-class heaps that can be destroyed in one go. </p>
+<h2 class="groupheader">Typedef Documentation</h2>
+<a id="ga34a47cde5a5b38c29f1aa3c5e76943c2"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga34a47cde5a5b38c29f1aa3c5e76943c2">◆ </a></span>mi_heap_t</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">typedef struct mi_heap_s <a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Type of first-class heaps. </p>
+<p>A heap can only be used for (re)allocation in the thread that created this heap! Any allocated blocks can be freed by any other thread though. </p>
+
+</div>
+</div>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="gaa6702b3c48e9e53e50e81b36f5011d55"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaa6702b3c48e9e53e50e81b36f5011d55">◆ </a></span>mi_heap_calloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_calloc </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> zero-initialized elements in a specific heap. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d" title="Allocate zero-initialized count elements of size bytes.">mi_calloc()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga4af03a6e2b93fae77424d93f889705c3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4af03a6e2b93fae77424d93f889705c3">◆ </a></span>mi_heap_calloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_calloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga08ca6419a5c057a4d965868998eef487"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga08ca6419a5c057a4d965868998eef487">◆ </a></span>mi_heap_calloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_calloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga7922f7495cde30b1984d0e6072419298"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7922f7495cde30b1984d0e6072419298">◆ </a></span>mi_heap_collect()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_heap_collect </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>force</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Release outstanding resources in a specific heap. </p>
+
+</div>
+</div>
+<a id="ga2ab1af8d438819b55319c7ef51d1e409"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga2ab1af8d438819b55319c7ef51d1e409">◆ </a></span>mi_heap_delete()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_heap_delete </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Delete a previously allocated heap. </p>
+<p>This will release resources and migrate any still allocated blocks in this heap (efficienty) to the default heap.</p>
+<p>If <em>heap</em> is the default heap, the default heap is set to the backing heap. </p>
+
+</div>
+</div>
+<a id="ga9f9c0844edb9717f4feacd79116b8e0d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga9f9c0844edb9717f4feacd79116b8e0d">◆ </a></span>mi_heap_destroy()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_heap_destroy </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Destroy a heap, freeing all its still allocated blocks. </p>
+<p>Use with care as this will free all blocks still allocated in the heap. However, this can be a very efficient way to free all heap memory in one go.</p>
+<p>If <em>heap</em> is the default heap, the default heap is set to the backing heap. </p>
+
+</div>
+</div>
+<a id="ga5d03fbe062ffcf38f0f417fd968357fc"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga5d03fbe062ffcf38f0f417fd968357fc">◆ </a></span>mi_heap_get_backing()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* mi_heap_get_backing </td>
+ <td>(</td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Get the backing heap. </p>
+<p>The <em>backing</em> heap is the initial default heap for a thread and always available for allocations. It cannot be destroyed or deleted except by exiting the thread. </p>
+
+</div>
+</div>
+<a id="ga8db4cbb87314a989a9a187464d6b5e05"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga8db4cbb87314a989a9a187464d6b5e05">◆ </a></span>mi_heap_get_default()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* mi_heap_get_default </td>
+ <td>(</td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Get the default heap that is used for <a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> et al. </p>
+<dl class="section return"><dt>Returns</dt><dd>The current default heap. </dd></dl>
+
+</div>
+</div>
+<a id="ga9cbed01e42c0647907295de92c3fa296"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga9cbed01e42c0647907295de92c3fa296">◆ </a></span>mi_heap_malloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_malloc </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate in a specific heap. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gab5b87e1805306f70df38789fcfcf6653"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gab5b87e1805306f70df38789fcfcf6653">◆ </a></span>mi_heap_malloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_malloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga23acd7680fb0976dde3783254c6c874b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga23acd7680fb0976dde3783254c6c874b">◆ </a></span>mi_heap_malloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_malloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gaa1a1c7a1f4da6826b5a25b70ef878368"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaa1a1c7a1f4da6826b5a25b70ef878368">◆ </a></span>mi_heap_malloc_small()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_malloc_small </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a small object in a specific heap. </p>
+<p><em>size</em> must be smaller or equal to <a class="el" href="group__extended.html#ga1ea64283508718d9d645c38efc2f4305" title="Maximum size allowed for small allocations in mi_malloc_small and mi_zalloc_small (usually 128*sizeof...">MI_SMALL_SIZE_MAX()</a>. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga851da6c43fe0b71c1376cee8aef90db0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga851da6c43fe0b71c1376cee8aef90db0">◆ </a></span>mi_heap_mallocn()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_mallocn </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> elements in a specific heap. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6" title="Allocate count elements of size bytes.">mi_mallocn()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga766f672ba56f2fbfeb9d9dbb0b7f6b11"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga766f672ba56f2fbfeb9d9dbb0b7f6b11">◆ </a></span>mi_heap_new()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* mi_heap_new </td>
+ <td>(</td>
+ <td class="paramname"></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Create a new heap that can be used for allocation. </p>
+
+</div>
+</div>
+<a id="gaaef3395f66be48f37bdc8322509c5d81"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaaef3395f66be48f37bdc8322509c5d81">◆ </a></span>mi_heap_realloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_realloc </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gafc603b696bd14cae6da28658f950d98c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gafc603b696bd14cae6da28658f950d98c">◆ </a></span>mi_heap_realloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_realloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gaf96c788a1bf553fe2d371de9365e047c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf96c788a1bf553fe2d371de9365e047c">◆ </a></span>mi_heap_realloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_realloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga4a21070eb4e7cce018133c8d5f4b0527"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4a21070eb4e7cce018133c8d5f4b0527">◆ </a></span>mi_heap_reallocf()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_reallocf </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gac74e94ad9b0c9b57c1c4d88b8825b7a8"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gac74e94ad9b0c9b57c1c4d88b8825b7a8">◆ </a></span>mi_heap_reallocn()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_reallocn </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga00e95ba1e01acac3cfd95bb7a357a6f0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga00e95ba1e01acac3cfd95bb7a357a6f0">◆ </a></span>mi_heap_realpath()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">char* mi_heap_realpath </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">const char * </td>
+ <td class="paramname"><em>fname</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">char * </td>
+ <td class="paramname"><em>resolved_name</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Resolve a file path name using a specific <em>heap</em> to allocate the result. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe" title="Resolve a file path name.">mi_realpath()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gab8631ec88c8d26641b68b5d25dcd4422"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gab8631ec88c8d26641b68b5d25dcd4422">◆ </a></span>mi_heap_set_default()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* mi_heap_set_default </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Set the default heap to use for <a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> et al. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">heap</td><td>The new default heap. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>The previous default heap. </dd></dl>
+
+</div>
+</div>
+<a id="ga139d6b09dbf50c3c2523d0f4d1cfdeb5"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga139d6b09dbf50c3c2523d0f4d1cfdeb5">◆ </a></span>mi_heap_strdup()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">char* mi_heap_strdup </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">const char * </td>
+ <td class="paramname"><em>s</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Duplicate a string in a specific heap. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2" title="Allocate and duplicate a string.">mi_strdup()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga8e3dbd46650dd26573cf307a2c8f1f5a"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga8e3dbd46650dd26573cf307a2c8f1f5a">◆ </a></span>mi_heap_strndup()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">char* mi_heap_strndup </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">const char * </td>
+ <td class="paramname"><em>s</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>n</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Duplicate a string of at most length <em>n</em> in a specific heap. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#gaaabf971c2571891433477e2d21a35266" title="Allocate and duplicate a string up to n bytes.">mi_strndup()</a> </dd></dl>
+
+</div>
+</div>
+<a id="ga903104592c8ed53417a3762da6241133"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga903104592c8ed53417a3762da6241133">◆ </a></span>mi_heap_zalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_zalloc </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate zero-initialized in a specific heap. </p>
+<dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000" title="Allocate zero-initialized size bytes.">mi_zalloc()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gaa450a59c6c7ae5fdbd1c2b80a8329ef0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaa450a59c6c7ae5fdbd1c2b80a8329ef0">◆ </a></span>mi_heap_zalloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_zalloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga45fb43a62776fbebbdf1edd99b527954"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga45fb43a62776fbebbdf1edd99b527954">◆ </a></span>mi_heap_zalloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_zalloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__heap =
+[
+ [ "mi_heap_t", "group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2", null ],
+ [ "mi_heap_calloc", "group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55", null ],
+ [ "mi_heap_calloc_aligned", "group__heap.html#ga4af03a6e2b93fae77424d93f889705c3", null ],
+ [ "mi_heap_calloc_aligned_at", "group__heap.html#ga08ca6419a5c057a4d965868998eef487", null ],
+ [ "mi_heap_collect", "group__heap.html#ga7922f7495cde30b1984d0e6072419298", null ],
+ [ "mi_heap_delete", "group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409", null ],
+ [ "mi_heap_destroy", "group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d", null ],
+ [ "mi_heap_get_backing", "group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc", null ],
+ [ "mi_heap_get_default", "group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05", null ],
+ [ "mi_heap_malloc", "group__heap.html#ga9cbed01e42c0647907295de92c3fa296", null ],
+ [ "mi_heap_malloc_aligned", "group__heap.html#gab5b87e1805306f70df38789fcfcf6653", null ],
+ [ "mi_heap_malloc_aligned_at", "group__heap.html#ga23acd7680fb0976dde3783254c6c874b", null ],
+ [ "mi_heap_malloc_small", "group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368", null ],
+ [ "mi_heap_mallocn", "group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0", null ],
+ [ "mi_heap_new", "group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11", null ],
+ [ "mi_heap_realloc", "group__heap.html#gaaef3395f66be48f37bdc8322509c5d81", null ],
+ [ "mi_heap_realloc_aligned", "group__heap.html#gafc603b696bd14cae6da28658f950d98c", null ],
+ [ "mi_heap_realloc_aligned_at", "group__heap.html#gaf96c788a1bf553fe2d371de9365e047c", null ],
+ [ "mi_heap_reallocf", "group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527", null ],
+ [ "mi_heap_reallocn", "group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8", null ],
+ [ "mi_heap_realpath", "group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0", null ],
+ [ "mi_heap_set_default", "group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422", null ],
+ [ "mi_heap_strdup", "group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5", null ],
+ [ "mi_heap_strndup", "group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a", null ],
+ [ "mi_heap_zalloc", "group__heap.html#ga903104592c8ed53417a3762da6241133", null ],
+ [ "mi_heap_zalloc_aligned", "group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0", null ],
+ [ "mi_heap_zalloc_aligned_at", "group__heap.html#ga45fb43a62776fbebbdf1edd99b527954", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Basic Allocation</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__malloc.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Basic Allocation</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>The basic allocation interface.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:gaf2c7b89c327d1f60f59e68b9ea644d95"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95">mi_free</a> (void *p)</td></tr>
+<tr class="memdesc:gaf2c7b89c327d1f60f59e68b9ea644d95"><td class="mdescLeft"> </td><td class="mdescRight">Free previously allocated memory. <a href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95">More...</a><br /></td></tr>
+<tr class="separator:gaf2c7b89c327d1f60f59e68b9ea644d95"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga3406e8b168bc74c8637b11571a6da83a"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a">mi_malloc</a> (size_t size)</td></tr>
+<tr class="memdesc:ga3406e8b168bc74c8637b11571a6da83a"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>size</em> bytes. <a href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a">More...</a><br /></td></tr>
+<tr class="separator:ga3406e8b168bc74c8637b11571a6da83a"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gafdd9d8bb2986e668ba9884f28af38000"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000">mi_zalloc</a> (size_t size)</td></tr>
+<tr class="memdesc:gafdd9d8bb2986e668ba9884f28af38000"><td class="mdescLeft"> </td><td class="mdescRight">Allocate zero-initialized <code>size</code> bytes. <a href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000">More...</a><br /></td></tr>
+<tr class="separator:gafdd9d8bb2986e668ba9884f28af38000"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga97fedb4f7107c592fd7f0f0a8949a57d"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d">mi_calloc</a> (size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga97fedb4f7107c592fd7f0f0a8949a57d"><td class="mdescLeft"> </td><td class="mdescRight">Allocate zero-initialized <em>count</em> elements of <em>size</em> bytes. <a href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d">More...</a><br /></td></tr>
+<tr class="separator:ga97fedb4f7107c592fd7f0f0a8949a57d"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaf11eb497da57bdfb2de65eb191c69db6"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6">mi_realloc</a> (void *p, size_t newsize)</td></tr>
+<tr class="memdesc:gaf11eb497da57bdfb2de65eb191c69db6"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate memory to <em>newsize</em> bytes. <a href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6">More...</a><br /></td></tr>
+<tr class="separator:gaf11eb497da57bdfb2de65eb191c69db6"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga23a0fbb452b5dce8e31fab1a1958cacc"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">mi_recalloc</a> (void *p, size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga23a0fbb452b5dce8e31fab1a1958cacc"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate memory to <em>count</em> elements of <em>size</em> bytes, with extra memory initialized to zero. <a href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">More...</a><br /></td></tr>
+<tr class="separator:ga23a0fbb452b5dce8e31fab1a1958cacc"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaaee66a1d483c3e28f585525fb96707e4"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4">mi_expand</a> (void *p, size_t newsize)</td></tr>
+<tr class="memdesc:gaaee66a1d483c3e28f585525fb96707e4"><td class="mdescLeft"> </td><td class="mdescRight">Try to re-allocate memory to <em>newsize</em> bytes <em>in place</em>. <a href="group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4">More...</a><br /></td></tr>
+<tr class="separator:gaaee66a1d483c3e28f585525fb96707e4"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga0b05e2bf0f73e7401ae08597ff782ac6"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6">mi_mallocn</a> (size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga0b05e2bf0f73e7401ae08597ff782ac6"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> elements of <em>size</em> bytes. <a href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6">More...</a><br /></td></tr>
+<tr class="separator:ga0b05e2bf0f73e7401ae08597ff782ac6"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga61d57b4144ba24fba5c1e9b956d13853"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853">mi_reallocn</a> (void *p, size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga61d57b4144ba24fba5c1e9b956d13853"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate memory to <em>count</em> elements of <em>size</em> bytes. <a href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853">More...</a><br /></td></tr>
+<tr class="separator:ga61d57b4144ba24fba5c1e9b956d13853"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gafe68ac7c5e24a65cd55c9d6b152211a0"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0">mi_reallocf</a> (void *p, size_t newsize)</td></tr>
+<tr class="memdesc:gafe68ac7c5e24a65cd55c9d6b152211a0"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate memory to <em>newsize</em> bytes,. <a href="group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0">More...</a><br /></td></tr>
+<tr class="separator:gafe68ac7c5e24a65cd55c9d6b152211a0"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gac7cffe13f1f458ed16789488bf92b9b2"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2">mi_strdup</a> (const char *s)</td></tr>
+<tr class="memdesc:gac7cffe13f1f458ed16789488bf92b9b2"><td class="mdescLeft"> </td><td class="mdescRight">Allocate and duplicate a string. <a href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2">More...</a><br /></td></tr>
+<tr class="separator:gac7cffe13f1f458ed16789488bf92b9b2"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaaabf971c2571891433477e2d21a35266"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#gaaabf971c2571891433477e2d21a35266">mi_strndup</a> (const char *s, size_t n)</td></tr>
+<tr class="memdesc:gaaabf971c2571891433477e2d21a35266"><td class="mdescLeft"> </td><td class="mdescRight">Allocate and duplicate a string up to <em>n</em> bytes. <a href="group__malloc.html#gaaabf971c2571891433477e2d21a35266">More...</a><br /></td></tr>
+<tr class="separator:gaaabf971c2571891433477e2d21a35266"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga08cec32dd5bbe7da91c78d19f1b5bebe"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe">mi_realpath</a> (const char *fname, char *resolved_name)</td></tr>
+<tr class="memdesc:ga08cec32dd5bbe7da91c78d19f1b5bebe"><td class="mdescLeft"> </td><td class="mdescRight">Resolve a file path name. <a href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe">More...</a><br /></td></tr>
+<tr class="separator:ga08cec32dd5bbe7da91c78d19f1b5bebe"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>The basic allocation interface. </p>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="ga97fedb4f7107c592fd7f0f0a8949a57d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga97fedb4f7107c592fd7f0f0a8949a57d">◆ </a></span>mi_calloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_calloc </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate zero-initialized <em>count</em> elements of <em>size</em> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">count</td><td>number of elements. </td></tr>
+ <tr><td class="paramname">size</td><td>size of each element. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the allocated memory of <em>size*<em>count</em> bytes</em>, or <em>NULL</em> if either out of memory or when <code>count*size</code> overflows.</dd></dl>
+<p>Returns a unique pointer if called with either <em>size</em> or <em>count</em> of 0. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000" title="Allocate zero-initialized size bytes.">mi_zalloc()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gaaee66a1d483c3e28f585525fb96707e4"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaaee66a1d483c3e28f585525fb96707e4">◆ </a></span>mi_expand()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_expand </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Try to re-allocate memory to <em>newsize</em> bytes <em>in place</em>. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>pointer to previously allocated memory (or <em>NULL</em>). </td></tr>
+ <tr><td class="paramname">newsize</td><td>the new required size in bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the re-allocated memory of <em>newsize</em> bytes (always equal to <em>p</em>), or <em>NULL</em> if either out of memory or if the memory could not be expanded in place. If <em>NULL</em> is returned, the pointer <em>p</em> is not freed. Otherwise the original pointer is returned as the reallocated result since it fits in-place with the new size. If <em>newsize</em> is larger than the original <em>size</em> allocated for <em>p</em>, the bytes after <em>size</em> are uninitialized. </dd></dl>
+
+</div>
+</div>
+<a id="gaf2c7b89c327d1f60f59e68b9ea644d95"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf2c7b89c327d1f60f59e68b9ea644d95">◆ </a></span>mi_free()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_free </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Free previously allocated memory. </p>
+<p>The pointer <code>p</code> must have been allocated before (or be <em>NULL</em>). </p><dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>pointer to free, or <em>NULL</em>. </td></tr>
+ </table>
+ </dd>
+</dl>
+
+</div>
+</div>
+<a id="ga3406e8b168bc74c8637b11571a6da83a"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga3406e8b168bc74c8637b11571a6da83a">◆ </a></span>mi_malloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_malloc </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>size</em> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>number of bytes to allocate. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the allocated memory or <em>NULL</em> if out of memory. Returns a unique pointer if called with <em>size</em> 0. </dd></dl>
+
+</div>
+</div>
+<a id="ga0b05e2bf0f73e7401ae08597ff782ac6"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga0b05e2bf0f73e7401ae08597ff782ac6">◆ </a></span>mi_mallocn()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_mallocn </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> elements of <em>size</em> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">count</td><td>The number of elements. </td></tr>
+ <tr><td class="paramname">size</td><td>The size of each element. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>A pointer to a block of <em>count</em> * <em>size</em> bytes, or <em>NULL</em> if out of memory or if <em>count</em> * <em>size</em> overflows.</dd></dl>
+<p>If there is no overflow, it behaves exactly like <code>mi_malloc(p,count*size)</code>. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d" title="Allocate zero-initialized count elements of size bytes.">mi_calloc()</a> </dd>
+<dd>
+mi_zallocn() </dd></dl>
+
+</div>
+</div>
+<a id="gaf11eb497da57bdfb2de65eb191c69db6"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf11eb497da57bdfb2de65eb191c69db6">◆ </a></span>mi_realloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_realloc </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate memory to <em>newsize</em> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>pointer to previously allocated memory (or <em>NULL</em>). </td></tr>
+ <tr><td class="paramname">newsize</td><td>the new required size in bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the re-allocated memory of <em>newsize</em> bytes, or <em>NULL</em> if out of memory. If <em>NULL</em> is returned, the pointer <em>p</em> is not freed. Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer <em>p</em> is <em>NULL</em>, it behaves as <em>mi_malloc</em>(<em>newsize</em>). If <em>newsize</em> is larger than the original <em>size</em> allocated for <em>p</em>, the bytes after <em>size</em> are uninitialized. </dd></dl>
+
+</div>
+</div>
+<a id="gafe68ac7c5e24a65cd55c9d6b152211a0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gafe68ac7c5e24a65cd55c9d6b152211a0">◆ </a></span>mi_reallocf()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_reallocf </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate memory to <em>newsize</em> bytes,. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>pointer to previously allocated memory (or <em>NULL</em>). </td></tr>
+ <tr><td class="paramname">newsize</td><td>the new required size in bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>pointer to the re-allocated memory of <em>newsize</em> bytes, or <em>NULL</em> if out of memory.</dd></dl>
+<p>In contrast to <a class="el" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6" title="Re-allocate memory to newsize bytes.">mi_realloc()</a>, if <em>NULL</em> is returned, the original pointer <em>p</em> is freed (if it was not <em>NULL</em> itself). Otherwise the original pointer is either freed or returned as the reallocated result (in case it fits in-place with the new size). If the pointer <em>p</em> is <em>NULL</em>, it behaves as <em>mi_malloc</em>(<em>newsize</em>). If <em>newsize</em> is larger than the original <em>size</em> allocated for <em>p</em>, the bytes after <em>size</em> are uninitialized.</p>
+<dl class="section see"><dt>See also</dt><dd><a href="https://www.freebsd.org/cgi/man.cgi?query=reallocf">reallocf</a> (on BSD) </dd></dl>
+
+</div>
+</div>
+<a id="ga61d57b4144ba24fba5c1e9b956d13853"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga61d57b4144ba24fba5c1e9b956d13853">◆ </a></span>mi_reallocn()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_reallocn </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate memory to <em>count</em> elements of <em>size</em> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>Pointer to a previously allocated block (or <em>NULL</em>). </td></tr>
+ <tr><td class="paramname">count</td><td>The number of elements. </td></tr>
+ <tr><td class="paramname">size</td><td>The size of each element. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>A pointer to a re-allocated block of <em>count</em> * <em>size</em> bytes, or <em>NULL</em> if out of memory or if <em>count</em> * <em>size</em> overflows.</dd></dl>
+<p>If there is no overflow, it behaves exactly like <code>mi_realloc(p,count*size)</code>. </p><dl class="section see"><dt>See also</dt><dd><a href="http://man.openbsd.org/reallocarray">reallocarray()</a> (on BSD) </dd></dl>
+
+</div>
+</div>
+<a id="ga08cec32dd5bbe7da91c78d19f1b5bebe"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga08cec32dd5bbe7da91c78d19f1b5bebe">◆ </a></span>mi_realpath()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">char* mi_realpath </td>
+ <td>(</td>
+ <td class="paramtype">const char * </td>
+ <td class="paramname"><em>fname</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">char * </td>
+ <td class="paramname"><em>resolved_name</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Resolve a file path name. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">fname</td><td>File name. </td></tr>
+ <tr><td class="paramname">resolved_name</td><td>Should be <em>NULL</em> (but can also point to a buffer of at least <em>PATH_MAX</em> bytes). </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>If successful a pointer to the resolved absolute file name, or <em>NULL</em> on failure (with <em>errno</em> set to the error code).</dd></dl>
+<p>If <em>resolved_name</em> was <em>NULL</em>, the returned result should be freed with <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a>.</p>
+<p>Replacement for the standard <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html">realpath()</a> such that <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a> can be used on the returned result (if <em>resolved_name</em> was <em>NULL</em>). </p>
+
+</div>
+</div>
+<a id="ga23a0fbb452b5dce8e31fab1a1958cacc"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga23a0fbb452b5dce8e31fab1a1958cacc">◆ </a></span>mi_recalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void * mi_recalloc </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate memory to <em>count</em> elements of <em>size</em> bytes, with extra memory initialized to zero. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">p</td><td>Pointer to a previously allocated block (or <em>NULL</em>). </td></tr>
+ <tr><td class="paramname">count</td><td>The number of elements. </td></tr>
+ <tr><td class="paramname">size</td><td>The size of each element. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>A pointer to a re-allocated block of <em>count</em> * <em>size</em> bytes, or <em>NULL</em> if out of memory or if <em>count</em> * <em>size</em> overflows.</dd></dl>
+<p>If there is no overflow, it behaves exactly like <code>mi_rezalloc(p,count*size)</code>. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853" title="Re-allocate memory to count elements of size bytes.">mi_reallocn()</a> </dd>
+<dd>
+<a href="http://man.openbsd.org/reallocarray">recallocarray()</a> (on BSD). </dd></dl>
+
+</div>
+</div>
+<a id="gac7cffe13f1f458ed16789488bf92b9b2"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gac7cffe13f1f458ed16789488bf92b9b2">◆ </a></span>mi_strdup()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">char* mi_strdup </td>
+ <td>(</td>
+ <td class="paramtype">const char * </td>
+ <td class="paramname"><em>s</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate and duplicate a string. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">s</td><td>string to duplicate (or <em>NULL</em>). </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>a pointer to newly allocated memory initialized to string <em>s</em>, or <em>NULL</em> if either out of memory or if <em>s</em> is <em>NULL</em>.</dd></dl>
+<p>Replacement for the standard <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html">strdup()</a> such that <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a> can be used on the returned result. </p>
+
+</div>
+</div>
+<a id="gaaabf971c2571891433477e2d21a35266"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaaabf971c2571891433477e2d21a35266">◆ </a></span>mi_strndup()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">char* mi_strndup </td>
+ <td>(</td>
+ <td class="paramtype">const char * </td>
+ <td class="paramname"><em>s</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>n</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate and duplicate a string up to <em>n</em> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">s</td><td>string to duplicate (or <em>NULL</em>). </td></tr>
+ <tr><td class="paramname">n</td><td>maximum number of bytes to copy (excluding the terminating zero). </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>a pointer to newly allocated memory initialized to string <em>s</em> up to the first <em>n</em> bytes (and always zero terminated), or <em>NULL</em> if either out of memory or if <em>s</em> is <em>NULL</em>.</dd></dl>
+<p>Replacement for the standard <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html">strndup()</a> such that <a class="el" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95" title="Free previously allocated memory.">mi_free()</a> can be used on the returned result. </p>
+
+</div>
+</div>
+<a id="gafdd9d8bb2986e668ba9884f28af38000"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gafdd9d8bb2986e668ba9884f28af38000">◆ </a></span>mi_zalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_zalloc </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate zero-initialized <code>size</code> bytes. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">size</td><td>The size in bytes. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>Pointer to newly allocated zero initialized memory, or <em>NULL</em> if out of memory. </dd></dl>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__malloc =
+[
+ [ "mi_calloc", "group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d", null ],
+ [ "mi_expand", "group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4", null ],
+ [ "mi_free", "group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95", null ],
+ [ "mi_malloc", "group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a", null ],
+ [ "mi_mallocn", "group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6", null ],
+ [ "mi_realloc", "group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6", null ],
+ [ "mi_reallocf", "group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0", null ],
+ [ "mi_reallocn", "group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853", null ],
+ [ "mi_realpath", "group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe", null ],
+ [ "mi_recalloc", "group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc", null ],
+ [ "mi_strdup", "group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2", null ],
+ [ "mi_strndup", "group__malloc.html#gaaabf971c2571891433477e2d21a35266", null ],
+ [ "mi_zalloc", "group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Runtime Options</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__options.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#enum-members">Enumerations</a> |
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Runtime Options</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>Set runtime behavior.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr class="memitem:gafebf7ed116adb38ae5218bc3ce06884c"><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> { <br />
+  <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0">mi_option_show_errors</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda">mi_option_show_stats</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777">mi_option_verbose</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b">mi_option_eager_commit</a>
+, <br />
+  <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad">mi_option_eager_region_commit</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e">mi_option_large_os_pages</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2">mi_option_reserve_huge_os_pages</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c">mi_option_reserve_huge_os_pages_at</a>
+, <br />
+  <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1">mi_option_segment_cache</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968">mi_option_page_reset</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d">mi_option_segment_reset</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5">mi_option_reset_delay</a>
+, <br />
+  <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74">mi_option_use_numa_nodes</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536">mi_option_reset_decommits</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c">mi_option_eager_commit_delay</a>
+, <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf">mi_option_os_tag</a>
+, <br />
+  <a class="el" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a">_mi_option_last</a>
+<br />
+ }</td></tr>
+<tr class="memdesc:gafebf7ed116adb38ae5218bc3ce06884c"><td class="mdescLeft"> </td><td class="mdescRight">Runtime options. <a href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">More...</a><br /></td></tr>
+<tr class="separator:gafebf7ed116adb38ae5218bc3ce06884c"><td class="memSeparator" colspan="2"> </td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:ga459ad98f18b3fc9275474807fe0ca188"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#ga459ad98f18b3fc9275474807fe0ca188">mi_option_is_enabled</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option)</td></tr>
+<tr class="separator:ga459ad98f18b3fc9275474807fe0ca188"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga04180ae41b0d601421dd62ced40ca050"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#ga04180ae41b0d601421dd62ced40ca050">mi_option_enable</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option)</td></tr>
+<tr class="separator:ga04180ae41b0d601421dd62ced40ca050"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaebf6ff707a2e688ebb1a2296ca564054"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#gaebf6ff707a2e688ebb1a2296ca564054">mi_option_disable</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option)</td></tr>
+<tr class="separator:gaebf6ff707a2e688ebb1a2296ca564054"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga9a13d05fcb77489cb06d4d017ebd8bed"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed">mi_option_set_enabled</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, bool enable)</td></tr>
+<tr class="separator:ga9a13d05fcb77489cb06d4d017ebd8bed"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga65518b69ec5d32336b50e07f74b3f629"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#ga65518b69ec5d32336b50e07f74b3f629">mi_option_set_enabled_default</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, bool enable)</td></tr>
+<tr class="separator:ga65518b69ec5d32336b50e07f74b3f629"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga7e8af195cc81d3fa64ccf2662caa565a"><td class="memItemLeft" align="right" valign="top">long </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a">mi_option_get</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option)</td></tr>
+<tr class="separator:ga7e8af195cc81d3fa64ccf2662caa565a"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaf84921c32375e25754dc2ee6a911fa60"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#gaf84921c32375e25754dc2ee6a911fa60">mi_option_set</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, long value)</td></tr>
+<tr class="separator:gaf84921c32375e25754dc2ee6a911fa60"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga7ef623e440e6e5545cb08c94e71e4b90"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90">mi_option_set_default</a> (<a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, long value)</td></tr>
+<tr class="separator:ga7ef623e440e6e5545cb08c94e71e4b90"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>Set runtime behavior. </p>
+<h2 class="groupheader">Enumeration Type Documentation</h2>
+<a id="gafebf7ed116adb38ae5218bc3ce06884c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gafebf7ed116adb38ae5218bc3ce06884c">◆ </a></span>mi_option_t</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">enum <a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Runtime options. </p>
+<table class="fieldtable">
+<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0"></a>mi_option_show_errors </td><td class="fielddoc"><p>Print error messages to <code>stderr</code>. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda"></a>mi_option_show_stats </td><td class="fielddoc"><p>Print statistics to <code>stderr</code> when the program is done. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777"></a>mi_option_verbose </td><td class="fielddoc"><p>Print verbose messages to <code>stderr</code>. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b"></a>mi_option_eager_commit </td><td class="fielddoc"><p>Eagerly commit segments (4MiB) (enabled by default). </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad"></a>mi_option_eager_region_commit </td><td class="fielddoc"><p>Eagerly commit large (256MiB) memory regions (enabled by default, except on Windows) </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e"></a>mi_option_large_os_pages </td><td class="fielddoc"><p>Use large OS pages (2MiB in size) if possible. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2"></a>mi_option_reserve_huge_os_pages </td><td class="fielddoc"><p>The number of huge OS pages (1GiB in size) to reserve at the start of the program. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c"></a>mi_option_reserve_huge_os_pages_at </td><td class="fielddoc"><p>Reserve huge OS pages at node N. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1"></a>mi_option_segment_cache </td><td class="fielddoc"><p>The number of segments per thread to keep cached. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968"></a>mi_option_page_reset </td><td class="fielddoc"><p>Reset page memory after <em>mi_option_reset_delay</em> milliseconds when it becomes free. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d"></a>mi_option_segment_reset </td><td class="fielddoc"><p>Experimental. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5"></a>mi_option_reset_delay </td><td class="fielddoc"><p>Delay in milli-seconds before resetting a page (100ms by default) </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74"></a>mi_option_use_numa_nodes </td><td class="fielddoc"><p>Pretend there are at most N NUMA nodes. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536"></a>mi_option_reset_decommits </td><td class="fielddoc"><p>Experimental. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c"></a>mi_option_eager_commit_delay </td><td class="fielddoc"><p>Experimental. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf"></a>mi_option_os_tag </td><td class="fielddoc"><p>OS tag to assign to mimalloc'd memory. </p>
+</td></tr>
+<tr><td class="fieldname"><a id="ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a"></a>_mi_option_last </td><td class="fielddoc"></td></tr>
+</table>
+
+</div>
+</div>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="gaebf6ff707a2e688ebb1a2296ca564054"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaebf6ff707a2e688ebb1a2296ca564054">◆ </a></span>mi_option_disable()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_option_disable </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga04180ae41b0d601421dd62ced40ca050"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga04180ae41b0d601421dd62ced40ca050">◆ </a></span>mi_option_enable()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_option_enable </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga7e8af195cc81d3fa64ccf2662caa565a"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7e8af195cc81d3fa64ccf2662caa565a">◆ </a></span>mi_option_get()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">long mi_option_get </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga459ad98f18b3fc9275474807fe0ca188"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga459ad98f18b3fc9275474807fe0ca188">◆ </a></span>mi_option_is_enabled()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">bool mi_option_is_enabled </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gaf84921c32375e25754dc2ee6a911fa60"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf84921c32375e25754dc2ee6a911fa60">◆ </a></span>mi_option_set()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_option_set </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">long </td>
+ <td class="paramname"><em>value</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga7ef623e440e6e5545cb08c94e71e4b90"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7ef623e440e6e5545cb08c94e71e4b90">◆ </a></span>mi_option_set_default()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_option_set_default </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">long </td>
+ <td class="paramname"><em>value</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga9a13d05fcb77489cb06d4d017ebd8bed"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga9a13d05fcb77489cb06d4d017ebd8bed">◆ </a></span>mi_option_set_enabled()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_option_set_enabled </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>enable</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga65518b69ec5d32336b50e07f74b3f629"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga65518b69ec5d32336b50e07f74b3f629">◆ </a></span>mi_option_set_enabled_default()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_option_set_enabled_default </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> </td>
+ <td class="paramname"><em>option</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">bool </td>
+ <td class="paramname"><em>enable</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__options =
+[
+ [ "mi_option_t", "group__options.html#gafebf7ed116adb38ae5218bc3ce06884c", [
+ [ "mi_option_show_errors", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0", null ],
+ [ "mi_option_show_stats", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda", null ],
+ [ "mi_option_verbose", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777", null ],
+ [ "mi_option_eager_commit", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b", null ],
+ [ "mi_option_eager_region_commit", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad", null ],
+ [ "mi_option_large_os_pages", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e", null ],
+ [ "mi_option_reserve_huge_os_pages", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2", null ],
+ [ "mi_option_reserve_huge_os_pages_at", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c", null ],
+ [ "mi_option_segment_cache", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1", null ],
+ [ "mi_option_page_reset", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968", null ],
+ [ "mi_option_segment_reset", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d", null ],
+ [ "mi_option_reset_delay", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5", null ],
+ [ "mi_option_use_numa_nodes", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74", null ],
+ [ "mi_option_reset_decommits", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536", null ],
+ [ "mi_option_eager_commit_delay", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c", null ],
+ [ "mi_option_os_tag", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf", null ],
+ [ "_mi_option_last", "group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a", null ]
+ ] ],
+ [ "mi_option_disable", "group__options.html#gaebf6ff707a2e688ebb1a2296ca564054", null ],
+ [ "mi_option_enable", "group__options.html#ga04180ae41b0d601421dd62ced40ca050", null ],
+ [ "mi_option_get", "group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a", null ],
+ [ "mi_option_is_enabled", "group__options.html#ga459ad98f18b3fc9275474807fe0ca188", null ],
+ [ "mi_option_set", "group__options.html#gaf84921c32375e25754dc2ee6a911fa60", null ],
+ [ "mi_option_set_default", "group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90", null ],
+ [ "mi_option_set_enabled", "group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed", null ],
+ [ "mi_option_set_enabled_default", "group__options.html#ga65518b69ec5d32336b50e07f74b3f629", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Posix</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__posix.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Posix</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><code>mi_</code> prefixed implementations of various Posix, Unix, and C++ allocation functions.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:ga4531c9e775bb3ae12db57c1ba8a5d7de"><td class="memItemLeft" align="right" valign="top">size_t </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de">mi_malloc_size</a> (const void *p)</td></tr>
+<tr class="separator:ga4531c9e775bb3ae12db57c1ba8a5d7de"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga06d07cf357bbac5c73ba5d0c0c421e17"><td class="memItemLeft" align="right" valign="top">size_t </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17">mi_malloc_usable_size</a> (const void *p)</td></tr>
+<tr class="separator:ga06d07cf357bbac5c73ba5d0c0c421e17"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga705dc7a64bffacfeeb0141501a5c35d7"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7">mi_cfree</a> (void *p)</td></tr>
+<tr class="memdesc:ga705dc7a64bffacfeeb0141501a5c35d7"><td class="mdescLeft"> </td><td class="mdescRight">Just as <code>free</code> but also checks if the pointer <code>p</code> belongs to our heap. <a href="group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7">More...</a><br /></td></tr>
+<tr class="separator:ga705dc7a64bffacfeeb0141501a5c35d7"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gacff84f226ba9feb2031b8992e5579447"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#gacff84f226ba9feb2031b8992e5579447">mi_posix_memalign</a> (void **p, size_t alignment, size_t size)</td></tr>
+<tr class="separator:gacff84f226ba9feb2031b8992e5579447"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gad5a69c8fea96aa2b7a7c818c2130090a"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a">mi__posix_memalign</a> (void **p, size_t alignment, size_t size)</td></tr>
+<tr class="separator:gad5a69c8fea96aa2b7a7c818c2130090a"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaab7fa71ea93b96873f5d9883db57d40e"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e">mi_memalign</a> (size_t alignment, size_t size)</td></tr>
+<tr class="separator:gaab7fa71ea93b96873f5d9883db57d40e"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga73baaf5951f5165ba0763d0c06b6a93b"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b">mi_valloc</a> (size_t size)</td></tr>
+<tr class="separator:ga73baaf5951f5165ba0763d0c06b6a93b"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaeb325c39b887d3b90d85d1eb1712fb1e"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e">mi_pvalloc</a> (size_t size)</td></tr>
+<tr class="separator:gaeb325c39b887d3b90d85d1eb1712fb1e"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga1326d2e4388630b5f81ca7206318b8e5"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5">mi_aligned_alloc</a> (size_t alignment, size_t size)</td></tr>
+<tr class="separator:ga1326d2e4388630b5f81ca7206318b8e5"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga48fad8648a2f1dab9c87ea9448a52088"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088">mi_reallocarray</a> (void *p, size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga48fad8648a2f1dab9c87ea9448a52088"><td class="mdescLeft"> </td><td class="mdescRight">Correspond s to <a href="https://www.freebsd.org/cgi/man.cgi?query=reallocarray&sektion=3&manpath=freebsd-release-ports">reallocarray</a> in FreeBSD. <a href="group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088">More...</a><br /></td></tr>
+<tr class="separator:ga48fad8648a2f1dab9c87ea9448a52088"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga7e1934d60a3e697950eeb48e042bfad5"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5">mi_reallocarr</a> (void *p, size_t count, size_t size)</td></tr>
+<tr class="memdesc:ga7e1934d60a3e697950eeb48e042bfad5"><td class="mdescLeft"> </td><td class="mdescRight">Corresponds to <a href="https://man.netbsd.org/reallocarr.3">reallocarr</a> in NetBSD. <a href="group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5">More...</a><br /></td></tr>
+<tr class="separator:ga7e1934d60a3e697950eeb48e042bfad5"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gae01389eedab8d67341ff52e2aad80ebb"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#gae01389eedab8d67341ff52e2aad80ebb">mi_free_size</a> (void *p, size_t size)</td></tr>
+<tr class="separator:gae01389eedab8d67341ff52e2aad80ebb"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga72e9d7ffb5fe94d69bc722c8506e27bc"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc">mi_free_size_aligned</a> (void *p, size_t size, size_t alignment)</td></tr>
+<tr class="separator:ga72e9d7ffb5fe94d69bc722c8506e27bc"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga0d28d5cf61e6bfbb18c63092939fe5c9"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9">mi_free_aligned</a> (void *p, size_t alignment)</td></tr>
+<tr class="separator:ga0d28d5cf61e6bfbb18c63092939fe5c9"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p><code>mi_</code> prefixed implementations of various Posix, Unix, and C++ allocation functions. </p>
+<p>Defined for convenience as all redirect to the regular mimalloc API. </p>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="gad5a69c8fea96aa2b7a7c818c2130090a"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gad5a69c8fea96aa2b7a7c818c2130090a">◆ </a></span>mi__posix_memalign()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int mi__posix_memalign </td>
+ <td>(</td>
+ <td class="paramtype">void ** </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga1326d2e4388630b5f81ca7206318b8e5"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga1326d2e4388630b5f81ca7206318b8e5">◆ </a></span>mi_aligned_alloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_aligned_alloc </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga705dc7a64bffacfeeb0141501a5c35d7"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga705dc7a64bffacfeeb0141501a5c35d7">◆ </a></span>mi_cfree()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_cfree </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Just as <code>free</code> but also checks if the pointer <code>p</code> belongs to our heap. </p>
+
+</div>
+</div>
+<a id="ga0d28d5cf61e6bfbb18c63092939fe5c9"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga0d28d5cf61e6bfbb18c63092939fe5c9">◆ </a></span>mi_free_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_free_aligned </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gae01389eedab8d67341ff52e2aad80ebb"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gae01389eedab8d67341ff52e2aad80ebb">◆ </a></span>mi_free_size()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_free_size </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga72e9d7ffb5fe94d69bc722c8506e27bc"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga72e9d7ffb5fe94d69bc722c8506e27bc">◆ </a></span>mi_free_size_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void mi_free_size_aligned </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga4531c9e775bb3ae12db57c1ba8a5d7de"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4531c9e775bb3ae12db57c1ba8a5d7de">◆ </a></span>mi_malloc_size()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t mi_malloc_size </td>
+ <td>(</td>
+ <td class="paramtype">const void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga06d07cf357bbac5c73ba5d0c0c421e17"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga06d07cf357bbac5c73ba5d0c0c421e17">◆ </a></span>mi_malloc_usable_size()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">size_t mi_malloc_usable_size </td>
+ <td>(</td>
+ <td class="paramtype">const void * </td>
+ <td class="paramname"><em>p</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gaab7fa71ea93b96873f5d9883db57d40e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaab7fa71ea93b96873f5d9883db57d40e">◆ </a></span>mi_memalign()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_memalign </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gacff84f226ba9feb2031b8992e5579447"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gacff84f226ba9feb2031b8992e5579447">◆ </a></span>mi_posix_memalign()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int mi_posix_memalign </td>
+ <td>(</td>
+ <td class="paramtype">void ** </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gaeb325c39b887d3b90d85d1eb1712fb1e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaeb325c39b887d3b90d85d1eb1712fb1e">◆ </a></span>mi_pvalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_pvalloc </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga7e1934d60a3e697950eeb48e042bfad5"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga7e1934d60a3e697950eeb48e042bfad5">◆ </a></span>mi_reallocarr()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">int mi_reallocarr </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Corresponds to <a href="https://man.netbsd.org/reallocarr.3">reallocarr</a> in NetBSD. </p>
+
+</div>
+</div>
+<a id="ga48fad8648a2f1dab9c87ea9448a52088"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga48fad8648a2f1dab9c87ea9448a52088">◆ </a></span>mi_reallocarray()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_reallocarray </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>count</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Correspond s to <a href="https://www.freebsd.org/cgi/man.cgi?query=reallocarray&sektion=3&manpath=freebsd-release-ports">reallocarray</a> in FreeBSD. </p>
+
+</div>
+</div>
+<a id="ga73baaf5951f5165ba0763d0c06b6a93b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga73baaf5951f5165ba0763d0c06b6a93b">◆ </a></span>mi_valloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_valloc </td>
+ <td>(</td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em></td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__posix =
+[
+ [ "mi__posix_memalign", "group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a", null ],
+ [ "mi_aligned_alloc", "group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5", null ],
+ [ "mi_cfree", "group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7", null ],
+ [ "mi_free_aligned", "group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9", null ],
+ [ "mi_free_size", "group__posix.html#gae01389eedab8d67341ff52e2aad80ebb", null ],
+ [ "mi_free_size_aligned", "group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc", null ],
+ [ "mi_malloc_size", "group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de", null ],
+ [ "mi_malloc_usable_size", "group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17", null ],
+ [ "mi_memalign", "group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e", null ],
+ [ "mi_posix_memalign", "group__posix.html#gacff84f226ba9feb2031b8992e5579447", null ],
+ [ "mi_pvalloc", "group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e", null ],
+ [ "mi_reallocarr", "group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5", null ],
+ [ "mi_reallocarray", "group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088", null ],
+ [ "mi_valloc", "group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Typed Macros</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__typed.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#define-members">Macros</a> </div>
+ <div class="headertitle">
+<div class="title">Typed Macros</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>Typed allocation macros.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
+Macros</h2></td></tr>
+<tr class="memitem:ga0619a62c5fd886f1016030abe91f0557"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#ga0619a62c5fd886f1016030abe91f0557">mi_malloc_tp</a>(tp)</td></tr>
+<tr class="memdesc:ga0619a62c5fd886f1016030abe91f0557"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a block of type <em>tp</em>. <a href="group__typed.html#ga0619a62c5fd886f1016030abe91f0557">More...</a><br /></td></tr>
+<tr class="separator:ga0619a62c5fd886f1016030abe91f0557"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gac77a61bdaf680a803785fe307820b48c"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#gac77a61bdaf680a803785fe307820b48c">mi_zalloc_tp</a>(tp)</td></tr>
+<tr class="memdesc:gac77a61bdaf680a803785fe307820b48c"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a zero-initialized block of type <em>tp</em>. <a href="group__typed.html#gac77a61bdaf680a803785fe307820b48c">More...</a><br /></td></tr>
+<tr class="separator:gac77a61bdaf680a803785fe307820b48c"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gae80c47c9d4cab10961fff1a8ac98fc07"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#gae80c47c9d4cab10961fff1a8ac98fc07">mi_calloc_tp</a>(tp, count)</td></tr>
+<tr class="memdesc:gae80c47c9d4cab10961fff1a8ac98fc07"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> zero-initialized blocks of type <em>tp</em>. <a href="group__typed.html#gae80c47c9d4cab10961fff1a8ac98fc07">More...</a><br /></td></tr>
+<tr class="separator:gae80c47c9d4cab10961fff1a8ac98fc07"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gae5cb6e0fafc9f23169c5622e077afe8b"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#gae5cb6e0fafc9f23169c5622e077afe8b">mi_mallocn_tp</a>(tp, count)</td></tr>
+<tr class="memdesc:gae5cb6e0fafc9f23169c5622e077afe8b"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> blocks of type <em>tp</em>. <a href="group__typed.html#gae5cb6e0fafc9f23169c5622e077afe8b">More...</a><br /></td></tr>
+<tr class="separator:gae5cb6e0fafc9f23169c5622e077afe8b"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga1158b49a55dfa81f58a4426a7578f523"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#ga1158b49a55dfa81f58a4426a7578f523">mi_reallocn_tp</a>(p, tp, count)</td></tr>
+<tr class="memdesc:ga1158b49a55dfa81f58a4426a7578f523"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate to <em>count</em> blocks of type <em>tp</em>. <a href="group__typed.html#ga1158b49a55dfa81f58a4426a7578f523">More...</a><br /></td></tr>
+<tr class="separator:ga1158b49a55dfa81f58a4426a7578f523"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga653bcb24ac495bc19940ecd6898f9cd7"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#ga653bcb24ac495bc19940ecd6898f9cd7">mi_heap_malloc_tp</a>(hp, tp)</td></tr>
+<tr class="memdesc:ga653bcb24ac495bc19940ecd6898f9cd7"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a block of type <em>tp</em> in a heap <em>hp</em>. <a href="group__typed.html#ga653bcb24ac495bc19940ecd6898f9cd7">More...</a><br /></td></tr>
+<tr class="separator:ga653bcb24ac495bc19940ecd6898f9cd7"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gad6e87e86e994aa14416ae9b5d4c188fe"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#gad6e87e86e994aa14416ae9b5d4c188fe">mi_heap_zalloc_tp</a>(hp, tp)</td></tr>
+<tr class="memdesc:gad6e87e86e994aa14416ae9b5d4c188fe"><td class="mdescLeft"> </td><td class="mdescRight">Allocate a zero-initialized block of type <em>tp</em> in a heap <em>hp</em>. <a href="group__typed.html#gad6e87e86e994aa14416ae9b5d4c188fe">More...</a><br /></td></tr>
+<tr class="separator:gad6e87e86e994aa14416ae9b5d4c188fe"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga4e5d1f1707c90e5f55e023ac5f45fe74"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#ga4e5d1f1707c90e5f55e023ac5f45fe74">mi_heap_calloc_tp</a>(hp, tp, count)</td></tr>
+<tr class="memdesc:ga4e5d1f1707c90e5f55e023ac5f45fe74"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> zero-initialized blocks of type <em>tp</em> in a heap <em>hp</em>. <a href="group__typed.html#ga4e5d1f1707c90e5f55e023ac5f45fe74">More...</a><br /></td></tr>
+<tr class="separator:ga4e5d1f1707c90e5f55e023ac5f45fe74"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga6b75cb9c4b9c647661d0924552dc6e83"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#ga6b75cb9c4b9c647661d0924552dc6e83">mi_heap_mallocn_tp</a>(hp, tp, count)</td></tr>
+<tr class="memdesc:ga6b75cb9c4b9c647661d0924552dc6e83"><td class="mdescLeft"> </td><td class="mdescRight">Allocate <em>count</em> blocks of type <em>tp</em> in a heap <em>hp</em>. <a href="group__typed.html#ga6b75cb9c4b9c647661d0924552dc6e83">More...</a><br /></td></tr>
+<tr class="separator:ga6b75cb9c4b9c647661d0924552dc6e83"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gaf213d5422ec35e7f6caad827c79bc948"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#gaf213d5422ec35e7f6caad827c79bc948">mi_heap_reallocn_tp</a>(hp, p, tp, count)</td></tr>
+<tr class="memdesc:gaf213d5422ec35e7f6caad827c79bc948"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate to <em>count</em> blocks of type <em>tp</em> in a heap <em>hp</em>. <a href="group__typed.html#gaf213d5422ec35e7f6caad827c79bc948">More...</a><br /></td></tr>
+<tr class="separator:gaf213d5422ec35e7f6caad827c79bc948"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga3e50a1600958fcaf1a7f3560c9174f9e"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__typed.html#ga3e50a1600958fcaf1a7f3560c9174f9e">mi_heap_recalloc_tp</a>(hp, p, tp, count)</td></tr>
+<tr class="memdesc:ga3e50a1600958fcaf1a7f3560c9174f9e"><td class="mdescLeft"> </td><td class="mdescRight">Re-allocate to <em>count</em> zero initialized blocks of type <em>tp</em> in a heap <em>hp</em>. <a href="group__typed.html#ga3e50a1600958fcaf1a7f3560c9174f9e">More...</a><br /></td></tr>
+<tr class="separator:ga3e50a1600958fcaf1a7f3560c9174f9e"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>Typed allocation macros. </p>
+<p>For example: </p><div class="fragment"><div class="line"><span class="keywordtype">int</span>* p = <a class="code" href="group__typed.html#ga0619a62c5fd886f1016030abe91f0557">mi_malloc_tp</a>(<span class="keywordtype">int</span>)</div>
+<div class="ttc" id="agroup__typed_html_ga0619a62c5fd886f1016030abe91f0557"><div class="ttname"><a href="group__typed.html#ga0619a62c5fd886f1016030abe91f0557">mi_malloc_tp</a></div><div class="ttdeci">#define mi_malloc_tp(tp)</div><div class="ttdoc">Allocate a block of type tp.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:692</div></div>
+</div><!-- fragment --> <h2 class="groupheader">Macro Definition Documentation</h2>
+<a id="gae80c47c9d4cab10961fff1a8ac98fc07"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gae80c47c9d4cab10961fff1a8ac98fc07">◆ </a></span>mi_calloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_calloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> zero-initialized blocks of type <em>tp</em>. </p>
+
+</div>
+</div>
+<a id="ga4e5d1f1707c90e5f55e023ac5f45fe74"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4e5d1f1707c90e5f55e023ac5f45fe74">◆ </a></span>mi_heap_calloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_heap_calloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">hp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> zero-initialized blocks of type <em>tp</em> in a heap <em>hp</em>. </p>
+
+</div>
+</div>
+<a id="ga653bcb24ac495bc19940ecd6898f9cd7"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga653bcb24ac495bc19940ecd6898f9cd7">◆ </a></span>mi_heap_malloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_heap_malloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">hp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a block of type <em>tp</em> in a heap <em>hp</em>. </p>
+
+</div>
+</div>
+<a id="ga6b75cb9c4b9c647661d0924552dc6e83"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga6b75cb9c4b9c647661d0924552dc6e83">◆ </a></span>mi_heap_mallocn_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_heap_mallocn_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">hp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> blocks of type <em>tp</em> in a heap <em>hp</em>. </p>
+
+</div>
+</div>
+<a id="gaf213d5422ec35e7f6caad827c79bc948"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gaf213d5422ec35e7f6caad827c79bc948">◆ </a></span>mi_heap_reallocn_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_heap_reallocn_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">hp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">p, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate to <em>count</em> blocks of type <em>tp</em> in a heap <em>hp</em>. </p>
+
+</div>
+</div>
+<a id="ga3e50a1600958fcaf1a7f3560c9174f9e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga3e50a1600958fcaf1a7f3560c9174f9e">◆ </a></span>mi_heap_recalloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_heap_recalloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">hp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">p, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate to <em>count</em> zero initialized blocks of type <em>tp</em> in a heap <em>hp</em>. </p>
+
+</div>
+</div>
+<a id="gad6e87e86e994aa14416ae9b5d4c188fe"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gad6e87e86e994aa14416ae9b5d4c188fe">◆ </a></span>mi_heap_zalloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_heap_zalloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">hp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a zero-initialized block of type <em>tp</em> in a heap <em>hp</em>. </p>
+
+</div>
+</div>
+<a id="ga0619a62c5fd886f1016030abe91f0557"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga0619a62c5fd886f1016030abe91f0557">◆ </a></span>mi_malloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_malloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp</td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a block of type <em>tp</em>. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+ <table class="params">
+ <tr><td class="paramname">tp</td><td>The type of the block to allocate. </td></tr>
+ </table>
+ </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>A pointer to an object of type <em>tp</em>, or <em>NULL</em> if out of memory.</dd></dl>
+<p><b>Example:</b> </p><div class="fragment"><div class="line"><span class="keywordtype">int</span>* p = <a class="code" href="group__typed.html#ga0619a62c5fd886f1016030abe91f0557">mi_malloc_tp</a>(<span class="keywordtype">int</span>)</div>
+</div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a" title="Allocate size bytes.">mi_malloc()</a> </dd></dl>
+
+</div>
+</div>
+<a id="gae5cb6e0fafc9f23169c5622e077afe8b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gae5cb6e0fafc9f23169c5622e077afe8b">◆ </a></span>mi_mallocn_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_mallocn_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate <em>count</em> blocks of type <em>tp</em>. </p>
+
+</div>
+</div>
+<a id="ga1158b49a55dfa81f58a4426a7578f523"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga1158b49a55dfa81f58a4426a7578f523">◆ </a></span>mi_reallocn_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_reallocn_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">p, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype"> </td>
+ <td class="paramname">count </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Re-allocate to <em>count</em> blocks of type <em>tp</em>. </p>
+
+</div>
+</div>
+<a id="gac77a61bdaf680a803785fe307820b48c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gac77a61bdaf680a803785fe307820b48c">◆ </a></span>mi_zalloc_tp</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">#define mi_zalloc_tp</td>
+ <td>(</td>
+ <td class="paramtype"> </td>
+ <td class="paramname">tp</td><td>)</td>
+ <td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+<p>Allocate a zero-initialized block of type <em>tp</em>. </p>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__typed =
+[
+ [ "mi_calloc_tp", "group__typed.html#gae80c47c9d4cab10961fff1a8ac98fc07", null ],
+ [ "mi_heap_calloc_tp", "group__typed.html#ga4e5d1f1707c90e5f55e023ac5f45fe74", null ],
+ [ "mi_heap_malloc_tp", "group__typed.html#ga653bcb24ac495bc19940ecd6898f9cd7", null ],
+ [ "mi_heap_mallocn_tp", "group__typed.html#ga6b75cb9c4b9c647661d0924552dc6e83", null ],
+ [ "mi_heap_reallocn_tp", "group__typed.html#gaf213d5422ec35e7f6caad827c79bc948", null ],
+ [ "mi_heap_recalloc_tp", "group__typed.html#ga3e50a1600958fcaf1a7f3560c9174f9e", null ],
+ [ "mi_heap_zalloc_tp", "group__typed.html#gad6e87e86e994aa14416ae9b5d4c188fe", null ],
+ [ "mi_malloc_tp", "group__typed.html#ga0619a62c5fd886f1016030abe91f0557", null ],
+ [ "mi_mallocn_tp", "group__typed.html#gae5cb6e0fafc9f23169c5622e077afe8b", null ],
+ [ "mi_reallocn_tp", "group__typed.html#ga1158b49a55dfa81f58a4426a7578f523", null ],
+ [ "mi_zalloc_tp", "group__typed.html#gac77a61bdaf680a803785fe307820b48c", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Zero initialized re-allocation</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('group__zeroinit.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="summary">
+<a href="#func-members">Functions</a> </div>
+ <div class="headertitle">
+<div class="title">Zero initialized re-allocation</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p>The zero-initialized re-allocations are only valid on memory that was originally allocated with zero initialization too.
+<a href="#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
+Functions</h2></td></tr>
+<tr class="memitem:ga8c292e142110229a2980b37ab036dbc6"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6">mi_rezalloc</a> (void *p, size_t newsize)</td></tr>
+<tr class="separator:ga8c292e142110229a2980b37ab036dbc6"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gacd71a7bce96aab38ae6de17af2eb2cf0"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0">mi_rezalloc_aligned</a> (void *p, size_t newsize, size_t alignment)</td></tr>
+<tr class="separator:gacd71a7bce96aab38ae6de17af2eb2cf0"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gae8b358c417e61d5307da002702b0a8e1"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1">mi_rezalloc_aligned_at</a> (void *p, size_t newsize, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:gae8b358c417e61d5307da002702b0a8e1"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga3e7e5c291acf1c7fd7ffd9914a9f945f"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f">mi_recalloc_aligned</a> (void *p, size_t newcount, size_t size, size_t alignment)</td></tr>
+<tr class="separator:ga3e7e5c291acf1c7fd7ffd9914a9f945f"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga4ff5e92ad73585418a072c9d059e5cf9"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9">mi_recalloc_aligned_at</a> (void *p, size_t newcount, size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga4ff5e92ad73585418a072c9d059e5cf9"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gacfad83f14eb5d6a42a497a898e19fc76"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76">mi_heap_rezalloc</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize)</td></tr>
+<tr class="separator:gacfad83f14eb5d6a42a497a898e19fc76"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga8648c5fbb22a80f0262859099f06dfbd"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd">mi_heap_recalloc</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newcount, size_t size)</td></tr>
+<tr class="separator:ga8648c5fbb22a80f0262859099f06dfbd"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga375fa8a611c51905e592d5d467c49664"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664">mi_heap_rezalloc_aligned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize, size_t alignment)</td></tr>
+<tr class="separator:ga375fa8a611c51905e592d5d467c49664"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:gac90da54fa7e5d10bdc97ce0b51dce2eb"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb">mi_heap_rezalloc_aligned_at</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newsize, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:gac90da54fa7e5d10bdc97ce0b51dce2eb"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga9f3f999396c8f77ca5e80e7b40ac29e3"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3">mi_heap_recalloc_aligned</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newcount, size_t size, size_t alignment)</td></tr>
+<tr class="separator:ga9f3f999396c8f77ca5e80e7b40ac29e3"><td class="memSeparator" colspan="2"> </td></tr>
+<tr class="memitem:ga496452c96f1de8c500be9fddf52edaf7"><td class="memItemLeft" align="right" valign="top">void * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7">mi_heap_recalloc_aligned_at</a> (<a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> *heap, void *p, size_t newcount, size_t size, size_t alignment, size_t offset)</td></tr>
+<tr class="separator:ga496452c96f1de8c500be9fddf52edaf7"><td class="memSeparator" colspan="2"> </td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<p>The zero-initialized re-allocations are only valid on memory that was originally allocated with zero initialization too. </p>
+<p>e.g. <code>mi_calloc</code>, <code>mi_zalloc</code>, <code>mi_zalloc_aligned</code> etc. see <a href="https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992">https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992</a> </p>
+<h2 class="groupheader">Function Documentation</h2>
+<a id="ga8648c5fbb22a80f0262859099f06dfbd"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga8648c5fbb22a80f0262859099f06dfbd">◆ </a></span>mi_heap_recalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_recalloc </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newcount</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga9f3f999396c8f77ca5e80e7b40ac29e3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga9f3f999396c8f77ca5e80e7b40ac29e3">◆ </a></span>mi_heap_recalloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_recalloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newcount</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga496452c96f1de8c500be9fddf52edaf7"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga496452c96f1de8c500be9fddf52edaf7">◆ </a></span>mi_heap_recalloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_recalloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newcount</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gacfad83f14eb5d6a42a497a898e19fc76"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gacfad83f14eb5d6a42a497a898e19fc76">◆ </a></span>mi_heap_rezalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_rezalloc </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga375fa8a611c51905e592d5d467c49664"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga375fa8a611c51905e592d5d467c49664">◆ </a></span>mi_heap_rezalloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_rezalloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gac90da54fa7e5d10bdc97ce0b51dce2eb"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gac90da54fa7e5d10bdc97ce0b51dce2eb">◆ </a></span>mi_heap_rezalloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_heap_rezalloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype"><a class="el" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a> * </td>
+ <td class="paramname"><em>heap</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga3e7e5c291acf1c7fd7ffd9914a9f945f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga3e7e5c291acf1c7fd7ffd9914a9f945f">◆ </a></span>mi_recalloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_recalloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newcount</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga4ff5e92ad73585418a072c9d059e5cf9"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga4ff5e92ad73585418a072c9d059e5cf9">◆ </a></span>mi_recalloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_recalloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newcount</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>size</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="ga8c292e142110229a2980b37ab036dbc6"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ga8c292e142110229a2980b37ab036dbc6">◆ </a></span>mi_rezalloc()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_rezalloc </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gacd71a7bce96aab38ae6de17af2eb2cf0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gacd71a7bce96aab38ae6de17af2eb2cf0">◆ </a></span>mi_rezalloc_aligned()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_rezalloc_aligned </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+<a id="gae8b358c417e61d5307da002702b0a8e1"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#gae8b358c417e61d5307da002702b0a8e1">◆ </a></span>mi_rezalloc_aligned_at()</h2>
+
+<div class="memitem">
+<div class="memproto">
+ <table class="memname">
+ <tr>
+ <td class="memname">void* mi_rezalloc_aligned_at </td>
+ <td>(</td>
+ <td class="paramtype">void * </td>
+ <td class="paramname"><em>p</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>newsize</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>alignment</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">size_t </td>
+ <td class="paramname"><em>offset</em> </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>)</td>
+ <td></td><td></td>
+ </tr>
+ </table>
+</div><div class="memdoc">
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var group__zeroinit =
+[
+ [ "mi_heap_recalloc", "group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd", null ],
+ [ "mi_heap_recalloc_aligned", "group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3", null ],
+ [ "mi_heap_recalloc_aligned_at", "group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7", null ],
+ [ "mi_heap_rezalloc", "group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76", null ],
+ [ "mi_heap_rezalloc_aligned", "group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664", null ],
+ [ "mi_heap_rezalloc_aligned_at", "group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb", null ],
+ [ "mi_recalloc_aligned", "group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f", null ],
+ [ "mi_recalloc_aligned_at", "group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9", null ],
+ [ "mi_rezalloc", "group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6", null ],
+ [ "mi_rezalloc_aligned", "group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0", null ],
+ [ "mi_rezalloc_aligned_at", "group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1", null ]
+];
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Main Page</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('index.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="PageDoc"><div class="header">
+ <div class="headertitle">
+<div class="title">mi-malloc Documentation</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>This is the API documentation of the <a href="https://github.com/microsoft/mimalloc">mimalloc</a> allocator (pronounced "me-malloc") – a general purpose allocator with excellent <a href="bench.html">performance</a> characteristics. Initially developed by Daan Leijen for the run-time systems of the <a href="https://github.com/koka-lang/koka">Koka</a> and <a href="https://github.com/leanprover/lean">Lean</a> languages.</p>
+<p>It is a drop-in replacement for <code>malloc</code> and can be used in other programs without code changes, for example, on Unix you can use it as: </p><div class="fragment"><div class="line">> LD_PRELOAD=/usr/bin/libmimalloc.so myprogram</div>
+</div><!-- fragment --><p>Notable aspects of the design include:</p>
+<ul>
+<li><b>small and consistent</b>: the library is about 8k LOC using simple and consistent data structures. This makes it very suitable to integrate and adapt in other projects. For runtime systems it provides hooks for a monotonic <em>heartbeat</em> and deferred freeing (for bounded worst-case times with reference counting).</li>
+<li><b>free list sharding</b>: instead of one big free list (per size class) we have many smaller lists per "mimalloc page" which reduces fragmentation and increases locality – things that are allocated close in time get allocated close in memory. (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system).</li>
+<li><b>free list multi-sharding</b>: the big idea! Not only do we shard the free list per mimalloc page, but for each page we have multiple free lists. In particular, there is one list for thread-local <code>free</code> operations, and another one for concurrent <code>free</code> operations. Free-ing from another thread can now be a single CAS without needing sophisticated coordination between threads. Since there will be thousands of separate free lists, contention is naturally distributed over the heap, and the chance of contending on a single location will be low – this is quite similar to randomized algorithms like skip lists where adding a random oracle removes the need for a more complex algorithm.</li>
+<li><b>eager page reset</b>: when a "page" becomes empty (with increased chance due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged") reducing (real) memory pressure and fragmentation, especially in long running programs.</li>
+<li><b>secure</b>: <em>mimalloc</em> can be build in secure mode, adding guard pages, randomized allocation, encrypted free lists, etc. to protect against various heap vulnerabilities. The performance penalty is only around 5% on average over our benchmarks.</li>
+<li><b>first-class heaps</b>: efficiently create and use multiple heaps to allocate across different regions. A heap can be destroyed at once instead of deallocating each object separately.</li>
+<li><b>bounded</b>: it does not suffer from <em>blowup</em> [1], has bounded worst-case allocation times (<em>wcat</em>), bounded space overhead (~0.2% meta-data, with at most 12.5% waste in allocation sizes), and has no internal points of contention using only atomic operations.</li>
+<li><b>fast</b>: In our benchmarks (see <a href="#performance">below</a>), <em>mimalloc</em> outperforms all other leading allocators (<em>jemalloc</em>, <em>tcmalloc</em>, <em>Hoard</em>, etc), and usually uses less memory (up to 25% more in the worst case). A nice property is that it does consistently well over a wide range of benchmarks.</li>
+</ul>
+<p>You can read more on the design of <em>mimalloc</em> in the <a href="https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action">technical report</a> which also has detailed benchmark results.</p>
+<p>Further information:</p>
+<ul>
+<li><a class="el" href="build.html">Building</a></li>
+<li><a class="el" href="using.html">Using the library</a></li>
+<li><a class="el" href="environment.html">Environment Options</a></li>
+<li><a class="el" href="overrides.html">Overriding Malloc</a></li>
+<li><a class="el" href="bench.html">Performance</a></li>
+<li><a class="el" href="group__malloc.html">Basic Allocation</a></li>
+<li><a class="el" href="group__extended.html">Extended Functions</a></li>
+<li><a class="el" href="group__aligned.html">Aligned Allocation</a></li>
+<li><a class="el" href="group__heap.html">Heap Allocation</a></li>
+<li><a class="el" href="group__typed.html">Typed Macros</a></li>
+<li><a class="el" href="group__analysis.html">Heap Introspection</a></li>
+<li><a class="el" href="group__options.html">Runtime Options</a></li>
+<li><a class="el" href="group__posix.html">Posix</a></li>
+<li><a class="el" href="group__cpp.html">C++ wrappers</a> </li>
+</ul>
+</div></div><!-- PageDoc -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[k]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[S,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[k]&&(v=Ce(v)),y&&!y[k]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[k]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=N[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[k]?i.push(a):o.push(a);(a=N(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=S+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t===C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument===C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(S=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=k.split("").sort(D).join("")===k,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;var T=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=k.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&N.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!N.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return"undefined"!=typeof e.contentDocument?e.contentDocument:(A(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var R=/[^\x20\t\r\n\f]+/g;function M(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(R)||[],function(e,t){n[t]=!0}),n):k.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){k.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return k.each(arguments,function(e,t){var n;while(-1<(n=k.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<k.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return k.Deferred(function(r){k.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,M,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,M,s),l(u,o,I,s),l(u,o,M,o.notifyWith))):(a!==M&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:M,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:M)),o[2][3].add(l(0,e,m(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=k.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(W(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)W(i[t],a(t),o.reject);return o.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var F=k.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),k.ready()}k.fn.ready=function(e){return F.then(e)["catch"](function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||F.resolveWith(E,[k])}}),k.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(k(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,U=/-([a-z])/g;function X(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(U,X)}var G=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(R)||[]).length;while(n--)delete r[t[n]]}(void 0===t||k.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=J.get(o,n))?t:void 0!==(t=ee(o,n))?t:void 0;this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=k.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Q.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var te=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ne=new RegExp("^(?:([+-])=|)("+te+")([a-z%]*)$","i"),re=["Top","Right","Bottom","Left"],ie=E.documentElement,oe=function(e){return k.contains(e.ownerDocument,e)},ae={composed:!0};ie.getRootNode&&(oe=function(e){return k.contains(e.ownerDocument,e)||e.getRootNode(ae)===e.ownerDocument});var se=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&oe(e)&&"none"===k.css(e,"display")},ue=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i};function le(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=e.nodeType&&(k.cssNumber[t]||"px"!==l&&+u)&&ne.exec(k.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ce={};function fe(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&se(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ce[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ce[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){se(this)?k(this).show():k(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;var me,xe,be=/<|&#?\w+;/;function we(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))k.merge(p,o.nodeType?[o]:o);else if(be.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;k.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<k.inArray(o,r))i&&i.push(o);else if(l=oe(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}me=E.createDocumentFragment().appendChild(E.createElement("div")),(xe=E.createElement("input")).setAttribute("type","radio"),xe.setAttribute("checked","checked"),xe.setAttribute("name","t"),me.appendChild(xe),y.checkClone=me.cloneNode(!0).cloneNode(!0).lastChild.checked,me.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){a=k.event.handlers.call(this,s,l),t=0;while((i=a[t++])&&!s.isPropagationStopped()){s.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!s.isImmediatePropagationStopped())s.rnamespace&&!1!==o.namespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<k(i,this).index(l):k.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(k.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click",ke),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Q.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?ke:Se,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Se,isPropagationStopped:Se,isImmediatePropagationStopped:Se,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=ke,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=ke,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=ke,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Te.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ce.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({focus:"focusin",blur:"focusout"},function(e,t){k.event.special[e]={setup:function(){return De(this,e,Ne),!1},trigger:function(){return De(this,e),!0},delegateType:t}}),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Ae(this,e,t,n,r)},one:function(e,t,n,r){return Ae(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Se),this.each(function(){k.event.remove(this,e,n,t)})}});var je=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/<script|<style|<link/i,Le=/checked\s*(?:[^=]|=\s*.checked.)/i,He=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Ie(n,r,i,o){r=g.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Le.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Ie(t,r,i,o)});if(f&&(t=(e=we(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(ve(e,"script"),Pe)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,Re),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&!u.noModule&&k._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")}):b(u.textContent.replace(He,""),u,l))}return n}function We(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(ve(r)),r.parentNode&&(n&&oe(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(je,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Me(o[r],a[r]);else Me(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Oe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!qe.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Ie(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var $e=new RegExp("^("+te+")(?!px)[a-z%]+$","i"),Fe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Be=new RegExp(re.join("|"),"i");function _e(e,t,n){var r,i,o,a,s=e.style;return(n=n||Fe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||oe(e)||(a=k.style(e,t)),!y.pixelBoxStyles()&&$e.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function ze(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(u){s.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",u.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",ie.appendChild(s).appendChild(u);var e=C.getComputedStyle(u);n="1%"!==e.top,a=12===t(e.marginLeft),u.style.right="60%",o=36===t(e.right),r=36===t(e.width),u.style.position="absolute",i=12===t(u.offsetWidth/3),ie.removeChild(s),u=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s=E.createElement("div"),u=E.createElement("div");u.style&&(u.style.backgroundClip="content-box",u.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===u.style.backgroundClip,k.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),a},scrollboxSize:function(){return e(),i}}))}();var Ue=["Webkit","Moz","ms"],Xe=E.createElement("div").style,Ve={};function Ge(e){var t=k.cssProps[e]||Ve[e];return t||(e in Xe?e:Ve[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Ue.length;while(n--)if((e=Ue[n]+t)in Xe)return e}(e)||e)}var Ye=/^(none|table(?!-c[ea]).+)/,Qe=/^--/,Je={position:"absolute",visibility:"hidden",display:"block"},Ke={letterSpacing:"0",fontWeight:"400"};function Ze(e,t,n){var r=ne.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function et(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=k.css(e,n+re[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+re[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+re[a]+"Width",!0,i))):(u+=k.css(e,"padding"+re[a],!0,i),"padding"!==n?u+=k.css(e,"border"+re[a]+"Width",!0,i):s+=k.css(e,"border"+re[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function tt(e,t,n){var r=Fe(e),i=(!y.boxSizingReliable()||n)&&"border-box"===k.css(e,"boxSizing",!1,r),o=i,a=_e(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if($e.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||"auto"===a||!parseFloat(a)&&"inline"===k.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===k.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+et(e,t,n||(i?"border":"content"),o,r,a)+"px"}function nt(e,t,n,r,i){return new nt.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=_e(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Qe.test(t),l=e.style;if(u||(t=Ge(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=ne.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Qe.test(t)||(t=Ge(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=_e(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,u){k.cssHooks[u]={get:function(e,t,n){if(t)return!Ye.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?tt(e,u,n):ue(e,Je,function(){return tt(e,u,n)})},set:function(e,t,n){var r,i=Fe(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===k.css(e,"boxSizing",!1,i),s=n?et(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-et(e,u,"border",!1,i)-.5)),s&&(r=ne.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=k.css(e,u)),Ze(0,t,s)}}}),k.cssHooks.marginLeft=ze(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(_e(e,"marginLeft"))||e.getBoundingClientRect().left-ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+re[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=Ze)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Fe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),((k.Tween=nt).prototype={constructor:nt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=nt.propHooks[this.prop];return e&&e.get?e.get(this):nt.propHooks._default.get(this)},run:function(e){var t,n=nt.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):nt.propHooks._default.set(this),this}}).init.prototype=nt.prototype,(nt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||!k.cssHooks[e.prop]&&null==e.elem.style[Ge(e.prop)]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=nt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=nt.prototype.init,k.fx.step={};var rt,it,ot,at,st=/^(?:toggle|show|hide)$/,ut=/queueHooks$/;function lt(){it&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(lt):C.setTimeout(lt,k.fx.interval),k.fx.tick())}function ct(){return C.setTimeout(function(){rt=void 0}),rt=Date.now()}function ft(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=re[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function pt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function dt(o,e,t){var n,a,r=0,i=dt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=rt||ct(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:rt||ct(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=dt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,pt,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(dt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return le(n.elem,e,ne.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(R);for(var n,r=0,i=e.length;r<i;r++)n=e[r],dt.tweeners[n]=dt.tweeners[n]||[],dt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&se(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],st.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=k.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&fe([e],!0),p.done(function(){for(r in g||fe([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=pt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?dt.prefilters.unshift(e):dt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(se).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=k.isEmptyObject(t),o=k.speed(e,n,r),a=function(){var e=dt(this,k.extend({},t),o);(i||Q.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&ut.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(ft(r,!0),e,t,n)}}),k.each({slideDown:ft("show"),slideUp:ft("hide"),slideToggle:ft("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(rt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),rt=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){it||(it=!0,lt())},k.fx.stop=function(){it=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},ot=E.createElement("input"),at=E.createElement("select").appendChild(E.createElement("option")),ot.type="checkbox",y.checkOn=""!==ot.value,y.optSelected=at.selected,(ot=E.createElement("input")).value="t",ot.type="radio",y.radioValue="t"===ot.value;var ht,gt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(R);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=gt[t]||k.find.attr;gt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=gt[o],gt[o]=r,r=null!=a(e,t,n)?o:null,gt[o]=i),r}});var vt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;function mt(e){return(e.match(R)||[]).join(" ")}function xt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(R)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):vt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).addClass(t.call(this,e,xt(this)))});if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).removeClass(t.call(this,e,xt(this)))});if(!arguments.length)return this.attr("class","");if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){k(this).toggleClass(i.call(this,e,xt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=k(this),r=bt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=xt(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Q.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+mt(xt(n))+" ").indexOf(t))return!0;return!1}});var wt=/\r/g;k.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(wt,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:mt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=k(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=k.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},y.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var Tt=/^(?:focusinfocus|focusoutblur)$/,Ct=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!Tt.test(d+k.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[k.expando]?e:new k.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:k.makeArray(t,[e]),c=k.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,Tt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Q.get(o,"events")||{})[e.type]&&Q.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&G(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!G(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),k.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Ct),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Ct),k.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),y.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){k.event.simulate(r,e.target,k.event.fix(e))};k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var Et=C.location,kt=Date.now(),St=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Nt=/\[\]$/,At=/\r?\n/g,Dt=/^(?:submit|button|image|reset|file)$/i,jt=/^(?:input|select|textarea|keygen)/i;function qt(n,e,r,i){var t;if(Array.isArray(e))k.each(e,function(e,t){r||Nt.test(n)?i(n,t):qt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)qt(n+"["+t+"]",e[t],r,i)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)qt(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&jt.test(this.nodeName)&&!Dt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(At,"\r\n")}}):{name:t.name,value:n.replace(At,"\r\n")}}).get()}});var Lt=/%20/g,Ht=/#.*$/,Ot=/([?&])_=[^&]*/,Pt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Rt=/^(?:GET|HEAD)$/,Mt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Ft=E.createElement("a");function Bt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(R)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function _t(t,i,o,a){var s={},u=t===Wt;function l(e){var r;return s[e]=!0,k.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}Ft.href=Et.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,k.ajaxSettings),t):zt(k.ajaxSettings,e)},ajaxPrefilter:Bt(It),ajaxTransport:Bt(Wt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Pt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+"").replace(Mt,Et.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(R)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Ft.protocol+"//"+Ft.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),_t(It,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Rt.test(v.type),f=v.url.replace(Ht,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Lt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(St.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Ot,"$1"),o=(St.test(f)?"&":"?")+"_="+kt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+$t+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=_t(Wt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e,t){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){k.globalEval(e,t)}})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Xt=k.ajaxSettings.xhr();y.cors=!!Xt&&"withCredentials"in Xt,y.ajax=Xt=!!Xt,k.ajaxTransport(function(i){var o,a;if(y.cors||Xt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Ut[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=k("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=mt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),k.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=A,k.isFunction=m,k.isWindow=x,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var Qt=C.jQuery,Jt=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=Jt),e&&C.jQuery===k&&(C.jQuery=Qt),k},e||(C.jQuery=C.$=k),k});
+/*! jQuery UI - v1.12.1 - 2019-01-27
+* http://jqueryui.com
+* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/resizable.js, widgets/mouse.js
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}t.ui=t.ui||{},t.ui.version="1.12.1";var i=0,s=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,n,o=s.call(arguments,1),a=0,r=o.length;r>a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,m,g,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),x={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,m=_.offset,g=t.extend({},m),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),x[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?g.left+=p:"center"===n.at[0]&&(g.left+=p/2),"bottom"===n.at[1]?g.top+=f:"center"===n.at[1]&&(g.top+=f/2),u=e(x.at,p,f),g.left+=u[0],g.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),k=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},g),T=e(x.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=T[0],D.top+=T[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:k,collisionHeight:C,offset:[u[0]+T[0],u[1]+T[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=m.left-D.left,i=e+p-l,s=m.top-D.top,r=s+f-c,u={target:{element:v,left:m.left,top:m.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element
+},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/**
+ * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler
+ * Licensed under MIT
+ * @author Ariel Flesler
+ * @version 2.1.2
+ */
+;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1<b.axis.length;u&&(d/=2);b.offset=h(b.offset);b.over=h(b.over);return this.each(function(){function k(a){var k=$.extend({},b,{queue:!0,duration:d,complete:a&&function(){a.call(q,e,b)}});r.animate(f,k)}if(null!==a){var l=n(this),q=l?this.contentWindow||window:this,r=$(q),e=a,f={},t;switch(typeof e){case "number":case "string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(e)){e= h(e);break}e=l?$(e):$(e,q);case "object":if(e.length===0)return;if(e.is||e.style)t=(e=$(e)).offset()}var v=$.isFunction(b.offset)&&b.offset(q,e)||b.offset;$.each(b.axis.split(""),function(a,c){var d="x"===c?"Left":"Top",m=d.toLowerCase(),g="scroll"+d,h=r[g](),n=p.max(q,c);t?(f[g]=t[m]+(l?0:h-r.offset()[m]),b.margin&&(f[g]-=parseInt(e.css("margin"+d),10)||0,f[g]-=parseInt(e.css("border"+d+"Width"),10)||0),f[g]+=v[m]||0,b.over[m]&&(f[g]+=e["x"===c?"width":"height"]()*b.over[m])):(d=e[m],f[g]=d.slice&& "%"===d.slice(-1)?parseFloat(d)/100*n:d);b.limit&&/^\d+$/.test(f[g])&&(f[g]=0>=f[g]?0:Math.min(f[g],n));!a&&1<b.axis.length&&(h===f[g]?f={}:u&&(k(b.onAfterFirst),f={}))});k(b.onAfter)}})};p.max=function(a,d){var b="x"===d?"Width":"Height",h="scroll"+b;if(!n(a))return a[h]-$(a)[b.toLowerCase()]();var b="client"+b,k=a.ownerDocument||a.document,l=k.documentElement,k=k.body;return Math.max(l[h],k[h])-Math.min(l[b],k[b])};$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(a){return $(a.elem)[a.prop]()}, set:function(a){var d=this.get(a);if(a.options.interrupt&&a._last&&a._last!==d)return $(a.elem).stop();var b=Math.round(a.now);d!==b&&($(a.elem)[a.prop](b),a._last=this.get(a))}};return p});
+/*!
+ PowerTip v1.3.1 (2018-04-15)
+ https://stevenbenner.github.io/jquery-powertip/
+ Copyright (c) 2018 Steven Benner (http://stevenbenner.com/).
+ Released under MIT license.
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
+*/
+(function(root,factory){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else if(typeof module==="object"&&module.exports){module.exports=factory(require("jquery"))}else{factory(root.jQuery)}})(this,function($){var $document=$(document),$window=$(window),$body=$("body");var DATA_DISPLAYCONTROLLER="displayController",DATA_HASACTIVEHOVER="hasActiveHover",DATA_FORCEDOPEN="forcedOpen",DATA_HASMOUSEMOVE="hasMouseMove",DATA_MOUSEONTOTIP="mouseOnToPopup",DATA_ORIGINALTITLE="originalTitle",DATA_POWERTIP="powertip",DATA_POWERTIPJQ="powertipjq",DATA_POWERTIPTARGET="powertiptarget",EVENT_NAMESPACE=".powertip",RAD2DEG=180/Math.PI,MOUSE_EVENTS=["click","dblclick","mousedown","mouseup","mousemove","mouseover","mouseout","mouseenter","mouseleave","contextmenu"];var session={tooltips:null,isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,closeDelayTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var Collision={none:0,top:1,bottom:2,left:4,right:8};$.fn.powerTip=function(opts,arg){var targetElements=this,options,tipController;if(!targetElements.length){return targetElements}if($.type(opts)==="string"&&$.powerTip[opts]){return $.powerTip[opts].call(targetElements,targetElements,arg)}options=$.extend({},$.fn.powerTip.defaults,opts);tipController=new TooltipController(options);initTracking();targetElements.each(function elementSetup(){var $this=$(this),dataPowertip=$this.data(DATA_POWERTIP),dataElem=$this.data(DATA_POWERTIPJQ),dataTarget=$this.data(DATA_POWERTIPTARGET),title=$this.attr("title");if(!dataPowertip&&!dataTarget&&!dataElem&&title){$this.data(DATA_POWERTIP,title);$this.data(DATA_ORIGINALTITLE,title);$this.removeAttr("title")}$this.data(DATA_DISPLAYCONTROLLER,new DisplayController($this,options,tipController))});if(!options.manual){$.each(options.openEvents,function(idx,evt){if($.inArray(evt,options.closeEvents)>-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference<options.intentSensitivity){cancelClose();closeAnyDelayed();tipController.showTip(element)}else{session.previousX=session.currentX;session.previousY=session.currentY;openTooltip()}}function cancelTimer(stopClose){hoverTimer=clearTimeout(hoverTimer);if(session.closeDelayTimeout&&myCloseDelay===session.closeDelayTimeout||stopClose){cancelClose()}}function cancelClose(){session.closeDelayTimeout=clearTimeout(session.closeDelayTimeout);session.delayInProgress=false}function closeAnyDelayed(){if(session.delayInProgress&&session.activeHover&&!session.activeHover.is(element)){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide(true)}}function repositionTooltip(){tipController.resetPosition(element)}this.show=openTooltip;this.hide=closeTooltip;this.cancel=cancelTimer;this.resetPosition=repositionTooltip}function PlacementCalculator(){function computePlacementCoords(element,placement,tipWidth,tipHeight,offset){var placementBase=placement.split("-")[0],coords=new CSSCoordinates,position;if(isSvgElement(element)){position=getSvgPlacement(element,placementBase)}else{position=getHtmlPlacement(element,placementBase)}switch(placement){case"n":coords.set("left",position.left-tipWidth/2);coords.set("bottom",session.windowHeight-position.top+offset);break;case"e":coords.set("left",position.left+offset);coords.set("top",position.top-tipHeight/2);break;case"s":coords.set("left",position.left-tipWidth/2);coords.set("top",position.top+offset);break;case"w":coords.set("top",position.top-tipHeight/2);coords.set("right",session.windowWidth-position.left+offset);break;case"nw":coords.set("bottom",session.windowHeight-position.top+offset);coords.set("right",session.windowWidth-position.left-20);break;case"nw-alt":coords.set("left",position.left);coords.set("bottom",session.windowHeight-position.top+offset);break;case"ne":coords.set("left",position.left-20);coords.set("bottom",session.windowHeight-position.top+offset);break;case"ne-alt":coords.set("bottom",session.windowHeight-position.top+offset);coords.set("right",session.windowWidth-position.left);break;case"sw":coords.set("top",position.top+offset);coords.set("right",session.windowWidth-position.left-20);break;case"sw-alt":coords.set("left",position.left);coords.set("top",position.top+offset);break;case"se":coords.set("left",position.left-20);coords.set("top",position.top+offset);break;case"se-alt":coords.set("top",position.top+offset);coords.set("right",session.windowWidth-position.left);break}return coords}function getHtmlPlacement(element,placement){var objectOffset=element.offset(),objectWidth=element.outerWidth(),objectHeight=element.outerHeight(),left,top;switch(placement){case"n":left=objectOffset.left+objectWidth/2;top=objectOffset.top;break;case"e":left=objectOffset.left+objectWidth;top=objectOffset.top+objectHeight/2;break;case"s":left=objectOffset.left+objectWidth/2;top=objectOffset.top+objectHeight;break;case"w":left=objectOffset.left;top=objectOffset.top+objectHeight/2;break;case"nw":left=objectOffset.left;top=objectOffset.top;break;case"ne":left=objectOffset.left+objectWidth;top=objectOffset.top;break;case"sw":left=objectOffset.left;top=objectOffset.top+objectHeight;break;case"se":left=objectOffset.left+objectWidth;top=objectOffset.top+objectHeight;break}return{top:top,left:left}}function getSvgPlacement(element,placement){var svgElement=element.closest("svg")[0],domElement=element[0],point=svgElement.createSVGPoint(),boundingBox=domElement.getBBox(),matrix=domElement.getScreenCTM(),halfWidth=boundingBox.width/2,halfHeight=boundingBox.height/2,placements=[],placementKeys=["nw","n","ne","e","se","s","sw","w"],coords,rotation,steps,x;function pushPlacement(){placements.push(point.matrixTransform(matrix))}point.x=boundingBox.x;point.y=boundingBox.y;pushPlacement();point.x+=halfWidth;pushPlacement();point.x+=halfWidth;pushPlacement();point.y+=halfHeight;pushPlacement();point.y+=halfHeight;pushPlacement();point.x-=halfWidth;pushPlacement();point.x-=halfWidth;pushPlacement();point.y-=halfHeight;pushPlacement();if(placements[0].y!==placements[1].y||placements[0].x!==placements[7].x){rotation=Math.atan2(matrix.b,matrix.a)*RAD2DEG;steps=Math.ceil((rotation%360-22.5)/45);if(steps<1){steps+=8}while(steps--){placementKeys.push(placementKeys.shift())}}for(x=0;x<placements.length;x++){if(placementKeys[x]===placement){coords=placements[x];break}}return{top:coords.y+session.scrollTop,left:coords.x+session.scrollLeft}}this.compute=computePlacementCoords}function TooltipController(options){var placementCalculator=new PlacementCalculator,tipElement=$("#"+options.popupId);if(tipElement.length===0){tipElement=$("<div/>",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.top<viewportTop||Math.abs(coords.bottom-session.windowHeight)-elementHeight<viewportTop){collisions|=Collision.top}if(coords.top+elementHeight>viewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.left<viewportLeft||coords.right+elementWidth>viewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right<viewportLeft){collisions|=Collision.right}return collisions}function countFlags(value){var count=0;while(value){value&=value-1;count++}return count}return $.powerTip});/*!
+ * jQuery UI Touch Punch 0.2.3
+ *
+ * Copyright 2011–2014, Dave Furfero
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ * jquery.ui.mouse.js
+ */
+!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017
+ * http://www.smartmenus.org/
+ * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("<span/>").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('<div class="sm-jquery-disable-overlay"/>').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0],$('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y<o.upEnd)&&a.eq(o.up?1:0).show(),o.y==n)mouse&&a.eq(o.up?0:1).hide(),this.menuScrollStop(t);else if(!e){this.opts.scrollAccelerate&&o.step<this.opts.scrollStep&&(o.step+=.2);var h=this;this.scrollTimeout=requestAnimationFrame(function(){h.menuScroll(t)})}},menuScrollMousewheel:function(t,e){if(this.getClosestMenu(e.target)==t[0]){e=e.originalEvent;var i=(e.wheelDelta||-e.detail)>0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$});
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: mimalloc-doc.h Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('mimalloc-doc_8h_source.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">mimalloc-doc.h</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> <span class="comment">/* ----------------------------------------------------------------------------</span></div>
+<div class="line"><a name="l00002"></a><span class="lineno"> 2</span> <span class="comment">Copyright (c) 2018-2021, Microsoft Research, Daan Leijen</span></div>
+<div class="line"><a name="l00003"></a><span class="lineno"> 3</span> <span class="comment">This is free software; you can redistribute it and/or modify it under the</span></div>
+<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="comment">terms of the MIT license. A copy of the license can be found in the file</span></div>
+<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> <span class="comment">"LICENSE" at the root of this distribution.</span></div>
+<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="comment">-----------------------------------------------------------------------------*/</span></div>
+<div class="line"><a name="l00007"></a><span class="lineno"> 7</span>  </div>
+<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="preprocessor">#error "documentation file only!"</span></div>
+<div class="line"><a name="l00009"></a><span class="lineno"> 9</span>  </div>
+<div class="line"><a name="l00010"></a><span class="lineno"> 10</span>  </div>
+<div class="line"><a name="l00094"></a><span class="lineno"> 94</span>  </div>
+<div class="line"><a name="l00095"></a><span class="lineno"> 95</span>  </div>
+<div class="line"><a name="l00099"></a><span class="lineno"><a class="line" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95"> 99</a></span> <span class="keywordtype">void</span> <a class="code" href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95">mi_free</a>(<span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00100"></a><span class="lineno"> 100</span>  </div>
+<div class="line"><a name="l00105"></a><span class="lineno"><a class="line" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a"> 105</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a">mi_malloc</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00106"></a><span class="lineno"> 106</span>  </div>
+<div class="line"><a name="l00111"></a><span class="lineno"><a class="line" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000"> 111</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000">mi_zalloc</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00112"></a><span class="lineno"> 112</span>  </div>
+<div class="line"><a name="l00122"></a><span class="lineno"><a class="line" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d"> 122</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d">mi_calloc</a>(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00123"></a><span class="lineno"> 123</span>  </div>
+<div class="line"><a name="l00136"></a><span class="lineno"><a class="line" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6"> 136</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6">mi_realloc</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00137"></a><span class="lineno"> 137</span>  </div>
+<div class="line"><a name="l00148"></a><span class="lineno"><a class="line" href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc"> 148</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">mi_recalloc</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00149"></a><span class="lineno"> 149</span>  </div>
+<div class="line"><a name="l00163"></a><span class="lineno"><a class="line" href="group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4"> 163</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4">mi_expand</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00164"></a><span class="lineno"> 164</span>  </div>
+<div class="line"><a name="l00174"></a><span class="lineno"><a class="line" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6"> 174</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6">mi_mallocn</a>(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00175"></a><span class="lineno"> 175</span>  </div>
+<div class="line"><a name="l00185"></a><span class="lineno"><a class="line" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853"> 185</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853">mi_reallocn</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00186"></a><span class="lineno"> 186</span>  </div>
+<div class="line"><a name="l00203"></a><span class="lineno"><a class="line" href="group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0"> 203</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0">mi_reallocf</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00204"></a><span class="lineno"> 204</span>  </div>
+<div class="line"><a name="l00205"></a><span class="lineno"> 205</span>  </div>
+<div class="line"><a name="l00214"></a><span class="lineno"><a class="line" href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2"> 214</a></span> <span class="keywordtype">char</span>* <a class="code" href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2">mi_strdup</a>(<span class="keyword">const</span> <span class="keywordtype">char</span>* s);</div>
+<div class="line"><a name="l00215"></a><span class="lineno"> 215</span>  </div>
+<div class="line"><a name="l00225"></a><span class="lineno"><a class="line" href="group__malloc.html#gaaabf971c2571891433477e2d21a35266"> 225</a></span> <span class="keywordtype">char</span>* <a class="code" href="group__malloc.html#gaaabf971c2571891433477e2d21a35266">mi_strndup</a>(<span class="keyword">const</span> <span class="keywordtype">char</span>* s, <span class="keywordtype">size_t</span> n);</div>
+<div class="line"><a name="l00226"></a><span class="lineno"> 226</span>  </div>
+<div class="line"><a name="l00239"></a><span class="lineno"><a class="line" href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe"> 239</a></span> <span class="keywordtype">char</span>* <a class="code" href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe">mi_realpath</a>(<span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">char</span>* resolved_name);</div>
+<div class="line"><a name="l00240"></a><span class="lineno"> 240</span>  </div>
+<div class="line"><a name="l00242"></a><span class="lineno"> 242</span>  </div>
+<div class="line"><a name="l00243"></a><span class="lineno"> 243</span> <span class="comment">// ------------------------------------------------------</span></div>
+<div class="line"><a name="l00244"></a><span class="lineno"> 244</span> <span class="comment">// Extended functionality</span></div>
+<div class="line"><a name="l00245"></a><span class="lineno"> 245</span> <span class="comment">// ------------------------------------------------------</span></div>
+<div class="line"><a name="l00246"></a><span class="lineno"> 246</span>  </div>
+<div class="line"><a name="l00250"></a><span class="lineno"> 250</span>  </div>
+<div class="line"><a name="l00253"></a><span class="lineno"><a class="line" href="group__extended.html#ga1ea64283508718d9d645c38efc2f4305"> 253</a></span> <span class="preprocessor">#define MI_SMALL_SIZE_MAX (128*sizeof(void*))</span></div>
+<div class="line"><a name="l00254"></a><span class="lineno"> 254</span>  </div>
+<div class="line"><a name="l00262"></a><span class="lineno"><a class="line" href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99"> 262</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99">mi_malloc_small</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00263"></a><span class="lineno"> 263</span>  </div>
+<div class="line"><a name="l00271"></a><span class="lineno"><a class="line" href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152"> 271</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152">mi_zalloc_small</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00272"></a><span class="lineno"> 272</span>  </div>
+<div class="line"><a name="l00287"></a><span class="lineno"><a class="line" href="group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee"> 287</a></span> <span class="keywordtype">size_t</span> <a class="code" href="group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee">mi_usable_size</a>(<span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00288"></a><span class="lineno"> 288</span>  </div>
+<div class="line"><a name="l00298"></a><span class="lineno"><a class="line" href="group__extended.html#gac057927cd06c854b45fe7847e921bd47"> 298</a></span> <span class="keywordtype">size_t</span> <a class="code" href="group__extended.html#gac057927cd06c854b45fe7847e921bd47">mi_good_size</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00299"></a><span class="lineno"> 299</span>  </div>
+<div class="line"><a name="l00307"></a><span class="lineno"><a class="line" href="group__extended.html#ga421430e2226d7d468529cec457396756"> 307</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga421430e2226d7d468529cec457396756">mi_collect</a>(<span class="keywordtype">bool</span> force);</div>
+<div class="line"><a name="l00308"></a><span class="lineno"> 308</span>  </div>
+<div class="line"><a name="l00313"></a><span class="lineno"><a class="line" href="group__extended.html#ga2d126e5c62d3badc35445e5d84166df2"> 313</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga2d126e5c62d3badc35445e5d84166df2">mi_stats_print</a>(<span class="keywordtype">void</span>* out);</div>
+<div class="line"><a name="l00314"></a><span class="lineno"> 314</span>  </div>
+<div class="line"><a name="l00320"></a><span class="lineno"><a class="line" href="group__extended.html#ga537f13b299ddf801e49a5a94fde02c79"> 320</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga537f13b299ddf801e49a5a94fde02c79">mi_stats_print_out</a>(<a class="code" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a>* out, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00321"></a><span class="lineno"> 321</span>  </div>
+<div class="line"><a name="l00323"></a><span class="lineno"><a class="line" href="group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99"> 323</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99">mi_stats_reset</a>(<span class="keywordtype">void</span>);</div>
+<div class="line"><a name="l00324"></a><span class="lineno"> 324</span>  </div>
+<div class="line"><a name="l00326"></a><span class="lineno"><a class="line" href="group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1"> 326</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1">mi_stats_merge</a>(<span class="keywordtype">void</span>);</div>
+<div class="line"><a name="l00327"></a><span class="lineno"> 327</span>  </div>
+<div class="line"><a name="l00331"></a><span class="lineno"><a class="line" href="group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17"> 331</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17">mi_thread_init</a>(<span class="keywordtype">void</span>);</div>
+<div class="line"><a name="l00332"></a><span class="lineno"> 332</span>  </div>
+<div class="line"><a name="l00337"></a><span class="lineno"><a class="line" href="group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf"> 337</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf">mi_thread_done</a>(<span class="keywordtype">void</span>);</div>
+<div class="line"><a name="l00338"></a><span class="lineno"> 338</span>  </div>
+<div class="line"><a name="l00344"></a><span class="lineno"><a class="line" href="group__extended.html#gab1dac8476c46cb9eecab767eb40c1525"> 344</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#gab1dac8476c46cb9eecab767eb40c1525">mi_thread_stats_print_out</a>(<a class="code" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a>* out, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00345"></a><span class="lineno"> 345</span>  </div>
+<div class="line"><a name="l00352"></a><span class="lineno"><a class="line" href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be"> 352</a></span> <span class="keyword">typedef</span> void (<a class="code" href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">mi_deferred_free_fun</a>)(<span class="keywordtype">bool</span> force, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> heartbeat, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00353"></a><span class="lineno"> 353</span>  </div>
+<div class="line"><a name="l00369"></a><span class="lineno"><a class="line" href="group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece"> 369</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece">mi_register_deferred_free</a>(<a class="code" href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">mi_deferred_free_fun</a>* deferred_free, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00370"></a><span class="lineno"> 370</span>  </div>
+<div class="line"><a name="l00376"></a><span class="lineno"><a class="line" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c"> 376</a></span> <span class="keyword">typedef</span> void (<a class="code" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a>)(<span class="keyword">const</span> <span class="keywordtype">char</span>* msg, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00377"></a><span class="lineno"> 377</span>  </div>
+<div class="line"><a name="l00384"></a><span class="lineno"><a class="line" href="group__extended.html#gae5b17ff027cd2150b43a33040250cf3f"> 384</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#gae5b17ff027cd2150b43a33040250cf3f">mi_register_output</a>(<a class="code" href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a>* out, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00385"></a><span class="lineno"> 385</span>  </div>
+<div class="line"><a name="l00391"></a><span class="lineno"><a class="line" href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5"> 391</a></span> <span class="keyword">typedef</span> void (<a class="code" href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">mi_error_fun</a>)(<span class="keywordtype">int</span> err, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00392"></a><span class="lineno"> 392</span>  </div>
+<div class="line"><a name="l00408"></a><span class="lineno"><a class="line" href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45"> 408</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45">mi_register_error</a>(<a class="code" href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">mi_error_fun</a>* errfun, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00409"></a><span class="lineno"> 409</span>  </div>
+<div class="line"><a name="l00414"></a><span class="lineno"><a class="line" href="group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6"> 414</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6">mi_is_in_heap_region</a>(<span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00415"></a><span class="lineno"> 415</span>  </div>
+<div class="line"><a name="l00424"></a><span class="lineno"><a class="line" href="group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767"> 424</a></span> <span class="keywordtype">int</span> <a class="code" href="group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767">mi_reserve_os_memory</a>(<span class="keywordtype">size_t</span> size, <span class="keywordtype">bool</span> commit, <span class="keywordtype">bool</span> allow_large);</div>
+<div class="line"><a name="l00425"></a><span class="lineno"> 425</span>  </div>
+<div class="line"><a name="l00437"></a><span class="lineno"><a class="line" href="group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf"> 437</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf">mi_manage_os_memory</a>(<span class="keywordtype">void</span>* start, <span class="keywordtype">size_t</span> size, <span class="keywordtype">bool</span> is_committed, <span class="keywordtype">bool</span> is_large, <span class="keywordtype">bool</span> is_zero, <span class="keywordtype">int</span> numa_node);</div>
+<div class="line"><a name="l00438"></a><span class="lineno"> 438</span>  </div>
+<div class="line"><a name="l00451"></a><span class="lineno"><a class="line" href="group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50"> 451</a></span> <span class="keywordtype">int</span> <a class="code" href="group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50">mi_reserve_huge_os_pages_interleave</a>(<span class="keywordtype">size_t</span> pages, <span class="keywordtype">size_t</span> numa_nodes, <span class="keywordtype">size_t</span> timeout_msecs);</div>
+<div class="line"><a name="l00452"></a><span class="lineno"> 452</span>  </div>
+<div class="line"><a name="l00465"></a><span class="lineno"><a class="line" href="group__extended.html#ga7795a13d20087447281858d2c771cca1"> 465</a></span> <span class="keywordtype">int</span> <a class="code" href="group__extended.html#ga7795a13d20087447281858d2c771cca1">mi_reserve_huge_os_pages_at</a>(<span class="keywordtype">size_t</span> pages, <span class="keywordtype">int</span> numa_node, <span class="keywordtype">size_t</span> timeout_msecs);</div>
+<div class="line"><a name="l00466"></a><span class="lineno"> 466</span>  </div>
+<div class="line"><a name="l00467"></a><span class="lineno"> 467</span>  </div>
+<div class="line"><a name="l00472"></a><span class="lineno"><a class="line" href="group__extended.html#gaad25050b19f30cd79397b227e0157a3f"> 472</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__extended.html#gaad25050b19f30cd79397b227e0157a3f">mi_is_redirected</a>();</div>
+<div class="line"><a name="l00473"></a><span class="lineno"> 473</span>  </div>
+<div class="line"><a name="l00487"></a><span class="lineno"><a class="line" href="group__extended.html#ga7d862c2affd5790381da14eb102a364d"> 487</a></span> <span class="keywordtype">void</span> <a class="code" href="group__extended.html#ga7d862c2affd5790381da14eb102a364d">mi_process_info</a>(<span class="keywordtype">size_t</span>* elapsed_msecs, <span class="keywordtype">size_t</span>* user_msecs, <span class="keywordtype">size_t</span>* system_msecs, <span class="keywordtype">size_t</span>* current_rss, <span class="keywordtype">size_t</span>* peak_rss, <span class="keywordtype">size_t</span>* current_commit, <span class="keywordtype">size_t</span>* peak_commit, <span class="keywordtype">size_t</span>* page_faults);</div>
+<div class="line"><a name="l00488"></a><span class="lineno"> 488</span>  </div>
+<div class="line"><a name="l00490"></a><span class="lineno"> 490</span>  </div>
+<div class="line"><a name="l00491"></a><span class="lineno"> 491</span> <span class="comment">// ------------------------------------------------------</span></div>
+<div class="line"><a name="l00492"></a><span class="lineno"> 492</span> <span class="comment">// Aligned allocation</span></div>
+<div class="line"><a name="l00493"></a><span class="lineno"> 493</span> <span class="comment">// ------------------------------------------------------</span></div>
+<div class="line"><a name="l00494"></a><span class="lineno"> 494</span>  </div>
+<div class="line"><a name="l00500"></a><span class="lineno"> 500</span>  </div>
+<div class="line"><a name="l00502"></a><span class="lineno"><a class="line" href="group__aligned.html#ga83c03016066b438f51a8095e9140be06"> 502</a></span> <span class="preprocessor">#define MI_ALIGNMENT_MAX (1024*1024UL) </span></div>
+<div class="line"><a name="l00503"></a><span class="lineno"> 503</span>  </div>
+<div class="line"><a name="l00516"></a><span class="lineno"><a class="line" href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56"> 516</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56">mi_malloc_aligned</a>(<span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00517"></a><span class="lineno"><a class="line" href="group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819"> 517</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819">mi_zalloc_aligned</a>(<span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00518"></a><span class="lineno"><a class="line" href="group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9"> 518</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9">mi_calloc_aligned</a>(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00519"></a><span class="lineno"><a class="line" href="group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae"> 519</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae">mi_realloc_aligned</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00520"></a><span class="lineno"> 520</span>  </div>
+<div class="line"><a name="l00531"></a><span class="lineno"><a class="line" href="group__aligned.html#ga5850da130c936bd77db039dcfbc8295d"> 531</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga5850da130c936bd77db039dcfbc8295d">mi_malloc_aligned_at</a>(<span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00532"></a><span class="lineno"><a class="line" href="group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8"> 532</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8">mi_zalloc_aligned_at</a>(<span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00533"></a><span class="lineno"><a class="line" href="group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3"> 533</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3">mi_calloc_aligned_at</a>(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00534"></a><span class="lineno"><a class="line" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2"> 534</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb">mi_realloc_aligned_at</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00535"></a><span class="lineno"> 535</span>  </div>
+<div class="line"><a name="l00537"></a><span class="lineno"> 537</span>  </div>
+<div class="line"><a name="l00543"></a><span class="lineno"> 543</span>  </div>
+<div class="line"><a name="l00548"></a><span class="lineno"> 548</span> <span class="keyword">struct </span>mi_heap_s;</div>
+<div class="line"><a name="l00549"></a><span class="lineno"> 549</span>  </div>
+<div class="line"><a name="l00554"></a><span class="lineno"> 554</span> <span class="keyword">typedef</span> <span class="keyword">struct </span>mi_heap_s <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>;</div>
+<div class="line"><a name="l00555"></a><span class="lineno"> 555</span>  </div>
+<div class="line"><a name="l00557"></a><span class="lineno"><a class="line" href="group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11"> 557</a></span> <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* <a class="code" href="group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11">mi_heap_new</a>();</div>
+<div class="line"><a name="l00558"></a><span class="lineno"> 558</span>  </div>
+<div class="line"><a name="l00566"></a><span class="lineno"><a class="line" href="group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409"> 566</a></span> <span class="keywordtype">void</span> <a class="code" href="group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409">mi_heap_delete</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap);</div>
+<div class="line"><a name="l00567"></a><span class="lineno"> 567</span>  </div>
+<div class="line"><a name="l00575"></a><span class="lineno"><a class="line" href="group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d"> 575</a></span> <span class="keywordtype">void</span> <a class="code" href="group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d">mi_heap_destroy</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap);</div>
+<div class="line"><a name="l00576"></a><span class="lineno"> 576</span>  </div>
+<div class="line"><a name="l00580"></a><span class="lineno"><a class="line" href="group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422"> 580</a></span> <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* <a class="code" href="group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422">mi_heap_set_default</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap);</div>
+<div class="line"><a name="l00581"></a><span class="lineno"> 581</span>  </div>
+<div class="line"><a name="l00584"></a><span class="lineno"><a class="line" href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05"> 584</a></span> <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* <a class="code" href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05">mi_heap_get_default</a>();</div>
+<div class="line"><a name="l00585"></a><span class="lineno"> 585</span>  </div>
+<div class="line"><a name="l00591"></a><span class="lineno"><a class="line" href="group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc"> 591</a></span> <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* <a class="code" href="group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc">mi_heap_get_backing</a>();</div>
+<div class="line"><a name="l00592"></a><span class="lineno"> 592</span>  </div>
+<div class="line"><a name="l00594"></a><span class="lineno"><a class="line" href="group__heap.html#ga7922f7495cde30b1984d0e6072419298"> 594</a></span> <span class="keywordtype">void</span> <a class="code" href="group__heap.html#ga7922f7495cde30b1984d0e6072419298">mi_heap_collect</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">bool</span> force);</div>
+<div class="line"><a name="l00595"></a><span class="lineno"> 595</span>  </div>
+<div class="line"><a name="l00598"></a><span class="lineno"><a class="line" href="group__heap.html#ga9cbed01e42c0647907295de92c3fa296"> 598</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga9cbed01e42c0647907295de92c3fa296">mi_heap_malloc</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00599"></a><span class="lineno"> 599</span>  </div>
+<div class="line"><a name="l00603"></a><span class="lineno"><a class="line" href="group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368"> 603</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368">mi_heap_malloc_small</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00604"></a><span class="lineno"> 604</span>  </div>
+<div class="line"><a name="l00607"></a><span class="lineno"><a class="line" href="group__heap.html#ga903104592c8ed53417a3762da6241133"> 607</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga903104592c8ed53417a3762da6241133">mi_heap_zalloc</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00608"></a><span class="lineno"> 608</span>  </div>
+<div class="line"><a name="l00611"></a><span class="lineno"><a class="line" href="group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55"> 611</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55">mi_heap_calloc</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00612"></a><span class="lineno"> 612</span>  </div>
+<div class="line"><a name="l00615"></a><span class="lineno"><a class="line" href="group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0"> 615</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0">mi_heap_mallocn</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00616"></a><span class="lineno"> 616</span>  </div>
+<div class="line"><a name="l00619"></a><span class="lineno"><a class="line" href="group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5"> 619</a></span> <span class="keywordtype">char</span>* <a class="code" href="group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5">mi_heap_strdup</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keyword">const</span> <span class="keywordtype">char</span>* s);</div>
+<div class="line"><a name="l00620"></a><span class="lineno"> 620</span>  </div>
+<div class="line"><a name="l00623"></a><span class="lineno"><a class="line" href="group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a"> 623</a></span> <span class="keywordtype">char</span>* <a class="code" href="group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a">mi_heap_strndup</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keyword">const</span> <span class="keywordtype">char</span>* s, <span class="keywordtype">size_t</span> n);</div>
+<div class="line"><a name="l00624"></a><span class="lineno"> 624</span>  </div>
+<div class="line"><a name="l00627"></a><span class="lineno"><a class="line" href="group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0"> 627</a></span> <span class="keywordtype">char</span>* <a class="code" href="group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0">mi_heap_realpath</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">char</span>* resolved_name);</div>
+<div class="line"><a name="l00628"></a><span class="lineno"> 628</span>  </div>
+<div class="line"><a name="l00629"></a><span class="lineno"><a class="line" href="group__heap.html#gaaef3395f66be48f37bdc8322509c5d81"> 629</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gaaef3395f66be48f37bdc8322509c5d81">mi_heap_realloc</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00630"></a><span class="lineno"><a class="line" href="group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8"> 630</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8">mi_heap_reallocn</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00631"></a><span class="lineno"><a class="line" href="group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527"> 631</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527">mi_heap_reallocf</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00632"></a><span class="lineno"> 632</span>  </div>
+<div class="line"><a name="l00633"></a><span class="lineno"><a class="line" href="group__heap.html#gab5b87e1805306f70df38789fcfcf6653"> 633</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gab5b87e1805306f70df38789fcfcf6653">mi_heap_malloc_aligned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00634"></a><span class="lineno"><a class="line" href="group__heap.html#ga23acd7680fb0976dde3783254c6c874b"> 634</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga23acd7680fb0976dde3783254c6c874b">mi_heap_malloc_aligned_at</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00635"></a><span class="lineno"><a class="line" href="group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0"> 635</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0">mi_heap_zalloc_aligned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00636"></a><span class="lineno"><a class="line" href="group__heap.html#ga45fb43a62776fbebbdf1edd99b527954"> 636</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga45fb43a62776fbebbdf1edd99b527954">mi_heap_zalloc_aligned_at</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00637"></a><span class="lineno"><a class="line" href="group__heap.html#ga4af03a6e2b93fae77424d93f889705c3"> 637</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga4af03a6e2b93fae77424d93f889705c3">mi_heap_calloc_aligned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00638"></a><span class="lineno"><a class="line" href="group__heap.html#ga08ca6419a5c057a4d965868998eef487"> 638</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#ga08ca6419a5c057a4d965868998eef487">mi_heap_calloc_aligned_at</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00639"></a><span class="lineno"><a class="line" href="group__heap.html#gafc603b696bd14cae6da28658f950d98c"> 639</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gafc603b696bd14cae6da28658f950d98c">mi_heap_realloc_aligned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00640"></a><span class="lineno"><a class="line" href="group__heap.html#gaf96c788a1bf553fe2d371de9365e047c"> 640</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__heap.html#gaf96c788a1bf553fe2d371de9365e047c">mi_heap_realloc_aligned_at</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00641"></a><span class="lineno"> 641</span>  </div>
+<div class="line"><a name="l00643"></a><span class="lineno"> 643</span>  </div>
+<div class="line"><a name="l00644"></a><span class="lineno"> 644</span>  </div>
+<div class="line"><a name="l00653"></a><span class="lineno"> 653</span>  </div>
+<div class="line"><a name="l00654"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6"> 654</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6">mi_rezalloc</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00655"></a><span class="lineno"> 655</span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">mi_recalloc</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size) ;</div>
+<div class="line"><a name="l00656"></a><span class="lineno"> 656</span>  </div>
+<div class="line"><a name="l00657"></a><span class="lineno"><a class="line" href="group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0"> 657</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0">mi_rezalloc_aligned</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00658"></a><span class="lineno"><a class="line" href="group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1"> 658</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1">mi_rezalloc_aligned_at</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00659"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f"> 659</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f">mi_recalloc_aligned</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00660"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9"> 660</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9">mi_recalloc_aligned_at</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00661"></a><span class="lineno"> 661</span>  </div>
+<div class="line"><a name="l00662"></a><span class="lineno"><a class="line" href="group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76"> 662</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76">mi_heap_rezalloc</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00663"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd"> 663</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd">mi_heap_recalloc</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00664"></a><span class="lineno"> 664</span>  </div>
+<div class="line"><a name="l00665"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664"> 665</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664">mi_heap_rezalloc_aligned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00666"></a><span class="lineno"><a class="line" href="group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb"> 666</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb">mi_heap_rezalloc_aligned_at</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00667"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3"> 667</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3">mi_heap_recalloc_aligned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00668"></a><span class="lineno"><a class="line" href="group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7"> 668</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7">mi_heap_recalloc_aligned_at</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> offset);</div>
+<div class="line"><a name="l00669"></a><span class="lineno"> 669</span>  </div>
+<div class="line"><a name="l00671"></a><span class="lineno"> 671</span>  </div>
+<div class="line"><a name="l00680"></a><span class="lineno"> 680</span>  </div>
+<div class="line"><a name="l00692"></a><span class="lineno"><a class="line" href="group__typed.html#ga0619a62c5fd886f1016030abe91f0557"> 692</a></span> <span class="preprocessor">#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp)))</span></div>
+<div class="line"><a name="l00693"></a><span class="lineno"> 693</span>  </div>
+<div class="line"><a name="l00695"></a><span class="lineno"><a class="line" href="group__typed.html#gac77a61bdaf680a803785fe307820b48c"> 695</a></span> <span class="preprocessor">#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp)))</span></div>
+<div class="line"><a name="l00696"></a><span class="lineno"> 696</span>  </div>
+<div class="line"><a name="l00698"></a><span class="lineno"><a class="line" href="group__typed.html#gae80c47c9d4cab10961fff1a8ac98fc07"> 698</a></span> <span class="preprocessor">#define mi_calloc_tp(tp,count) ((tp*)mi_calloc(count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00699"></a><span class="lineno"> 699</span>  </div>
+<div class="line"><a name="l00701"></a><span class="lineno"><a class="line" href="group__typed.html#gae5cb6e0fafc9f23169c5622e077afe8b"> 701</a></span> <span class="preprocessor">#define mi_mallocn_tp(tp,count) ((tp*)mi_mallocn(count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00702"></a><span class="lineno"> 702</span>  </div>
+<div class="line"><a name="l00704"></a><span class="lineno"><a class="line" href="group__typed.html#ga1158b49a55dfa81f58a4426a7578f523"> 704</a></span> <span class="preprocessor">#define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00705"></a><span class="lineno"> 705</span>  </div>
+<div class="line"><a name="l00707"></a><span class="lineno"><a class="line" href="group__typed.html#ga653bcb24ac495bc19940ecd6898f9cd7"> 707</a></span> <span class="preprocessor">#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))</span></div>
+<div class="line"><a name="l00708"></a><span class="lineno"> 708</span>  </div>
+<div class="line"><a name="l00710"></a><span class="lineno"><a class="line" href="group__typed.html#gad6e87e86e994aa14416ae9b5d4c188fe"> 710</a></span> <span class="preprocessor">#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))</span></div>
+<div class="line"><a name="l00711"></a><span class="lineno"> 711</span>  </div>
+<div class="line"><a name="l00713"></a><span class="lineno"><a class="line" href="group__typed.html#ga4e5d1f1707c90e5f55e023ac5f45fe74"> 713</a></span> <span class="preprocessor">#define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00714"></a><span class="lineno"> 714</span>  </div>
+<div class="line"><a name="l00716"></a><span class="lineno"><a class="line" href="group__typed.html#ga6b75cb9c4b9c647661d0924552dc6e83"> 716</a></span> <span class="preprocessor">#define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00717"></a><span class="lineno"> 717</span>  </div>
+<div class="line"><a name="l00719"></a><span class="lineno"><a class="line" href="group__typed.html#gaf213d5422ec35e7f6caad827c79bc948"> 719</a></span> <span class="preprocessor">#define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00720"></a><span class="lineno"> 720</span>  </div>
+<div class="line"><a name="l00722"></a><span class="lineno"><a class="line" href="group__typed.html#ga3e50a1600958fcaf1a7f3560c9174f9e"> 722</a></span> <span class="preprocessor">#define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp)))</span></div>
+<div class="line"><a name="l00723"></a><span class="lineno"> 723</span>  </div>
+<div class="line"><a name="l00725"></a><span class="lineno"> 725</span>  </div>
+<div class="line"><a name="l00731"></a><span class="lineno"> 731</span>  </div>
+<div class="line"><a name="l00738"></a><span class="lineno"><a class="line" href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af"> 738</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af">mi_heap_contains_block</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00739"></a><span class="lineno"> 739</span>  </div>
+<div class="line"><a name="l00748"></a><span class="lineno"><a class="line" href="group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377"> 748</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377">mi_heap_check_owned</a>(<a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00749"></a><span class="lineno"> 749</span>  </div>
+<div class="line"><a name="l00757"></a><span class="lineno"><a class="line" href="group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5"> 757</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5">mi_check_owned</a>(<span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00758"></a><span class="lineno"> 758</span>  </div>
+<div class="line"><a name="l00761"></a><span class="lineno"><a class="line" href="group__analysis.html"> 761</a></span> <span class="keyword">typedef</span> <span class="keyword">struct </span>mi_heap_area_s {</div>
+<div class="line"><a name="l00762"></a><span class="lineno"><a class="line" href="group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8"> 762</a></span>  <span class="keywordtype">void</span>* <a class="code" href="group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8">blocks</a>; </div>
+<div class="line"><a name="l00763"></a><span class="lineno"><a class="line" href="group__analysis.html#ae848a3e6840414891035423948ca0383"> 763</a></span>  <span class="keywordtype">size_t</span> <a class="code" href="group__analysis.html#ae848a3e6840414891035423948ca0383">reserved</a>; </div>
+<div class="line"><a name="l00764"></a><span class="lineno"><a class="line" href="group__analysis.html#ab47526df656d8837ec3e97f11b83f835"> 764</a></span>  <span class="keywordtype">size_t</span> <a class="code" href="group__analysis.html#ab47526df656d8837ec3e97f11b83f835">committed</a>; </div>
+<div class="line"><a name="l00765"></a><span class="lineno"><a class="line" href="group__analysis.html#ab820302c5cd0df133eb8e51650a008b4"> 765</a></span>  <span class="keywordtype">size_t</span> <a class="code" href="group__analysis.html#ab820302c5cd0df133eb8e51650a008b4">used</a>; </div>
+<div class="line"><a name="l00766"></a><span class="lineno"><a class="line" href="group__analysis.html#a332a6c14d736a99699d5453a1cb04b41"> 766</a></span>  <span class="keywordtype">size_t</span> <a class="code" href="group__analysis.html#a332a6c14d736a99699d5453a1cb04b41">block_size</a>; </div>
+<div class="line"><a name="l00767"></a><span class="lineno"> 767</span> } <a class="code" href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a>;</div>
+<div class="line"><a name="l00768"></a><span class="lineno"> 768</span>  </div>
+<div class="line"><a name="l00776"></a><span class="lineno"><a class="line" href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65"> 776</a></span> <span class="keyword">typedef</span> bool (<a class="code" href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">mi_block_visit_fun</a>)(<span class="keyword">const</span> <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keyword">const</span> <a class="code" href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a>* area, <span class="keywordtype">void</span>* block, <span class="keywordtype">size_t</span> block_size, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00777"></a><span class="lineno"> 777</span>  </div>
+<div class="line"><a name="l00789"></a><span class="lineno"><a class="line" href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed"> 789</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed">mi_heap_visit_blocks</a>(<span class="keyword">const</span> <a class="code" href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a>* heap, <span class="keywordtype">bool</span> visit_all_blocks, <a class="code" href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">mi_block_visit_fun</a>* visitor, <span class="keywordtype">void</span>* arg);</div>
+<div class="line"><a name="l00790"></a><span class="lineno"> 790</span>  </div>
+<div class="line"><a name="l00792"></a><span class="lineno"> 792</span>  </div>
+<div class="line"><a name="l00798"></a><span class="lineno"> 798</span>  </div>
+<div class="line"><a name="l00800"></a><span class="lineno"><a class="line" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c"> 800</a></span> <span class="keyword">typedef</span> <span class="keyword">enum</span> mi_option_e {</div>
+<div class="line"><a name="l00801"></a><span class="lineno"> 801</span>  <span class="comment">// stable options</span></div>
+<div class="line"><a name="l00802"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0"> 802</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0">mi_option_show_errors</a>, </div>
+<div class="line"><a name="l00803"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda"> 803</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda">mi_option_show_stats</a>, </div>
+<div class="line"><a name="l00804"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777"> 804</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777">mi_option_verbose</a>, </div>
+<div class="line"><a name="l00805"></a><span class="lineno"> 805</span>  <span class="comment">// the following options are experimental</span></div>
+<div class="line"><a name="l00806"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b"> 806</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b">mi_option_eager_commit</a>, </div>
+<div class="line"><a name="l00807"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad"> 807</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad">mi_option_eager_region_commit</a>, </div>
+<div class="line"><a name="l00808"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e"> 808</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e">mi_option_large_os_pages</a>, </div>
+<div class="line"><a name="l00809"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2"> 809</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2">mi_option_reserve_huge_os_pages</a>, </div>
+<div class="line"><a name="l00810"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c"> 810</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c">mi_option_reserve_huge_os_pages_at</a>, </div>
+<div class="line"><a name="l00811"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1"> 811</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1">mi_option_segment_cache</a>, </div>
+<div class="line"><a name="l00812"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968"> 812</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968">mi_option_page_reset</a>, </div>
+<div class="line"><a name="l00813"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d"> 813</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d">mi_option_segment_reset</a>, </div>
+<div class="line"><a name="l00814"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5"> 814</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5">mi_option_reset_delay</a>, </div>
+<div class="line"><a name="l00815"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74"> 815</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74">mi_option_use_numa_nodes</a>, </div>
+<div class="line"><a name="l00816"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536"> 816</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536">mi_option_reset_decommits</a>, </div>
+<div class="line"><a name="l00817"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c"> 817</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c">mi_option_eager_commit_delay</a>, </div>
+<div class="line"><a name="l00818"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf"> 818</a></span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf">mi_option_os_tag</a>, </div>
+<div class="line"><a name="l00819"></a><span class="lineno"> 819</span>  <a class="code" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a">_mi_option_last</a></div>
+<div class="line"><a name="l00820"></a><span class="lineno"><a class="line" href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a"> 820</a></span> } <a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a>;</div>
+<div class="line"><a name="l00821"></a><span class="lineno"> 821</span>  </div>
+<div class="line"><a name="l00822"></a><span class="lineno"> 822</span>  </div>
+<div class="line"><a name="l00823"></a><span class="lineno"><a class="line" href="group__options.html#ga459ad98f18b3fc9275474807fe0ca188"> 823</a></span> <span class="keywordtype">bool</span> <a class="code" href="group__options.html#ga459ad98f18b3fc9275474807fe0ca188">mi_option_is_enabled</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option);</div>
+<div class="line"><a name="l00824"></a><span class="lineno"><a class="line" href="group__options.html#ga04180ae41b0d601421dd62ced40ca050"> 824</a></span> <span class="keywordtype">void</span> <a class="code" href="group__options.html#ga04180ae41b0d601421dd62ced40ca050">mi_option_enable</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option);</div>
+<div class="line"><a name="l00825"></a><span class="lineno"><a class="line" href="group__options.html#gaebf6ff707a2e688ebb1a2296ca564054"> 825</a></span> <span class="keywordtype">void</span> <a class="code" href="group__options.html#gaebf6ff707a2e688ebb1a2296ca564054">mi_option_disable</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option);</div>
+<div class="line"><a name="l00826"></a><span class="lineno"><a class="line" href="group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed"> 826</a></span> <span class="keywordtype">void</span> <a class="code" href="group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed">mi_option_set_enabled</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, <span class="keywordtype">bool</span> enable);</div>
+<div class="line"><a name="l00827"></a><span class="lineno"><a class="line" href="group__options.html#ga65518b69ec5d32336b50e07f74b3f629"> 827</a></span> <span class="keywordtype">void</span> <a class="code" href="group__options.html#ga65518b69ec5d32336b50e07f74b3f629">mi_option_set_enabled_default</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, <span class="keywordtype">bool</span> enable);</div>
+<div class="line"><a name="l00828"></a><span class="lineno"> 828</span>  </div>
+<div class="line"><a name="l00829"></a><span class="lineno"><a class="line" href="group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a"> 829</a></span> <span class="keywordtype">long</span> <a class="code" href="group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a">mi_option_get</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option);</div>
+<div class="line"><a name="l00830"></a><span class="lineno"><a class="line" href="group__options.html#gaf84921c32375e25754dc2ee6a911fa60"> 830</a></span> <span class="keywordtype">void</span> <a class="code" href="group__options.html#gaf84921c32375e25754dc2ee6a911fa60">mi_option_set</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, <span class="keywordtype">long</span> value);</div>
+<div class="line"><a name="l00831"></a><span class="lineno"><a class="line" href="group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90"> 831</a></span> <span class="keywordtype">void</span> <a class="code" href="group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90">mi_option_set_default</a>(<a class="code" href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a> option, <span class="keywordtype">long</span> value);</div>
+<div class="line"><a name="l00832"></a><span class="lineno"> 832</span>  </div>
+<div class="line"><a name="l00833"></a><span class="lineno"> 833</span>  </div>
+<div class="line"><a name="l00835"></a><span class="lineno"> 835</span>  </div>
+<div class="line"><a name="l00842"></a><span class="lineno"> 842</span>  </div>
+<div class="line"><a name="l00843"></a><span class="lineno"> 843</span> <span class="keywordtype">void</span>* <a class="code" href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">mi_recalloc</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00844"></a><span class="lineno"><a class="line" href="group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de"> 844</a></span> <span class="keywordtype">size_t</span> <a class="code" href="group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de">mi_malloc_size</a>(<span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00845"></a><span class="lineno"><a class="line" href="group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17"> 845</a></span> <span class="keywordtype">size_t</span> <a class="code" href="group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17">mi_malloc_usable_size</a>(<span class="keyword">const</span> <span class="keywordtype">void</span> *p);</div>
+<div class="line"><a name="l00846"></a><span class="lineno"> 846</span>  </div>
+<div class="line"><a name="l00848"></a><span class="lineno"><a class="line" href="group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7"> 848</a></span> <span class="keywordtype">void</span> <a class="code" href="group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7">mi_cfree</a>(<span class="keywordtype">void</span>* p);</div>
+<div class="line"><a name="l00849"></a><span class="lineno"> 849</span>  </div>
+<div class="line"><a name="l00850"></a><span class="lineno"><a class="line" href="group__posix.html#gacff84f226ba9feb2031b8992e5579447"> 850</a></span> <span class="keywordtype">int</span> <a class="code" href="group__posix.html#gacff84f226ba9feb2031b8992e5579447">mi_posix_memalign</a>(<span class="keywordtype">void</span>** p, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00851"></a><span class="lineno"><a class="line" href="group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a"> 851</a></span> <span class="keywordtype">int</span> <a class="code" href="group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a">mi__posix_memalign</a>(<span class="keywordtype">void</span>** p, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00852"></a><span class="lineno"><a class="line" href="group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e"> 852</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e">mi_memalign</a>(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00853"></a><span class="lineno"><a class="line" href="group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b"> 853</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b">mi_valloc</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00854"></a><span class="lineno"> 854</span>  </div>
+<div class="line"><a name="l00855"></a><span class="lineno"><a class="line" href="group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e"> 855</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e">mi_pvalloc</a>(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00856"></a><span class="lineno"><a class="line" href="group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5"> 856</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5">mi_aligned_alloc</a>(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00857"></a><span class="lineno"> 857</span>  </div>
+<div class="line"><a name="l00860"></a><span class="lineno"><a class="line" href="group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088"> 860</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088">mi_reallocarray</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00861"></a><span class="lineno"> 861</span>  </div>
+<div class="line"><a name="l00863"></a><span class="lineno"><a class="line" href="group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5"> 863</a></span> <span class="keywordtype">int</span> <a class="code" href="group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5">mi_reallocarr</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00864"></a><span class="lineno"> 864</span>  </div>
+<div class="line"><a name="l00865"></a><span class="lineno"><a class="line" href="group__posix.html#gae01389eedab8d67341ff52e2aad80ebb"> 865</a></span> <span class="keywordtype">void</span> <a class="code" href="group__posix.html#gae01389eedab8d67341ff52e2aad80ebb">mi_free_size</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00866"></a><span class="lineno"><a class="line" href="group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc"> 866</a></span> <span class="keywordtype">void</span> <a class="code" href="group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc">mi_free_size_aligned</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00867"></a><span class="lineno"><a class="line" href="group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9"> 867</a></span> <span class="keywordtype">void</span> <a class="code" href="group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9">mi_free_aligned</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00868"></a><span class="lineno"> 868</span>  </div>
+<div class="line"><a name="l00870"></a><span class="lineno"> 870</span>  </div>
+<div class="line"><a name="l00883"></a><span class="lineno"> 883</span>  </div>
+<div class="line"><a name="l00885"></a><span class="lineno"><a class="line" href="group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545"> 885</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545">mi_new</a>(std::size_t n) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"><a name="l00886"></a><span class="lineno"> 886</span>  </div>
+<div class="line"><a name="l00888"></a><span class="lineno"><a class="line" href="group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81"> 888</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81">mi_new_n</a>(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"><a name="l00889"></a><span class="lineno"> 889</span>  </div>
+<div class="line"><a name="l00891"></a><span class="lineno"><a class="line" href="group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3"> 891</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3">mi_new_aligned</a>(std::size_t n, std::align_val_t alignment) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"><a name="l00892"></a><span class="lineno"> 892</span>  </div>
+<div class="line"><a name="l00894"></a><span class="lineno"><a class="line" href="group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a"> 894</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a">mi_new_nothrow</a>(<span class="keywordtype">size_t</span> n);</div>
+<div class="line"><a name="l00895"></a><span class="lineno"> 895</span>  </div>
+<div class="line"><a name="l00897"></a><span class="lineno"><a class="line" href="group__cpp.html#gab5e29558926d934c3f1cae8c815f942c"> 897</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#gab5e29558926d934c3f1cae8c815f942c">mi_new_aligned_nothrow</a>(<span class="keywordtype">size_t</span> n, <span class="keywordtype">size_t</span> alignment);</div>
+<div class="line"><a name="l00898"></a><span class="lineno"> 898</span>  </div>
+<div class="line"><a name="l00900"></a><span class="lineno"><a class="line" href="group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e"> 900</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e">mi_new_realloc</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><a name="l00901"></a><span class="lineno"> 901</span>  </div>
+<div class="line"><a name="l00903"></a><span class="lineno"><a class="line" href="group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907"> 903</a></span> <span class="keywordtype">void</span>* <a class="code" href="group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907">mi_new_reallocn</a>(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newcount, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><a name="l00904"></a><span class="lineno"> 904</span>  </div>
+<div class="line"><a name="l00912"></a><span class="lineno"><a class="line" href="group__cpp.html"> 912</a></span> <span class="keyword">template</span><<span class="keyword">class</span> T> <span class="keyword">struct </span><a class="code" href="group__cpp.html#structmi__stl__allocator">mi_stl_allocator</a> { }</div>
+<div class="line"><a name="l00913"></a><span class="lineno"> 913</span>  </div>
+<div class="line"><a name="l00915"></a><span class="lineno"> 915</span>  </div>
+<div class="ttc" id="agroup__aligned_html_ga08647c4593f3b2eef24a919a73eba3a3"><div class="ttname"><a href="group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3">mi_calloc_aligned_at</a></div><div class="ttdeci">void * mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__aligned_html_ga0cadbcf5b89a7b6fb171bc8df8734819"><div class="ttname"><a href="group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819">mi_zalloc_aligned</a></div><div class="ttdeci">void * mi_zalloc_aligned(size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__aligned_html_ga4028d1cf4aa4c87c880747044a8322ae"><div class="ttname"><a href="group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae">mi_realloc_aligned</a></div><div class="ttdeci">void * mi_realloc_aligned(void *p, size_t newsize, size_t alignment)</div></div>
+<div class="ttc" id="agroup__aligned_html_ga53dddb4724042a90315b94bc268fb4c9"><div class="ttname"><a href="group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9">mi_calloc_aligned</a></div><div class="ttdeci">void * mi_calloc_aligned(size_t count, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__aligned_html_ga5850da130c936bd77db039dcfbc8295d"><div class="ttname"><a href="group__aligned.html#ga5850da130c936bd77db039dcfbc8295d">mi_malloc_aligned_at</a></div><div class="ttdeci">void * mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset)</div><div class="ttdoc">Allocate size bytes aligned by alignment at a specified offset.</div></div>
+<div class="ttc" id="agroup__aligned_html_ga5f8c2353766db522565e642fafd8a3f8"><div class="ttname"><a href="group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8">mi_zalloc_aligned_at</a></div><div class="ttdeci">void * mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__aligned_html_ga68930196751fa2cca9e1fd0d71bade56"><div class="ttname"><a href="group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56">mi_malloc_aligned</a></div><div class="ttdeci">void * mi_malloc_aligned(size_t size, size_t alignment)</div><div class="ttdoc">Allocate size bytes aligned by alignment.</div></div>
+<div class="ttc" id="agroup__aligned_html_gaf66a9ae6c6f08bd6be6fb6ea771faffb"><div class="ttname"><a href="group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb">mi_realloc_aligned_at</a></div><div class="ttdeci">void * mi_realloc_aligned_at(void *p, size_t newsize, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__analysis_html_a332a6c14d736a99699d5453a1cb04b41"><div class="ttname"><a href="group__analysis.html#a332a6c14d736a99699d5453a1cb04b41">mi_heap_area_t::block_size</a></div><div class="ttdeci">size_t block_size</div><div class="ttdoc">size in bytes of one block</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:766</div></div>
+<div class="ttc" id="agroup__analysis_html_ab47526df656d8837ec3e97f11b83f835"><div class="ttname"><a href="group__analysis.html#ab47526df656d8837ec3e97f11b83f835">mi_heap_area_t::committed</a></div><div class="ttdeci">size_t committed</div><div class="ttdoc">current committed bytes of this area</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:764</div></div>
+<div class="ttc" id="agroup__analysis_html_ab820302c5cd0df133eb8e51650a008b4"><div class="ttname"><a href="group__analysis.html#ab820302c5cd0df133eb8e51650a008b4">mi_heap_area_t::used</a></div><div class="ttdeci">size_t used</div><div class="ttdoc">bytes in use by allocated blocks</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:765</div></div>
+<div class="ttc" id="agroup__analysis_html_ae0085e6e1cf059a4eb7767e30e9991b8"><div class="ttname"><a href="group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8">mi_heap_area_t::blocks</a></div><div class="ttdeci">void * blocks</div><div class="ttdoc">start of the area containing heap blocks</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:762</div></div>
+<div class="ttc" id="agroup__analysis_html_ae848a3e6840414891035423948ca0383"><div class="ttname"><a href="group__analysis.html#ae848a3e6840414891035423948ca0383">mi_heap_area_t::reserved</a></div><div class="ttdeci">size_t reserved</div><div class="ttdoc">bytes reserved for this area</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:763</div></div>
+<div class="ttc" id="agroup__analysis_html_ga0d67c1789faaa15ff366c024fcaf6377"><div class="ttname"><a href="group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377">mi_heap_check_owned</a></div><div class="ttdeci">bool mi_heap_check_owned(mi_heap_t *heap, const void *p)</div><div class="ttdoc">Check safely if any pointer is part of a heap.</div></div>
+<div class="ttc" id="agroup__analysis_html_ga628c237489c2679af84a4d0d143b3dd5"><div class="ttname"><a href="group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5">mi_check_owned</a></div><div class="ttdeci">bool mi_check_owned(const void *p)</div><div class="ttdoc">Check safely if any pointer is part of the default heap of this thread.</div></div>
+<div class="ttc" id="agroup__analysis_html_ga70c46687dc6e9dc98b232b02646f8bed"><div class="ttname"><a href="group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed">mi_heap_visit_blocks</a></div><div class="ttdeci">bool mi_heap_visit_blocks(const mi_heap_t *heap, bool visit_all_blocks, mi_block_visit_fun *visitor, void *arg)</div><div class="ttdoc">Visit all areas and blocks in a heap.</div></div>
+<div class="ttc" id="agroup__analysis_html_gaa862aa8ed8d57d84cae41fc1022d71af"><div class="ttname"><a href="group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af">mi_heap_contains_block</a></div><div class="ttdeci">bool mi_heap_contains_block(mi_heap_t *heap, const void *p)</div><div class="ttdoc">Does a heap contain a pointer to a previously allocated block?</div></div>
+<div class="ttc" id="agroup__analysis_html_gadfa01e2900f0e5d515ad5506b26f6d65"><div class="ttname"><a href="group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65">mi_block_visit_fun</a></div><div class="ttdeci">bool() mi_block_visit_fun(const mi_heap_t *heap, const mi_heap_area_t *area, void *block, size_t block_size, void *arg)</div><div class="ttdoc">Visitor function passed to mi_heap_visit_blocks()</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:776</div></div>
+<div class="ttc" id="agroup__analysis_html_structmi__heap__area__t"><div class="ttname"><a href="group__analysis.html#structmi__heap__area__t">mi_heap_area_t</a></div><div class="ttdoc">An area of heap space contains blocks of a single size.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:761</div></div>
+<div class="ttc" id="agroup__cpp_html_ga756f4b2bc6a7ecd0a90baea8e90c7907"><div class="ttname"><a href="group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907">mi_new_reallocn</a></div><div class="ttdeci">void * mi_new_reallocn(void *p, size_t newcount, size_t size)</div><div class="ttdoc">like mi_reallocn(), but when out of memory, use std::get_new_handler and raise std::bad_alloc excepti...</div></div>
+<div class="ttc" id="agroup__cpp_html_gaab78a32f55149e9fbf432d5288e38e1e"><div class="ttname"><a href="group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e">mi_new_realloc</a></div><div class="ttdeci">void * mi_new_realloc(void *p, size_t newsize)</div><div class="ttdoc">like mi_realloc(), but when out of memory, use std::get_new_handler and raise std::bad_alloc exceptio...</div></div>
+<div class="ttc" id="agroup__cpp_html_gaad048a9fce3d02c5909cd05c6ec24545"><div class="ttname"><a href="group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545">mi_new</a></div><div class="ttdeci">void * mi_new(std::size_t n) noexcept(false)</div><div class="ttdoc">like mi_malloc(), but when out of memory, use std::get_new_handler and raise std::bad_alloc exception...</div></div>
+<div class="ttc" id="agroup__cpp_html_gab5e29558926d934c3f1cae8c815f942c"><div class="ttname"><a href="group__cpp.html#gab5e29558926d934c3f1cae8c815f942c">mi_new_aligned_nothrow</a></div><div class="ttdeci">void * mi_new_aligned_nothrow(size_t n, size_t alignment)</div><div class="ttdoc">like mi_malloc_aligned, but when out of memory, use std::get_new_handler but return NULL on failure.</div></div>
+<div class="ttc" id="agroup__cpp_html_gae7bc4f56cd57ed3359060ff4f38bda81"><div class="ttname"><a href="group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81">mi_new_n</a></div><div class="ttdeci">void * mi_new_n(size_t count, size_t size) noexcept(false)</div><div class="ttdoc">like mi_mallocn(), but when out of memory, use std::get_new_handler and raise std::bad_alloc exceptio...</div></div>
+<div class="ttc" id="agroup__cpp_html_gaeaded64eda71ed6b1d569d3e723abc4a"><div class="ttname"><a href="group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a">mi_new_nothrow</a></div><div class="ttdeci">void * mi_new_nothrow(size_t n)</div><div class="ttdoc">like mi_malloc, but when out of memory, use std::get_new_handler but return NULL on failure.</div></div>
+<div class="ttc" id="agroup__cpp_html_gaef2c2bdb4f70857902d3c8903ac095f3"><div class="ttname"><a href="group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3">mi_new_aligned</a></div><div class="ttdeci">void * mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false)</div><div class="ttdoc">like mi_malloc_aligned(), but when out of memory, use std::get_new_handler and raise std::bad_alloc e...</div></div>
+<div class="ttc" id="agroup__cpp_html_structmi__stl__allocator"><div class="ttname"><a href="group__cpp.html#structmi__stl__allocator">mi_stl_allocator</a></div><div class="ttdoc">std::allocator implementation for mimalloc for use in STL containers.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:912</div></div>
+<div class="ttc" id="agroup__extended_html_ga00ec3324b6b2591c7fe3677baa30a767"><div class="ttname"><a href="group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767">mi_reserve_os_memory</a></div><div class="ttdeci">int mi_reserve_os_memory(size_t size, bool commit, bool allow_large)</div><div class="ttdoc">Reserve OS memory for use by mimalloc.</div></div>
+<div class="ttc" id="agroup__extended_html_ga089c859d9eddc5f9b4bd946cd53cebee"><div class="ttname"><a href="group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee">mi_usable_size</a></div><div class="ttdeci">size_t mi_usable_size(void *p)</div><div class="ttdoc">Return the available bytes in a memory block.</div></div>
+<div class="ttc" id="agroup__extended_html_ga0ae4581e85453456a0d658b2b98bf7bf"><div class="ttname"><a href="group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf">mi_thread_done</a></div><div class="ttdeci">void mi_thread_done(void)</div><div class="ttdoc">Uninitialize mimalloc on a thread.</div></div>
+<div class="ttc" id="agroup__extended_html_ga220f29f40a44404b0061c15bc1c31152"><div class="ttname"><a href="group__extended.html#ga220f29f40a44404b0061c15bc1c31152">mi_zalloc_small</a></div><div class="ttdeci">void * mi_zalloc_small(size_t size)</div><div class="ttdoc">Allocate a zero initialized small object.</div></div>
+<div class="ttc" id="agroup__extended_html_ga251d369cda3f1c2a955c555486ed90e5"><div class="ttname"><a href="group__extended.html#ga251d369cda3f1c2a955c555486ed90e5">mi_error_fun</a></div><div class="ttdeci">void() mi_error_fun(int err, void *arg)</div><div class="ttdoc">Type of error callback functions.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:391</div></div>
+<div class="ttc" id="agroup__extended_html_ga299dae78d25ce112e384a98b7309c5be"><div class="ttname"><a href="group__extended.html#ga299dae78d25ce112e384a98b7309c5be">mi_deferred_free_fun</a></div><div class="ttdeci">void() mi_deferred_free_fun(bool force, unsigned long long heartbeat, void *arg)</div><div class="ttdoc">Type of deferred free functions.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:352</div></div>
+<div class="ttc" id="agroup__extended_html_ga2d126e5c62d3badc35445e5d84166df2"><div class="ttname"><a href="group__extended.html#ga2d126e5c62d3badc35445e5d84166df2">mi_stats_print</a></div><div class="ttdeci">void mi_stats_print(void *out)</div><div class="ttdoc">Deprecated.</div></div>
+<div class="ttc" id="agroup__extended_html_ga3132f521fb756fc0e8ec0b74fb58df50"><div class="ttname"><a href="group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50">mi_reserve_huge_os_pages_interleave</a></div><div class="ttdeci">int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs)</div><div class="ttdoc">Reserve pages of huge OS pages (1GiB) evenly divided over numa_nodes nodes, but stops after at most t...</div></div>
+<div class="ttc" id="agroup__extended_html_ga3460a6ca91af97be4058f523d3cb8ece"><div class="ttname"><a href="group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece">mi_register_deferred_free</a></div><div class="ttdeci">void mi_register_deferred_free(mi_deferred_free_fun *deferred_free, void *arg)</div><div class="ttdoc">Register a deferred free function.</div></div>
+<div class="ttc" id="agroup__extended_html_ga3bb8468b8cfcc6e2a61d98aee85c5f99"><div class="ttname"><a href="group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99">mi_stats_reset</a></div><div class="ttdeci">void mi_stats_reset(void)</div><div class="ttdoc">Reset statistics.</div></div>
+<div class="ttc" id="agroup__extended_html_ga421430e2226d7d468529cec457396756"><div class="ttname"><a href="group__extended.html#ga421430e2226d7d468529cec457396756">mi_collect</a></div><div class="ttdeci">void mi_collect(bool force)</div><div class="ttdoc">Eagerly free memory.</div></div>
+<div class="ttc" id="agroup__extended_html_ga4c6486a1fdcd7a423b5f25fe4be8e0cf"><div class="ttname"><a href="group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf">mi_manage_os_memory</a></div><div class="ttdeci">bool mi_manage_os_memory(void *start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node)</div><div class="ttdoc">Manage a particular memory area for use by mimalloc.</div></div>
+<div class="ttc" id="agroup__extended_html_ga537f13b299ddf801e49a5a94fde02c79"><div class="ttname"><a href="group__extended.html#ga537f13b299ddf801e49a5a94fde02c79">mi_stats_print_out</a></div><div class="ttdeci">void mi_stats_print_out(mi_output_fun *out, void *arg)</div><div class="ttdoc">Print the main statistics.</div></div>
+<div class="ttc" id="agroup__extended_html_ga5f071b10d4df1c3658e04e7fd67a94e6"><div class="ttname"><a href="group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6">mi_is_in_heap_region</a></div><div class="ttdeci">bool mi_is_in_heap_region(const void *p)</div><div class="ttdoc">Is a pointer part of our heap?</div></div>
+<div class="ttc" id="agroup__extended_html_ga7136c2e55cb22c98ecf95d08d6debb99"><div class="ttname"><a href="group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99">mi_malloc_small</a></div><div class="ttdeci">void * mi_malloc_small(size_t size)</div><div class="ttdoc">Allocate a small object.</div></div>
+<div class="ttc" id="agroup__extended_html_ga7795a13d20087447281858d2c771cca1"><div class="ttname"><a href="group__extended.html#ga7795a13d20087447281858d2c771cca1">mi_reserve_huge_os_pages_at</a></div><div class="ttdeci">int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs)</div><div class="ttdoc">Reserve pages of huge OS pages (1GiB) at a specific numa_node, but stops after at most timeout_msecs ...</div></div>
+<div class="ttc" id="agroup__extended_html_ga7d862c2affd5790381da14eb102a364d"><div class="ttname"><a href="group__extended.html#ga7d862c2affd5790381da14eb102a364d">mi_process_info</a></div><div class="ttdeci">void mi_process_info(size_t *elapsed_msecs, size_t *user_msecs, size_t *system_msecs, size_t *current_rss, size_t *peak_rss, size_t *current_commit, size_t *peak_commit, size_t *page_faults)</div><div class="ttdoc">Return process information (time and memory usage).</div></div>
+<div class="ttc" id="agroup__extended_html_ga854b1de8cb067c7316286c28b2fcd3d1"><div class="ttname"><a href="group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1">mi_stats_merge</a></div><div class="ttdeci">void mi_stats_merge(void)</div><div class="ttdoc">Merge thread local statistics with the main statistics and reset.</div></div>
+<div class="ttc" id="agroup__extended_html_gaa1d55e0e894be240827e5d87ec3a1f45"><div class="ttname"><a href="group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45">mi_register_error</a></div><div class="ttdeci">void mi_register_error(mi_error_fun *errfun, void *arg)</div><div class="ttdoc">Register an error callback function.</div></div>
+<div class="ttc" id="agroup__extended_html_gaad25050b19f30cd79397b227e0157a3f"><div class="ttname"><a href="group__extended.html#gaad25050b19f30cd79397b227e0157a3f">mi_is_redirected</a></div><div class="ttdeci">bool mi_is_redirected()</div><div class="ttdoc">Is the C runtime malloc API redirected?</div></div>
+<div class="ttc" id="agroup__extended_html_gab1dac8476c46cb9eecab767eb40c1525"><div class="ttname"><a href="group__extended.html#gab1dac8476c46cb9eecab767eb40c1525">mi_thread_stats_print_out</a></div><div class="ttdeci">void mi_thread_stats_print_out(mi_output_fun *out, void *arg)</div><div class="ttdoc">Print out heap statistics for this thread.</div></div>
+<div class="ttc" id="agroup__extended_html_gac057927cd06c854b45fe7847e921bd47"><div class="ttname"><a href="group__extended.html#gac057927cd06c854b45fe7847e921bd47">mi_good_size</a></div><div class="ttdeci">size_t mi_good_size(size_t size)</div><div class="ttdoc">Return the used allocation size.</div></div>
+<div class="ttc" id="agroup__extended_html_gad823d23444a4b77a40f66bf075a98a0c"><div class="ttname"><a href="group__extended.html#gad823d23444a4b77a40f66bf075a98a0c">mi_output_fun</a></div><div class="ttdeci">void() mi_output_fun(const char *msg, void *arg)</div><div class="ttdoc">Type of output functions.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:376</div></div>
+<div class="ttc" id="agroup__extended_html_gae5b17ff027cd2150b43a33040250cf3f"><div class="ttname"><a href="group__extended.html#gae5b17ff027cd2150b43a33040250cf3f">mi_register_output</a></div><div class="ttdeci">void mi_register_output(mi_output_fun *out, void *arg)</div><div class="ttdoc">Register an output function.</div></div>
+<div class="ttc" id="agroup__extended_html_gaf8e73efc2cbca9ebfdfb166983a04c17"><div class="ttname"><a href="group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17">mi_thread_init</a></div><div class="ttdeci">void mi_thread_init(void)</div><div class="ttdoc">Initialize mimalloc on a thread.</div></div>
+<div class="ttc" id="agroup__heap_html_ga00e95ba1e01acac3cfd95bb7a357a6f0"><div class="ttname"><a href="group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0">mi_heap_realpath</a></div><div class="ttdeci">char * mi_heap_realpath(mi_heap_t *heap, const char *fname, char *resolved_name)</div><div class="ttdoc">Resolve a file path name using a specific heap to allocate the result.</div></div>
+<div class="ttc" id="agroup__heap_html_ga08ca6419a5c057a4d965868998eef487"><div class="ttname"><a href="group__heap.html#ga08ca6419a5c057a4d965868998eef487">mi_heap_calloc_aligned_at</a></div><div class="ttdeci">void * mi_heap_calloc_aligned_at(mi_heap_t *heap, size_t count, size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__heap_html_ga139d6b09dbf50c3c2523d0f4d1cfdeb5"><div class="ttname"><a href="group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5">mi_heap_strdup</a></div><div class="ttdeci">char * mi_heap_strdup(mi_heap_t *heap, const char *s)</div><div class="ttdoc">Duplicate a string in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga23acd7680fb0976dde3783254c6c874b"><div class="ttname"><a href="group__heap.html#ga23acd7680fb0976dde3783254c6c874b">mi_heap_malloc_aligned_at</a></div><div class="ttdeci">void * mi_heap_malloc_aligned_at(mi_heap_t *heap, size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__heap_html_ga2ab1af8d438819b55319c7ef51d1e409"><div class="ttname"><a href="group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409">mi_heap_delete</a></div><div class="ttdeci">void mi_heap_delete(mi_heap_t *heap)</div><div class="ttdoc">Delete a previously allocated heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga34a47cde5a5b38c29f1aa3c5e76943c2"><div class="ttname"><a href="group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2">mi_heap_t</a></div><div class="ttdeci">struct mi_heap_s mi_heap_t</div><div class="ttdoc">Type of first-class heaps.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:554</div></div>
+<div class="ttc" id="agroup__heap_html_ga45fb43a62776fbebbdf1edd99b527954"><div class="ttname"><a href="group__heap.html#ga45fb43a62776fbebbdf1edd99b527954">mi_heap_zalloc_aligned_at</a></div><div class="ttdeci">void * mi_heap_zalloc_aligned_at(mi_heap_t *heap, size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__heap_html_ga4a21070eb4e7cce018133c8d5f4b0527"><div class="ttname"><a href="group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527">mi_heap_reallocf</a></div><div class="ttdeci">void * mi_heap_reallocf(mi_heap_t *heap, void *p, size_t newsize)</div></div>
+<div class="ttc" id="agroup__heap_html_ga4af03a6e2b93fae77424d93f889705c3"><div class="ttname"><a href="group__heap.html#ga4af03a6e2b93fae77424d93f889705c3">mi_heap_calloc_aligned</a></div><div class="ttdeci">void * mi_heap_calloc_aligned(mi_heap_t *heap, size_t count, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__heap_html_ga5d03fbe062ffcf38f0f417fd968357fc"><div class="ttname"><a href="group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc">mi_heap_get_backing</a></div><div class="ttdeci">mi_heap_t * mi_heap_get_backing()</div><div class="ttdoc">Get the backing heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga766f672ba56f2fbfeb9d9dbb0b7f6b11"><div class="ttname"><a href="group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11">mi_heap_new</a></div><div class="ttdeci">mi_heap_t * mi_heap_new()</div><div class="ttdoc">Create a new heap that can be used for allocation.</div></div>
+<div class="ttc" id="agroup__heap_html_ga7922f7495cde30b1984d0e6072419298"><div class="ttname"><a href="group__heap.html#ga7922f7495cde30b1984d0e6072419298">mi_heap_collect</a></div><div class="ttdeci">void mi_heap_collect(mi_heap_t *heap, bool force)</div><div class="ttdoc">Release outstanding resources in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga851da6c43fe0b71c1376cee8aef90db0"><div class="ttname"><a href="group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0">mi_heap_mallocn</a></div><div class="ttdeci">void * mi_heap_mallocn(mi_heap_t *heap, size_t count, size_t size)</div><div class="ttdoc">Allocate count elements in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga8db4cbb87314a989a9a187464d6b5e05"><div class="ttname"><a href="group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05">mi_heap_get_default</a></div><div class="ttdeci">mi_heap_t * mi_heap_get_default()</div><div class="ttdoc">Get the default heap that is used for mi_malloc() et al.</div></div>
+<div class="ttc" id="agroup__heap_html_ga8e3dbd46650dd26573cf307a2c8f1f5a"><div class="ttname"><a href="group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a">mi_heap_strndup</a></div><div class="ttdeci">char * mi_heap_strndup(mi_heap_t *heap, const char *s, size_t n)</div><div class="ttdoc">Duplicate a string of at most length n in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga903104592c8ed53417a3762da6241133"><div class="ttname"><a href="group__heap.html#ga903104592c8ed53417a3762da6241133">mi_heap_zalloc</a></div><div class="ttdeci">void * mi_heap_zalloc(mi_heap_t *heap, size_t size)</div><div class="ttdoc">Allocate zero-initialized in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga9cbed01e42c0647907295de92c3fa296"><div class="ttname"><a href="group__heap.html#ga9cbed01e42c0647907295de92c3fa296">mi_heap_malloc</a></div><div class="ttdeci">void * mi_heap_malloc(mi_heap_t *heap, size_t size)</div><div class="ttdoc">Allocate in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_ga9f9c0844edb9717f4feacd79116b8e0d"><div class="ttname"><a href="group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d">mi_heap_destroy</a></div><div class="ttdeci">void mi_heap_destroy(mi_heap_t *heap)</div><div class="ttdoc">Destroy a heap, freeing all its still allocated blocks.</div></div>
+<div class="ttc" id="agroup__heap_html_gaa1a1c7a1f4da6826b5a25b70ef878368"><div class="ttname"><a href="group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368">mi_heap_malloc_small</a></div><div class="ttdeci">void * mi_heap_malloc_small(mi_heap_t *heap, size_t size)</div><div class="ttdoc">Allocate a small object in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_gaa450a59c6c7ae5fdbd1c2b80a8329ef0"><div class="ttname"><a href="group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0">mi_heap_zalloc_aligned</a></div><div class="ttdeci">void * mi_heap_zalloc_aligned(mi_heap_t *heap, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__heap_html_gaa6702b3c48e9e53e50e81b36f5011d55"><div class="ttname"><a href="group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55">mi_heap_calloc</a></div><div class="ttdeci">void * mi_heap_calloc(mi_heap_t *heap, size_t count, size_t size)</div><div class="ttdoc">Allocate count zero-initialized elements in a specific heap.</div></div>
+<div class="ttc" id="agroup__heap_html_gaaef3395f66be48f37bdc8322509c5d81"><div class="ttname"><a href="group__heap.html#gaaef3395f66be48f37bdc8322509c5d81">mi_heap_realloc</a></div><div class="ttdeci">void * mi_heap_realloc(mi_heap_t *heap, void *p, size_t newsize)</div></div>
+<div class="ttc" id="agroup__heap_html_gab5b87e1805306f70df38789fcfcf6653"><div class="ttname"><a href="group__heap.html#gab5b87e1805306f70df38789fcfcf6653">mi_heap_malloc_aligned</a></div><div class="ttdeci">void * mi_heap_malloc_aligned(mi_heap_t *heap, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__heap_html_gab8631ec88c8d26641b68b5d25dcd4422"><div class="ttname"><a href="group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422">mi_heap_set_default</a></div><div class="ttdeci">mi_heap_t * mi_heap_set_default(mi_heap_t *heap)</div><div class="ttdoc">Set the default heap to use for mi_malloc() et al.</div></div>
+<div class="ttc" id="agroup__heap_html_gac74e94ad9b0c9b57c1c4d88b8825b7a8"><div class="ttname"><a href="group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8">mi_heap_reallocn</a></div><div class="ttdeci">void * mi_heap_reallocn(mi_heap_t *heap, void *p, size_t count, size_t size)</div></div>
+<div class="ttc" id="agroup__heap_html_gaf96c788a1bf553fe2d371de9365e047c"><div class="ttname"><a href="group__heap.html#gaf96c788a1bf553fe2d371de9365e047c">mi_heap_realloc_aligned_at</a></div><div class="ttdeci">void * mi_heap_realloc_aligned_at(mi_heap_t *heap, void *p, size_t newsize, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__heap_html_gafc603b696bd14cae6da28658f950d98c"><div class="ttname"><a href="group__heap.html#gafc603b696bd14cae6da28658f950d98c">mi_heap_realloc_aligned</a></div><div class="ttdeci">void * mi_heap_realloc_aligned(mi_heap_t *heap, void *p, size_t newsize, size_t alignment)</div></div>
+<div class="ttc" id="agroup__malloc_html_ga08cec32dd5bbe7da91c78d19f1b5bebe"><div class="ttname"><a href="group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe">mi_realpath</a></div><div class="ttdeci">char * mi_realpath(const char *fname, char *resolved_name)</div><div class="ttdoc">Resolve a file path name.</div></div>
+<div class="ttc" id="agroup__malloc_html_ga0b05e2bf0f73e7401ae08597ff782ac6"><div class="ttname"><a href="group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6">mi_mallocn</a></div><div class="ttdeci">void * mi_mallocn(size_t count, size_t size)</div><div class="ttdoc">Allocate count elements of size bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_ga23a0fbb452b5dce8e31fab1a1958cacc"><div class="ttname"><a href="group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc">mi_recalloc</a></div><div class="ttdeci">void * mi_recalloc(void *p, size_t count, size_t size)</div><div class="ttdoc">Re-allocate memory to count elements of size bytes, with extra memory initialized to zero.</div></div>
+<div class="ttc" id="agroup__malloc_html_ga3406e8b168bc74c8637b11571a6da83a"><div class="ttname"><a href="group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a">mi_malloc</a></div><div class="ttdeci">void * mi_malloc(size_t size)</div><div class="ttdoc">Allocate size bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_ga61d57b4144ba24fba5c1e9b956d13853"><div class="ttname"><a href="group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853">mi_reallocn</a></div><div class="ttdeci">void * mi_reallocn(void *p, size_t count, size_t size)</div><div class="ttdoc">Re-allocate memory to count elements of size bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_ga97fedb4f7107c592fd7f0f0a8949a57d"><div class="ttname"><a href="group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d">mi_calloc</a></div><div class="ttdeci">void * mi_calloc(size_t count, size_t size)</div><div class="ttdoc">Allocate zero-initialized count elements of size bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_gaaabf971c2571891433477e2d21a35266"><div class="ttname"><a href="group__malloc.html#gaaabf971c2571891433477e2d21a35266">mi_strndup</a></div><div class="ttdeci">char * mi_strndup(const char *s, size_t n)</div><div class="ttdoc">Allocate and duplicate a string up to n bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_gaaee66a1d483c3e28f585525fb96707e4"><div class="ttname"><a href="group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4">mi_expand</a></div><div class="ttdeci">void * mi_expand(void *p, size_t newsize)</div><div class="ttdoc">Try to re-allocate memory to newsize bytes in place.</div></div>
+<div class="ttc" id="agroup__malloc_html_gac7cffe13f1f458ed16789488bf92b9b2"><div class="ttname"><a href="group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2">mi_strdup</a></div><div class="ttdeci">char * mi_strdup(const char *s)</div><div class="ttdoc">Allocate and duplicate a string.</div></div>
+<div class="ttc" id="agroup__malloc_html_gaf11eb497da57bdfb2de65eb191c69db6"><div class="ttname"><a href="group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6">mi_realloc</a></div><div class="ttdeci">void * mi_realloc(void *p, size_t newsize)</div><div class="ttdoc">Re-allocate memory to newsize bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_gaf2c7b89c327d1f60f59e68b9ea644d95"><div class="ttname"><a href="group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95">mi_free</a></div><div class="ttdeci">void mi_free(void *p)</div><div class="ttdoc">Free previously allocated memory.</div></div>
+<div class="ttc" id="agroup__malloc_html_gafdd9d8bb2986e668ba9884f28af38000"><div class="ttname"><a href="group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000">mi_zalloc</a></div><div class="ttdeci">void * mi_zalloc(size_t size)</div><div class="ttdoc">Allocate zero-initialized size bytes.</div></div>
+<div class="ttc" id="agroup__malloc_html_gafe68ac7c5e24a65cd55c9d6b152211a0"><div class="ttname"><a href="group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0">mi_reallocf</a></div><div class="ttdeci">void * mi_reallocf(void *p, size_t newsize)</div><div class="ttdoc">Re-allocate memory to newsize bytes,.</div></div>
+<div class="ttc" id="agroup__options_html_ga04180ae41b0d601421dd62ced40ca050"><div class="ttname"><a href="group__options.html#ga04180ae41b0d601421dd62ced40ca050">mi_option_enable</a></div><div class="ttdeci">void mi_option_enable(mi_option_t option)</div></div>
+<div class="ttc" id="agroup__options_html_ga459ad98f18b3fc9275474807fe0ca188"><div class="ttname"><a href="group__options.html#ga459ad98f18b3fc9275474807fe0ca188">mi_option_is_enabled</a></div><div class="ttdeci">bool mi_option_is_enabled(mi_option_t option)</div></div>
+<div class="ttc" id="agroup__options_html_ga65518b69ec5d32336b50e07f74b3f629"><div class="ttname"><a href="group__options.html#ga65518b69ec5d32336b50e07f74b3f629">mi_option_set_enabled_default</a></div><div class="ttdeci">void mi_option_set_enabled_default(mi_option_t option, bool enable)</div></div>
+<div class="ttc" id="agroup__options_html_ga7e8af195cc81d3fa64ccf2662caa565a"><div class="ttname"><a href="group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a">mi_option_get</a></div><div class="ttdeci">long mi_option_get(mi_option_t option)</div></div>
+<div class="ttc" id="agroup__options_html_ga7ef623e440e6e5545cb08c94e71e4b90"><div class="ttname"><a href="group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90">mi_option_set_default</a></div><div class="ttdeci">void mi_option_set_default(mi_option_t option, long value)</div></div>
+<div class="ttc" id="agroup__options_html_ga9a13d05fcb77489cb06d4d017ebd8bed"><div class="ttname"><a href="group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed">mi_option_set_enabled</a></div><div class="ttdeci">void mi_option_set_enabled(mi_option_t option, bool enable)</div></div>
+<div class="ttc" id="agroup__options_html_gaebf6ff707a2e688ebb1a2296ca564054"><div class="ttname"><a href="group__options.html#gaebf6ff707a2e688ebb1a2296ca564054">mi_option_disable</a></div><div class="ttdeci">void mi_option_disable(mi_option_t option)</div></div>
+<div class="ttc" id="agroup__options_html_gaf84921c32375e25754dc2ee6a911fa60"><div class="ttname"><a href="group__options.html#gaf84921c32375e25754dc2ee6a911fa60">mi_option_set</a></div><div class="ttdeci">void mi_option_set(mi_option_t option, long value)</div></div>
+<div class="ttc" id="agroup__options_html_gafebf7ed116adb38ae5218bc3ce06884c"><div class="ttname"><a href="group__options.html#gafebf7ed116adb38ae5218bc3ce06884c">mi_option_t</a></div><div class="ttdeci">mi_option_t</div><div class="ttdoc">Runtime options.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:800</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda">mi_option_show_stats</a></div><div class="ttdeci">@ mi_option_show_stats</div><div class="ttdoc">Print statistics to stderr when the program is done.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:803</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74">mi_option_use_numa_nodes</a></div><div class="ttdeci">@ mi_option_use_numa_nodes</div><div class="ttdoc">Pretend there are at most N NUMA nodes.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:815</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5">mi_option_reset_delay</a></div><div class="ttdeci">@ mi_option_reset_delay</div><div class="ttdoc">Delay in milli-seconds before resetting a page (100ms by default)</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:814</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c">mi_option_eager_commit_delay</a></div><div class="ttdeci">@ mi_option_eager_commit_delay</div><div class="ttdoc">Experimental.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:817</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b">mi_option_eager_commit</a></div><div class="ttdeci">@ mi_option_eager_commit</div><div class="ttdoc">Eagerly commit segments (4MiB) (enabled by default).</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:806</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1">mi_option_segment_cache</a></div><div class="ttdeci">@ mi_option_segment_cache</div><div class="ttdoc">The number of segments per thread to keep cached.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:811</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad">mi_option_eager_region_commit</a></div><div class="ttdeci">@ mi_option_eager_region_commit</div><div class="ttdoc">Eagerly commit large (256MiB) memory regions (enabled by default, except on Windows)</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:807</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e">mi_option_large_os_pages</a></div><div class="ttdeci">@ mi_option_large_os_pages</div><div class="ttdoc">Use large OS pages (2MiB in size) if possible.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:808</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf">mi_option_os_tag</a></div><div class="ttdeci">@ mi_option_os_tag</div><div class="ttdoc">OS tag to assign to mimalloc'd memory.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:818</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a">_mi_option_last</a></div><div class="ttdeci">@ _mi_option_last</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:819</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777">mi_option_verbose</a></div><div class="ttdeci">@ mi_option_verbose</div><div class="ttdoc">Print verbose messages to stderr.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:804</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c">mi_option_reserve_huge_os_pages_at</a></div><div class="ttdeci">@ mi_option_reserve_huge_os_pages_at</div><div class="ttdoc">Reserve huge OS pages at node N.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:810</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536">mi_option_reset_decommits</a></div><div class="ttdeci">@ mi_option_reset_decommits</div><div class="ttdoc">Experimental.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:816</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2">mi_option_reserve_huge_os_pages</a></div><div class="ttdeci">@ mi_option_reserve_huge_os_pages</div><div class="ttdoc">The number of huge OS pages (1GiB in size) to reserve at the start of the program.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:809</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968">mi_option_page_reset</a></div><div class="ttdeci">@ mi_option_page_reset</div><div class="ttdoc">Reset page memory after mi_option_reset_delay milliseconds when it becomes free.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:812</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d">mi_option_segment_reset</a></div><div class="ttdeci">@ mi_option_segment_reset</div><div class="ttdoc">Experimental.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:813</div></div>
+<div class="ttc" id="agroup__options_html_ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0"><div class="ttname"><a href="group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0">mi_option_show_errors</a></div><div class="ttdeci">@ mi_option_show_errors</div><div class="ttdoc">Print error messages to stderr.</div><div class="ttdef"><b>Definition:</b> mimalloc-doc.h:802</div></div>
+<div class="ttc" id="agroup__posix_html_ga06d07cf357bbac5c73ba5d0c0c421e17"><div class="ttname"><a href="group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17">mi_malloc_usable_size</a></div><div class="ttdeci">size_t mi_malloc_usable_size(const void *p)</div></div>
+<div class="ttc" id="agroup__posix_html_ga0d28d5cf61e6bfbb18c63092939fe5c9"><div class="ttname"><a href="group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9">mi_free_aligned</a></div><div class="ttdeci">void mi_free_aligned(void *p, size_t alignment)</div></div>
+<div class="ttc" id="agroup__posix_html_ga1326d2e4388630b5f81ca7206318b8e5"><div class="ttname"><a href="group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5">mi_aligned_alloc</a></div><div class="ttdeci">void * mi_aligned_alloc(size_t alignment, size_t size)</div></div>
+<div class="ttc" id="agroup__posix_html_ga4531c9e775bb3ae12db57c1ba8a5d7de"><div class="ttname"><a href="group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de">mi_malloc_size</a></div><div class="ttdeci">size_t mi_malloc_size(const void *p)</div></div>
+<div class="ttc" id="agroup__posix_html_ga48fad8648a2f1dab9c87ea9448a52088"><div class="ttname"><a href="group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088">mi_reallocarray</a></div><div class="ttdeci">void * mi_reallocarray(void *p, size_t count, size_t size)</div><div class="ttdoc">Correspond s to reallocarray in FreeBSD.</div></div>
+<div class="ttc" id="agroup__posix_html_ga705dc7a64bffacfeeb0141501a5c35d7"><div class="ttname"><a href="group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7">mi_cfree</a></div><div class="ttdeci">void mi_cfree(void *p)</div><div class="ttdoc">Just as free but also checks if the pointer p belongs to our heap.</div></div>
+<div class="ttc" id="agroup__posix_html_ga72e9d7ffb5fe94d69bc722c8506e27bc"><div class="ttname"><a href="group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc">mi_free_size_aligned</a></div><div class="ttdeci">void mi_free_size_aligned(void *p, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__posix_html_ga73baaf5951f5165ba0763d0c06b6a93b"><div class="ttname"><a href="group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b">mi_valloc</a></div><div class="ttdeci">void * mi_valloc(size_t size)</div></div>
+<div class="ttc" id="agroup__posix_html_ga7e1934d60a3e697950eeb48e042bfad5"><div class="ttname"><a href="group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5">mi_reallocarr</a></div><div class="ttdeci">int mi_reallocarr(void *p, size_t count, size_t size)</div><div class="ttdoc">Corresponds to reallocarr in NetBSD.</div></div>
+<div class="ttc" id="agroup__posix_html_gaab7fa71ea93b96873f5d9883db57d40e"><div class="ttname"><a href="group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e">mi_memalign</a></div><div class="ttdeci">void * mi_memalign(size_t alignment, size_t size)</div></div>
+<div class="ttc" id="agroup__posix_html_gacff84f226ba9feb2031b8992e5579447"><div class="ttname"><a href="group__posix.html#gacff84f226ba9feb2031b8992e5579447">mi_posix_memalign</a></div><div class="ttdeci">int mi_posix_memalign(void **p, size_t alignment, size_t size)</div></div>
+<div class="ttc" id="agroup__posix_html_gad5a69c8fea96aa2b7a7c818c2130090a"><div class="ttname"><a href="group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a">mi__posix_memalign</a></div><div class="ttdeci">int mi__posix_memalign(void **p, size_t alignment, size_t size)</div></div>
+<div class="ttc" id="agroup__posix_html_gae01389eedab8d67341ff52e2aad80ebb"><div class="ttname"><a href="group__posix.html#gae01389eedab8d67341ff52e2aad80ebb">mi_free_size</a></div><div class="ttdeci">void mi_free_size(void *p, size_t size)</div></div>
+<div class="ttc" id="agroup__posix_html_gaeb325c39b887d3b90d85d1eb1712fb1e"><div class="ttname"><a href="group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e">mi_pvalloc</a></div><div class="ttdeci">void * mi_pvalloc(size_t size)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga375fa8a611c51905e592d5d467c49664"><div class="ttname"><a href="group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664">mi_heap_rezalloc_aligned</a></div><div class="ttdeci">void * mi_heap_rezalloc_aligned(mi_heap_t *heap, void *p, size_t newsize, size_t alignment)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga3e7e5c291acf1c7fd7ffd9914a9f945f"><div class="ttname"><a href="group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f">mi_recalloc_aligned</a></div><div class="ttdeci">void * mi_recalloc_aligned(void *p, size_t newcount, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga496452c96f1de8c500be9fddf52edaf7"><div class="ttname"><a href="group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7">mi_heap_recalloc_aligned_at</a></div><div class="ttdeci">void * mi_heap_recalloc_aligned_at(mi_heap_t *heap, void *p, size_t newcount, size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga4ff5e92ad73585418a072c9d059e5cf9"><div class="ttname"><a href="group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9">mi_recalloc_aligned_at</a></div><div class="ttdeci">void * mi_recalloc_aligned_at(void *p, size_t newcount, size_t size, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga8648c5fbb22a80f0262859099f06dfbd"><div class="ttname"><a href="group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd">mi_heap_recalloc</a></div><div class="ttdeci">void * mi_heap_recalloc(mi_heap_t *heap, void *p, size_t newcount, size_t size)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga8c292e142110229a2980b37ab036dbc6"><div class="ttname"><a href="group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6">mi_rezalloc</a></div><div class="ttdeci">void * mi_rezalloc(void *p, size_t newsize)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_ga9f3f999396c8f77ca5e80e7b40ac29e3"><div class="ttname"><a href="group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3">mi_heap_recalloc_aligned</a></div><div class="ttdeci">void * mi_heap_recalloc_aligned(mi_heap_t *heap, void *p, size_t newcount, size_t size, size_t alignment)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_gac90da54fa7e5d10bdc97ce0b51dce2eb"><div class="ttname"><a href="group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb">mi_heap_rezalloc_aligned_at</a></div><div class="ttdeci">void * mi_heap_rezalloc_aligned_at(mi_heap_t *heap, void *p, size_t newsize, size_t alignment, size_t offset)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_gacd71a7bce96aab38ae6de17af2eb2cf0"><div class="ttname"><a href="group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0">mi_rezalloc_aligned</a></div><div class="ttdeci">void * mi_rezalloc_aligned(void *p, size_t newsize, size_t alignment)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_gacfad83f14eb5d6a42a497a898e19fc76"><div class="ttname"><a href="group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76">mi_heap_rezalloc</a></div><div class="ttdeci">void * mi_heap_rezalloc(mi_heap_t *heap, void *p, size_t newsize)</div></div>
+<div class="ttc" id="agroup__zeroinit_html_gae8b358c417e61d5307da002702b0a8e1"><div class="ttname"><a href="group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1">mi_rezalloc_aligned_at</a></div><div class="ttdeci">void * mi_rezalloc_aligned_at(void *p, size_t newsize, size_t alignment, size_t offset)</div></div>
+</div><!-- fragment --></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="navelem"><b>mimalloc-doc.h</b></li>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+#projectlogo img {
+ padding: 1ex;
+}
+tt, code, kbd, samp, div.memproto, div.fragment, div.line, table.memname {
+ font-family: Consolas, Monaco, Inconsolata, "Courier New", monospace;
+}
+.image img, .textblock img {
+ max-width: 99%;
+ max-height: 350px;
+}
+table.memname, .memname{
+ font-weight: bold;
+}
+code {
+ background-color: #EEE;
+ padding: 0ex 0.25ex;
+}
+body {
+ margin: 1ex 1ex 0ex 1ex;
+ border: 1px solid black;
+}
+.contents table, .contents div, .contents p, .contents dl {
+ font-size: 16px;
+ line-height: 1.44;
+}
+body #nav-tree .label {
+ font-size: 14px;
+}
+a{
+ text-decoration: underline;
+}
+#side-nav {
+ margin-left: 1ex;
+ border-left: 1px solid black;
+}
+#nav-tree {
+ padding-left: 1ex;
+}
+#nav-path {
+ display: none;
+}
+div.fragment {
+ background-color: #EEE;
+ padding: 0.25ex 0.5ex;
+ border-color: black;
+}
+#nav-sync img {
+ display: none;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="20mm"
+ height="20mm"
+ viewBox="0 0 10 10"
+ version="1.1"
+ id="svg8"
+ sodipodi:docname="mimalloc-logo.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <defs
+ id="defs2">
+ <linearGradient
+ id="linearGradient6471"
+ osb:paint="solid">
+ <stop
+ style="stop-color:#008da3;stop-opacity:1;"
+ offset="0"
+ id="stop6469" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="23.706667"
+ inkscape:cx="24.864771"
+ inkscape:cy="35.79485"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="3840"
+ inkscape:window-height="2050"
+ inkscape:window-x="-12"
+ inkscape:window-y="-12"
+ inkscape:window-maximized="1"
+ inkscape:snap-object-midpoints="false"
+ inkscape:snap-bbox="false"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:bbox-nodes="false"
+ inkscape:bbox-paths="false"
+ inkscape:snap-bbox-edge-midpoints="false"
+ showguides="false"
+ showborder="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid815"
+ units="mm"
+ spacingx="0.99999997"
+ spacingy="0.99999997" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-287)">
+ <circle
+ id="path840"
+ cx="5"
+ cy="292"
+ style="fill:#0d8ca4;fill-opacity:0.64444448;fill-rule:nonzero;stroke:#000000;stroke-width:0.56603777;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ r="4.7169809" />
+ <ellipse
+ id="path4522"
+ style="fill:none;stroke:#000000;stroke-width:0.6;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ cx="5.171"
+ cy="292"
+ r="4.8711185" />
+ <g
+ aria-label="malloc"
+ transform="matrix(0.9031136,0,0,0.80782132,0.58122269,37.023319)"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28599727"
+ id="text6501">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 1.7799307,318.87079 c 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.70159 c 0.013406,-0.0223 0.031281,-0.0469 0.05139,-0.0693 0.017875,-0.0223 0.049156,-0.0447 0.089374,-0.0693 0.040218,-0.0223 0.082671,-0.0358 0.1273581,-0.0358 0.040218,0 0.078202,0.0179 0.1117177,0.0536 0.031281,0.0358 0.049156,0.0827 0.049156,0.143 v 0.67924 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.67924 -0.0223 c 0.0067,-0.0112 0.01564,-0.0223 0.024578,-0.0358 0.00894,-0.0134 0.022344,-0.0268 0.040218,-0.0447 0.017875,-0.0179 0.03575,-0.0335 0.053624,-0.0469 0.017875,-0.0134 0.042453,-0.0246 0.069265,-0.0335 0.026812,-0.009 0.053625,-0.0134 0.080437,-0.0134 0.040218,0 0.078202,0.0179 0.1117177,0.0536 0.031281,0.0358 0.049156,0.0827 0.049156,0.143 v 0.67924 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 0.029047,0 0.053624,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.67924 c 0,-0.11396 -0.037984,-0.21003 -0.1094833,-0.29047 -0.073734,-0.0804 -0.1631078,-0.12066 -0.2658881,-0.12066 -0.073734,0 -0.1407643,0.0156 -0.1988575,0.0425 -0.058093,0.0268 -0.1094833,0.0626 -0.1541704,0.10725 -0.075968,-0.0983 -0.1720452,-0.14971 -0.290466,-0.14971 -0.1027802,0 -0.1943887,0.029 -0.2748255,0.0849 -0.00894,-0.0179 -0.022343,-0.0335 -0.040218,-0.0469 -0.017875,-0.0134 -0.037984,-0.0201 -0.060328,-0.0201 -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 0.96524 c 0,0.0313 0.00894,0.0559 0.031281,0.076 0.020109,0.0223 0.044687,0.0313 0.075968,0.0313 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6515" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 4.2824069,317.69105 c -0.01564,0 -0.029047,0.004 -0.042453,0.009 -0.013406,0.007 -0.026812,0.0156 -0.03575,0.0246 -0.00894,0.0112 -0.017875,0.0223 -0.022344,0.0335 -0.078202,-0.0559 -0.1631079,-0.0849 -0.2569507,-0.0849 -0.145233,0 -0.2658881,0.0626 -0.359731,0.18322 -0.093843,0.12066 -0.1407642,0.26366 -0.1407642,0.42453 0,0.16311 0.046921,0.30611 0.1407642,0.42676 0.093843,0.12066 0.214498,0.18098 0.359731,0.18098 0.093843,0 0.1787483,-0.0268 0.2569507,-0.0849 0.00894,0.0201 0.022344,0.0358 0.040218,0.0491 0.017875,0.0134 0.037984,0.0179 0.060328,0.0179 0.029047,0 0.053625,-0.009 0.075968,-0.0313 0.020109,-0.0201 0.031281,-0.0447 0.031281,-0.076 v -0.96524 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z m -0.107249,0.77979 c -0.017875,0.0424 -0.040218,0.0782 -0.067031,0.10948 -0.026812,0.0313 -0.055859,0.0559 -0.08714,0.0715 -0.031281,0.0156 -0.064796,0.0224 -0.096077,0.0224 -0.073734,0 -0.1407643,-0.0358 -0.1988575,-0.10949 -0.058093,-0.0737 -0.08714,-0.16757 -0.08714,-0.28376 0,-0.11395 0.029047,-0.2078 0.08714,-0.28153 0.058093,-0.0737 0.1251238,-0.11172 0.1988575,-0.11172 0.049156,0 0.098312,0.0179 0.1429986,0.0536 0.044687,0.0358 0.080437,0.0871 0.107249,0.1497 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6517" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 4.7471525,317.2263 c -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 1.21549 c 0,0.10502 0.0067,0.18545 0.022343,0.24131 0.00447,0.0268 0.017875,0.0469 0.037984,0.0603 0.017875,0.0134 0.040218,0.0201 0.064796,0.0201 0.00894,0 0.017875,0 0.026812,-0.002 0.00447,-0.002 0.011172,-0.004 0.017875,-0.009 0.0067,-0.002 0.013406,-0.004 0.017875,-0.009 0.00447,-0.004 0.011172,-0.009 0.01564,-0.0134 0.00447,-0.004 0.0067,-0.0112 0.011172,-0.0156 0.00447,-0.004 0.0067,-0.0112 0.00894,-0.0179 0.00223,-0.007 0.00447,-0.0134 0.0067,-0.0201 0,-0.007 0.00223,-0.0134 0.00223,-0.0201 v -0.007 c 0,-0.002 -0.00223,-0.004 -0.00223,-0.007 0,-0.002 0,-0.004 0,-0.009 -0.011172,-0.0447 -0.01564,-0.10725 -0.01564,-0.19216 v -1.21549 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6519" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 5.2655226,317.2263 c -0.031281,0 -0.055859,0.0112 -0.075968,0.0313 -0.022343,0.0223 -0.031281,0.0469 -0.031281,0.076 v 1.21549 c 0,0.10502 0.0067,0.18545 0.022344,0.24131 0.00447,0.0268 0.017875,0.0469 0.037984,0.0603 0.017875,0.0134 0.040218,0.0201 0.064796,0.0201 0.00894,0 0.017875,0 0.026812,-0.002 0.00447,-0.002 0.011172,-0.004 0.017875,-0.009 0.0067,-0.002 0.013406,-0.004 0.017875,-0.009 0.00447,-0.004 0.011172,-0.009 0.01564,-0.0134 0.00447,-0.004 0.0067,-0.0112 0.011172,-0.0156 0.00447,-0.004 0.0067,-0.0112 0.00894,-0.0179 0.00223,-0.007 0.00447,-0.0134 0.0067,-0.0201 0,-0.007 0.00223,-0.0134 0.00223,-0.0201 v -0.007 c 0,-0.002 -0.00223,-0.004 -0.00223,-0.007 0,-0.002 0,-0.004 0,-0.009 -0.011172,-0.0447 -0.01564,-0.10725 -0.01564,-0.19216 v -1.21549 c 0,-0.029 -0.011172,-0.0536 -0.031281,-0.076 -0.022343,-0.0201 -0.046921,-0.0313 -0.075968,-0.0313 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6521" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 6.6061344,318.28092 c 0,-0.16087 -0.049156,-0.30387 -0.1429986,-0.42453 -0.093843,-0.12065 -0.2144979,-0.18322 -0.3574966,-0.18322 -0.145233,0 -0.2658881,0.0626 -0.3597309,0.18322 -0.093843,0.12066 -0.1407643,0.26366 -0.1407643,0.42453 0,0.16311 0.046921,0.30611 0.1407643,0.42676 0.093843,0.12066 0.2144979,0.18098 0.3597309,0.18098 0.1429987,0 0.2636538,-0.0603 0.3574966,-0.18098 0.093843,-0.12065 0.1429986,-0.26365 0.1429986,-0.42676 z m -0.2144979,0 c 0,0.11619 -0.031281,0.21003 -0.089374,0.28376 -0.058093,0.0737 -0.1251238,0.10949 -0.1966231,0.10949 -0.073734,0 -0.1407643,-0.0358 -0.1988575,-0.10949 -0.058093,-0.0737 -0.08714,-0.16757 -0.08714,-0.28376 0,-0.11395 0.029047,-0.2078 0.08714,-0.28153 0.058093,-0.0737 0.1251238,-0.11172 0.1988575,-0.11172 0.071499,0 0.1385299,0.038 0.1966231,0.11172 0.058093,0.0737 0.089374,0.16758 0.089374,0.28153 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6523" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 7.6406407,318.47754 c -0.00894,-0.004 -0.01564,-0.007 -0.024578,-0.009 -0.00894,-0.002 -0.017875,-0.004 -0.026812,-0.004 -0.044687,0 -0.075968,0.0201 -0.093843,0.0559 -0.026812,0.0514 -0.060328,0.0894 -0.098312,0.11618 -0.040218,0.0268 -0.080437,0.038 -0.1206551,0.038 -0.071499,0 -0.1340612,-0.0358 -0.1921544,-0.10949 -0.058093,-0.0737 -0.084905,-0.16757 -0.084905,-0.28376 0,-0.11395 0.026812,-0.2078 0.084905,-0.28153 0.058093,-0.0737 0.1206551,-0.11172 0.1921544,-0.11172 0.080437,0 0.1474674,0.0447 0.2055606,0.1296 0.020109,0.0335 0.049156,0.0491 0.089374,0.0491 0.022343,0 0.040218,-0.004 0.058093,-0.0179 0.0067,-0.004 0.013406,-0.009 0.020109,-0.0156 0.0067,-0.007 0.011172,-0.0134 0.01564,-0.0224 0.00447,-0.009 0.0067,-0.0156 0.00894,-0.0246 0.00223,-0.009 0.00447,-0.0179 0.00447,-0.0268 0,-0.004 -0.00223,-0.0112 -0.00223,-0.0156 0,-0.004 -0.00223,-0.009 -0.00223,-0.0134 -0.00223,-0.004 -0.00447,-0.0112 -0.0067,-0.0156 -0.00223,-0.004 -0.00447,-0.009 -0.0067,-0.0134 -0.031281,-0.0447 -0.064796,-0.0827 -0.1027803,-0.11619 -0.037984,-0.0335 -0.080437,-0.0603 -0.1295925,-0.0804 -0.049156,-0.0201 -0.1005459,-0.0313 -0.1519361,-0.0313 -0.1429986,0 -0.2614194,0.0626 -0.3530279,0.18322 -0.093843,0.12066 -0.1385299,0.26366 -0.1385299,0.42453 0,0.16311 0.044687,0.30611 0.1385299,0.42676 0.091608,0.12066 0.2100293,0.18098 0.3530279,0.18098 0.084905,0 0.1631078,-0.0246 0.2346072,-0.0737 0.071499,-0.0492 0.1273581,-0.11172 0.1720452,-0.19215 0.0067,-0.0134 0.011172,-0.0313 0.013406,-0.0514 0,-0.0425 -0.020109,-0.0737 -0.055859,-0.0939 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.28797817px;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.28599727"
+ id="path6525" />
+ </g>
+ <g
+ aria-label="m"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.3694315px;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578"
+ id="text848">
+ <path
+ d="m 2.3718985,293.17081 c 0.080862,0 0.1492836,-0.0249 0.211485,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.95313 c 0.037321,-0.0622 0.087082,-0.13062 0.1430634,-0.19282 0.049761,-0.0622 0.1368433,-0.1244 0.2488059,-0.19283 0.1119627,-0.0622 0.2301455,-0.0995 0.3545485,-0.0995 0.1119626,0 0.2177051,0.0498 0.3110074,0.14929 0.087082,0.0995 0.1368432,0.23014 0.1368432,0.39808 v 1.89093 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.89093 -0.0622 c 0.018661,-0.0311 0.043541,-0.0622 0.068422,-0.0995 0.024881,-0.0373 0.062201,-0.0746 0.1119626,-0.1244 0.049761,-0.0498 0.099522,-0.0933 0.1492836,-0.13063 0.049761,-0.0373 0.1181828,-0.0684 0.1928246,-0.0933 0.074642,-0.0249 0.1492835,-0.0373 0.2239253,-0.0373 0.1119626,0 0.2177052,0.0498 0.3110074,0.14929 0.087082,0.0995 0.1368432,0.23014 0.1368432,0.39808 v 1.89093 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21148 v -1.89093 c 0,-0.31722 -0.1057425,-0.58469 -0.3047872,-0.80861 -0.2052649,-0.22393 -0.4540708,-0.33589 -0.7401976,-0.33589 -0.2052649,0 -0.3918693,0.0435 -0.5535932,0.11818 -0.1617238,0.0746 -0.3047872,0.17416 -0.4291902,0.29857 -0.211485,-0.27369 -0.4789514,-0.41675 -0.8086192,-0.41675 -0.2861268,0 -0.5411529,0.0809 -0.7650782,0.23636 -0.024881,-0.0498 -0.062202,-0.0933 -0.1119627,-0.13062 -0.049761,-0.0373 -0.1057425,-0.056 -0.167944,-0.056 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.087082,0.13062 -0.087082,0.21149 v 2.6871 c 0,0.0871 0.024881,0.1555 0.087082,0.21148 0.055981,0.0622 0.1244029,0.0871 0.211485,0.0871 z"
+ style="stroke-width:0.15923578"
+ id="path834" />
+ </g>
+ <g
+ id="g28"
+ transform="translate(-0.23995531,0.02790178)">
+ <g
+ id="g835">
+ <g
+ transform="matrix(1.0000001,0,0,0.98554676,-7.6075554e-7,4.2369817)"
+ id="g25">
+ <path
+ d="m 7.426334,293.15097 c 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.087082,-0.1244 0.087082,-0.21149 v -2.6871 c 0,-0.0809 -0.031101,-0.14928 -0.087082,-0.21149 -0.062201,-0.056 -0.1306232,-0.0871 -0.2114851,-0.0871 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.087082,0.13063 -0.087082,0.21149 v 2.6871 c 0,0.0871 0.024881,0.15551 0.087082,0.21149 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578"
+ id="path896"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 7.4249389,289.61754 c 0.080862,0 0.1492836,-0.0249 0.2114851,-0.0871 0.055981,-0.056 0.086228,-0.1244 0.087082,-0.21149 l 0.0014,-0.14231 c 7.93e-4,-0.0809 -0.031101,-0.14929 -0.087082,-0.21149 -0.062201,-0.056 -0.1306232,-0.0871 -0.2114851,-0.0871 -0.087082,0 -0.1555037,0.0311 -0.211485,0.0871 -0.062202,0.0622 -0.086289,0.13062 -0.087082,0.21149 l -0.0014,0.14231 c -8.538e-4,0.0871 0.024881,0.15551 0.087082,0.21149 0.055981,0.0622 0.124403,0.0871 0.211485,0.0871 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:RoutedGothicEx;-inkscape-font-specification:'RoutedGothicEx, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15923578"
+ id="path898"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="scsscscsscs" />
+ </g>
+ </g>
+ </g>
+</svg>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Modules</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('modules.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">Modules</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here is a list of all modules:</div><div class="directory">
+<table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__malloc.html" target="_self">Basic Allocation</a></td><td class="desc">The basic allocation interface </td></tr>
+<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__extended.html" target="_self">Extended Functions</a></td><td class="desc">Extended functionality </td></tr>
+<tr id="row_2_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__aligned.html" target="_self">Aligned Allocation</a></td><td class="desc">Allocating aligned memory blocks </td></tr>
+<tr id="row_3_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__heap.html" target="_self">Heap Allocation</a></td><td class="desc">First-class heaps that can be destroyed in one go </td></tr>
+<tr id="row_4_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__zeroinit.html" target="_self">Zero initialized re-allocation</a></td><td class="desc">The zero-initialized re-allocations are only valid on memory that was originally allocated with zero initialization too </td></tr>
+<tr id="row_5_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__typed.html" target="_self">Typed Macros</a></td><td class="desc">Typed allocation macros </td></tr>
+<tr id="row_6_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__analysis.html" target="_self">Heap Introspection</a></td><td class="desc">Inspect the heap at runtime </td></tr>
+<tr id="row_7_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__options.html" target="_self">Runtime Options</a></td><td class="desc">Set runtime behavior </td></tr>
+<tr id="row_8_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__posix.html" target="_self">Posix</a></td><td class="desc"><code>mi_</code> prefixed implementations of various Posix, Unix, and C++ allocation functions </td></tr>
+<tr id="row_9_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="group__cpp.html" target="_self">C++ wrappers</a></td><td class="desc"><code>mi_</code> prefixed implementations of various allocation functions that use C++ semantics on out-of-memory, generally calling <code>std::get_new_handler</code> and raising a <code>std::bad_alloc</code> exception on failure </td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+var modules =
+[
+ [ "Basic Allocation", "group__malloc.html", "group__malloc" ],
+ [ "Extended Functions", "group__extended.html", "group__extended" ],
+ [ "Aligned Allocation", "group__aligned.html", "group__aligned" ],
+ [ "Heap Allocation", "group__heap.html", "group__heap" ],
+ [ "Zero initialized re-allocation", "group__zeroinit.html", "group__zeroinit" ],
+ [ "Typed Macros", "group__typed.html", "group__typed" ],
+ [ "Heap Introspection", "group__analysis.html", "group__analysis" ],
+ [ "Runtime Options", "group__options.html", "group__options" ],
+ [ "Posix", "group__posix.html", "group__posix" ],
+ [ "C++ wrappers", "group__cpp.html", "group__cpp" ]
+];
\ No newline at end of file
--- /dev/null
+#nav-tree .children_ul {
+ margin:0;
+ padding:4px;
+}
+
+#nav-tree ul {
+ list-style:none outside none;
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree li {
+ white-space:nowrap;
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree .plus {
+ margin:0px;
+}
+
+#nav-tree .selected {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+#nav-tree img {
+ margin:0px;
+ padding:0px;
+ border:0px;
+ vertical-align: middle;
+}
+
+#nav-tree a {
+ text-decoration:none;
+ padding:0px;
+ margin:0px;
+ outline:none;
+}
+
+#nav-tree .label {
+ margin:0px;
+ padding:0px;
+ font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+#nav-tree .label a {
+ padding:2px;
+}
+
+#nav-tree .selected a {
+ text-decoration:none;
+ color:#fff;
+}
+
+#nav-tree .children_ul {
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree .item {
+ margin:0px;
+ padding:0px;
+}
+
+#nav-tree {
+ padding: 0px 0px;
+ background-color: #FAFAFF;
+ font-size:14px;
+ overflow:auto;
+}
+
+#doc-content {
+ overflow:auto;
+ display:block;
+ padding:0px;
+ margin:0px;
+ -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#side-nav {
+ padding:0 6px 0 0;
+ margin: 0px;
+ display:block;
+ position: absolute;
+ left: 0px;
+ width: 180px;
+}
+
+.ui-resizable .ui-resizable-handle {
+ display:block;
+}
+
+.ui-resizable-e {
+ background-image:url("splitbar.png");
+ background-size:100%;
+ background-repeat:repeat-y;
+ background-attachment: scroll;
+ cursor:ew-resize;
+ height:100%;
+ right:0;
+ top:0;
+ width:6px;
+}
+
+.ui-resizable-handle {
+ display:none;
+ font-size:0.1px;
+ position:absolute;
+ z-index:1;
+}
+
+#nav-tree-contents {
+ margin: 6px 0px 0px 0px;
+}
+
+#nav-tree {
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F2F3F3;
+ -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#nav-sync {
+ position:absolute;
+ top:5px;
+ right:24px;
+ z-index:0;
+}
+
+#nav-sync img {
+ opacity:0.3;
+}
+
+#nav-sync img:hover {
+ opacity:0.9;
+}
+
+@media print
+{
+ #nav-tree { display: none; }
+ div.ui-resizable-handle { display: none; position: relative; }
+}
+
--- /dev/null
+/*
+ @licstart The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend The above is the entire license notice for the JavaScript code in this file
+ */
+var navTreeSubIndices = new Array();
+var arrowDown = '▼';
+var arrowRight = '►';
+
+function getData(varName)
+{
+ var i = varName.lastIndexOf('/');
+ var n = i>=0 ? varName.substring(i+1) : varName;
+ return eval(n.replace(/\-/g,'_'));
+}
+
+function stripPath(uri)
+{
+ return uri.substring(uri.lastIndexOf('/')+1);
+}
+
+function stripPath2(uri)
+{
+ var i = uri.lastIndexOf('/');
+ var s = uri.substring(i+1);
+ var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
+ return m ? uri.substring(i-6) : s;
+}
+
+function hashValue()
+{
+ return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
+}
+
+function hashUrl()
+{
+ return '#'+hashValue();
+}
+
+function pathName()
+{
+ return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
+}
+
+function localStorageSupported()
+{
+ try {
+ return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
+ }
+ catch(e) {
+ return false;
+ }
+}
+
+function storeLink(link)
+{
+ if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
+ window.localStorage.setItem('navpath',link);
+ }
+}
+
+function deleteLink()
+{
+ if (localStorageSupported()) {
+ window.localStorage.setItem('navpath','');
+ }
+}
+
+function cachedLink()
+{
+ if (localStorageSupported()) {
+ return window.localStorage.getItem('navpath');
+ } else {
+ return '';
+ }
+}
+
+function getScript(scriptName,func,show)
+{
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement('script');
+ script.id = scriptName;
+ script.type = 'text/javascript';
+ script.onload = func;
+ script.src = scriptName+'.js';
+ head.appendChild(script);
+}
+
+function createIndent(o,domNode,node,level)
+{
+ var level=-1;
+ var n = node;
+ while (n.parentNode) { level++; n=n.parentNode; }
+ if (node.childrenData) {
+ var imgNode = document.createElement("span");
+ imgNode.className = 'arrow';
+ imgNode.style.paddingLeft=(16*level).toString()+'px';
+ imgNode.innerHTML=arrowRight;
+ node.plus_img = imgNode;
+ node.expandToggle = document.createElement("a");
+ node.expandToggle.href = "javascript:void(0)";
+ node.expandToggle.onclick = function() {
+ if (node.expanded) {
+ $(node.getChildrenUL()).slideUp("fast");
+ node.plus_img.innerHTML=arrowRight;
+ node.expanded = false;
+ } else {
+ expandNode(o, node, false, false);
+ }
+ }
+ node.expandToggle.appendChild(imgNode);
+ domNode.appendChild(node.expandToggle);
+ } else {
+ var span = document.createElement("span");
+ span.className = 'arrow';
+ span.style.width = 16*(level+1)+'px';
+ span.innerHTML = ' ';
+ domNode.appendChild(span);
+ }
+}
+
+var animationInProgress = false;
+
+function gotoAnchor(anchor,aname,updateLocation)
+{
+ var pos, docContent = $('#doc-content');
+ var ancParent = $(anchor.parent());
+ if (ancParent.hasClass('memItemLeft') ||
+ ancParent.hasClass('memtitle') ||
+ ancParent.hasClass('fieldname') ||
+ ancParent.hasClass('fieldtype') ||
+ ancParent.is(':header'))
+ {
+ pos = ancParent.position().top;
+ } else if (anchor.position()) {
+ pos = anchor.position().top;
+ }
+ if (pos) {
+ var dist = Math.abs(Math.min(
+ pos-docContent.offset().top,
+ docContent[0].scrollHeight-
+ docContent.height()-docContent.scrollTop()));
+ animationInProgress=true;
+ docContent.animate({
+ scrollTop: pos + docContent.scrollTop() - docContent.offset().top
+ },Math.max(50,Math.min(500,dist)),function(){
+ if (updateLocation) window.location.href=aname;
+ animationInProgress=false;
+ });
+ }
+}
+
+function newNode(o, po, text, link, childrenData, lastNode)
+{
+ var node = new Object();
+ node.children = Array();
+ node.childrenData = childrenData;
+ node.depth = po.depth + 1;
+ node.relpath = po.relpath;
+ node.isLast = lastNode;
+
+ node.li = document.createElement("li");
+ po.getChildrenUL().appendChild(node.li);
+ node.parentNode = po;
+
+ node.itemDiv = document.createElement("div");
+ node.itemDiv.className = "item";
+
+ node.labelSpan = document.createElement("span");
+ node.labelSpan.className = "label";
+
+ createIndent(o,node.itemDiv,node,0);
+ node.itemDiv.appendChild(node.labelSpan);
+ node.li.appendChild(node.itemDiv);
+
+ var a = document.createElement("a");
+ node.labelSpan.appendChild(a);
+ node.label = document.createTextNode(text);
+ node.expanded = false;
+ a.appendChild(node.label);
+ if (link) {
+ var url;
+ if (link.substring(0,1)=='^') {
+ url = link.substring(1);
+ link = url;
+ } else {
+ url = node.relpath+link;
+ }
+ a.className = stripPath(link.replace('#',':'));
+ if (link.indexOf('#')!=-1) {
+ var aname = '#'+link.split('#')[1];
+ var srcPage = stripPath(pathName());
+ var targetPage = stripPath(link.split('#')[0]);
+ a.href = srcPage!=targetPage ? url : "javascript:void(0)";
+ a.onclick = function(){
+ storeLink(link);
+ if (!$(a).parent().parent().hasClass('selected'))
+ {
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ $(a).parent().parent().addClass('selected');
+ $(a).parent().parent().attr('id','selected');
+ }
+ var anchor = $(aname);
+ gotoAnchor(anchor,aname,true);
+ };
+ } else {
+ a.href = url;
+ a.onclick = function() { storeLink(link); }
+ }
+ } else {
+ if (childrenData != null)
+ {
+ a.className = "nolink";
+ a.href = "javascript:void(0)";
+ a.onclick = node.expandToggle.onclick;
+ }
+ }
+
+ node.childrenUL = null;
+ node.getChildrenUL = function() {
+ if (!node.childrenUL) {
+ node.childrenUL = document.createElement("ul");
+ node.childrenUL.className = "children_ul";
+ node.childrenUL.style.display = "none";
+ node.li.appendChild(node.childrenUL);
+ }
+ return node.childrenUL;
+ };
+
+ return node;
+}
+
+function showRoot()
+{
+ var headerHeight = $("#top").height();
+ var footerHeight = $("#nav-path").height();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ (function (){ // retry until we can scroll to the selected item
+ try {
+ var navtree=$('#nav-tree');
+ navtree.scrollTo('#selected',100,{offset:-windowHeight/2});
+ } catch (err) {
+ setTimeout(arguments.callee, 0);
+ }
+ })();
+}
+
+function expandNode(o, node, imm, showRoot)
+{
+ if (node.childrenData && !node.expanded) {
+ if (typeof(node.childrenData)==='string') {
+ var varName = node.childrenData;
+ getScript(node.relpath+varName,function(){
+ node.childrenData = getData(varName);
+ expandNode(o, node, imm, showRoot);
+ }, showRoot);
+ } else {
+ if (!node.childrenVisited) {
+ getNode(o, node);
+ }
+ $(node.getChildrenUL()).slideDown("fast");
+ node.plus_img.innerHTML = arrowDown;
+ node.expanded = true;
+ }
+ }
+}
+
+function glowEffect(n,duration)
+{
+ n.addClass('glow').delay(duration).queue(function(next){
+ $(this).removeClass('glow');next();
+ });
+}
+
+function highlightAnchor()
+{
+ var aname = hashUrl();
+ var anchor = $(aname);
+ if (anchor.parent().attr('class')=='memItemLeft'){
+ var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
+ glowEffect(rows.children(),300); // member without details
+ } else if (anchor.parent().attr('class')=='fieldname'){
+ glowEffect(anchor.parent().parent(),1000); // enum value
+ } else if (anchor.parent().attr('class')=='fieldtype'){
+ glowEffect(anchor.parent().parent(),1000); // struct field
+ } else if (anchor.parent().is(":header")) {
+ glowEffect(anchor.parent(),1000); // section header
+ } else {
+ glowEffect(anchor.next(),1000); // normal member
+ }
+}
+
+function selectAndHighlight(hash,n)
+{
+ var a;
+ if (hash) {
+ var link=stripPath(pathName())+':'+hash.substring(1);
+ a=$('.item a[class$="'+link+'"]');
+ }
+ if (a && a.length) {
+ a.parent().parent().addClass('selected');
+ a.parent().parent().attr('id','selected');
+ highlightAnchor();
+ } else if (n) {
+ $(n.itemDiv).addClass('selected');
+ $(n.itemDiv).attr('id','selected');
+ }
+ if ($('#nav-tree-contents .item:first').hasClass('selected')) {
+ $('#nav-sync').css('top','30px');
+ } else {
+ $('#nav-sync').css('top','5px');
+ }
+ showRoot();
+}
+
+function showNode(o, node, index, hash)
+{
+ if (node && node.childrenData) {
+ if (typeof(node.childrenData)==='string') {
+ var varName = node.childrenData;
+ getScript(node.relpath+varName,function(){
+ node.childrenData = getData(varName);
+ showNode(o,node,index,hash);
+ },true);
+ } else {
+ if (!node.childrenVisited) {
+ getNode(o, node);
+ }
+ $(node.getChildrenUL()).css({'display':'block'});
+ node.plus_img.innerHTML = arrowDown;
+ node.expanded = true;
+ var n = node.children[o.breadcrumbs[index]];
+ if (index+1<o.breadcrumbs.length) {
+ showNode(o,n,index+1,hash);
+ } else {
+ if (typeof(n.childrenData)==='string') {
+ var varName = n.childrenData;
+ getScript(n.relpath+varName,function(){
+ n.childrenData = getData(varName);
+ node.expanded=false;
+ showNode(o,node,index,hash); // retry with child node expanded
+ },true);
+ } else {
+ var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
+ if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
+ expandNode(o, n, true, true);
+ }
+ selectAndHighlight(hash,n);
+ }
+ }
+ }
+ } else {
+ selectAndHighlight(hash);
+ }
+}
+
+function removeToInsertLater(element) {
+ var parentNode = element.parentNode;
+ var nextSibling = element.nextSibling;
+ parentNode.removeChild(element);
+ return function() {
+ if (nextSibling) {
+ parentNode.insertBefore(element, nextSibling);
+ } else {
+ parentNode.appendChild(element);
+ }
+ };
+}
+
+function getNode(o, po)
+{
+ var insertFunction = removeToInsertLater(po.li);
+ po.childrenVisited = true;
+ var l = po.childrenData.length-1;
+ for (var i in po.childrenData) {
+ var nodeData = po.childrenData[i];
+ po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
+ i==l);
+ }
+ insertFunction();
+}
+
+function gotoNode(o,subIndex,root,hash,relpath)
+{
+ var nti = navTreeSubIndices[subIndex][root+hash];
+ o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
+ if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
+ navTo(o,NAVTREE[0][1],"",relpath);
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ }
+ if (o.breadcrumbs) {
+ o.breadcrumbs.unshift(0); // add 0 for root node
+ showNode(o, o.node, 0, hash);
+ }
+}
+
+function navTo(o,root,hash,relpath)
+{
+ var link = cachedLink();
+ if (link) {
+ var parts = link.split('#');
+ root = parts[0];
+ if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
+ else hash='';
+ }
+ if (hash.match(/^#l\d+$/)) {
+ var anchor=$('a[name='+hash.substring(1)+']');
+ glowEffect(anchor.parent(),1000); // line number
+ hash=''; // strip line number anchors
+ }
+ var url=root+hash;
+ var i=-1;
+ while (NAVTREEINDEX[i+1]<=url) i++;
+ if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
+ if (navTreeSubIndices[i]) {
+ gotoNode(o,i,root,hash,relpath)
+ } else {
+ getScript(relpath+'navtreeindex'+i,function(){
+ navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
+ if (navTreeSubIndices[i]) {
+ gotoNode(o,i,root,hash,relpath);
+ }
+ },true);
+ }
+}
+
+function showSyncOff(n,relpath)
+{
+ n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
+}
+
+function showSyncOn(n,relpath)
+{
+ n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
+}
+
+function toggleSyncButton(relpath)
+{
+ var navSync = $('#nav-sync');
+ if (navSync.hasClass('sync')) {
+ navSync.removeClass('sync');
+ showSyncOff(navSync,relpath);
+ storeLink(stripPath2(pathName())+hashUrl());
+ } else {
+ navSync.addClass('sync');
+ showSyncOn(navSync,relpath);
+ deleteLink();
+ }
+}
+
+var loadTriggered = false;
+var readyTriggered = false;
+var loadObject,loadToRoot,loadUrl,loadRelPath;
+
+$(window).on('load',function(){
+ if (readyTriggered) { // ready first
+ navTo(loadObject,loadToRoot,loadUrl,loadRelPath);
+ showRoot();
+ }
+ loadTriggered=true;
+});
+
+function initNavTree(toroot,relpath)
+{
+ var o = new Object();
+ o.toroot = toroot;
+ o.node = new Object();
+ o.node.li = document.getElementById("nav-tree-contents");
+ o.node.childrenData = NAVTREE;
+ o.node.children = new Array();
+ o.node.childrenUL = document.createElement("ul");
+ o.node.getChildrenUL = function() { return o.node.childrenUL; };
+ o.node.li.appendChild(o.node.childrenUL);
+ o.node.depth = 0;
+ o.node.relpath = relpath;
+ o.node.expanded = false;
+ o.node.isLast = true;
+ o.node.plus_img = document.createElement("span");
+ o.node.plus_img.className = 'arrow';
+ o.node.plus_img.innerHTML = arrowRight;
+
+ if (localStorageSupported()) {
+ var navSync = $('#nav-sync');
+ if (cachedLink()) {
+ showSyncOff(navSync,relpath);
+ navSync.removeClass('sync');
+ } else {
+ showSyncOn(navSync,relpath);
+ }
+ navSync.click(function(){ toggleSyncButton(relpath); });
+ }
+
+ if (loadTriggered) { // load before ready
+ navTo(o,toroot,hashUrl(),relpath);
+ showRoot();
+ } else { // ready before load
+ loadObject = o;
+ loadToRoot = toroot;
+ loadUrl = hashUrl();
+ loadRelPath = relpath;
+ readyTriggered=true;
+ }
+
+ $(window).bind('hashchange', function(){
+ if (window.location.hash && window.location.hash.length>1){
+ var a;
+ if ($(location).attr('hash')){
+ var clslink=stripPath(pathName())+':'+hashValue();
+ a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
+ }
+ if (a==null || !$(a).parent().parent().hasClass('selected')){
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ }
+ var link=stripPath2(pathName());
+ navTo(o,link,hashUrl(),relpath);
+ } else if (!animationInProgress) {
+ $('#doc-content').scrollTop(0);
+ $('.item').removeClass('selected');
+ $('.item').removeAttr('id');
+ navTo(o,toroot,hashUrl(),relpath);
+ }
+ })
+}
+/* @license-end */
--- /dev/null
+/*
+ @licstart The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend The above is the entire license notice for the JavaScript code in this file
+*/
+var NAVTREE =
+[
+ [ "mi-malloc", "index.html", [
+ [ "Building", "build.html", null ],
+ [ "Using the library", "using.html", null ],
+ [ "Environment Options", "environment.html", null ],
+ [ "Overriding Malloc", "overrides.html", null ],
+ [ "Performance", "bench.html", null ],
+ [ "Modules", "modules.html", "modules" ],
+ [ "Data Structures", "annotated.html", [
+ [ "Data Structures", "annotated.html", "annotated_dup" ],
+ [ "Data Structure Index", "classes.html", null ],
+ [ "Data Fields", "functions.html", [
+ [ "All", "functions.html", null ],
+ [ "Variables", "functions_vars.html", null ]
+ ] ]
+ ] ]
+ ] ]
+];
+
+var NAVTREEINDEX =
+[
+"annotated.html"
+];
+
+var SYNCONMSG = 'click to disable panel synchronisation';
+var SYNCOFFMSG = 'click to enable panel synchronisation';
\ No newline at end of file
--- /dev/null
+var NAVTREEINDEX0 =
+{
+"annotated.html":[6,0],
+"bench.html":[4],
+"build.html":[0],
+"classes.html":[6,1],
+"environment.html":[2],
+"functions.html":[6,2,0],
+"functions_vars.html":[6,2,1],
+"group__aligned.html":[5,2],
+"group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3":[5,2,2],
+"group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819":[5,2,7],
+"group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae":[5,2,5],
+"group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9":[5,2,1],
+"group__aligned.html#ga5850da130c936bd77db039dcfbc8295d":[5,2,4],
+"group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8":[5,2,8],
+"group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56":[5,2,3],
+"group__aligned.html#ga83c03016066b438f51a8095e9140be06":[5,2,0],
+"group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb":[5,2,6],
+"group__analysis.html":[5,6],
+"group__analysis.html#a332a6c14d736a99699d5453a1cb04b41":[5,6,0,0],
+"group__analysis.html#ab47526df656d8837ec3e97f11b83f835":[5,6,0,2],
+"group__analysis.html#ab820302c5cd0df133eb8e51650a008b4":[5,6,0,4],
+"group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8":[5,6,0,1],
+"group__analysis.html#ae848a3e6840414891035423948ca0383":[5,6,0,3],
+"group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377":[5,6,3],
+"group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5":[5,6,2],
+"group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed":[5,6,5],
+"group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af":[5,6,4],
+"group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65":[5,6,1],
+"group__analysis.html#structmi__heap__area__t":[5,6,0],
+"group__cpp.html":[5,9],
+"group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907":[5,9,7],
+"group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e":[5,9,6],
+"group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545":[5,9,1],
+"group__cpp.html#gab5e29558926d934c3f1cae8c815f942c":[5,9,3],
+"group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81":[5,9,4],
+"group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a":[5,9,5],
+"group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3":[5,9,2],
+"group__cpp.html#structmi__stl__allocator":[5,9,0],
+"group__extended.html":[5,1],
+"group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767":[5,1,16],
+"group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee":[5,1,24],
+"group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf":[5,1,21],
+"group__extended.html#ga1ea64283508718d9d645c38efc2f4305":[5,1,0],
+"group__extended.html#ga220f29f40a44404b0061c15bc1c31152":[5,1,25],
+"group__extended.html#ga251d369cda3f1c2a955c555486ed90e5":[5,1,2],
+"group__extended.html#ga299dae78d25ce112e384a98b7309c5be":[5,1,1],
+"group__extended.html#ga2d126e5c62d3badc35445e5d84166df2":[5,1,18],
+"group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50":[5,1,15],
+"group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece":[5,1,11],
+"group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99":[5,1,20],
+"group__extended.html#ga421430e2226d7d468529cec457396756":[5,1,4],
+"group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf":[5,1,9],
+"group__extended.html#ga537f13b299ddf801e49a5a94fde02c79":[5,1,19],
+"group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6":[5,1,6],
+"group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99":[5,1,8],
+"group__extended.html#ga7795a13d20087447281858d2c771cca1":[5,1,14],
+"group__extended.html#ga7d862c2affd5790381da14eb102a364d":[5,1,10],
+"group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1":[5,1,17],
+"group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45":[5,1,12],
+"group__extended.html#gaad25050b19f30cd79397b227e0157a3f":[5,1,7],
+"group__extended.html#gab1dac8476c46cb9eecab767eb40c1525":[5,1,23],
+"group__extended.html#gac057927cd06c854b45fe7847e921bd47":[5,1,5],
+"group__extended.html#gad823d23444a4b77a40f66bf075a98a0c":[5,1,3],
+"group__extended.html#gae5b17ff027cd2150b43a33040250cf3f":[5,1,13],
+"group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17":[5,1,22],
+"group__heap.html":[5,3],
+"group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0":[5,3,20],
+"group__heap.html#ga08ca6419a5c057a4d965868998eef487":[5,3,3],
+"group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5":[5,3,22],
+"group__heap.html#ga23acd7680fb0976dde3783254c6c874b":[5,3,11],
+"group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409":[5,3,5],
+"group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2":[5,3,0],
+"group__heap.html#ga45fb43a62776fbebbdf1edd99b527954":[5,3,26],
+"group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527":[5,3,18],
+"group__heap.html#ga4af03a6e2b93fae77424d93f889705c3":[5,3,2],
+"group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc":[5,3,7],
+"group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11":[5,3,14],
+"group__heap.html#ga7922f7495cde30b1984d0e6072419298":[5,3,4],
+"group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0":[5,3,13],
+"group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05":[5,3,8],
+"group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a":[5,3,23],
+"group__heap.html#ga903104592c8ed53417a3762da6241133":[5,3,24],
+"group__heap.html#ga9cbed01e42c0647907295de92c3fa296":[5,3,9],
+"group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d":[5,3,6],
+"group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368":[5,3,12],
+"group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0":[5,3,25],
+"group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55":[5,3,1],
+"group__heap.html#gaaef3395f66be48f37bdc8322509c5d81":[5,3,15],
+"group__heap.html#gab5b87e1805306f70df38789fcfcf6653":[5,3,10],
+"group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422":[5,3,21],
+"group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8":[5,3,19],
+"group__heap.html#gaf96c788a1bf553fe2d371de9365e047c":[5,3,17],
+"group__heap.html#gafc603b696bd14cae6da28658f950d98c":[5,3,16],
+"group__malloc.html":[5,0],
+"group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe":[5,0,8],
+"group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6":[5,0,4],
+"group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc":[5,0,9],
+"group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a":[5,0,3],
+"group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853":[5,0,7],
+"group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d":[5,0,0],
+"group__malloc.html#gaaabf971c2571891433477e2d21a35266":[5,0,11],
+"group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4":[5,0,1],
+"group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2":[5,0,10],
+"group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6":[5,0,5],
+"group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95":[5,0,2],
+"group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000":[5,0,12],
+"group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0":[5,0,6],
+"group__options.html":[5,7],
+"group__options.html#ga04180ae41b0d601421dd62ced40ca050":[5,7,2],
+"group__options.html#ga459ad98f18b3fc9275474807fe0ca188":[5,7,4],
+"group__options.html#ga65518b69ec5d32336b50e07f74b3f629":[5,7,8],
+"group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a":[5,7,3],
+"group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90":[5,7,6],
+"group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed":[5,7,7],
+"group__options.html#gaebf6ff707a2e688ebb1a2296ca564054":[5,7,1],
+"group__options.html#gaf84921c32375e25754dc2ee6a911fa60":[5,7,5],
+"group__options.html#gafebf7ed116adb38ae5218bc3ce06884c":[5,7,0],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda":[5,7,0,1],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74":[5,7,0,12],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5":[5,7,0,11],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c":[5,7,0,14],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b":[5,7,0,3],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1":[5,7,0,8],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad":[5,7,0,4],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e":[5,7,0,5],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf":[5,7,0,15],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a":[5,7,0,16],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777":[5,7,0,2],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c":[5,7,0,7],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536":[5,7,0,13],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2":[5,7,0,6],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968":[5,7,0,9],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d":[5,7,0,10],
+"group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0":[5,7,0,0],
+"group__posix.html":[5,8],
+"group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17":[5,8,7],
+"group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9":[5,8,3],
+"group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5":[5,8,1],
+"group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de":[5,8,6],
+"group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088":[5,8,12],
+"group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7":[5,8,2],
+"group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc":[5,8,5],
+"group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b":[5,8,13],
+"group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5":[5,8,11],
+"group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e":[5,8,8],
+"group__posix.html#gacff84f226ba9feb2031b8992e5579447":[5,8,9],
+"group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a":[5,8,0],
+"group__posix.html#gae01389eedab8d67341ff52e2aad80ebb":[5,8,4],
+"group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e":[5,8,10],
+"group__typed.html":[5,5],
+"group__typed.html#ga0619a62c5fd886f1016030abe91f0557":[5,5,7],
+"group__typed.html#ga1158b49a55dfa81f58a4426a7578f523":[5,5,9],
+"group__typed.html#ga3e50a1600958fcaf1a7f3560c9174f9e":[5,5,5],
+"group__typed.html#ga4e5d1f1707c90e5f55e023ac5f45fe74":[5,5,1],
+"group__typed.html#ga653bcb24ac495bc19940ecd6898f9cd7":[5,5,2],
+"group__typed.html#ga6b75cb9c4b9c647661d0924552dc6e83":[5,5,3],
+"group__typed.html#gac77a61bdaf680a803785fe307820b48c":[5,5,10],
+"group__typed.html#gad6e87e86e994aa14416ae9b5d4c188fe":[5,5,6],
+"group__typed.html#gae5cb6e0fafc9f23169c5622e077afe8b":[5,5,8],
+"group__typed.html#gae80c47c9d4cab10961fff1a8ac98fc07":[5,5,0],
+"group__typed.html#gaf213d5422ec35e7f6caad827c79bc948":[5,5,4],
+"group__zeroinit.html":[5,4],
+"group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664":[5,4,4],
+"group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f":[5,4,6],
+"group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7":[5,4,2],
+"group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9":[5,4,7],
+"group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd":[5,4,0],
+"group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6":[5,4,8],
+"group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3":[5,4,1],
+"group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb":[5,4,5],
+"group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0":[5,4,9],
+"group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76":[5,4,3],
+"group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1":[5,4,10],
+"index.html":[],
+"modules.html":[5],
+"overrides.html":[3],
+"pages.html":[],
+"using.html":[1]
+};
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Overriding Malloc</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('overrides.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="PageDoc"><div class="header">
+ <div class="headertitle">
+<div class="title">Overriding Malloc </div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><p>Overriding the standard <code>malloc</code> can be done either <em>dynamically</em> or <em>statically</em>.</p>
+<h2>Dynamic override</h2>
+<p>This is the recommended way to override the standard malloc interface.</p>
+<h3>Linux, BSD</h3>
+<p>On these systems we preload the mimalloc shared library so all calls to the standard <code>malloc</code> interface are resolved to the <em>mimalloc</em> library.</p>
+<ul>
+<li><code>env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram</code></li>
+</ul>
+<p>You can set extra environment variables to check that mimalloc is running, like: </p><div class="fragment"><div class="line">env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram</div>
+</div><!-- fragment --><p> or run with the debug version to get detailed statistics: </p><div class="fragment"><div class="line">env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram</div>
+</div><!-- fragment --><h3>MacOS</h3>
+<p>On macOS we can also preload the mimalloc shared library so all calls to the standard <code>malloc</code> interface are resolved to the <em>mimalloc</em> library.</p>
+<ul>
+<li><code>env DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram</code></li>
+</ul>
+<p>Note that certain security restrictions may apply when doing this from the <a href="https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash">shell</a>.</p>
+<p>(Note: macOS support for dynamic overriding is recent, please report any issues.)</p>
+<h3>Windows</h3>
+<p>Overriding on Windows is robust and has the particular advantage to be able to redirect all malloc/free calls that go through the (dynamic) C runtime allocator, including those from other DLL's or libraries.</p>
+<p>The overriding on Windows requires that you link your program explicitly with the mimalloc DLL and use the C-runtime library as a DLL (using the <code>/MD</code> or <code>/MDd</code> switch). Also, the <code>mimalloc-redirect.dll</code> (or <code>mimalloc-redirect32.dll</code>) must be available in the same folder as the main <code>mimalloc-override.dll</code> at runtime (as it is a dependency). The redirection DLL ensures that all calls to the C runtime malloc API get redirected to mimalloc (in <code>mimalloc-override.dll</code>).</p>
+<p>To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some call to the mimalloc API in the <code>main</code> function, like <code>mi_version()</code> (or use the <code>/INCLUDE:mi_version</code> switch on the linker). See the <code>mimalloc-override-test</code> project for an example on how to use this. For best performance on Windows with C++, it is also recommended to also override the <code>new</code>/<code>delete</code> operations (by including <a href="https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h"><code>mimalloc-new-delete.h</code></a> a single(!) source file in your project without linking to the mimalloc library).</p>
+<p>The environment variable <code>MIMALLOC_DISABLE_REDIRECT=1</code> can be used to disable dynamic overriding at run-time. Use <code>MIMALLOC_VERBOSE=1</code> to check if mimalloc was successfully redirected.</p>
+<p>(Note: in principle, it is possible to even patch existing executables without any recompilation if they are linked with the dynamic C runtime (<code>ucrtbase.dll</code>) – just put the <code>mimalloc-override.dll</code> into the import table (and put <code>mimalloc-redirect.dll</code> in the same folder) Such patching can be done for example with <a href="https://ntcore.com/?page_id=388">CFF Explorer</a>).</p>
+<h2>Static override</h2>
+<p>On Unix systems, you can also statically link with <em>mimalloc</em> to override the standard malloc interface. The recommended way is to link the final program with the <em>mimalloc</em> single object file (<code>mimalloc-override.o</code>). We use an object file instead of a library file as linkers give preference to that over archives to resolve symbols. To ensure that the standard malloc interface resolves to the <em>mimalloc</em> library, link it as the first object file. For example:</p>
+<div class="fragment"><div class="line">gcc -o myprogram mimalloc-<span class="keyword">override</span>.o myfile1.c ...</div>
+</div><!-- fragment --><h2>List of Overrides:</h2>
+<p>The specific functions that get redirected to the <em>mimalloc</em> library are:</p>
+<div class="fragment"><div class="line"><span class="comment">// C</span></div>
+<div class="line"><span class="keywordtype">void</span>* malloc(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><span class="keywordtype">void</span>* calloc(<span class="keywordtype">size_t</span> size, <span class="keywordtype">size_t</span> n);</div>
+<div class="line"><span class="keywordtype">void</span>* realloc(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><span class="keywordtype">void</span> free(<span class="keywordtype">void</span>* p);</div>
+<div class="line"> </div>
+<div class="line"><span class="keywordtype">void</span>* aligned_alloc(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><span class="keywordtype">char</span>* strdup(<span class="keyword">const</span> <span class="keywordtype">char</span>* s);</div>
+<div class="line"><span class="keywordtype">char</span>* strndup(<span class="keyword">const</span> <span class="keywordtype">char</span>* s, <span class="keywordtype">size_t</span> n);</div>
+<div class="line"><span class="keywordtype">char</span>* realpath(<span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">char</span>* resolved_name);</div>
+<div class="line"> </div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// C++</span></div>
+<div class="line"><span class="keywordtype">void</span> <span class="keyword">operator</span> <span class="keyword">delete</span>(<span class="keywordtype">void</span>* p);</div>
+<div class="line"><span class="keywordtype">void</span> <span class="keyword">operator</span> <span class="keyword">delete</span>[](<span class="keywordtype">void</span>* p);</div>
+<div class="line"> </div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>(std::size_t n) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[](std::size_t n) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>( std::size_t n, std::align_val_t align) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[]( std::size_t n, std::align_val_t align) noexcept(<span class="keyword">false</span>);</div>
+<div class="line"> </div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span> ( std::size_t count, <span class="keyword">const</span> std::nothrow_t& tag);</div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[]( std::size_t count, <span class="keyword">const</span> std::nothrow_t& tag);</div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span> ( std::size_t count, std::align_val_t al, <span class="keyword">const</span> std::nothrow_t&);</div>
+<div class="line"><span class="keywordtype">void</span>* <span class="keyword">operator</span> <span class="keyword">new</span>[]( std::size_t count, std::align_val_t al, <span class="keyword">const</span> std::nothrow_t&);</div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// Posix</span></div>
+<div class="line"><span class="keywordtype">int</span> posix_memalign(<span class="keywordtype">void</span>** p, <span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// Linux</span></div>
+<div class="line"><span class="keywordtype">void</span>* memalign(<span class="keywordtype">size_t</span> alignment, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"><span class="keywordtype">void</span>* valloc(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><span class="keywordtype">void</span>* pvalloc(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"><span class="keywordtype">size_t</span> malloc_usable_size(<span class="keywordtype">void</span> *p);</div>
+<div class="line"><span class="keywordtype">void</span>* reallocf(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// macOS</span></div>
+<div class="line"><span class="keywordtype">void</span> vfree(<span class="keywordtype">void</span>* p);</div>
+<div class="line"><span class="keywordtype">size_t</span> malloc_size(<span class="keyword">const</span> <span class="keywordtype">void</span>* p);</div>
+<div class="line"><span class="keywordtype">size_t</span> malloc_good_size(<span class="keywordtype">size_t</span> size);</div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// BSD</span></div>
+<div class="line"><span class="keywordtype">void</span>* reallocarray( <span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size );</div>
+<div class="line"><span class="keywordtype">void</span>* reallocf(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><span class="keywordtype">void</span> cfree(<span class="keywordtype">void</span>* p);</div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// NetBSD</span></div>
+<div class="line"><span class="keywordtype">int</span> reallocarr(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size);</div>
+<div class="line"> </div>
+<div class="line"><span class="comment">// Windows</span></div>
+<div class="line"><span class="keywordtype">void</span>* _expand(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize);</div>
+<div class="line"><span class="keywordtype">size_t</span> _msize(<span class="keywordtype">void</span>* p);</div>
+<div class="line"> </div>
+<div class="line"><span class="keywordtype">void</span>* _malloc_dbg(<span class="keywordtype">size_t</span> size, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div>
+<div class="line"><span class="keywordtype">void</span>* _realloc_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> newsize, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div>
+<div class="line"><span class="keywordtype">void</span>* _calloc_dbg(<span class="keywordtype">size_t</span> count, <span class="keywordtype">size_t</span> size, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div>
+<div class="line"><span class="keywordtype">void</span>* _expand_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">size_t</span> size, <span class="keywordtype">int</span> block_type, <span class="keyword">const</span> <span class="keywordtype">char</span>* fname, <span class="keywordtype">int</span> line);</div>
+<div class="line"><span class="keywordtype">size_t</span> _msize_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">int</span> block_type);</div>
+<div class="line"><span class="keywordtype">void</span> _free_dbg(<span class="keywordtype">void</span>* p, <span class="keywordtype">int</span> block_type);</div>
+</div><!-- fragment --> </div></div><!-- contents -->
+</div><!-- PageDoc -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Related Pages</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('pages.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+ <div class="headertitle">
+<div class="title">Related Pages</div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here is a list of all related documentation pages:</div><div class="directory">
+<table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="build.html" target="_self">Building</a></td><td class="desc"></td></tr>
+<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="using.html" target="_self">Using the library</a></td><td class="desc"></td></tr>
+<tr id="row_2_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="environment.html" target="_self">Environment Options</a></td><td class="desc"></td></tr>
+<tr id="row_3_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="overrides.html" target="_self">Overriding Malloc</a></td><td class="desc"></td></tr>
+<tr id="row_4_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><a class="el" href="bench.html" target="_self">Performance</a></td><td class="desc"></td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
--- /dev/null
+/*
+ @licstart The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend The above is the entire license notice for the JavaScript code in this file
+ */
+function initResizable()
+{
+ var cookie_namespace = 'doxygen';
+ var sidenav,navtree,content,header,collapsed,collapsedWidth=0,barWidth=6,desktop_vp=768,titleHeight;
+
+ function readCookie(cookie)
+ {
+ var myCookie = cookie_namespace+"_"+cookie+"=";
+ if (document.cookie) {
+ var index = document.cookie.indexOf(myCookie);
+ if (index != -1) {
+ var valStart = index + myCookie.length;
+ var valEnd = document.cookie.indexOf(";", valStart);
+ if (valEnd == -1) {
+ valEnd = document.cookie.length;
+ }
+ var val = document.cookie.substring(valStart, valEnd);
+ return val;
+ }
+ }
+ return 0;
+ }
+
+ function writeCookie(cookie, val, expiration)
+ {
+ if (val==undefined) return;
+ if (expiration == null) {
+ var date = new Date();
+ date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
+ expiration = date.toGMTString();
+ }
+ document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/";
+ }
+
+ function resizeWidth()
+ {
+ var windowWidth = $(window).width() + "px";
+ var sidenavWidth = $(sidenav).outerWidth();
+ content.css({marginLeft:parseInt(sidenavWidth)+"px"});
+ writeCookie('width',sidenavWidth-barWidth, null);
+ }
+
+ function restoreWidth(navWidth)
+ {
+ var windowWidth = $(window).width() + "px";
+ content.css({marginLeft:parseInt(navWidth)+barWidth+"px"});
+ sidenav.css({width:navWidth + "px"});
+ }
+
+ function resizeHeight()
+ {
+ var headerHeight = header.outerHeight();
+ var footerHeight = footer.outerHeight();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ content.css({height:windowHeight + "px"});
+ navtree.css({height:windowHeight + "px"});
+ sidenav.css({height:windowHeight + "px"});
+ var width=$(window).width();
+ if (width!=collapsedWidth) {
+ if (width<desktop_vp && collapsedWidth>=desktop_vp) {
+ if (!collapsed) {
+ collapseExpand();
+ }
+ } else if (width>desktop_vp && collapsedWidth<desktop_vp) {
+ if (collapsed) {
+ collapseExpand();
+ }
+ }
+ collapsedWidth=width;
+ }
+ if (location.hash.slice(1)) {
+ (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView();
+ }
+ }
+
+ function collapseExpand()
+ {
+ if (sidenav.width()>0) {
+ restoreWidth(0);
+ collapsed=true;
+ }
+ else {
+ var width = readCookie('width');
+ if (width>200 && width<$(window).width()) { restoreWidth(width); } else { restoreWidth(200); }
+ collapsed=false;
+ }
+ }
+
+ header = $("#top");
+ sidenav = $("#side-nav");
+ content = $("#doc-content");
+ navtree = $("#nav-tree");
+ footer = $("#nav-path");
+ $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } });
+ $(sidenav).resizable({ minWidth: 0 });
+ $(window).resize(function() { resizeHeight(); });
+ var device = navigator.userAgent.toLowerCase();
+ var touch_device = device.match(/(iphone|ipod|ipad|android)/);
+ if (touch_device) { /* wider split bar for touch only devices */
+ $(sidenav).css({ paddingRight:'20px' });
+ $('.ui-resizable-e').css({ width:'20px' });
+ $('#nav-sync').css({ right:'34px' });
+ barWidth=20;
+ }
+ var width = readCookie('width');
+ if (width) { restoreWidth(width); } else { resizeWidth(); }
+ resizeHeight();
+ var url = location.href;
+ var i=url.indexOf("#");
+ if (i>=0) window.location.hash=url.substr(i);
+ var _preventDefault = function(evt) { evt.preventDefault(); };
+ $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);
+ $(".ui-resizable-handle").dblclick(collapseExpand);
+ $(window).on('load',resizeHeight);
+}
+/* @license-end */
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['_5fmi_5foption_5flast_0',['_mi_option_last',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['aligned_20allocation_1',['Aligned Allocation',['../group__aligned.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['basic_20allocation_2',['Basic Allocation',['../group__malloc.html',1,'']]],
+ ['block_5fsize_3',['block_size',['../group__analysis.html#a332a6c14d736a99699d5453a1cb04b41',1,'mi_heap_area_t']]],
+ ['blocks_4',['blocks',['../group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8',1,'mi_heap_area_t']]],
+ ['building_5',['Building',['../build.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['c_2b_2b_20wrappers_6',['C++ wrappers',['../group__cpp.html',1,'']]],
+ ['committed_7',['committed',['../group__analysis.html#ab47526df656d8837ec3e97f11b83f835',1,'mi_heap_area_t']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['environment_20options_8',['Environment Options',['../environment.html',1,'']]],
+ ['extended_20functions_9',['Extended Functions',['../group__extended.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_5.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['heap_20allocation_10',['Heap Allocation',['../group__heap.html',1,'']]],
+ ['heap_20introspection_11',['Heap Introspection',['../group__analysis.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_6.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5f_5fposix_5fmemalign_12',['mi__posix_memalign',['../group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a',1,'mimalloc-doc.h']]],
+ ['mi_5faligned_5falloc_13',['mi_aligned_alloc',['../group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5',1,'mimalloc-doc.h']]],
+ ['mi_5falignment_5fmax_14',['MI_ALIGNMENT_MAX',['../group__aligned.html#ga83c03016066b438f51a8095e9140be06',1,'mimalloc-doc.h']]],
+ ['mi_5fblock_5fvisit_5ffun_15',['mi_block_visit_fun',['../group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_16',['mi_calloc',['../group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_5faligned_17',['mi_calloc_aligned',['../group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_5faligned_5fat_18',['mi_calloc_aligned_at',['../group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_5ftp_19',['mi_calloc_tp',['../group__typed.html#gae80c47c9d4cab10961fff1a8ac98fc07',1,'mimalloc-doc.h']]],
+ ['mi_5fcfree_20',['mi_cfree',['../group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7',1,'mimalloc-doc.h']]],
+ ['mi_5fcheck_5fowned_21',['mi_check_owned',['../group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5',1,'mimalloc-doc.h']]],
+ ['mi_5fcollect_22',['mi_collect',['../group__extended.html#ga421430e2226d7d468529cec457396756',1,'mimalloc-doc.h']]],
+ ['mi_5fdeferred_5ffree_5ffun_23',['mi_deferred_free_fun',['../group__extended.html#ga299dae78d25ce112e384a98b7309c5be',1,'mimalloc-doc.h']]],
+ ['mi_5ferror_5ffun_24',['mi_error_fun',['../group__extended.html#ga251d369cda3f1c2a955c555486ed90e5',1,'mimalloc-doc.h']]],
+ ['mi_5fexpand_25',['mi_expand',['../group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_26',['mi_free',['../group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_5faligned_27',['mi_free_aligned',['../group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_5fsize_28',['mi_free_size',['../group__posix.html#gae01389eedab8d67341ff52e2aad80ebb',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_5fsize_5faligned_29',['mi_free_size_aligned',['../group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc',1,'mimalloc-doc.h']]],
+ ['mi_5fgood_5fsize_30',['mi_good_size',['../group__extended.html#gac057927cd06c854b45fe7847e921bd47',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5farea_5ft_31',['mi_heap_area_t',['../group__analysis.html#structmi__heap__area__t',1,'']]],
+ ['mi_5fheap_5fcalloc_32',['mi_heap_calloc',['../group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcalloc_5faligned_33',['mi_heap_calloc_aligned',['../group__heap.html#ga4af03a6e2b93fae77424d93f889705c3',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcalloc_5faligned_5fat_34',['mi_heap_calloc_aligned_at',['../group__heap.html#ga08ca6419a5c057a4d965868998eef487',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcalloc_5ftp_35',['mi_heap_calloc_tp',['../group__typed.html#ga4e5d1f1707c90e5f55e023ac5f45fe74',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcheck_5fowned_36',['mi_heap_check_owned',['../group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcollect_37',['mi_heap_collect',['../group__heap.html#ga7922f7495cde30b1984d0e6072419298',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcontains_5fblock_38',['mi_heap_contains_block',['../group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fdelete_39',['mi_heap_delete',['../group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fdestroy_40',['mi_heap_destroy',['../group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fget_5fbacking_41',['mi_heap_get_backing',['../group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fget_5fdefault_42',['mi_heap_get_default',['../group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_43',['mi_heap_malloc',['../group__heap.html#ga9cbed01e42c0647907295de92c3fa296',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5faligned_44',['mi_heap_malloc_aligned',['../group__heap.html#gab5b87e1805306f70df38789fcfcf6653',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5faligned_5fat_45',['mi_heap_malloc_aligned_at',['../group__heap.html#ga23acd7680fb0976dde3783254c6c874b',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5fsmall_46',['mi_heap_malloc_small',['../group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5ftp_47',['mi_heap_malloc_tp',['../group__typed.html#ga653bcb24ac495bc19940ecd6898f9cd7',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmallocn_48',['mi_heap_mallocn',['../group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmallocn_5ftp_49',['mi_heap_mallocn_tp',['../group__typed.html#ga6b75cb9c4b9c647661d0924552dc6e83',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fnew_50',['mi_heap_new',['../group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealloc_51',['mi_heap_realloc',['../group__heap.html#gaaef3395f66be48f37bdc8322509c5d81',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealloc_5faligned_52',['mi_heap_realloc_aligned',['../group__heap.html#gafc603b696bd14cae6da28658f950d98c',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealloc_5faligned_5fat_53',['mi_heap_realloc_aligned_at',['../group__heap.html#gaf96c788a1bf553fe2d371de9365e047c',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5freallocf_54',['mi_heap_reallocf',['../group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5freallocn_55',['mi_heap_reallocn',['../group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5freallocn_5ftp_56',['mi_heap_reallocn_tp',['../group__typed.html#gaf213d5422ec35e7f6caad827c79bc948',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealpath_57',['mi_heap_realpath',['../group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_58',['mi_heap_recalloc',['../group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_5faligned_59',['mi_heap_recalloc_aligned',['../group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_5faligned_5fat_60',['mi_heap_recalloc_aligned_at',['../group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_5ftp_61',['mi_heap_recalloc_tp',['../group__typed.html#ga3e50a1600958fcaf1a7f3560c9174f9e',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frezalloc_62',['mi_heap_rezalloc',['../group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frezalloc_5faligned_63',['mi_heap_rezalloc_aligned',['../group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frezalloc_5faligned_5fat_64',['mi_heap_rezalloc_aligned_at',['../group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fset_5fdefault_65',['mi_heap_set_default',['../group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fstrdup_66',['mi_heap_strdup',['../group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fstrndup_67',['mi_heap_strndup',['../group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5ft_68',['mi_heap_t',['../group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fvisit_5fblocks_69',['mi_heap_visit_blocks',['../group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_70',['mi_heap_zalloc',['../group__heap.html#ga903104592c8ed53417a3762da6241133',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_5faligned_71',['mi_heap_zalloc_aligned',['../group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_5faligned_5fat_72',['mi_heap_zalloc_aligned_at',['../group__heap.html#ga45fb43a62776fbebbdf1edd99b527954',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_5ftp_73',['mi_heap_zalloc_tp',['../group__typed.html#gad6e87e86e994aa14416ae9b5d4c188fe',1,'mimalloc-doc.h']]],
+ ['mi_5fis_5fin_5fheap_5fregion_74',['mi_is_in_heap_region',['../group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6',1,'mimalloc-doc.h']]],
+ ['mi_5fis_5fredirected_75',['mi_is_redirected',['../group__extended.html#gaad25050b19f30cd79397b227e0157a3f',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_76',['mi_malloc',['../group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5faligned_77',['mi_malloc_aligned',['../group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5faligned_5fat_78',['mi_malloc_aligned_at',['../group__aligned.html#ga5850da130c936bd77db039dcfbc8295d',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5fsize_79',['mi_malloc_size',['../group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5fsmall_80',['mi_malloc_small',['../group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5ftp_81',['mi_malloc_tp',['../group__typed.html#ga0619a62c5fd886f1016030abe91f0557',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5fusable_5fsize_82',['mi_malloc_usable_size',['../group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17',1,'mimalloc-doc.h']]],
+ ['mi_5fmallocn_83',['mi_mallocn',['../group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6',1,'mimalloc-doc.h']]],
+ ['mi_5fmallocn_5ftp_84',['mi_mallocn_tp',['../group__typed.html#gae5cb6e0fafc9f23169c5622e077afe8b',1,'mimalloc-doc.h']]],
+ ['mi_5fmanage_5fos_5fmemory_85',['mi_manage_os_memory',['../group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf',1,'mimalloc-doc.h']]],
+ ['mi_5fmemalign_86',['mi_memalign',['../group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_87',['mi_new',['../group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5faligned_88',['mi_new_aligned',['../group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5faligned_5fnothrow_89',['mi_new_aligned_nothrow',['../group__cpp.html#gab5e29558926d934c3f1cae8c815f942c',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5fn_90',['mi_new_n',['../group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5fnothrow_91',['mi_new_nothrow',['../group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5frealloc_92',['mi_new_realloc',['../group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5freallocn_93',['mi_new_reallocn',['../group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fdisable_94',['mi_option_disable',['../group__options.html#gaebf6ff707a2e688ebb1a2296ca564054',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5feager_5fcommit_95',['mi_option_eager_commit',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5feager_5fcommit_5fdelay_96',['mi_option_eager_commit_delay',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5feager_5fregion_5fcommit_97',['mi_option_eager_region_commit',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fenable_98',['mi_option_enable',['../group__options.html#ga04180ae41b0d601421dd62ced40ca050',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fget_99',['mi_option_get',['../group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fis_5fenabled_100',['mi_option_is_enabled',['../group__options.html#ga459ad98f18b3fc9275474807fe0ca188',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5flarge_5fos_5fpages_101',['mi_option_large_os_pages',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fos_5ftag_102',['mi_option_os_tag',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fpage_5freset_103',['mi_option_page_reset',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freserve_5fhuge_5fos_5fpages_104',['mi_option_reserve_huge_os_pages',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freserve_5fhuge_5fos_5fpages_5fat_105',['mi_option_reserve_huge_os_pages_at',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freset_5fdecommits_106',['mi_option_reset_decommits',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freset_5fdelay_107',['mi_option_reset_delay',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fsegment_5fcache_108',['mi_option_segment_cache',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fsegment_5freset_109',['mi_option_segment_reset',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_110',['mi_option_set',['../group__options.html#gaf84921c32375e25754dc2ee6a911fa60',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fdefault_111',['mi_option_set_default',['../group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled_112',['mi_option_set_enabled',['../group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled_5fdefault_113',['mi_option_set_enabled_default',['../group__options.html#ga65518b69ec5d32336b50e07f74b3f629',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fshow_5ferrors_114',['mi_option_show_errors',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fshow_5fstats_115',['mi_option_show_stats',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5ft_116',['mi_option_t',['../group__options.html#gafebf7ed116adb38ae5218bc3ce06884c',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fuse_5fnuma_5fnodes_117',['mi_option_use_numa_nodes',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fverbose_118',['mi_option_verbose',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777',1,'mimalloc-doc.h']]],
+ ['mi_5foutput_5ffun_119',['mi_output_fun',['../group__extended.html#gad823d23444a4b77a40f66bf075a98a0c',1,'mimalloc-doc.h']]],
+ ['mi_5fposix_5fmemalign_120',['mi_posix_memalign',['../group__posix.html#gacff84f226ba9feb2031b8992e5579447',1,'mimalloc-doc.h']]],
+ ['mi_5fprocess_5finfo_121',['mi_process_info',['../group__extended.html#ga7d862c2affd5790381da14eb102a364d',1,'mimalloc-doc.h']]],
+ ['mi_5fpvalloc_122',['mi_pvalloc',['../group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e',1,'mimalloc-doc.h']]],
+ ['mi_5frealloc_123',['mi_realloc',['../group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6',1,'mimalloc-doc.h']]],
+ ['mi_5frealloc_5faligned_124',['mi_realloc_aligned',['../group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae',1,'mimalloc-doc.h']]],
+ ['mi_5frealloc_5faligned_5fat_125',['mi_realloc_aligned_at',['../group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb',1,'mimalloc-doc.h']]],
+ ['mi_5freallocarr_126',['mi_reallocarr',['../group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5',1,'mimalloc-doc.h']]],
+ ['mi_5freallocarray_127',['mi_reallocarray',['../group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088',1,'mimalloc-doc.h']]],
+ ['mi_5freallocf_128',['mi_reallocf',['../group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0',1,'mimalloc-doc.h']]],
+ ['mi_5freallocn_129',['mi_reallocn',['../group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853',1,'mimalloc-doc.h']]],
+ ['mi_5freallocn_5ftp_130',['mi_reallocn_tp',['../group__typed.html#ga1158b49a55dfa81f58a4426a7578f523',1,'mimalloc-doc.h']]],
+ ['mi_5frealpath_131',['mi_realpath',['../group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe',1,'mimalloc-doc.h']]],
+ ['mi_5frecalloc_132',['mi_recalloc',['../group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc',1,'mimalloc-doc.h']]],
+ ['mi_5frecalloc_5faligned_133',['mi_recalloc_aligned',['../group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f',1,'mimalloc-doc.h']]],
+ ['mi_5frecalloc_5faligned_5fat_134',['mi_recalloc_aligned_at',['../group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9',1,'mimalloc-doc.h']]],
+ ['mi_5fregister_5fdeferred_5ffree_135',['mi_register_deferred_free',['../group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece',1,'mimalloc-doc.h']]],
+ ['mi_5fregister_5ferror_136',['mi_register_error',['../group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45',1,'mimalloc-doc.h']]],
+ ['mi_5fregister_5foutput_137',['mi_register_output',['../group__extended.html#gae5b17ff027cd2150b43a33040250cf3f',1,'mimalloc-doc.h']]],
+ ['mi_5freserve_5fhuge_5fos_5fpages_5fat_138',['mi_reserve_huge_os_pages_at',['../group__extended.html#ga7795a13d20087447281858d2c771cca1',1,'mimalloc-doc.h']]],
+ ['mi_5freserve_5fhuge_5fos_5fpages_5finterleave_139',['mi_reserve_huge_os_pages_interleave',['../group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50',1,'mimalloc-doc.h']]],
+ ['mi_5freserve_5fos_5fmemory_140',['mi_reserve_os_memory',['../group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767',1,'mimalloc-doc.h']]],
+ ['mi_5frezalloc_141',['mi_rezalloc',['../group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6',1,'mimalloc-doc.h']]],
+ ['mi_5frezalloc_5faligned_142',['mi_rezalloc_aligned',['../group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0',1,'mimalloc-doc.h']]],
+ ['mi_5frezalloc_5faligned_5fat_143',['mi_rezalloc_aligned_at',['../group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1',1,'mimalloc-doc.h']]],
+ ['mi_5fsmall_5fsize_5fmax_144',['MI_SMALL_SIZE_MAX',['../group__extended.html#ga1ea64283508718d9d645c38efc2f4305',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fmerge_145',['mi_stats_merge',['../group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint_146',['mi_stats_print',['../group__extended.html#ga2d126e5c62d3badc35445e5d84166df2',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint_5fout_147',['mi_stats_print_out',['../group__extended.html#ga537f13b299ddf801e49a5a94fde02c79',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5freset_148',['mi_stats_reset',['../group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99',1,'mimalloc-doc.h']]],
+ ['mi_5fstl_5fallocator_149',['mi_stl_allocator',['../group__cpp.html#structmi__stl__allocator',1,'']]],
+ ['mi_5fstrdup_150',['mi_strdup',['../group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2',1,'mimalloc-doc.h']]],
+ ['mi_5fstrndup_151',['mi_strndup',['../group__malloc.html#gaaabf971c2571891433477e2d21a35266',1,'mimalloc-doc.h']]],
+ ['mi_5fthread_5fdone_152',['mi_thread_done',['../group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf',1,'mimalloc-doc.h']]],
+ ['mi_5fthread_5finit_153',['mi_thread_init',['../group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17',1,'mimalloc-doc.h']]],
+ ['mi_5fthread_5fstats_5fprint_5fout_154',['mi_thread_stats_print_out',['../group__extended.html#gab1dac8476c46cb9eecab767eb40c1525',1,'mimalloc-doc.h']]],
+ ['mi_5fusable_5fsize_155',['mi_usable_size',['../group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee',1,'mimalloc-doc.h']]],
+ ['mi_5fvalloc_156',['mi_valloc',['../group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_157',['mi_zalloc',['../group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5faligned_158',['mi_zalloc_aligned',['../group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5faligned_5fat_159',['mi_zalloc_aligned_at',['../group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5fsmall_160',['mi_zalloc_small',['../group__extended.html#ga220f29f40a44404b0061c15bc1c31152',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5ftp_161',['mi_zalloc_tp',['../group__typed.html#gac77a61bdaf680a803785fe307820b48c',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_7.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['overriding_20malloc_162',['Overriding Malloc',['../overrides.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_8.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['performance_163',['Performance',['../bench.html',1,'']]],
+ ['posix_164',['Posix',['../group__posix.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_9.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['reserved_165',['reserved',['../group__analysis.html#ae848a3e6840414891035423948ca0383',1,'mi_heap_area_t']]],
+ ['runtime_20options_166',['Runtime Options',['../group__options.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_a.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['typed_20macros_167',['Typed Macros',['../group__typed.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_b.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['used_168',['used',['../group__analysis.html#ab820302c5cd0df133eb8e51650a008b4',1,'mi_heap_area_t']]],
+ ['using_20the_20library_169',['Using the library',['../using.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_c.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['zero_20initialized_20re_2dallocation_170',['Zero initialized re-allocation',['../group__zeroinit.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_d.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+/* @license-end */
+--></script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['zero_20initialized_20re_2dallocation',['Zero initialized re-allocation',['../group__zeroinit.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5fheap_5farea_5ft_171',['mi_heap_area_t',['../group__analysis.html#structmi__heap__area__t',1,'']]],
+ ['mi_5fstl_5fallocator_172',['mi_stl_allocator',['../group__cpp.html#structmi__stl__allocator',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enums_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5foption_5ft_296',['mi_option_t',['../group__options.html#gafebf7ed116adb38ae5218bc3ce06884c',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enumvalues_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['_5fmi_5foption_5flast_297',['_mi_option_last',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca5b4357b74be0d87568036c32eb1a2e4a',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enumvalues_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5foption_5feager_5fcommit_298',['mi_option_eager_commit',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca1e8de72c93da7ff22d91e1e27b52ac2b',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5feager_5fcommit_5fdelay_299',['mi_option_eager_commit_delay',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca17a190c25be381142d87e0468c4c068c',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5feager_5fregion_5fcommit_300',['mi_option_eager_region_commit',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca32ce97ece29f69e82579679cf8a307ad',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5flarge_5fos_5fpages_301',['mi_option_large_os_pages',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4192d491200d0055df0554d4cf65054e',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fos_5ftag_302',['mi_option_os_tag',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca4b74ae2a69e445de6c2361b73c1d14bf',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fpage_5freset_303',['mi_option_page_reset',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cada854dd272c66342f18a93ee254a2968',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freserve_5fhuge_5fos_5fpages_304',['mi_option_reserve_huge_os_pages',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caca7ed041be3b0b9d0b82432c7bf41af2',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freserve_5fhuge_5fos_5fpages_5fat_305',['mi_option_reserve_huge_os_pages_at',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884caa13e7926d4339d2aa6fbf61d4473fd5c',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freset_5fdecommits_306',['mi_option_reset_decommits',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cac81ee965b130fa81238913a3c239d536',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5freset_5fdelay_307',['mi_option_reset_delay',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca154fe170131d5212cff57e22b99523c5',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fsegment_5fcache_308',['mi_option_segment_cache',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca2ecbe7ef32f5c84de3739aa4f0b805a1',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fsegment_5freset_309',['mi_option_segment_reset',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafb121d30d87591850d5410ccc3a95c6d',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fshow_5ferrors_310',['mi_option_show_errors',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884cafbf4822e5c00732c5984b32a032837f0',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fshow_5fstats_311',['mi_option_show_stats',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0957ef73b2550764b4840edf48422fda',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fuse_5fnuma_5fnodes_312',['mi_option_use_numa_nodes',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca0ac33a18f6b659fcfaf44efb0bab1b74',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fverbose_313',['mi_option_verbose',['../group__options.html#ggafebf7ed116adb38ae5218bc3ce06884ca7c8b7bf5281c581bad64f5daa6442777',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5f_5fposix_5fmemalign_173',['mi__posix_memalign',['../group__posix.html#gad5a69c8fea96aa2b7a7c818c2130090a',1,'mimalloc-doc.h']]],
+ ['mi_5faligned_5falloc_174',['mi_aligned_alloc',['../group__posix.html#ga1326d2e4388630b5f81ca7206318b8e5',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_175',['mi_calloc',['../group__malloc.html#ga97fedb4f7107c592fd7f0f0a8949a57d',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_5faligned_176',['mi_calloc_aligned',['../group__aligned.html#ga53dddb4724042a90315b94bc268fb4c9',1,'mimalloc-doc.h']]],
+ ['mi_5fcalloc_5faligned_5fat_177',['mi_calloc_aligned_at',['../group__aligned.html#ga08647c4593f3b2eef24a919a73eba3a3',1,'mimalloc-doc.h']]],
+ ['mi_5fcfree_178',['mi_cfree',['../group__posix.html#ga705dc7a64bffacfeeb0141501a5c35d7',1,'mimalloc-doc.h']]],
+ ['mi_5fcheck_5fowned_179',['mi_check_owned',['../group__analysis.html#ga628c237489c2679af84a4d0d143b3dd5',1,'mimalloc-doc.h']]],
+ ['mi_5fcollect_180',['mi_collect',['../group__extended.html#ga421430e2226d7d468529cec457396756',1,'mimalloc-doc.h']]],
+ ['mi_5fexpand_181',['mi_expand',['../group__malloc.html#gaaee66a1d483c3e28f585525fb96707e4',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_182',['mi_free',['../group__malloc.html#gaf2c7b89c327d1f60f59e68b9ea644d95',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_5faligned_183',['mi_free_aligned',['../group__posix.html#ga0d28d5cf61e6bfbb18c63092939fe5c9',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_5fsize_184',['mi_free_size',['../group__posix.html#gae01389eedab8d67341ff52e2aad80ebb',1,'mimalloc-doc.h']]],
+ ['mi_5ffree_5fsize_5faligned_185',['mi_free_size_aligned',['../group__posix.html#ga72e9d7ffb5fe94d69bc722c8506e27bc',1,'mimalloc-doc.h']]],
+ ['mi_5fgood_5fsize_186',['mi_good_size',['../group__extended.html#gac057927cd06c854b45fe7847e921bd47',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcalloc_187',['mi_heap_calloc',['../group__heap.html#gaa6702b3c48e9e53e50e81b36f5011d55',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcalloc_5faligned_188',['mi_heap_calloc_aligned',['../group__heap.html#ga4af03a6e2b93fae77424d93f889705c3',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcalloc_5faligned_5fat_189',['mi_heap_calloc_aligned_at',['../group__heap.html#ga08ca6419a5c057a4d965868998eef487',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcheck_5fowned_190',['mi_heap_check_owned',['../group__analysis.html#ga0d67c1789faaa15ff366c024fcaf6377',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcollect_191',['mi_heap_collect',['../group__heap.html#ga7922f7495cde30b1984d0e6072419298',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fcontains_5fblock_192',['mi_heap_contains_block',['../group__analysis.html#gaa862aa8ed8d57d84cae41fc1022d71af',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fdelete_193',['mi_heap_delete',['../group__heap.html#ga2ab1af8d438819b55319c7ef51d1e409',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fdestroy_194',['mi_heap_destroy',['../group__heap.html#ga9f9c0844edb9717f4feacd79116b8e0d',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fget_5fbacking_195',['mi_heap_get_backing',['../group__heap.html#ga5d03fbe062ffcf38f0f417fd968357fc',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fget_5fdefault_196',['mi_heap_get_default',['../group__heap.html#ga8db4cbb87314a989a9a187464d6b5e05',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_197',['mi_heap_malloc',['../group__heap.html#ga9cbed01e42c0647907295de92c3fa296',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5faligned_198',['mi_heap_malloc_aligned',['../group__heap.html#gab5b87e1805306f70df38789fcfcf6653',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5faligned_5fat_199',['mi_heap_malloc_aligned_at',['../group__heap.html#ga23acd7680fb0976dde3783254c6c874b',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmalloc_5fsmall_200',['mi_heap_malloc_small',['../group__heap.html#gaa1a1c7a1f4da6826b5a25b70ef878368',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fmallocn_201',['mi_heap_mallocn',['../group__heap.html#ga851da6c43fe0b71c1376cee8aef90db0',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fnew_202',['mi_heap_new',['../group__heap.html#ga766f672ba56f2fbfeb9d9dbb0b7f6b11',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealloc_203',['mi_heap_realloc',['../group__heap.html#gaaef3395f66be48f37bdc8322509c5d81',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealloc_5faligned_204',['mi_heap_realloc_aligned',['../group__heap.html#gafc603b696bd14cae6da28658f950d98c',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealloc_5faligned_5fat_205',['mi_heap_realloc_aligned_at',['../group__heap.html#gaf96c788a1bf553fe2d371de9365e047c',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5freallocf_206',['mi_heap_reallocf',['../group__heap.html#ga4a21070eb4e7cce018133c8d5f4b0527',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5freallocn_207',['mi_heap_reallocn',['../group__heap.html#gac74e94ad9b0c9b57c1c4d88b8825b7a8',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frealpath_208',['mi_heap_realpath',['../group__heap.html#ga00e95ba1e01acac3cfd95bb7a357a6f0',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_209',['mi_heap_recalloc',['../group__zeroinit.html#ga8648c5fbb22a80f0262859099f06dfbd',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_5faligned_210',['mi_heap_recalloc_aligned',['../group__zeroinit.html#ga9f3f999396c8f77ca5e80e7b40ac29e3',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frecalloc_5faligned_5fat_211',['mi_heap_recalloc_aligned_at',['../group__zeroinit.html#ga496452c96f1de8c500be9fddf52edaf7',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frezalloc_212',['mi_heap_rezalloc',['../group__zeroinit.html#gacfad83f14eb5d6a42a497a898e19fc76',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frezalloc_5faligned_213',['mi_heap_rezalloc_aligned',['../group__zeroinit.html#ga375fa8a611c51905e592d5d467c49664',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5frezalloc_5faligned_5fat_214',['mi_heap_rezalloc_aligned_at',['../group__zeroinit.html#gac90da54fa7e5d10bdc97ce0b51dce2eb',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fset_5fdefault_215',['mi_heap_set_default',['../group__heap.html#gab8631ec88c8d26641b68b5d25dcd4422',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fstrdup_216',['mi_heap_strdup',['../group__heap.html#ga139d6b09dbf50c3c2523d0f4d1cfdeb5',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fstrndup_217',['mi_heap_strndup',['../group__heap.html#ga8e3dbd46650dd26573cf307a2c8f1f5a',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fvisit_5fblocks_218',['mi_heap_visit_blocks',['../group__analysis.html#ga70c46687dc6e9dc98b232b02646f8bed',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_219',['mi_heap_zalloc',['../group__heap.html#ga903104592c8ed53417a3762da6241133',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_5faligned_220',['mi_heap_zalloc_aligned',['../group__heap.html#gaa450a59c6c7ae5fdbd1c2b80a8329ef0',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5fzalloc_5faligned_5fat_221',['mi_heap_zalloc_aligned_at',['../group__heap.html#ga45fb43a62776fbebbdf1edd99b527954',1,'mimalloc-doc.h']]],
+ ['mi_5fis_5fin_5fheap_5fregion_222',['mi_is_in_heap_region',['../group__extended.html#ga5f071b10d4df1c3658e04e7fd67a94e6',1,'mimalloc-doc.h']]],
+ ['mi_5fis_5fredirected_223',['mi_is_redirected',['../group__extended.html#gaad25050b19f30cd79397b227e0157a3f',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_224',['mi_malloc',['../group__malloc.html#ga3406e8b168bc74c8637b11571a6da83a',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5faligned_225',['mi_malloc_aligned',['../group__aligned.html#ga68930196751fa2cca9e1fd0d71bade56',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5faligned_5fat_226',['mi_malloc_aligned_at',['../group__aligned.html#ga5850da130c936bd77db039dcfbc8295d',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5fsize_227',['mi_malloc_size',['../group__posix.html#ga4531c9e775bb3ae12db57c1ba8a5d7de',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5fsmall_228',['mi_malloc_small',['../group__extended.html#ga7136c2e55cb22c98ecf95d08d6debb99',1,'mimalloc-doc.h']]],
+ ['mi_5fmalloc_5fusable_5fsize_229',['mi_malloc_usable_size',['../group__posix.html#ga06d07cf357bbac5c73ba5d0c0c421e17',1,'mimalloc-doc.h']]],
+ ['mi_5fmallocn_230',['mi_mallocn',['../group__malloc.html#ga0b05e2bf0f73e7401ae08597ff782ac6',1,'mimalloc-doc.h']]],
+ ['mi_5fmanage_5fos_5fmemory_231',['mi_manage_os_memory',['../group__extended.html#ga4c6486a1fdcd7a423b5f25fe4be8e0cf',1,'mimalloc-doc.h']]],
+ ['mi_5fmemalign_232',['mi_memalign',['../group__posix.html#gaab7fa71ea93b96873f5d9883db57d40e',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_233',['mi_new',['../group__cpp.html#gaad048a9fce3d02c5909cd05c6ec24545',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5faligned_234',['mi_new_aligned',['../group__cpp.html#gaef2c2bdb4f70857902d3c8903ac095f3',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5faligned_5fnothrow_235',['mi_new_aligned_nothrow',['../group__cpp.html#gab5e29558926d934c3f1cae8c815f942c',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5fn_236',['mi_new_n',['../group__cpp.html#gae7bc4f56cd57ed3359060ff4f38bda81',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5fnothrow_237',['mi_new_nothrow',['../group__cpp.html#gaeaded64eda71ed6b1d569d3e723abc4a',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5frealloc_238',['mi_new_realloc',['../group__cpp.html#gaab78a32f55149e9fbf432d5288e38e1e',1,'mimalloc-doc.h']]],
+ ['mi_5fnew_5freallocn_239',['mi_new_reallocn',['../group__cpp.html#ga756f4b2bc6a7ecd0a90baea8e90c7907',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fdisable_240',['mi_option_disable',['../group__options.html#gaebf6ff707a2e688ebb1a2296ca564054',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fenable_241',['mi_option_enable',['../group__options.html#ga04180ae41b0d601421dd62ced40ca050',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fget_242',['mi_option_get',['../group__options.html#ga7e8af195cc81d3fa64ccf2662caa565a',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fis_5fenabled_243',['mi_option_is_enabled',['../group__options.html#ga459ad98f18b3fc9275474807fe0ca188',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_244',['mi_option_set',['../group__options.html#gaf84921c32375e25754dc2ee6a911fa60',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fdefault_245',['mi_option_set_default',['../group__options.html#ga7ef623e440e6e5545cb08c94e71e4b90',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled_246',['mi_option_set_enabled',['../group__options.html#ga9a13d05fcb77489cb06d4d017ebd8bed',1,'mimalloc-doc.h']]],
+ ['mi_5foption_5fset_5fenabled_5fdefault_247',['mi_option_set_enabled_default',['../group__options.html#ga65518b69ec5d32336b50e07f74b3f629',1,'mimalloc-doc.h']]],
+ ['mi_5fposix_5fmemalign_248',['mi_posix_memalign',['../group__posix.html#gacff84f226ba9feb2031b8992e5579447',1,'mimalloc-doc.h']]],
+ ['mi_5fprocess_5finfo_249',['mi_process_info',['../group__extended.html#ga7d862c2affd5790381da14eb102a364d',1,'mimalloc-doc.h']]],
+ ['mi_5fpvalloc_250',['mi_pvalloc',['../group__posix.html#gaeb325c39b887d3b90d85d1eb1712fb1e',1,'mimalloc-doc.h']]],
+ ['mi_5frealloc_251',['mi_realloc',['../group__malloc.html#gaf11eb497da57bdfb2de65eb191c69db6',1,'mimalloc-doc.h']]],
+ ['mi_5frealloc_5faligned_252',['mi_realloc_aligned',['../group__aligned.html#ga4028d1cf4aa4c87c880747044a8322ae',1,'mimalloc-doc.h']]],
+ ['mi_5frealloc_5faligned_5fat_253',['mi_realloc_aligned_at',['../group__aligned.html#gaf66a9ae6c6f08bd6be6fb6ea771faffb',1,'mimalloc-doc.h']]],
+ ['mi_5freallocarr_254',['mi_reallocarr',['../group__posix.html#ga7e1934d60a3e697950eeb48e042bfad5',1,'mimalloc-doc.h']]],
+ ['mi_5freallocarray_255',['mi_reallocarray',['../group__posix.html#ga48fad8648a2f1dab9c87ea9448a52088',1,'mimalloc-doc.h']]],
+ ['mi_5freallocf_256',['mi_reallocf',['../group__malloc.html#gafe68ac7c5e24a65cd55c9d6b152211a0',1,'mimalloc-doc.h']]],
+ ['mi_5freallocn_257',['mi_reallocn',['../group__malloc.html#ga61d57b4144ba24fba5c1e9b956d13853',1,'mimalloc-doc.h']]],
+ ['mi_5frealpath_258',['mi_realpath',['../group__malloc.html#ga08cec32dd5bbe7da91c78d19f1b5bebe',1,'mimalloc-doc.h']]],
+ ['mi_5frecalloc_259',['mi_recalloc',['../group__malloc.html#ga23a0fbb452b5dce8e31fab1a1958cacc',1,'mimalloc-doc.h']]],
+ ['mi_5frecalloc_5faligned_260',['mi_recalloc_aligned',['../group__zeroinit.html#ga3e7e5c291acf1c7fd7ffd9914a9f945f',1,'mimalloc-doc.h']]],
+ ['mi_5frecalloc_5faligned_5fat_261',['mi_recalloc_aligned_at',['../group__zeroinit.html#ga4ff5e92ad73585418a072c9d059e5cf9',1,'mimalloc-doc.h']]],
+ ['mi_5fregister_5fdeferred_5ffree_262',['mi_register_deferred_free',['../group__extended.html#ga3460a6ca91af97be4058f523d3cb8ece',1,'mimalloc-doc.h']]],
+ ['mi_5fregister_5ferror_263',['mi_register_error',['../group__extended.html#gaa1d55e0e894be240827e5d87ec3a1f45',1,'mimalloc-doc.h']]],
+ ['mi_5fregister_5foutput_264',['mi_register_output',['../group__extended.html#gae5b17ff027cd2150b43a33040250cf3f',1,'mimalloc-doc.h']]],
+ ['mi_5freserve_5fhuge_5fos_5fpages_5fat_265',['mi_reserve_huge_os_pages_at',['../group__extended.html#ga7795a13d20087447281858d2c771cca1',1,'mimalloc-doc.h']]],
+ ['mi_5freserve_5fhuge_5fos_5fpages_5finterleave_266',['mi_reserve_huge_os_pages_interleave',['../group__extended.html#ga3132f521fb756fc0e8ec0b74fb58df50',1,'mimalloc-doc.h']]],
+ ['mi_5freserve_5fos_5fmemory_267',['mi_reserve_os_memory',['../group__extended.html#ga00ec3324b6b2591c7fe3677baa30a767',1,'mimalloc-doc.h']]],
+ ['mi_5frezalloc_268',['mi_rezalloc',['../group__zeroinit.html#ga8c292e142110229a2980b37ab036dbc6',1,'mimalloc-doc.h']]],
+ ['mi_5frezalloc_5faligned_269',['mi_rezalloc_aligned',['../group__zeroinit.html#gacd71a7bce96aab38ae6de17af2eb2cf0',1,'mimalloc-doc.h']]],
+ ['mi_5frezalloc_5faligned_5fat_270',['mi_rezalloc_aligned_at',['../group__zeroinit.html#gae8b358c417e61d5307da002702b0a8e1',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fmerge_271',['mi_stats_merge',['../group__extended.html#ga854b1de8cb067c7316286c28b2fcd3d1',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint_272',['mi_stats_print',['../group__extended.html#ga2d126e5c62d3badc35445e5d84166df2',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5fprint_5fout_273',['mi_stats_print_out',['../group__extended.html#ga537f13b299ddf801e49a5a94fde02c79',1,'mimalloc-doc.h']]],
+ ['mi_5fstats_5freset_274',['mi_stats_reset',['../group__extended.html#ga3bb8468b8cfcc6e2a61d98aee85c5f99',1,'mimalloc-doc.h']]],
+ ['mi_5fstrdup_275',['mi_strdup',['../group__malloc.html#gac7cffe13f1f458ed16789488bf92b9b2',1,'mimalloc-doc.h']]],
+ ['mi_5fstrndup_276',['mi_strndup',['../group__malloc.html#gaaabf971c2571891433477e2d21a35266',1,'mimalloc-doc.h']]],
+ ['mi_5fthread_5fdone_277',['mi_thread_done',['../group__extended.html#ga0ae4581e85453456a0d658b2b98bf7bf',1,'mimalloc-doc.h']]],
+ ['mi_5fthread_5finit_278',['mi_thread_init',['../group__extended.html#gaf8e73efc2cbca9ebfdfb166983a04c17',1,'mimalloc-doc.h']]],
+ ['mi_5fthread_5fstats_5fprint_5fout_279',['mi_thread_stats_print_out',['../group__extended.html#gab1dac8476c46cb9eecab767eb40c1525',1,'mimalloc-doc.h']]],
+ ['mi_5fusable_5fsize_280',['mi_usable_size',['../group__extended.html#ga089c859d9eddc5f9b4bd946cd53cebee',1,'mimalloc-doc.h']]],
+ ['mi_5fvalloc_281',['mi_valloc',['../group__posix.html#ga73baaf5951f5165ba0763d0c06b6a93b',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_282',['mi_zalloc',['../group__malloc.html#gafdd9d8bb2986e668ba9884f28af38000',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5faligned_283',['mi_zalloc_aligned',['../group__aligned.html#ga0cadbcf5b89a7b6fb171bc8df8734819',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5faligned_5fat_284',['mi_zalloc_aligned_at',['../group__aligned.html#ga5f8c2353766db522565e642fafd8a3f8',1,'mimalloc-doc.h']]],
+ ['mi_5fzalloc_5fsmall_285',['mi_zalloc_small',['../group__extended.html#ga220f29f40a44404b0061c15bc1c31152',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+/* @license-end */
+--></script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['void',['void',['../group__extended.html#gadc49452cc1634aa03ac83ffe9b97a19c',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['aligned_20allocation_314',['Aligned Allocation',['../group__aligned.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['basic_20allocation_315',['Basic Allocation',['../group__malloc.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['c_2b_2b_20wrappers_316',['C++ wrappers',['../group__cpp.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['extended_20functions_317',['Extended Functions',['../group__extended.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['heap_20allocation_318',['Heap Allocation',['../group__heap.html',1,'']]],
+ ['heap_20introspection_319',['Heap Introspection',['../group__analysis.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_5.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['posix_320',['Posix',['../group__posix.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_6.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['runtime_20options_321',['Runtime Options',['../group__options.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_7.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['typed_20macros_322',['Typed Macros',['../group__typed.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="groups_8.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['zero_20initialized_20re_2dallocation_323',['Zero initialized re-allocation',['../group__zeroinit.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="NoMatches">No Matches</div>
+</div>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="pages_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['building_324',['Building',['../build.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="pages_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['environment_20options_325',['Environment Options',['../environment.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="pages_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['overriding_20malloc_326',['Overriding Malloc',['../overrides.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="pages_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['performance_327',['Performance',['../bench.html',1,'']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="pages_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['using_20the_20library_328',['Using the library',['../using.html',1,'']]]
+];
--- /dev/null
+/*---------------- Search Box */
+
+#FSearchBox {
+ float: left;
+}
+
+#MSearchBox {
+ white-space : nowrap;
+ float: none;
+ margin-top: 0px;
+ right: 0px;
+ width: 170px;
+ height: 24px;
+ z-index: 102;
+ display: inline;
+ position: absolute;
+}
+
+#MSearchBox .left
+{
+ display:block;
+ position:absolute;
+ left:10px;
+ width:20px;
+ height:19px;
+ background:url('search_l.png') no-repeat;
+ background-position:right;
+}
+
+#MSearchSelect {
+ display:block;
+ position:absolute;
+ width:20px;
+ height:19px;
+}
+
+.left #MSearchSelect {
+ left:4px;
+}
+
+.right #MSearchSelect {
+ right:5px;
+}
+
+#MSearchField {
+ display:block;
+ position:absolute;
+ height:19px;
+ background:url('search_m.png') repeat-x;
+ border:none;
+ width:111px;
+ margin-left:20px;
+ padding-left:4px;
+ color: #909090;
+ outline: none;
+ font: 9pt Arial, Verdana, sans-serif;
+ -webkit-border-radius: 0px;
+}
+
+#FSearchBox #MSearchField {
+ margin-left:15px;
+}
+
+#MSearchBox .right {
+ display:block;
+ position:absolute;
+ right:10px;
+ top:0px;
+ width:20px;
+ height:19px;
+ background:url('search_r.png') no-repeat;
+ background-position:left;
+}
+
+#MSearchClose {
+ display: none;
+ position: absolute;
+ top: 4px;
+ background : none;
+ border: none;
+ margin: 0px 4px 0px 0px;
+ padding: 0px 0px;
+ outline: none;
+}
+
+.left #MSearchClose {
+ left: 6px;
+}
+
+.right #MSearchClose {
+ right: 2px;
+}
+
+.MSearchBoxActive #MSearchField {
+ color: #000000;
+}
+
+/*---------------- Search filter selection */
+
+#MSearchSelectWindow {
+ display: none;
+ position: absolute;
+ left: 0; top: 0;
+ border: 1px solid #4F5657;
+ background-color: #F2F3F3;
+ z-index: 10001;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+.SelectItem {
+ font: 8pt Arial, Verdana, sans-serif;
+ padding-left: 2px;
+ padding-right: 12px;
+ border: 0px;
+}
+
+span.SelectionMark {
+ margin-right: 4px;
+ font-family: monospace;
+ outline-style: none;
+ text-decoration: none;
+}
+
+a.SelectItem {
+ display: block;
+ outline-style: none;
+ color: #000000;
+ text-decoration: none;
+ padding-left: 6px;
+ padding-right: 12px;
+}
+
+a.SelectItem:focus,
+a.SelectItem:active {
+ color: #000000;
+ outline-style: none;
+ text-decoration: none;
+}
+
+a.SelectItem:hover {
+ color: #FFFFFF;
+ background-color: #0F1010;
+ outline-style: none;
+ text-decoration: none;
+ cursor: pointer;
+ display: block;
+}
+
+/*---------------- Search results window */
+
+iframe#MSearchResults {
+ width: 60ex;
+ height: 15em;
+}
+
+#MSearchResultsWindow {
+ display: none;
+ position: absolute;
+ left: 0; top: 0;
+ border: 1px solid #000;
+ background-color: #DADDDE;
+ z-index:10000;
+}
+
+/* ----------------------------------- */
+
+
+#SRIndex {
+ clear:both;
+ padding-bottom: 15px;
+}
+
+.SREntry {
+ font-size: 10pt;
+ padding-left: 1ex;
+}
+
+.SRPage .SREntry {
+ font-size: 8pt;
+ padding: 1px 5px;
+}
+
+body.SRPage {
+ margin: 5px 2px;
+}
+
+.SRChildren {
+ padding-left: 3ex; padding-bottom: .5em
+}
+
+.SRPage .SRChildren {
+ display: none;
+}
+
+.SRSymbol {
+ font-weight: bold;
+ color: #121414;
+ font-family: Arial, Verdana, sans-serif;
+ text-decoration: none;
+ outline: none;
+}
+
+a.SRScope {
+ display: block;
+ color: #121414;
+ font-family: Arial, Verdana, sans-serif;
+ text-decoration: none;
+ outline: none;
+}
+
+a.SRSymbol:focus, a.SRSymbol:active,
+a.SRScope:focus, a.SRScope:active {
+ text-decoration: underline;
+}
+
+span.SRScope {
+ padding-left: 4px;
+}
+
+.SRPage .SRStatus {
+ padding: 2px 5px;
+ font-size: 8pt;
+ font-style: italic;
+}
+
+.SRResult {
+ display: none;
+}
+
+DIV.searchresults {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+/*---------------- External search page results */
+
+.searchresult {
+ background-color: #DFE1E2;
+}
+
+.pages b {
+ color: white;
+ padding: 5px 5px 3px 5px;
+ background-image: url("../tab_a.png");
+ background-repeat: repeat-x;
+ text-shadow: 0 1px 1px #000000;
+}
+
+.pages {
+ line-height: 17px;
+ margin-left: 4px;
+ text-decoration: none;
+}
+
+.hl {
+ font-weight: bold;
+}
+
+#searchresults {
+ margin-bottom: 20px;
+}
+
+.searchpages {
+ margin-top: 10px;
+}
+
--- /dev/null
+/*
+ @licstart The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend The above is the entire license notice for the JavaScript code in this file
+ */
+function convertToId(search)
+{
+ var result = '';
+ for (i=0;i<search.length;i++)
+ {
+ var c = search.charAt(i);
+ var cn = c.charCodeAt(0);
+ if (c.match(/[a-z0-9\u0080-\uFFFF]/))
+ {
+ result+=c;
+ }
+ else if (cn<16)
+ {
+ result+="_0"+cn.toString(16);
+ }
+ else
+ {
+ result+="_"+cn.toString(16);
+ }
+ }
+ return result;
+}
+
+function getXPos(item)
+{
+ var x = 0;
+ if (item.offsetWidth)
+ {
+ while (item && item!=document.body)
+ {
+ x += item.offsetLeft;
+ item = item.offsetParent;
+ }
+ }
+ return x;
+}
+
+function getYPos(item)
+{
+ var y = 0;
+ if (item.offsetWidth)
+ {
+ while (item && item!=document.body)
+ {
+ y += item.offsetTop;
+ item = item.offsetParent;
+ }
+ }
+ return y;
+}
+
+/* A class handling everything associated with the search panel.
+
+ Parameters:
+ name - The name of the global variable that will be
+ storing this instance. Is needed to be able to set timeouts.
+ resultPath - path to use for external files
+*/
+function SearchBox(name, resultsPath, inFrame, label, extension)
+{
+ if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }
+ if (!extension || extension == "") { extension = ".html"; }
+
+ // ---------- Instance variables
+ this.name = name;
+ this.resultsPath = resultsPath;
+ this.keyTimeout = 0;
+ this.keyTimeoutLength = 500;
+ this.closeSelectionTimeout = 300;
+ this.lastSearchValue = "";
+ this.lastResultsPage = "";
+ this.hideTimeout = 0;
+ this.searchIndex = 0;
+ this.searchActive = false;
+ this.insideFrame = inFrame;
+ this.searchLabel = label;
+ this.extension = extension;
+
+ // ----------- DOM Elements
+
+ this.DOMSearchField = function()
+ { return document.getElementById("MSearchField"); }
+
+ this.DOMSearchSelect = function()
+ { return document.getElementById("MSearchSelect"); }
+
+ this.DOMSearchSelectWindow = function()
+ { return document.getElementById("MSearchSelectWindow"); }
+
+ this.DOMPopupSearchResults = function()
+ { return document.getElementById("MSearchResults"); }
+
+ this.DOMPopupSearchResultsWindow = function()
+ { return document.getElementById("MSearchResultsWindow"); }
+
+ this.DOMSearchClose = function()
+ { return document.getElementById("MSearchClose"); }
+
+ this.DOMSearchBox = function()
+ { return document.getElementById("MSearchBox"); }
+
+ // ------------ Event Handlers
+
+ // Called when focus is added or removed from the search field.
+ this.OnSearchFieldFocus = function(isActive)
+ {
+ this.Activate(isActive);
+ }
+
+ this.OnSearchSelectShow = function()
+ {
+ var searchSelectWindow = this.DOMSearchSelectWindow();
+ var searchField = this.DOMSearchSelect();
+
+ if (this.insideFrame)
+ {
+ var left = getXPos(searchField);
+ var top = getYPos(searchField);
+ left += searchField.offsetWidth + 6;
+ top += searchField.offsetHeight;
+
+ // show search selection popup
+ searchSelectWindow.style.display='block';
+ left -= searchSelectWindow.offsetWidth;
+ searchSelectWindow.style.left = left + 'px';
+ searchSelectWindow.style.top = top + 'px';
+ }
+ else
+ {
+ var left = getXPos(searchField);
+ var top = getYPos(searchField);
+ top += searchField.offsetHeight;
+
+ // show search selection popup
+ searchSelectWindow.style.display='block';
+ searchSelectWindow.style.left = left + 'px';
+ searchSelectWindow.style.top = top + 'px';
+ }
+
+ // stop selection hide timer
+ if (this.hideTimeout)
+ {
+ clearTimeout(this.hideTimeout);
+ this.hideTimeout=0;
+ }
+ return false; // to avoid "image drag" default event
+ }
+
+ this.OnSearchSelectHide = function()
+ {
+ this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
+ this.closeSelectionTimeout);
+ }
+
+ // Called when the content of the search field is changed.
+ this.OnSearchFieldChange = function(evt)
+ {
+ if (this.keyTimeout) // kill running timer
+ {
+ clearTimeout(this.keyTimeout);
+ this.keyTimeout = 0;
+ }
+
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==40 || e.keyCode==13)
+ {
+ if (e.shiftKey==1)
+ {
+ this.OnSearchSelectShow();
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ child.focus();
+ return;
+ }
+ }
+ return;
+ }
+ else
+ {
+ window.frames.MSearchResults.postMessage("take_focus", "*");
+ }
+ }
+ else if (e.keyCode==27) // Escape out of the search field
+ {
+ this.DOMSearchField().blur();
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.lastSearchValue = '';
+ this.Activate(false);
+ return;
+ }
+
+ // strip whitespaces
+ var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+
+ if (searchValue != this.lastSearchValue) // search value has changed
+ {
+ if (searchValue != "") // non-empty search
+ {
+ // set timer for search update
+ this.keyTimeout = setTimeout(this.name + '.Search()',
+ this.keyTimeoutLength);
+ }
+ else // empty search field
+ {
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.lastSearchValue = '';
+ }
+ }
+ }
+
+ this.SelectItemCount = function(id)
+ {
+ var count=0;
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ this.SelectItemSet = function(id)
+ {
+ var i,j=0;
+ var win=this.DOMSearchSelectWindow();
+ for (i=0;i<win.childNodes.length;i++)
+ {
+ var child = win.childNodes[i]; // get span within a
+ if (child.className=='SelectItem')
+ {
+ var node = child.firstChild;
+ if (j==id)
+ {
+ node.innerHTML='•';
+ }
+ else
+ {
+ node.innerHTML=' ';
+ }
+ j++;
+ }
+ }
+ }
+
+ // Called when an search filter selection is made.
+ // set item with index id as the active item
+ this.OnSelectItem = function(id)
+ {
+ this.searchIndex = id;
+ this.SelectItemSet(id);
+ var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+ if (searchValue!="" && this.searchActive) // something was found -> do a search
+ {
+ this.Search();
+ }
+ }
+
+ this.OnSearchSelectKey = function(evt)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
+ {
+ this.searchIndex++;
+ this.OnSelectItem(this.searchIndex);
+ }
+ else if (e.keyCode==38 && this.searchIndex>0) // Up
+ {
+ this.searchIndex--;
+ this.OnSelectItem(this.searchIndex);
+ }
+ else if (e.keyCode==13 || e.keyCode==27)
+ {
+ this.OnSelectItem(this.searchIndex);
+ this.CloseSelectionWindow();
+ this.DOMSearchField().focus();
+ }
+ return false;
+ }
+
+ // --------- Actions
+
+ // Closes the results window.
+ this.CloseResultsWindow = function()
+ {
+ this.DOMPopupSearchResultsWindow().style.display = 'none';
+ this.DOMSearchClose().style.display = 'none';
+ this.Activate(false);
+ }
+
+ this.CloseSelectionWindow = function()
+ {
+ this.DOMSearchSelectWindow().style.display = 'none';
+ }
+
+ // Performs a search.
+ this.Search = function()
+ {
+ this.keyTimeout = 0;
+
+ // strip leading whitespace
+ var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
+
+ var code = searchValue.toLowerCase().charCodeAt(0);
+ var idxChar = searchValue.substr(0, 1).toLowerCase();
+ if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
+ {
+ idxChar = searchValue.substr(0, 2);
+ }
+
+ var resultsPage;
+ var resultsPageWithSearch;
+ var hasResultsPage;
+
+ var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
+ if (idx!=-1)
+ {
+ var hexCode=idx.toString(16);
+ resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension;
+ resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
+ hasResultsPage = true;
+ }
+ else // nothing available for this search term
+ {
+ resultsPage = this.resultsPath + '/nomatches' + this.extension;
+ resultsPageWithSearch = resultsPage;
+ hasResultsPage = false;
+ }
+
+ window.frames.MSearchResults.location = resultsPageWithSearch;
+ var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
+
+ if (domPopupSearchResultsWindow.style.display!='block')
+ {
+ var domSearchBox = this.DOMSearchBox();
+ this.DOMSearchClose().style.display = 'inline-block';
+ if (this.insideFrame)
+ {
+ var domPopupSearchResults = this.DOMPopupSearchResults();
+ domPopupSearchResultsWindow.style.position = 'relative';
+ domPopupSearchResultsWindow.style.display = 'block';
+ var width = document.body.clientWidth - 8; // the -8 is for IE :-(
+ domPopupSearchResultsWindow.style.width = width + 'px';
+ domPopupSearchResults.style.width = width + 'px';
+ }
+ else
+ {
+ var domPopupSearchResults = this.DOMPopupSearchResults();
+ var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
+ var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
+ domPopupSearchResultsWindow.style.display = 'block';
+ left -= domPopupSearchResults.offsetWidth;
+ domPopupSearchResultsWindow.style.top = top + 'px';
+ domPopupSearchResultsWindow.style.left = left + 'px';
+ }
+ }
+
+ this.lastSearchValue = searchValue;
+ this.lastResultsPage = resultsPage;
+ }
+
+ // -------- Activation Functions
+
+ // Activates or deactivates the search panel, resetting things to
+ // their default values if necessary.
+ this.Activate = function(isActive)
+ {
+ if (isActive || // open it
+ this.DOMPopupSearchResultsWindow().style.display == 'block'
+ )
+ {
+ this.DOMSearchBox().className = 'MSearchBoxActive';
+
+ var searchField = this.DOMSearchField();
+
+ if (searchField.value == this.searchLabel) // clear "Search" term upon entry
+ {
+ searchField.value = '';
+ this.searchActive = true;
+ }
+ }
+ else if (!isActive) // directly remove the panel
+ {
+ this.DOMSearchBox().className = 'MSearchBoxInactive';
+ this.DOMSearchField().value = this.searchLabel;
+ this.searchActive = false;
+ this.lastSearchValue = ''
+ this.lastResultsPage = '';
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// The class that handles everything on the search results page.
+function SearchResults(name)
+{
+ // The number of matches from the last run of <Search()>.
+ this.lastMatchCount = 0;
+ this.lastKey = 0;
+ this.repeatOn = false;
+
+ // Toggles the visibility of the passed element ID.
+ this.FindChildElement = function(id)
+ {
+ var parentElement = document.getElementById(id);
+ var element = parentElement.firstChild;
+
+ while (element && element!=parentElement)
+ {
+ if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren')
+ {
+ return element;
+ }
+
+ if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes())
+ {
+ element = element.firstChild;
+ }
+ else if (element.nextSibling)
+ {
+ element = element.nextSibling;
+ }
+ else
+ {
+ do
+ {
+ element = element.parentNode;
+ }
+ while (element && element!=parentElement && !element.nextSibling);
+
+ if (element && element!=parentElement)
+ {
+ element = element.nextSibling;
+ }
+ }
+ }
+ }
+
+ this.Toggle = function(id)
+ {
+ var element = this.FindChildElement(id);
+ if (element)
+ {
+ if (element.style.display == 'block')
+ {
+ element.style.display = 'none';
+ }
+ else
+ {
+ element.style.display = 'block';
+ }
+ }
+ }
+
+ // Searches for the passed string. If there is no parameter,
+ // it takes it from the URL query.
+ //
+ // Always returns true, since other documents may try to call it
+ // and that may or may not be possible.
+ this.Search = function(search)
+ {
+ if (!search) // get search word from URL
+ {
+ search = window.location.search;
+ search = search.substring(1); // Remove the leading '?'
+ search = unescape(search);
+ }
+
+ search = search.replace(/^ +/, ""); // strip leading spaces
+ search = search.replace(/ +$/, ""); // strip trailing spaces
+ search = search.toLowerCase();
+ search = convertToId(search);
+
+ var resultRows = document.getElementsByTagName("div");
+ var matches = 0;
+
+ var i = 0;
+ while (i < resultRows.length)
+ {
+ var row = resultRows.item(i);
+ if (row.className == "SRResult")
+ {
+ var rowMatchName = row.id.toLowerCase();
+ rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
+
+ if (search.length<=rowMatchName.length &&
+ rowMatchName.substr(0, search.length)==search)
+ {
+ row.style.display = 'block';
+ matches++;
+ }
+ else
+ {
+ row.style.display = 'none';
+ }
+ }
+ i++;
+ }
+ document.getElementById("Searching").style.display='none';
+ if (matches == 0) // no results
+ {
+ document.getElementById("NoMatches").style.display='block';
+ }
+ else // at least one result
+ {
+ document.getElementById("NoMatches").style.display='none';
+ }
+ this.lastMatchCount = matches;
+ return true;
+ }
+
+ // return the first item with index index or higher that is visible
+ this.NavNext = function(index)
+ {
+ var focusItem;
+ while (1)
+ {
+ var focusName = 'Item'+index;
+ focusItem = document.getElementById(focusName);
+ if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+ {
+ break;
+ }
+ else if (!focusItem) // last element
+ {
+ break;
+ }
+ focusItem=null;
+ index++;
+ }
+ return focusItem;
+ }
+
+ this.NavPrev = function(index)
+ {
+ var focusItem;
+ while (1)
+ {
+ var focusName = 'Item'+index;
+ focusItem = document.getElementById(focusName);
+ if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+ {
+ break;
+ }
+ else if (!focusItem) // last element
+ {
+ break;
+ }
+ focusItem=null;
+ index--;
+ }
+ return focusItem;
+ }
+
+ this.ProcessKeys = function(e)
+ {
+ if (e.type == "keydown")
+ {
+ this.repeatOn = false;
+ this.lastKey = e.keyCode;
+ }
+ else if (e.type == "keypress")
+ {
+ if (!this.repeatOn)
+ {
+ if (this.lastKey) this.repeatOn = true;
+ return false; // ignore first keypress after keydown
+ }
+ }
+ else if (e.type == "keyup")
+ {
+ this.lastKey = 0;
+ this.repeatOn = false;
+ }
+ return this.lastKey!=0;
+ }
+
+ this.Nav = function(evt,itemIndex)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==13) return true;
+ if (!this.ProcessKeys(e)) return false;
+
+ if (this.lastKey==38) // Up
+ {
+ var newIndex = itemIndex-1;
+ var focusItem = this.NavPrev(newIndex);
+ if (focusItem)
+ {
+ var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
+ if (child && child.style.display == 'block') // children visible
+ {
+ var n=0;
+ var tmpElem;
+ while (1) // search for last child
+ {
+ tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
+ if (tmpElem)
+ {
+ focusItem = tmpElem;
+ }
+ else // found it!
+ {
+ break;
+ }
+ n++;
+ }
+ }
+ }
+ if (focusItem)
+ {
+ focusItem.focus();
+ }
+ else // return focus to search field
+ {
+ parent.document.getElementById("MSearchField").focus();
+ }
+ }
+ else if (this.lastKey==40) // Down
+ {
+ var newIndex = itemIndex+1;
+ var focusItem;
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem && elem.style.display == 'block') // children visible
+ {
+ focusItem = document.getElementById('Item'+itemIndex+'_c0');
+ }
+ if (!focusItem) focusItem = this.NavNext(newIndex);
+ if (focusItem) focusItem.focus();
+ }
+ else if (this.lastKey==39) // Right
+ {
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem) elem.style.display = 'block';
+ }
+ else if (this.lastKey==37) // Left
+ {
+ var item = document.getElementById('Item'+itemIndex);
+ var elem = this.FindChildElement(item.parentNode.parentNode.id);
+ if (elem) elem.style.display = 'none';
+ }
+ else if (this.lastKey==27) // Escape
+ {
+ parent.searchBox.CloseResultsWindow();
+ parent.document.getElementById("MSearchField").focus();
+ }
+ else if (this.lastKey==13) // Enter
+ {
+ return true;
+ }
+ return false;
+ }
+
+ this.NavChild = function(evt,itemIndex,childIndex)
+ {
+ var e = (evt) ? evt : window.event; // for IE
+ if (e.keyCode==13) return true;
+ if (!this.ProcessKeys(e)) return false;
+
+ if (this.lastKey==38) // Up
+ {
+ if (childIndex>0)
+ {
+ var newIndex = childIndex-1;
+ document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
+ }
+ else // already at first child, jump to parent
+ {
+ document.getElementById('Item'+itemIndex).focus();
+ }
+ }
+ else if (this.lastKey==40) // Down
+ {
+ var newIndex = childIndex+1;
+ var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
+ if (!elem) // last child, jump to parent next parent
+ {
+ elem = this.NavNext(itemIndex+1);
+ }
+ if (elem)
+ {
+ elem.focus();
+ }
+ }
+ else if (this.lastKey==27) // Escape
+ {
+ parent.searchBox.CloseResultsWindow();
+ parent.document.getElementById("MSearchField").focus();
+ }
+ else if (this.lastKey==13) // Enter
+ {
+ return true;
+ }
+ return false;
+ }
+}
+
+function setKeyActions(elem,action)
+{
+ elem.setAttribute('onkeydown',action);
+ elem.setAttribute('onkeypress',action);
+ elem.setAttribute('onkeyup',action);
+}
+
+function setClassAttr(elem,attr)
+{
+ elem.setAttribute('class',attr);
+ elem.setAttribute('className',attr);
+}
+
+function createResults()
+{
+ var results = document.getElementById("SRResults");
+ for (var e=0; e<searchData.length; e++)
+ {
+ var id = searchData[e][0];
+ var srResult = document.createElement('div');
+ srResult.setAttribute('id','SR_'+id);
+ setClassAttr(srResult,'SRResult');
+ var srEntry = document.createElement('div');
+ setClassAttr(srEntry,'SREntry');
+ var srLink = document.createElement('a');
+ srLink.setAttribute('id','Item'+e);
+ setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
+ setClassAttr(srLink,'SRSymbol');
+ srLink.innerHTML = searchData[e][1][0];
+ srEntry.appendChild(srLink);
+ if (searchData[e][1].length==2) // single result
+ {
+ srLink.setAttribute('href',searchData[e][1][1][0]);
+ if (searchData[e][1][1][1])
+ {
+ srLink.setAttribute('target','_parent');
+ }
+ var srScope = document.createElement('span');
+ setClassAttr(srScope,'SRScope');
+ srScope.innerHTML = searchData[e][1][1][2];
+ srEntry.appendChild(srScope);
+ }
+ else // multiple results
+ {
+ srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
+ var srChildren = document.createElement('div');
+ setClassAttr(srChildren,'SRChildren');
+ for (var c=0; c<searchData[e][1].length-1; c++)
+ {
+ var srChild = document.createElement('a');
+ srChild.setAttribute('id','Item'+e+'_c'+c);
+ setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
+ setClassAttr(srChild,'SRScope');
+ srChild.setAttribute('href',searchData[e][1][c+1][0]);
+ if (searchData[e][1][c+1][1])
+ {
+ srChild.setAttribute('target','_parent');
+ }
+ srChild.innerHTML = searchData[e][1][c+1][2];
+ srChildren.appendChild(srChild);
+ }
+ srEntry.appendChild(srChildren);
+ }
+ srResult.appendChild(srEntry);
+ results.appendChild(srResult);
+ }
+}
+
+function init_search()
+{
+ var results = document.getElementById("MSearchSelectWindow");
+ for (var key in indexSectionLabels)
+ {
+ var link = document.createElement('a');
+ link.setAttribute('class','SelectItem');
+ link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
+ link.href='javascript:void(0)';
+ link.innerHTML='<span class="SelectionMark"> </span>'+indexSectionLabels[key];
+ results.appendChild(link);
+ }
+ searchBox.OnSelectItem(0);
+}
+/* @license-end */
--- /dev/null
+var indexSectionsWithContent =
+{
+ 0: "_abcehmoprtuz",
+ 1: "m",
+ 2: "m",
+ 3: "bcru",
+ 4: "m",
+ 5: "m",
+ 6: "_m",
+ 7: "abcehprtz",
+ 8: "beopu"
+};
+
+var indexSectionNames =
+{
+ 0: "all",
+ 1: "classes",
+ 2: "functions",
+ 3: "variables",
+ 4: "typedefs",
+ 5: "enums",
+ 6: "enumvalues",
+ 7: "groups",
+ 8: "pages"
+};
+
+var indexSectionLabels =
+{
+ 0: "All",
+ 1: "Data Structures",
+ 2: "Functions",
+ 3: "Variables",
+ 4: "Typedefs",
+ 5: "Enumerations",
+ 6: "Enumerator",
+ 7: "Modules",
+ 8: "Pages"
+};
+
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="typedefs_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5fblock_5fvisit_5ffun_291',['mi_block_visit_fun',['../group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65',1,'mimalloc-doc.h']]],
+ ['mi_5fdeferred_5ffree_5ffun_292',['mi_deferred_free_fun',['../group__extended.html#ga299dae78d25ce112e384a98b7309c5be',1,'mimalloc-doc.h']]],
+ ['mi_5ferror_5ffun_293',['mi_error_fun',['../group__extended.html#ga251d369cda3f1c2a955c555486ed90e5',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5ft_294',['mi_heap_t',['../group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2',1,'mimalloc-doc.h']]],
+ ['mi_5foutput_5ffun_295',['mi_output_fun',['../group__extended.html#gad823d23444a4b77a40f66bf075a98a0c',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="typedefs_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+/* @license-end */
+--></script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['heartbeat',['heartbeat',['../group__extended.html#ga411f6e94394a2400aa460c796beff8d8',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.8.15"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="typedefs_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+--></script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript"><!--
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+/* @license-end */
+--></script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['mi_5fblock_5fvisit_5ffun',['mi_block_visit_fun',['../group__analysis.html#gadfa01e2900f0e5d515ad5506b26f6d65',1,'mimalloc-doc.h']]],
+ ['mi_5fheap_5ft',['mi_heap_t',['../group__heap.html#ga34a47cde5a5b38c29f1aa3c5e76943c2',1,'mimalloc-doc.h']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['block_5fsize_286',['block_size',['../group__analysis.html#a332a6c14d736a99699d5453a1cb04b41',1,'mi_heap_area_t']]],
+ ['blocks_287',['blocks',['../group__analysis.html#ae0085e6e1cf059a4eb7767e30e9991b8',1,'mi_heap_area_t']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['committed_288',['committed',['../group__analysis.html#ab47526df656d8837ec3e97f11b83f835',1,'mi_heap_area_t']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['reserved_289',['reserved',['../group__analysis.html#ae848a3e6840414891035423948ca0383',1,'mi_heap_area_t']]]
+];
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+ if (event.data == "take_focus") {
+ var elem = searchResults.NavNext(0);
+ if (elem) elem.focus();
+ }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
--- /dev/null
+var searchData=
+[
+ ['used_290',['used',['../group__analysis.html#ab820302c5cd0df133eb8e51650a008b4',1,'mi_heap_area_t']]]
+];
--- /dev/null
+.tabs, .tabs2, .tabs3 {
+ background-image: url('tab_b.png');
+ width: 100%;
+ z-index: 101;
+ font-size: 13px;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+.tabs2 {
+ font-size: 10px;
+}
+.tabs3 {
+ font-size: 9px;
+}
+
+.tablist {
+ margin: 0;
+ padding: 0;
+ display: table;
+}
+
+.tablist li {
+ float: left;
+ display: table-cell;
+ background-image: url('tab_b.png');
+ line-height: 36px;
+ list-style: none;
+}
+
+.tablist a {
+ display: block;
+ padding: 0 20px;
+ font-weight: bold;
+ background-image:url('tab_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color: #040404;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+ outline: none;
+}
+
+.tabs3 .tablist a {
+ padding: 0 10px;
+}
+
+.tablist a:hover {
+ background-image: url('tab_h.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+ text-decoration: none;
+}
+
+.tablist li.current a {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.9.1"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>mi-malloc: Using the library</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+ $(document).ready(function() { init_search(); });
+/* @license-end */
+</script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="mimalloc-doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="mimalloc-logo.svg"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">mi-malloc
+  <span id="projectnumber">1.7/2.0</span>
+ </div>
+ </td>
+ <td> <div id="MSearchBox" class="MSearchBoxInactive">
+ <span class="left">
+ <img id="MSearchSelect" src="search/mag_sel.svg"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ alt=""/>
+ <input type="text" id="MSearchField" value="Search" accesskey="S"
+ onfocus="searchBox.OnSearchFieldFocus(true)"
+ onblur="searchBox.OnSearchFieldFocus(false)"
+ onkeyup="searchBox.OnSearchFieldChange(event)"/>
+ </span><span class="right">
+ <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
+ </span>
+ </div>
+</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.1 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
+/* @license-end */
+</script>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+ <div id="nav-tree">
+ <div id="nav-tree-contents">
+ <div id="nav-sync" class="sync"></div>
+ </div>
+ </div>
+ <div id="splitbar" style="-moz-user-select:none;"
+ class="ui-resizable-handle">
+ </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
+$(document).ready(function(){initNavTree('using.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+ onmouseover="return searchBox.OnSearchSelectShow()"
+ onmouseout="return searchBox.OnSearchSelectHide()"
+ onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0"
+ name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="PageDoc"><div class="header">
+ <div class="headertitle">
+<div class="title">Using the library </div> </div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock"><h3>Build</h3>
+<p>The preferred usage is including <code><mimalloc.h></code>, linking with the shared- or static library, and using the <code>mi_malloc</code> API exclusively for allocation. For example, </p><div class="fragment"><div class="line">gcc -o myprogram -lmimalloc myfile.c</div>
+</div><!-- fragment --><p>mimalloc uses only safe OS calls (<code>mmap</code> and <code>VirtualAlloc</code>) and can co-exist with other allocators linked to the same program. If you use <code>cmake</code>, you can simply use: </p><div class="fragment"><div class="line">find_package(mimalloc 1.0 REQUIRED)</div>
+</div><!-- fragment --><p> in your <code>CMakeLists.txt</code> to find a locally installed mimalloc. Then use either: </p><div class="fragment"><div class="line">target_link_libraries(myapp PUBLIC mimalloc)</div>
+</div><!-- fragment --><p> to link with the shared (dynamic) library, or: </p><div class="fragment"><div class="line">target_link_libraries(myapp PUBLIC mimalloc-<span class="keyword">static</span>)</div>
+</div><!-- fragment --><p> to link with the static library. See <code>test\CMakeLists.txt</code> for an example.</p>
+<h3>C++</h3>
+<p>For best performance in C++ programs, it is also recommended to override the global <code>new</code> and <code>delete</code> operators. For convience, mimalloc provides <a href="https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h"><code>mimalloc-new-delete.h</code></a> which does this for you – just include it in a single(!) source file in your project without linking to the mimalloc's library.</p>
+<p>In C++, mimalloc also provides the <code><a class="el" href="group__cpp.html#structmi__stl__allocator" title="std::allocator implementation for mimalloc for use in STL containers.">mi_stl_allocator</a></code> struct which implements the <code>std::allocator</code> interface. For example: </p><div class="fragment"><div class="line">std::vector<some_struct, mi_stl_allocator<some_struct>> vec;</div>
+<div class="line">vec.push_back(some_struct());</div>
+</div><!-- fragment --><h3>Statistics</h3>
+<p>You can pass environment variables to print verbose messages (<code>MIMALLOC_VERBOSE=1</code>) and statistics (<code>MIMALLOC_SHOW_STATS=1</code>) (in the debug version): </p><div class="fragment"><div class="line">> env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363</div>
+<div class="line"> </div>
+<div class="line">175451865205073170563711388363 = 374456281610909315237213 * 468551</div>
+<div class="line"> </div>
+<div class="line">heap stats: peak total freed unit</div>
+<div class="line">normal 2: 16.4 kb 17.5 mb 17.5 mb 16 b ok</div>
+<div class="line">normal 3: 16.3 kb 15.2 mb 15.2 mb 24 b ok</div>
+<div class="line">normal 4: 64 b 4.6 kb 4.6 kb 32 b ok</div>
+<div class="line">normal 5: 80 b 118.4 kb 118.4 kb 40 b ok</div>
+<div class="line">normal 6: 48 b 48 b 48 b 48 b ok</div>
+<div class="line">normal 17: 960 b 960 b 960 b 320 b ok</div>
+<div class="line"> </div>
+<div class="line">heap stats: peak total freed unit</div>
+<div class="line"> normal: 33.9 kb 32.8 mb 32.8 mb 1 b ok</div>
+<div class="line"> huge: 0 b 0 b 0 b 1 b ok</div>
+<div class="line"> total: 33.9 kb 32.8 mb 32.8 mb 1 b ok</div>
+<div class="line">malloc requested: 32.8 mb</div>
+<div class="line"> </div>
+<div class="line"> committed: 58.2 kb 58.2 kb 58.2 kb 1 b ok</div>
+<div class="line"> reserved: 2.0 mb 2.0 mb 2.0 mb 1 b ok</div>
+<div class="line"> reset: 0 b 0 b 0 b 1 b ok</div>
+<div class="line"> segments: 1 1 1</div>
+<div class="line">-abandoned: 0</div>
+<div class="line"> pages: 6 6 6</div>
+<div class="line">-abandoned: 0</div>
+<div class="line"> mmaps: 3</div>
+<div class="line"> mmap fast: 0</div>
+<div class="line"> mmap slow: 1</div>
+<div class="line"> threads: 0</div>
+<div class="line"> elapsed: 2.022s</div>
+<div class="line"> process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb</div>
+</div><!-- fragment --><p>The above model of using the <code>mi_</code> prefixed API is not always possible though in existing programs that already use the standard malloc interface, and another option is to override the standard malloc interface completely and redirect all calls to the <em>mimalloc</em> library instead.</p>
+<p>See <a class="el" href="overrides.html">Overriding Malloc</a> for more info. </p>
+</div></div><!-- contents -->
+</div><!-- PageDoc -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
+ </ul>
+</div>
+</body>
+</html>
<ClInclude Include="..\..\include\mimalloc-new-delete.h" />
<ClInclude Include="..\..\include\mimalloc-override.h" />
<ClInclude Include="..\..\include\mimalloc-types.h" />
+ <ClInclude Include="..\..\src\bitmap.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\alloc-aligned.c">
<ClCompile Include="..\..\src\alloc-posix.c" />
<ClCompile Include="..\..\src\alloc.c" />
<ClCompile Include="..\..\src\arena.c" />
+ <ClCompile Include="..\..\src\bitmap.c" />
<ClCompile Include="..\..\src\heap.c" />
<ClCompile Include="..\..\src\init.c" />
- <ClCompile Include="..\..\src\region.c" />
<ClCompile Include="..\..\src\options.c" />
<ClCompile Include="..\..\src\os.c" />
<ClCompile Include="..\..\src\page-queue.c">
</ClCompile>
<ClCompile Include="..\..\src\page.c" />
<ClCompile Include="..\..\src\random.c" />
+ <ClCompile Include="..\..\src\segment-cache.c" />
<ClCompile Include="..\..\src\segment.c" />
<ClCompile Include="..\..\src\stats.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
<ClInclude Include="..\..\include\mimalloc-new-delete.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\bitmap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\alloc.c">
<ClCompile Include="..\..\src\init.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\region.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\alloc-override.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\random.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\bitmap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\segment-cache.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions>
- <CompileAs>CompileAsCpp</CompileAs>
+ <CompileAs>CompileAsC</CompileAs>
<SupportJustMyCode>false</SupportJustMyCode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MI_DEBUG=3;%(PreprocessorDefinitions);</PreprocessorDefinitions>
- <CompileAs>CompileAsCpp</CompileAs>
+ <CompileAs>CompileAsC</CompileAs>
<SupportJustMyCode>false</SupportJustMyCode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<WholeProgramOptimization>false</WholeProgramOptimization>
<BufferSecurityCheck>false</BufferSecurityCheck>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
- <CompileAs>CompileAsCpp</CompileAs>
+ <CompileAs>CompileAsC</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<WholeProgramOptimization>false</WholeProgramOptimization>
<BufferSecurityCheck>false</BufferSecurityCheck>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
- <CompileAs>CompileAsCpp</CompileAs>
+ <CompileAs>CompileAsC</CompileAs>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<ClCompile Include="..\..\src\alloc-posix.c" />
<ClCompile Include="..\..\src\alloc.c" />
<ClCompile Include="..\..\src\arena.c" />
+ <ClCompile Include="..\..\src\bitmap.c" />
<ClCompile Include="..\..\src\heap.c" />
<ClCompile Include="..\..\src\init.c" />
- <ClCompile Include="..\..\src\region.c" />
<ClCompile Include="..\..\src\options.c" />
<ClCompile Include="..\..\src\page-queue.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\page.c" />
<ClCompile Include="..\..\src\random.c" />
+ <ClCompile Include="..\..\src\segment-cache.c" />
<ClCompile Include="..\..\src\segment.c" />
<ClCompile Include="..\..\src\os.c" />
<ClCompile Include="..\..\src\stats.c" />
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc-override.h" />
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc-types.h" />
<ClInclude Include="..\..\include\mimalloc-new-delete.h" />
+ <ClInclude Include="..\..\src\bitmap.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
<ClCompile Include="..\..\src\init.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\region.c">
+ <ClCompile Include="..\..\src\alloc-posix.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\alloc-posix.c">
+ <ClCompile Include="..\..\src\arena.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\arena.c">
<ClCompile Include="..\..\src\random.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\bitmap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\segment-cache.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h">
<ClInclude Include="..\..\include\mimalloc-new-delete.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\bitmap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
<ClInclude Include="..\..\include\mimalloc-new-delete.h" />
<ClInclude Include="..\..\include\mimalloc-override.h" />
<ClInclude Include="..\..\include\mimalloc-types.h" />
+ <ClInclude Include="..\..\src\bitmap.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\alloc-aligned.c">
<ClCompile Include="..\..\src\alloc-posix.c" />
<ClCompile Include="..\..\src\alloc.c" />
<ClCompile Include="..\..\src\arena.c" />
- <ClCompile Include="..\..\src\bitmap.inc.c">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- </ClCompile>
+ <ClCompile Include="..\..\src\bitmap.c" />
<ClCompile Include="..\..\src\heap.c" />
<ClCompile Include="..\..\src\init.c" />
- <ClCompile Include="..\..\src\region.c" />
<ClCompile Include="..\..\src\options.c" />
<ClCompile Include="..\..\src\os.c" />
<ClCompile Include="..\..\src\page-queue.c">
</ClCompile>
<ClCompile Include="..\..\src\page.c" />
<ClCompile Include="..\..\src\random.c" />
+ <ClCompile Include="..\..\src\segment-cache.c" />
<ClCompile Include="..\..\src\segment.c" />
<ClCompile Include="..\..\src\stats.c" />
</ItemGroup>
<ClCompile Include="..\..\src\init.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\region.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\os.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\arena.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\bitmap.inc.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\random.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\options.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\bitmap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\segment-cache.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h">
<ClInclude Include="..\..\include\mimalloc-types.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\bitmap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
</ClCompile>
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="mimalloc-override.vcxproj">
- <Project>{abb5eae7-b3e6-432e-b636-333449892ea7}</Project>
+ <ProjectReference Include="mimalloc.vcxproj">
+ <Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
- <WarningLevel>Level3</WarningLevel>
+ <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
- <WarningLevel>Level3</WarningLevel>
+ <WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<ConformanceMode>true</ConformanceMode>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
- <WarningLevel>Level3</WarningLevel>
+ <WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<ConformanceMode>true</ConformanceMode>
<ClCompile Include="..\..\src\alloc-posix.c" />
<ClCompile Include="..\..\src\alloc.c" />
<ClCompile Include="..\..\src\arena.c" />
- <ClCompile Include="..\..\src\bitmap.inc.c">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ClCompile Include="..\..\src\bitmap.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\heap.c" />
<ClCompile Include="..\..\src\init.c" />
- <ClCompile Include="..\..\src\region.c" />
<ClCompile Include="..\..\src\options.c" />
<ClCompile Include="..\..\src\page-queue.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\page.c" />
<ClCompile Include="..\..\src\random.c" />
+ <ClCompile Include="..\..\src\segment-cache.c" />
<ClCompile Include="..\..\src\segment.c" />
<ClCompile Include="..\..\src\os.c" />
<ClCompile Include="..\..\src\stats.c" />
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc-override.h" />
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc-types.h" />
<ClInclude Include="..\..\include\mimalloc-new-delete.h" />
+ <ClInclude Include="..\..\src\bitmap.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<ClCompile Include="..\..\src\init.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\region.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\options.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\arena.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\bitmap.inc.c">
+ <ClCompile Include="..\..\src\random.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\random.c">
+ <ClCompile Include="..\..\src\bitmap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\segment-cache.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc-types.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\bitmap.h">
+ <Filter>Source Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{852a14ae-6dde-4e95-8077-ca705e97e5af}</UniqueIdentifier>
</Filter>
</ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021 Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#ifndef MIMALLOC_ATOMIC_H
#define MIMALLOC_ATOMIC_H
-// ------------------------------------------------------
+// --------------------------------------------------------------------------------------------
// Atomics
// We need to be portable between C, C++, and MSVC.
-// ------------------------------------------------------
+// We base the primitives on the C/C++ atomics and create a mimimal wrapper for MSVC in C compilation mode.
+// This is why we try to use only `uintptr_t` and `<type>*` as atomic types.
+// To gain better insight in the range of used atomics, we use explicitly named memory order operations
+// instead of passing the memory order as a parameter.
+// -----------------------------------------------------------------------------------------------
-#if defined(_MSC_VER)
-#define _Atomic(tp) tp
-#define ATOMIC_VAR_INIT(x) x
-#elif defined(__cplusplus)
+#if defined(__cplusplus)
+// Use C++ atomics
#include <atomic>
-#define _Atomic(tp) std::atomic<tp>
+#define _Atomic(tp) std::atomic<tp>
+#define mi_atomic(name) std::atomic_##name
+#define mi_memory_order(name) std::memory_order_##name
+#if !defined(ATOMIC_VAR_INIT) || (__cplusplus >= 202002L) // c++20, see issue #571
+ #define MI_ATOMIC_VAR_INIT(x) x
+#else
+ #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
+#endif
+#elif defined(_MSC_VER)
+// Use MSVC C wrapper for C11 atomics
+#define _Atomic(tp) tp
+#define MI_ATOMIC_VAR_INIT(x) x
+#define mi_atomic(name) mi_atomic_##name
+#define mi_memory_order(name) mi_memory_order_##name
#else
+// Use C11 atomics
#include <stdatomic.h>
+#define mi_atomic(name) atomic_##name
+#define mi_memory_order(name) memory_order_##name
+#define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
#endif
-// ------------------------------------------------------
-// Atomic operations specialized for mimalloc
-// ------------------------------------------------------
-
-// Atomically add a value; returns the previous value. Memory ordering is relaxed.
-static inline uintptr_t mi_atomic_add(volatile _Atomic(uintptr_t)* p, uintptr_t add);
-
-// Atomically "and" a value; returns the previous value. Memory ordering is relaxed.
-static inline uintptr_t mi_atomic_and(volatile _Atomic(uintptr_t)* p, uintptr_t x);
-
-// Atomically "or" a value; returns the previous value. Memory ordering is relaxed.
-static inline uintptr_t mi_atomic_or(volatile _Atomic(uintptr_t)* p, uintptr_t x);
-
-// Atomically compare and exchange a value; returns `true` if successful.
-// May fail spuriously. Memory ordering as release on success, and relaxed on failure.
-// (Note: expected and desired are in opposite order from atomic_compare_exchange)
-static inline bool mi_atomic_cas_weak(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected);
+// Various defines for all used memory orders in mimalloc
+#define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail) \
+ mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail)
+
+#define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail) \
+ mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail)
+
+#define mi_atomic_load_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire))
+#define mi_atomic_load_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed))
+#define mi_atomic_store_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_store_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))
+#define mi_atomic_exchange_release(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_exchange_acq_rel(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_cas_weak_release(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))
+#define mi_atomic_cas_weak_acq_rel(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))
+#define mi_atomic_cas_strong_release(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))
+#define mi_atomic_cas_strong_acq_rel(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))
+
+#define mi_atomic_add_relaxed(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed))
+#define mi_atomic_sub_relaxed(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed))
+#define mi_atomic_add_acq_rel(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_sub_acq_rel(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_and_acq_rel(p,x) mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_or_acq_rel(p,x) mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel))
+
+#define mi_atomic_increment_relaxed(p) mi_atomic_add_relaxed(p,(uintptr_t)1)
+#define mi_atomic_decrement_relaxed(p) mi_atomic_sub_relaxed(p,(uintptr_t)1)
+#define mi_atomic_increment_acq_rel(p) mi_atomic_add_acq_rel(p,(uintptr_t)1)
+#define mi_atomic_decrement_acq_rel(p) mi_atomic_sub_acq_rel(p,(uintptr_t)1)
-// Atomically compare and exchange a value; returns `true` if successful.
-// Memory ordering is acquire-release
-// (Note: expected and desired are in opposite order from atomic_compare_exchange)
-static inline bool mi_atomic_cas_strong(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected);
-
-// Atomically exchange a value. Memory ordering is acquire-release.
-static inline uintptr_t mi_atomic_exchange(volatile _Atomic(uintptr_t)* p, uintptr_t exchange);
-
-// Atomically read a value. Memory ordering is relaxed.
-static inline uintptr_t mi_atomic_read_relaxed(const volatile _Atomic(uintptr_t)* p);
-
-// Atomically read a value. Memory ordering is acquire.
-static inline uintptr_t mi_atomic_read(const volatile _Atomic(uintptr_t)* p);
-
-// Atomically write a value. Memory ordering is release.
-static inline void mi_atomic_write(volatile _Atomic(uintptr_t)* p, uintptr_t x);
-
-// Yield
static inline void mi_atomic_yield(void);
+static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add);
+static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub);
-// Atomically add a 64-bit value; returns the previous value.
-// Note: not using _Atomic(int64_t) as it is only used for statistics.
-static inline void mi_atomic_addi64(volatile int64_t* p, int64_t add);
-
-// Atomically update `*p` with the maximum of `*p` and `x` as a 64-bit value.
-// Returns the previous value. Note: not using _Atomic(int64_t) as it is only used for statistics.
-static inline void mi_atomic_maxi64(volatile int64_t* p, int64_t x);
-// Atomically read a 64-bit value
-// Note: not using _Atomic(int64_t) as it is only used for statistics.
-static inline int64_t mi_atomic_readi64(volatile int64_t* p);
+#if defined(__cplusplus) || !defined(_MSC_VER)
-// Atomically subtract a value; returns the previous value.
-static inline uintptr_t mi_atomic_sub(volatile _Atomic(uintptr_t)* p, uintptr_t sub) {
- return mi_atomic_add(p, (uintptr_t)(-((intptr_t)sub)));
-}
+// In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value)
+// We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well
+#define mi_atomic_load_ptr_acquire(tp,p) mi_atomic_load_acquire(p)
+#define mi_atomic_load_ptr_relaxed(tp,p) mi_atomic_load_relaxed(p)
-// Atomically increment a value; returns the incremented result.
-static inline uintptr_t mi_atomic_increment(volatile _Atomic(uintptr_t)* p) {
- return mi_atomic_add(p, 1);
-}
+// In C++ we need to add casts to help resolve templates if NULL is passed
+#if defined(__cplusplus)
+#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,(tp*)x)
+#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,(tp*)x)
+#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,(tp*)des)
+#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des)
+#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,(tp*)des)
+#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,(tp*)x)
+#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,(tp*)x)
+#else
+#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,x)
+#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,x)
+#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,des)
+#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,des)
+#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,des)
+#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,x)
+#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,x)
+#endif
-// Atomically decrement a value; returns the decremented result.
-static inline uintptr_t mi_atomic_decrement(volatile _Atomic(uintptr_t)* p) {
- return mi_atomic_sub(p, 1);
+// These are used by the statistics
+static inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) {
+ return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed));
}
-
-// Atomically add a signed value; returns the previous value.
-static inline intptr_t mi_atomic_addi(volatile _Atomic(intptr_t)* p, intptr_t add) {
- return (intptr_t)mi_atomic_add((volatile _Atomic(uintptr_t)*)p, (uintptr_t)add);
+static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) {
+ int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p);
+ while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, ¤t, x)) { /* nothing */ };
}
-// Atomically subtract a signed value; returns the previous value.
-static inline intptr_t mi_atomic_subi(volatile _Atomic(intptr_t)* p, intptr_t sub) {
- return (intptr_t)mi_atomic_addi(p,-sub);
-}
-
-// Atomically read a pointer; Memory order is relaxed (i.e. no fence, only atomic).
-#define mi_atomic_read_ptr_relaxed(T,p) \
- (T*)(mi_atomic_read_relaxed((const volatile _Atomic(uintptr_t)*)(p)))
+// Used by timers
+#define mi_atomic_loadi64_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire))
+#define mi_atomic_loadi64_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed))
+#define mi_atomic_storei64_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_storei64_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))
-// Atomically read a pointer; Memory order is acquire.
-#define mi_atomic_read_ptr(T,p) \
- (T*)(mi_atomic_read((const volatile _Atomic(uintptr_t)*)(p)))
-// Atomically write a pointer; Memory order is acquire.
-#define mi_atomic_write_ptr(T,p,x) \
- mi_atomic_write((volatile _Atomic(uintptr_t)*)(p), (uintptr_t)((T*)x))
-// Atomically compare and exchange a pointer; returns `true` if successful. May fail spuriously.
-// Memory order is release. (like a write)
-// (Note: expected and desired are in opposite order from atomic_compare_exchange)
-#define mi_atomic_cas_ptr_weak(T,p,desired,expected) \
- mi_atomic_cas_weak((volatile _Atomic(uintptr_t)*)(p), (uintptr_t)((T*)(desired)), (uintptr_t)((T*)(expected)))
-
-// Atomically compare and exchange a pointer; returns `true` if successful. Memory order is acquire_release.
-// (Note: expected and desired are in opposite order from atomic_compare_exchange)
-#define mi_atomic_cas_ptr_strong(T,p,desired,expected) \
- mi_atomic_cas_strong((volatile _Atomic(uintptr_t)*)(p),(uintptr_t)((T*)(desired)), (uintptr_t)((T*)(expected)))
+#elif defined(_MSC_VER)
-// Atomically exchange a pointer value.
-#define mi_atomic_exchange_ptr(T,p,exchange) \
- (T*)mi_atomic_exchange((volatile _Atomic(uintptr_t)*)(p), (uintptr_t)((T*)exchange))
-
-
-#ifdef _MSC_VER
+// MSVC C compilation wrapper that uses Interlocked operations to model C11 atomics.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <intrin.h>
typedef LONG msc_intptr_t;
#define MI_64(f) f
#endif
-static inline uintptr_t mi_atomic_add(volatile _Atomic(uintptr_t)* p, uintptr_t add) {
+
+typedef enum mi_memory_order_e {
+ mi_memory_order_relaxed,
+ mi_memory_order_consume,
+ mi_memory_order_acquire,
+ mi_memory_order_release,
+ mi_memory_order_acq_rel,
+ mi_memory_order_seq_cst
+} mi_memory_order;
+
+static inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) {
+ (void)(mo);
return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add);
}
-static inline uintptr_t mi_atomic_and(volatile _Atomic(uintptr_t)* p, uintptr_t x) {
+static inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) {
+ (void)(mo);
+ return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub));
+}
+static inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {
+ (void)(mo);
return (uintptr_t)MI_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x);
}
-static inline uintptr_t mi_atomic_or(volatile _Atomic(uintptr_t)* p, uintptr_t x) {
+static inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {
+ (void)(mo);
return (uintptr_t)MI_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x);
}
-static inline bool mi_atomic_cas_strong(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) {
- return (expected == (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)expected));
+static inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {
+ (void)(mo1); (void)(mo2);
+ uintptr_t read = (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected));
+ if (read == *expected) {
+ return true;
+ }
+ else {
+ *expected = read;
+ return false;
+ }
}
-static inline bool mi_atomic_cas_weak(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) {
- return mi_atomic_cas_strong(p,desired,expected);
+static inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {
+ return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2);
}
-static inline uintptr_t mi_atomic_exchange(volatile _Atomic(uintptr_t)* p, uintptr_t exchange) {
+static inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) {
+ (void)(mo);
return (uintptr_t)MI_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange);
}
-static inline uintptr_t mi_atomic_read(volatile _Atomic(uintptr_t) const* p) {
- return *p;
+static inline void mi_atomic_thread_fence(mi_memory_order mo) {
+ (void)(mo);
+ _Atomic(uintptr_t) x = 0;
+ mi_atomic_exchange_explicit(&x, 1, mo);
}
-static inline uintptr_t mi_atomic_read_relaxed(volatile _Atomic(uintptr_t) const* p) {
+static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) {
+ (void)(mo);
+#if defined(_M_IX86) || defined(_M_X64)
return *p;
+#else
+ uintptr_t x = *p;
+ if (mo > mi_memory_order_relaxed) {
+ while (!mi_atomic_compare_exchange_weak_explicit(p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ };
+ }
+ return x;
+#endif
}
-static inline void mi_atomic_write(volatile _Atomic(uintptr_t)* p, uintptr_t x) {
- #if defined(_M_IX86) || defined(_M_X64)
+static inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {
+ (void)(mo);
+#if defined(_M_IX86) || defined(_M_X64)
*p = x;
- #else
- mi_atomic_exchange(p,x);
- #endif
+#else
+ mi_atomic_exchange_explicit(p, x, mo);
+#endif
}
-static inline void mi_atomic_yield(void) {
- YieldProcessor();
+static inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) {
+ (void)(mo);
+#if defined(_M_X64)
+ return *p;
+#else
+ int64_t old = *p;
+ int64_t x = old;
+ while ((old = InterlockedCompareExchange64(p, x, old)) != x) {
+ x = old;
+ }
+ return x;
+#endif
+}
+static inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) {
+ (void)(mo);
+#if defined(x_M_IX86) || defined(_M_X64)
+ *p = x;
+#else
+ InterlockedExchange64(p, x);
+#endif
}
-static inline void mi_atomic_addi64(volatile _Atomic(int64_t)* p, int64_t add) {
- #ifdef _WIN64
- mi_atomic_addi(p,add);
- #else
+
+// These are used by the statistics
+static inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) {
+#ifdef _WIN64
+ return (int64_t)mi_atomic_addi((int64_t*)p, add);
+#else
int64_t current;
int64_t sum;
do {
current = *p;
sum = current + add;
} while (_InterlockedCompareExchange64(p, sum, current) != current);
- #endif
+ return current;
+#endif
}
-
-static inline void mi_atomic_maxi64(volatile _Atomic(int64_t)*p, int64_t x) {
+static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) {
int64_t current;
do {
current = *p;
} while (current < x && _InterlockedCompareExchange64(p, x, current) != current);
}
-static inline int64_t mi_atomic_readi64(volatile _Atomic(int64_t)*p) {
- #ifdef _WIN64
- return *p;
- #else
- int64_t current;
- do {
- current = *p;
- } while (_InterlockedCompareExchange64(p, current, current) != current);
- return current;
- #endif
-}
+// The pointer macros cast to `uintptr_t`.
+#define mi_atomic_load_ptr_acquire(tp,p) (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p))
+#define mi_atomic_load_ptr_relaxed(tp,p) (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p))
+#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))
+#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))
+#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
+#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
+#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
+#define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x)
+#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x)
+
+#define mi_atomic_loadi64_acquire(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire))
+#define mi_atomic_loadi64_relaxed(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed))
+#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed))
+
-#else
-#ifdef __cplusplus
-#define MI_USING_STD using namespace std;
-#else
-#define MI_USING_STD
#endif
-static inline uintptr_t mi_atomic_add(volatile _Atomic(uintptr_t)* p, uintptr_t add) {
- MI_USING_STD
- return atomic_fetch_add_explicit(p, add, memory_order_relaxed);
-}
-static inline uintptr_t mi_atomic_and(volatile _Atomic(uintptr_t)* p, uintptr_t x) {
- MI_USING_STD
- return atomic_fetch_and_explicit(p, x, memory_order_acq_rel);
-}
-static inline uintptr_t mi_atomic_or(volatile _Atomic(uintptr_t)* p, uintptr_t x) {
- MI_USING_STD
- return atomic_fetch_or_explicit(p, x, memory_order_acq_rel);
+
+
+// Atomically add a signed value; returns the previous value.
+static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) {
+ return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add);
}
-static inline bool mi_atomic_cas_weak(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) {
- MI_USING_STD
- return atomic_compare_exchange_weak_explicit(p, &expected, desired, memory_order_acq_rel, memory_order_acquire);
+
+// Atomically subtract a signed value; returns the previous value.
+static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) {
+ return (intptr_t)mi_atomic_addi(p, -sub);
}
-static inline bool mi_atomic_cas_strong(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) {
- MI_USING_STD
- return atomic_compare_exchange_strong_explicit(p, &expected, desired, memory_order_acq_rel, memory_order_acquire);
+
+// Yield
+#if defined(__cplusplus)
+#include <thread>
+static inline void mi_atomic_yield(void) {
+ std::this_thread::yield();
}
-static inline uintptr_t mi_atomic_exchange(volatile _Atomic(uintptr_t)* p, uintptr_t exchange) {
- MI_USING_STD
- return atomic_exchange_explicit(p, exchange, memory_order_acq_rel);
+#elif defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+static inline void mi_atomic_yield(void) {
+ YieldProcessor();
}
-static inline uintptr_t mi_atomic_read_relaxed(const volatile _Atomic(uintptr_t)* p) {
- MI_USING_STD
- return atomic_load_explicit((volatile _Atomic(uintptr_t)*) p, memory_order_relaxed);
+#elif defined(__SSE2__)
+#include <emmintrin.h>
+static inline void mi_atomic_yield(void) {
+ _mm_pause();
}
-static inline uintptr_t mi_atomic_read(const volatile _Atomic(uintptr_t)* p) {
- MI_USING_STD
- return atomic_load_explicit((volatile _Atomic(uintptr_t)*) p, memory_order_acquire);
+#elif (defined(__GNUC__) || defined(__clang__)) && \
+ (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__armel__) || defined(__ARMEL__) || \
+ defined(__aarch64__) || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__))
+#if defined(__x86_64__) || defined(__i386__)
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile ("pause" ::: "memory");
}
-static inline void mi_atomic_write(volatile _Atomic(uintptr_t)* p, uintptr_t x) {
- MI_USING_STD
- return atomic_store_explicit(p, x, memory_order_release);
+#elif defined(__aarch64__)
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile("wfe");
}
-static inline void mi_atomic_addi64(volatile int64_t* p, int64_t add) {
- MI_USING_STD
- atomic_fetch_add_explicit((volatile _Atomic(int64_t)*)p, add, memory_order_relaxed);
+#elif (defined(__arm__) && __ARM_ARCH__ >= 7)
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile("yield" ::: "memory");
}
-static inline int64_t mi_atomic_readi64(volatile int64_t* p) {
- MI_USING_STD
- return atomic_load_explicit((volatile _Atomic(int64_t)*) p, memory_order_relaxed);
+#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
+static inline void mi_atomic_yield(void) {
+ __asm__ __volatile__ ("or 27,27,27" ::: "memory");
}
-static inline void mi_atomic_maxi64(volatile int64_t* p, int64_t x) {
- MI_USING_STD
- int64_t current;
- do {
- current = mi_atomic_readi64(p);
- } while (current < x && !atomic_compare_exchange_weak_explicit((volatile _Atomic(int64_t)*)p, ¤t, x, memory_order_acq_rel, memory_order_relaxed));
+#elif defined(__armel__) || defined(__ARMEL__)
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile ("nop" ::: "memory");
}
-
-#if defined(__cplusplus)
- #include <thread>
- static inline void mi_atomic_yield(void) {
- std::this_thread::yield();
- }
-#elif (defined(__GNUC__) || defined(__clang__)) && \
- (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))
-#if defined(__x86_64__) || defined(__i386__)
- static inline void mi_atomic_yield(void) {
- asm volatile ("pause" ::: "memory");
- }
-#elif defined(__arm__) || defined(__aarch64__)
- static inline void mi_atomic_yield(void) {
- asm volatile("yield");
- }
#endif
+#elif defined(__sun)
+// Fallback for other archs
+#include <synch.h>
+static inline void mi_atomic_yield(void) {
+ smt_pause();
+}
#elif defined(__wasi__)
- #include <sched.h>
- static inline void mi_atomic_yield(void) {
- sched_yield();
- }
+#include <sched.h>
+static inline void mi_atomic_yield(void) {
+ sched_yield();
+}
#else
- #include <unistd.h>
- static inline void mi_atomic_yield(void) {
- sleep(0);
- }
+#include <unistd.h>
+static inline void mi_atomic_yield(void) {
+ sleep(0);
+}
#endif
-#endif
#endif // __MIMALLOC_ATOMIC_H
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2022, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#define MI_CACHE_LINE 64
#if defined(_MSC_VER)
#pragma warning(disable:4127) // suppress constant conditional warning (due to MI_SECURE paths)
+#pragma warning(disable:26812) // unscoped enum warning
#define mi_decl_noinline __declspec(noinline)
#define mi_decl_thread __declspec(thread)
#define mi_decl_cache_align __declspec(align(MI_CACHE_LINE))
-#elif (defined(__GNUC__) && (__GNUC__>=3)) // includes clang and icc
+#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc
#define mi_decl_noinline __attribute__((noinline))
#define mi_decl_thread __thread
#define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE)))
#define mi_decl_cache_align
#endif
+#if defined(__EMSCRIPTEN__) && !defined(__wasi__)
+#define __wasi__
+#endif
+
+#if defined(__cplusplus)
+#define mi_decl_externc extern "C"
+#else
+#define mi_decl_externc
+#endif
+
+#if !defined(_WIN32) && !defined(__wasi__)
+#define MI_USE_PTHREADS
+#include <pthread.h>
+#endif
// "options.c"
void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);
void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);
uintptr_t _mi_random_next(mi_random_ctx_t* ctx);
uintptr_t _mi_heap_random_next(mi_heap_t* heap);
-uintptr_t _os_random_weak(uintptr_t extra_seed);
+uintptr_t _mi_os_random_weak(uintptr_t extra_seed);
static inline uintptr_t _mi_random_shuffle(uintptr_t x);
// init.c
-extern mi_stats_t _mi_stats_main;
-extern const mi_page_t _mi_page_empty;
+extern mi_decl_cache_align mi_stats_t _mi_stats_main;
+extern mi_decl_cache_align const mi_page_t _mi_page_empty;
bool _mi_is_main_thread(void);
-bool _mi_preloading(); // true while the C runtime is not ready
+size_t _mi_current_thread_count(void);
+bool _mi_preloading(void); // true while the C runtime is not ready
// os.c
size_t _mi_os_page_size(void);
void _mi_os_init(void); // called from process init
void* _mi_os_alloc(size_t size, mi_stats_t* stats); // to allocate thread local data
void _mi_os_free(void* p, size_t size, mi_stats_t* stats); // to free thread local data
-size_t _mi_os_good_alloc_size(size_t size);
-// memory.c
-void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* id, mi_os_tld_t* tld);
-void _mi_mem_free(void* p, size_t size, size_t id, bool fully_committed, bool any_reset, mi_os_tld_t* tld);
+bool _mi_os_protect(void* addr, size_t size);
+bool _mi_os_unprotect(void* addr, size_t size);
+bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* stats);
+bool _mi_os_decommit(void* p, size_t size, mi_stats_t* stats);
+bool _mi_os_reset(void* p, size_t size, mi_stats_t* stats);
+// bool _mi_os_unreset(void* p, size_t size, bool* is_zero, mi_stats_t* stats);
+size_t _mi_os_good_alloc_size(size_t size);
+bool _mi_os_has_overcommit(void);
-bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld);
-bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld);
-bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld);
-bool _mi_mem_protect(void* addr, size_t size);
-bool _mi_mem_unprotect(void* addr, size_t size);
+// arena.c
+void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
+void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
+void _mi_arena_free(void* p, size_t size, size_t memid, bool is_committed, mi_os_tld_t* tld);
-void _mi_mem_collect(mi_os_tld_t* tld);
+// "segment-cache.c"
+void* _mi_segment_cache_pop(size_t size, mi_commit_mask_t* commit_mask, mi_commit_mask_t* decommit_mask, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
+bool _mi_segment_cache_push(void* start, size_t size, size_t memid, const mi_commit_mask_t* commit_mask, const mi_commit_mask_t* decommit_mask, bool is_large, bool is_pinned, mi_os_tld_t* tld);
+void _mi_segment_cache_collect(bool force, mi_os_tld_t* tld);
+void _mi_segment_map_allocated_at(const mi_segment_t* segment);
+void _mi_segment_map_freed_at(const mi_segment_t* segment);
// "segment.c"
mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_wsize, mi_segments_tld_t* tld, mi_os_tld_t* os_tld);
void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld);
void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld);
-uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size, size_t* pre_size); // page start for any page
+bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld);
+void _mi_segment_thread_collect(mi_segments_tld_t* tld);
void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
-void _mi_segment_thread_collect(mi_segments_tld_t* tld);
+uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page
void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld);
void _mi_abandoned_await_readers(void);
+void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld);
// "page.c"
void* _mi_malloc_generic(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc;
-void _mi_page_retire(mi_page_t* page); // free the page if there are no other pages with many free blocks
+void _mi_page_retire(mi_page_t* page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks
void _mi_page_unfull(mi_page_t* page);
void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page
void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread...
size_t _mi_bin_size(uint8_t bin); // for stats
uint8_t _mi_bin(size_t size); // for stats
-uint8_t _mi_bsr(uintptr_t x); // bit-scan-right, used on BSD in "os.c"
// "heap.c"
void _mi_heap_destroy_pages(mi_heap_t* heap);
// "alloc.c"
void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept; // called from `_mi_malloc_generic`
-void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero);
-void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero);
+void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;
+void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept;
mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p);
bool _mi_free_delayed_block(mi_block_t* block);
void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size);
// ------------------------------------------------------
#if defined(__GNUC__) || defined(__clang__)
-#define mi_unlikely(x) __builtin_expect((x),0)
-#define mi_likely(x) __builtin_expect((x),1)
+#define mi_unlikely(x) __builtin_expect(!!(x),false)
+#define mi_likely(x) __builtin_expect(!!(x),true)
#else
#define mi_unlikely(x) (x)
#define mi_likely(x) (x)
/* -----------------------------------------------------------
Inlined definitions
----------------------------------------------------------- */
-#define UNUSED(x) (void)(x)
+#define MI_UNUSED(x) (void)(x)
#if (MI_DEBUG>0)
-#define UNUSED_RELEASE(x)
+#define MI_UNUSED_RELEASE(x)
#else
-#define UNUSED_RELEASE(x) UNUSED(x)
+#define MI_UNUSED_RELEASE(x) MI_UNUSED(x)
#endif
#define MI_INIT4(x) x(),x(),x(),x()
}
}
+// Align downwards
+static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
+ mi_assert_internal(alignment != 0);
+ uintptr_t mask = alignment - 1;
+ if ((alignment & mask) == 0) { // power of two?
+ return (sz & ~mask);
+ }
+ else {
+ return ((sz / alignment) * alignment);
+ }
+}
+
// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`.
static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) {
mi_assert_internal(divider != 0);
return true;
}
+
// Align a byte size to a size in _machine words_,
// i.e. byte size == `wsize*sizeof(void*)`.
static inline size_t _mi_wsize_from_size(size_t size) {
return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
}
-// Does malloc satisfy the alignment constraints already?
-static inline bool mi_malloc_satisfies_alignment(size_t alignment, size_t size) {
- return (alignment == sizeof(void*) || (alignment == MI_MAX_ALIGN_SIZE && size > (MI_MAX_ALIGN_SIZE/2)));
-}
-
// Overflow detecting multiply
-#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
+#if __has_builtin(__builtin_umul_overflow) || (defined(__GNUC__) && (__GNUC__ >= 5))
#include <limits.h> // UINT_MAX, ULONG_MAX
#if defined(_CLOCK_T) // for Illumos
#undef _CLOCK_T
#endif
static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {
- #if (SIZE_MAX == UINT_MAX)
- return __builtin_umul_overflow(count, size, total);
- #elif (SIZE_MAX == ULONG_MAX)
- return __builtin_umull_overflow(count, size, total);
+ #if (SIZE_MAX == ULONG_MAX)
+ return __builtin_umull_overflow(count, size, (unsigned long *)total);
+ #elif (SIZE_MAX == UINT_MAX)
+ return __builtin_umul_overflow(count, size, (unsigned int *)total);
#else
- return __builtin_umulll_overflow(count, size, total);
+ return __builtin_umulll_overflow(count, size, (unsigned long long *)total);
#endif
}
#else /* __builtin_umul_overflow is unavailable */
- macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the
loader itself calls `malloc` even before the modules are initialized.
- OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS).
-- DragonFly: not yet working.
+- DragonFly: defaults are working but seem slow compared to freeBSD (see PR #323)
------------------------------------------------------------------------------------------- */
extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap
mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap
#if defined(MI_MALLOC_OVERRIDE)
-#if defined(__MACH__) // OSX
+#if defined(__APPLE__) // macOS
#define MI_TLS_SLOT 89 // seems unused?
+// #define MI_TLS_RECURSE_GUARD 1
// other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89)
// see <https://github.com/rweichler/substrate/blob/master/include/pthread_machdep.h>
#elif defined(__OpenBSD__)
// use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16)
// see <https://github.com/openbsd/src/blob/master/lib/libc/include/thread_private.h#L371>
#define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24)
-#elif defined(__DragonFly__)
-#warning "mimalloc is not working correctly on DragonFly yet."
-#define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) <https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libthread_xu/thread/thr_private.h#L458>
+// #elif defined(__DragonFly__)
+// #warning "mimalloc is not working correctly on DragonFly yet."
+// #define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) <https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libthread_xu/thread/thr_private.h#L458>
+#elif defined(__ANDROID__)
+// See issue #381
+#define MI_TLS_PTHREAD
#endif
#endif
#if defined(MI_TLS_SLOT)
static inline void* mi_tls_slot(size_t slot) mi_attr_noexcept; // forward declaration
#elif defined(MI_TLS_PTHREAD_SLOT_OFS)
-#include <pthread.h>
static inline mi_heap_t** mi_tls_pthread_heap_slot(void) {
pthread_t self = pthread_self();
#if defined(__DragonFly__)
if (self==NULL) {
- static mi_heap_t* pheap_main = _mi_heap_main_get();
+ mi_heap_t* pheap_main = _mi_heap_main_get();
return &pheap_main;
}
#endif
return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS);
}
#elif defined(MI_TLS_PTHREAD)
-#include <pthread.h>
extern pthread_key_t _mi_heap_default_key;
-#else
-extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from
#endif
+// Default heap to allocate from (if not using TLS- or pthread slots).
+// Do not use this directly but use through `mi_heap_get_default()` (or the unchecked `mi_get_default_heap`).
+// This thread local variable is only used when neither MI_TLS_SLOT, MI_TLS_PTHREAD, or MI_TLS_PTHREAD_SLOT_OFS are defined.
+// However, on the Apple M1 we do use the address of this variable as the unique thread-id (issue #356).
+extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from
+
static inline mi_heap_t* mi_get_default_heap(void) {
#if defined(MI_TLS_SLOT)
mi_heap_t* heap = (mi_heap_t*)mi_tls_slot(MI_TLS_SLOT);
- return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap);
+ if (mi_unlikely(heap == NULL)) {
+ #ifdef __GNUC__
+ __asm(""); // prevent conditional load of the address of _mi_heap_empty
+ #endif
+ heap = (mi_heap_t*)&_mi_heap_empty;
+ }
+ return heap;
#elif defined(MI_TLS_PTHREAD_SLOT_OFS)
mi_heap_t* heap = *mi_tls_pthread_heap_slot();
return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap);
mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key));
return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap);
#else
- #if defined(MI_TLS_RECURSE_GUARD)
+ #if defined(MI_TLS_RECURSE_GUARD)
if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get();
#endif
return _mi_heap_default;
return (mi_segment_t*)((uintptr_t)p & ~MI_SEGMENT_MASK);
}
+static inline mi_page_t* mi_slice_to_page(mi_slice_t* s) {
+ mi_assert_internal(s->slice_offset== 0 && s->slice_count > 0);
+ return (mi_page_t*)(s);
+}
+
+static inline mi_slice_t* mi_page_to_slice(mi_page_t* p) {
+ mi_assert_internal(p->slice_offset== 0 && p->slice_count > 0);
+ return (mi_slice_t*)(p);
+}
+
// Segment belonging to a page
static inline mi_segment_t* _mi_page_segment(const mi_page_t* page) {
- mi_segment_t* segment = _mi_ptr_segment(page);
- mi_assert_internal(segment == NULL || page == &segment->pages[page->segment_idx]);
+ mi_segment_t* segment = _mi_ptr_segment(page);
+ mi_assert_internal(segment == NULL || ((mi_slice_t*)page >= segment->slices && (mi_slice_t*)page < segment->slices + segment->slice_entries));
return segment;
}
-// used internally
-static inline uintptr_t _mi_segment_page_idx_of(const mi_segment_t* segment, const void* p) {
- // if (segment->page_size > MI_SEGMENT_SIZE) return &segment->pages[0]; // huge pages
- ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment;
- mi_assert_internal(diff >= 0 && (size_t)diff < MI_SEGMENT_SIZE);
- uintptr_t idx = (uintptr_t)diff >> segment->page_shift;
- mi_assert_internal(idx < segment->capacity);
- mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM || idx == 0);
- return idx;
+static inline mi_slice_t* mi_slice_first(const mi_slice_t* slice) {
+ mi_slice_t* start = (mi_slice_t*)((uint8_t*)slice - slice->slice_offset);
+ mi_assert_internal(start >= _mi_ptr_segment(slice)->slices);
+ mi_assert_internal(start->slice_offset == 0);
+ mi_assert_internal(start + start->slice_count > slice);
+ return start;
}
// Get the page containing the pointer
static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) {
- uintptr_t idx = _mi_segment_page_idx_of(segment, p);
- return &((mi_segment_t*)segment)->pages[idx];
+ ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment;
+ mi_assert_internal(diff >= 0 && diff < (ptrdiff_t)MI_SEGMENT_SIZE);
+ size_t idx = (size_t)diff >> MI_SEGMENT_SLICE_SHIFT;
+ mi_assert_internal(idx < segment->slice_entries);
+ mi_slice_t* slice0 = (mi_slice_t*)&segment->slices[idx];
+ mi_slice_t* slice = mi_slice_first(slice0); // adjust to the block that holds the page data
+ mi_assert_internal(slice->slice_offset == 0);
+ mi_assert_internal(slice >= segment->slices && slice < segment->slices + segment->slice_entries);
+ return mi_slice_to_page(slice);
}
// Quick page start for initialized pages
static inline uint8_t* _mi_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) {
- const size_t bsize = page->xblock_size;
- mi_assert_internal(bsize > 0 && (bsize%sizeof(void*)) == 0);
- return _mi_segment_page_start(segment, page, bsize, page_size, NULL);
+ return _mi_segment_page_start(segment, page, page_size);
}
// Get the page containing the pointer
return _mi_segment_page_of(_mi_ptr_segment(p), p);
}
-// Get the block size of a page (special cased for huge objects)
+// Get the block size of a page (special case for huge objects)
static inline size_t mi_page_block_size(const mi_page_t* page) {
const size_t bsize = page->xblock_size;
mi_assert_internal(bsize > 0);
}
else {
size_t psize;
- _mi_segment_page_start(_mi_page_segment(page), page, bsize, &psize, NULL);
+ _mi_segment_page_start(_mi_page_segment(page), page, &psize);
return psize;
}
}
return mi_page_block_size(page) - MI_PADDING_SIZE;
}
+// size of a segment
+static inline size_t mi_segment_size(mi_segment_t* segment) {
+ return segment->segment_slices * MI_SEGMENT_SLICE_SIZE;
+}
+
+static inline uint8_t* mi_segment_end(mi_segment_t* segment) {
+ return (uint8_t*)segment + mi_segment_size(segment);
+}
// Thread free access
static inline mi_block_t* mi_page_thread_free(const mi_page_t* page) {
- return (mi_block_t*)(mi_atomic_read_relaxed(&page->xthread_free) & ~3);
+ return (mi_block_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & ~3);
}
static inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) {
- return (mi_delayed_t)(mi_atomic_read_relaxed(&page->xthread_free) & 3);
+ return (mi_delayed_t)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & 3);
}
// Heap access
static inline mi_heap_t* mi_page_heap(const mi_page_t* page) {
- return (mi_heap_t*)(mi_atomic_read_relaxed(&page->xheap));
+ return (mi_heap_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xheap));
}
static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) {
mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING);
- mi_atomic_write(&page->xheap,(uintptr_t)heap);
+ mi_atomic_store_release(&page->xheap,(uintptr_t)heap);
}
// Thread free flag helpers
}
static inline bool mi_is_in_same_page(const void* p, const void* q) {
- mi_segment_t* segmentp = _mi_ptr_segment(p);
- mi_segment_t* segmentq = _mi_ptr_segment(q);
- if (segmentp != segmentq) return false;
- uintptr_t idxp = _mi_segment_page_idx_of(segmentp, p);
- uintptr_t idxq = _mi_segment_page_idx_of(segmentq, q);
- return (idxp == idxq);
+ mi_segment_t* segment = _mi_ptr_segment(p);
+ if (_mi_ptr_segment(q) != segment) return false;
+ // assume q may be invalid // return (_mi_segment_page_of(segment, p) == _mi_segment_page_of(segment, q));
+ mi_page_t* page = _mi_segment_page_of(segment, p);
+ size_t psize;
+ uint8_t* start = _mi_segment_page_start(segment, page, &psize);
+ return (start <= (uint8_t*)q && (uint8_t*)q < start + psize);
}
static inline uintptr_t mi_rotl(uintptr_t x, uintptr_t shift) {
#ifdef MI_ENCODE_FREELIST
return (mi_block_t*)mi_ptr_decode(null, block->next, keys);
#else
- UNUSED(keys); UNUSED(null);
+ MI_UNUSED(keys); MI_UNUSED(null);
return (mi_block_t*)block->next;
#endif
}
#ifdef MI_ENCODE_FREELIST
block->next = mi_ptr_encode(null, next, keys);
#else
- UNUSED(keys); UNUSED(null);
+ MI_UNUSED(keys); MI_UNUSED(null);
block->next = (mi_encoded_t)next;
#endif
}
}
return next;
#else
- UNUSED(page);
+ MI_UNUSED(page);
return mi_block_nextx(page,block,NULL);
#endif
}
#ifdef MI_ENCODE_FREELIST
mi_block_set_nextx(page,block,next, page->keys);
#else
- UNUSED(page);
+ MI_UNUSED(page);
mi_block_set_nextx(page,block,next,NULL);
#endif
}
+
+// -------------------------------------------------------------------
+// commit mask
+// -------------------------------------------------------------------
+
+static inline void mi_commit_mask_create_empty(mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ cm->mask[i] = 0;
+ }
+}
+
+static inline void mi_commit_mask_create_full(mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ cm->mask[i] = ~((size_t)0);
+ }
+}
+
+static inline bool mi_commit_mask_is_empty(const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ if (cm->mask[i] != 0) return false;
+ }
+ return true;
+}
+
+static inline bool mi_commit_mask_is_full(const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ if (cm->mask[i] != ~((size_t)0)) return false;
+ }
+ return true;
+}
+
+// defined in `segment.c`:
+size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total);
+size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx);
+
+#define mi_commit_mask_foreach(cm,idx,count) \
+ idx = 0; \
+ while ((count = _mi_commit_mask_next_run(cm,&idx)) > 0) {
+
+#define mi_commit_mask_foreach_end() \
+ idx += count; \
+ }
+
+
+
+
// -------------------------------------------------------------------
// Fast "random" shuffle
// -------------------------------------------------------------------
int _mi_os_numa_node_get(mi_os_tld_t* tld);
size_t _mi_os_numa_node_count_get(void);
-extern size_t _mi_numa_node_count;
+extern _Atomic(size_t) _mi_numa_node_count;
static inline int _mi_os_numa_node(mi_os_tld_t* tld) {
- if (mi_likely(_mi_numa_node_count == 1)) return 0;
+ if (mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1)) return 0;
else return _mi_os_numa_node_get(tld);
}
static inline size_t _mi_os_numa_node_count(void) {
- if (mi_likely(_mi_numa_node_count>0)) return _mi_numa_node_count;
+ const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count);
+ if (mi_likely(count>0)) return count;
else return _mi_os_numa_node_count_get();
}
// -------------------------------------------------------------------
// Getting the thread id should be performant as it is called in the
// fast path of `_mi_free` and we specialize for various platforms.
+// We only require _mi_threadid() to return a unique id for each thread.
// -------------------------------------------------------------------
#if defined(_WIN32)
+
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept {
+static inline mi_threadid_t _mi_thread_id(void) mi_attr_noexcept {
// Windows: works on Intel and ARM in both 32- and 64-bit
return (uintptr_t)NtCurrentTeb();
}
-#elif defined(__GNUC__) && \
- (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))
+// We use assembly for a fast thread id on the main platforms. The TLS layout depends on
+// both the OS and libc implementation so we use specific tests for each main platform.
+// If you test on another platform and it works please send a PR :-)
+// see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register.
+#elif defined(__GNUC__) && ( \
+ (defined(__GLIBC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \
+ || (defined(__APPLE__) && (defined(__x86_64__) || defined(__aarch64__))) \
+ || (defined(__BIONIC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \
+ || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \
+ || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \
+ )
-// TLS register on x86 is in the FS or GS register, see: https://akkadia.org/drepper/tls.pdf
static inline void* mi_tls_slot(size_t slot) mi_attr_noexcept {
void* res;
const size_t ofs = (slot*sizeof(void*));
-#if defined(__i386__)
- __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // 32-bit always uses GS
-#elif defined(__MACH__) && defined(__x86_64__)
- __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS
-#elif defined(__x86_64__)
- __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS
-#elif defined(__arm__)
- void** tcb; UNUSED(ofs);
- asm volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
- res = tcb[slot];
-#elif defined(__aarch64__)
- void** tcb; UNUSED(ofs);
- asm volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
- res = tcb[slot];
-#endif
+ #if defined(__i386__)
+ __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86 32-bit always uses GS
+ #elif defined(__APPLE__) && defined(__x86_64__)
+ __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS
+ #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)
+ __asm__("movl %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x32 ABI
+ #elif defined(__x86_64__)
+ __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS
+ #elif defined(__arm__)
+ void** tcb; MI_UNUSED(ofs);
+ __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
+ res = tcb[slot];
+ #elif defined(__aarch64__)
+ void** tcb; MI_UNUSED(ofs);
+ #if defined(__APPLE__) // M1, issue #343
+ __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb));
+ #else
+ __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
+ #endif
+ res = tcb[slot];
+ #endif
return res;
}
-// setting is only used on macOSX for now
+// setting a tls slot is only used on macOS for now
static inline void mi_tls_slot_set(size_t slot, void* value) mi_attr_noexcept {
const size_t ofs = (slot*sizeof(void*));
-#if defined(__i386__)
- __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS
-#elif defined(__MACH__) && defined(__x86_64__)
- __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOSX uses GS
-#elif defined(__x86_64__)
- __asm__("movq %1,%%fs:%1" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS
-#elif defined(__arm__)
- void** tcb; UNUSED(ofs);
- asm volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
- tcb[slot] = value;
-#elif defined(__aarch64__)
- void** tcb; UNUSED(ofs);
- asm volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
- tcb[slot] = value;
-#endif
+ #if defined(__i386__)
+ __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS
+ #elif defined(__APPLE__) && defined(__x86_64__)
+ __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOS uses GS
+ #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)
+ __asm__("movl %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x32 ABI
+ #elif defined(__x86_64__)
+ __asm__("movq %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS
+ #elif defined(__arm__)
+ void** tcb; MI_UNUSED(ofs);
+ __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
+ tcb[slot] = value;
+ #elif defined(__aarch64__)
+ void** tcb; MI_UNUSED(ofs);
+ #if defined(__APPLE__) // M1, issue #343
+ __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb));
+ #else
+ __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
+ #endif
+ tcb[slot] = value;
+ #endif
}
-static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept {
- // in all our targets, slot 0 is the pointer to the thread control block
- return (uintptr_t)mi_tls_slot(0);
+static inline mi_threadid_t _mi_thread_id(void) mi_attr_noexcept {
+ #if defined(__BIONIC__)
+ // issue #384, #495: on the Bionic libc (Android), slot 1 is the thread id
+ // see: https://github.com/aosp-mirror/platform_bionic/blob/c44b1d0676ded732df4b3b21c5f798eacae93228/libc/platform/bionic/tls_defines.h#L86
+ return (uintptr_t)mi_tls_slot(1);
+ #else
+ // in all our other targets, slot 0 is the thread id
+ // glibc: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysdeps/x86_64/nptl/tls.h
+ // apple: https://github.com/apple/darwin-xnu/blob/main/libsyscall/os/tsd.h#L36
+ return (uintptr_t)mi_tls_slot(0);
+ #endif
}
+
#else
-// otherwise use standard C
-static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept {
+
+// otherwise use portable C, taking the address of a thread local variable (this is still very fast on most platforms).
+static inline mi_threadid_t _mi_thread_id(void) mi_attr_noexcept {
return (uintptr_t)&_mi_heap_default;
}
+
+#endif
+
+
+// -----------------------------------------------------------------------
+// Count bits: trailing or leading zeros (with MI_INTPTR_BITS on all zero)
+// -----------------------------------------------------------------------
+
+#if defined(__GNUC__)
+
+#include <limits.h> // LONG_MAX
+#define MI_HAVE_FAST_BITSCAN
+static inline size_t mi_clz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (INTPTR_MAX == LONG_MAX)
+ return __builtin_clzl(x);
+#else
+ return __builtin_clzll(x);
+#endif
+}
+static inline size_t mi_ctz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (INTPTR_MAX == LONG_MAX)
+ return __builtin_ctzl(x);
+#else
+ return __builtin_ctzll(x);
+#endif
+}
+
+#elif defined(_MSC_VER)
+
+#include <limits.h> // LONG_MAX
+#define MI_HAVE_FAST_BITSCAN
+static inline size_t mi_clz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+ unsigned long idx;
+#if (INTPTR_MAX == LONG_MAX)
+ _BitScanReverse(&idx, x);
+#else
+ _BitScanReverse64(&idx, x);
+#endif
+ return ((MI_INTPTR_BITS - 1) - idx);
+}
+static inline size_t mi_ctz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+ unsigned long idx;
+#if (INTPTR_MAX == LONG_MAX)
+ _BitScanForward(&idx, x);
+#else
+ _BitScanForward64(&idx, x);
+#endif
+ return idx;
+}
+
+#else
+static inline size_t mi_ctz32(uint32_t x) {
+ // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
+ static const unsigned char debruijn[32] = {
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
+ };
+ if (x==0) return 32;
+ return debruijn[((x & -(int32_t)x) * 0x077CB531UL) >> 27];
+}
+static inline size_t mi_clz32(uint32_t x) {
+ // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
+ static const uint8_t debruijn[32] = {
+ 31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
+ 23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0
+ };
+ if (x==0) return 32;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return debruijn[(uint32_t)(x * 0x07C4ACDDUL) >> 27];
+}
+
+static inline size_t mi_clz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (MI_INTPTR_BITS <= 32)
+ return mi_clz32((uint32_t)x);
+#else
+ size_t count = mi_clz32((uint32_t)(x >> 32));
+ if (count < 32) return count;
+ return (32 + mi_clz32((uint32_t)x));
+#endif
+}
+static inline size_t mi_ctz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (MI_INTPTR_BITS <= 32)
+ return mi_ctz32((uint32_t)x);
+#else
+ size_t count = mi_ctz32((uint32_t)x);
+ if (count < 32) return count;
+ return (32 + mi_ctz32((uint32_t)(x>>32)));
+#endif
+}
+
+#endif
+
+// "bit scan reverse": Return index of the highest bit (or MI_INTPTR_BITS if `x` is zero)
+static inline size_t mi_bsr(uintptr_t x) {
+ return (x==0 ? MI_INTPTR_BITS : MI_INTPTR_BITS - 1 - mi_clz(x));
+}
+
+
+// ---------------------------------------------------------------------------------
+// Provide our own `_mi_memcpy` for potential performance optimizations.
+//
+// For now, only on Windows with msvc/clang-cl we optimize to `rep movsb` if
+// we happen to run on x86/x64 cpu's that have "fast short rep movsb" (FSRM) support
+// (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017). See also issue #201 and pr #253.
+// ---------------------------------------------------------------------------------
+
+#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
+#include <intrin.h>
+#include <string.h>
+extern bool _mi_cpu_has_fsrm;
+static inline void _mi_memcpy(void* dst, const void* src, size_t n) {
+ if (_mi_cpu_has_fsrm) {
+ __movsb((unsigned char*)dst, (const unsigned char*)src, n);
+ }
+ else {
+ memcpy(dst, src, n); // todo: use noinline?
+ }
+}
+#else
+#include <string.h>
+static inline void _mi_memcpy(void* dst, const void* src, size_t n) {
+ memcpy(dst, src, n);
+}
+#endif
+
+
+// -------------------------------------------------------------------------------
+// The `_mi_memcpy_aligned` can be used if the pointers are machine-word aligned
+// This is used for example in `mi_realloc`.
+// -------------------------------------------------------------------------------
+
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+// On GCC/CLang we provide a hint that the pointers are word aligned.
+#include <string.h>
+static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {
+ mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));
+ void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);
+ const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE);
+ _mi_memcpy(adst, asrc, n);
+}
+#else
+// Default fallback on `_mi_memcpy`
+static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {
+ mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));
+ _mi_memcpy(dst, src, n);
+}
#endif
/* ----------------------------------------------------------------------------
-Copyright (c) 2018,2019 Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
void operator delete(void* p) noexcept { mi_free(p); };
void operator delete[](void* p) noexcept { mi_free(p); };
+ void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); }
+ void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }
+
void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }
void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }
void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
-
- void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
- void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
+ void operator delete (void* p, std::align_val_t al, const std::nothrow_t& tag) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
+ void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& tag) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
+
+ void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
+ void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
#endif
/* ----------------------------------------------------------------------------
-Copyright (c) 2018,2019 Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#define free(p) mi_free(p)
#define strdup(s) mi_strdup(s)
-#define strndup(s) mi_strndup(s)
+#define strndup(s,n) mi_strndup(s,n)
#define realpath(f,n) mi_realpath(f,n)
// Microsoft extensions
#define _recalloc(p,n,c) mi_recalloc(p,n,c)
#define _strdup(s) mi_strdup(s)
-#define _strndup(s) mi_strndup(s)
+#define _strndup(s,n) mi_strndup(s,n)
#define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s))
#define _mbsdup(s) mi_mbsdup(s)
#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v)
#define valloc(n) mi_valloc(n)
#define pvalloc(n) mi_pvalloc(n)
#define reallocarray(p,s,n) mi_reallocarray(p,s,n)
+#define reallocarr(p,s,n) mi_reallocarr(p,s,n)
#define memalign(a,n) mi_memalign(a,n)
#define aligned_alloc(a,n) mi_aligned_alloc(a,n)
#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n)
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include <stddef.h> // ptrdiff_t
#include <stdint.h> // uintptr_t, uint16_t, etc
-#include <mimalloc-atomic.h> // _Atomic
+#include "mimalloc-atomic.h" // _Atomic
+
+#ifdef _MSC_VER
+#pragma warning(disable:4214) // bitfield is not int
+#endif
// Minimal alignment necessary. On most platforms 16 bytes are needed
-// due to SSE registers for example. This must be at least `MI_INTPTR_SIZE`
+// due to SSE registers for example. This must be at least `sizeof(void*)`
+#ifndef MI_MAX_ALIGN_SIZE
#define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t)
+#endif
// ------------------------------------------------------
// Variants
#define MI_ENCODE_FREELIST 1
#endif
+
// ------------------------------------------------------
// Platform specific values
// ------------------------------------------------------
// or otherwise one might define an intptr_t type that is larger than a pointer...
// ------------------------------------------------------
-#if INTPTR_MAX == 9223372036854775807LL
+#if INTPTR_MAX > INT64_MAX
+# define MI_INTPTR_SHIFT (4) // assume 128-bit (as on arm CHERI for example)
+#elif INTPTR_MAX == INT64_MAX
# define MI_INTPTR_SHIFT (3)
-#elif INTPTR_MAX == 2147483647LL
+#elif INTPTR_MAX == INT32_MAX
# define MI_INTPTR_SHIFT (2)
#else
-#error platform must be 32 or 64 bits
+#error platform pointers must be 32, 64, or 128 bits
+#endif
+
+#if SIZE_MAX == UINT64_MAX
+# define MI_SIZE_SHIFT (3)
+typedef int64_t mi_ssize_t;
+#elif SIZE_MAX == UINT32_MAX
+# define MI_SIZE_SHIFT (2)
+typedef int32_t mi_ssize_t;
+#else
+#error platform objects must be 32 or 64 bits
+#endif
+
+#if (SIZE_MAX/2) > LONG_MAX
+# define MI_ZU(x) x##ULL
+# define MI_ZI(x) x##LL
+#else
+# define MI_ZU(x) x##UL
+# define MI_ZI(x) x##L
#endif
#define MI_INTPTR_SIZE (1<<MI_INTPTR_SHIFT)
#define MI_INTPTR_BITS (MI_INTPTR_SIZE*8)
-#define KiB ((size_t)1024)
-#define MiB (KiB*KiB)
-#define GiB (MiB*KiB)
+#define MI_SIZE_SIZE (1<<MI_SIZE_SHIFT)
+#define MI_SIZE_BITS (MI_SIZE_SIZE*8)
+
+#define MI_KiB (MI_ZU(1024))
+#define MI_MiB (MI_KiB*MI_KiB)
+#define MI_GiB (MI_MiB*MI_KiB)
// ------------------------------------------------------
// ------------------------------------------------------
// Main tuning parameters for segment and page sizes
-// Sizes for 64-bit, divide by two for 32-bit
-#define MI_SMALL_PAGE_SHIFT (13 + MI_INTPTR_SHIFT) // 64kb
-#define MI_MEDIUM_PAGE_SHIFT ( 3 + MI_SMALL_PAGE_SHIFT) // 512kb
-#define MI_LARGE_PAGE_SHIFT ( 3 + MI_MEDIUM_PAGE_SHIFT) // 4mb
-#define MI_SEGMENT_SHIFT ( MI_LARGE_PAGE_SHIFT) // 4mb
+// Sizes for 64-bit (usually divide by two for 32-bit)
+#define MI_SEGMENT_SLICE_SHIFT (13 + MI_INTPTR_SHIFT) // 64KiB (32KiB on 32-bit)
+
+#if MI_INTPTR_SIZE > 4
+#define MI_SEGMENT_SHIFT (10 + MI_SEGMENT_SLICE_SHIFT) // 64MiB
+#else
+#define MI_SEGMENT_SHIFT ( 7 + MI_SEGMENT_SLICE_SHIFT) // 4MiB on 32-bit
+#endif
+
+#define MI_SMALL_PAGE_SHIFT (MI_SEGMENT_SLICE_SHIFT) // 64KiB
+#define MI_MEDIUM_PAGE_SHIFT ( 3 + MI_SMALL_PAGE_SHIFT) // 512KiB
+
// Derived constants
-#define MI_SEGMENT_SIZE (1UL<<MI_SEGMENT_SHIFT)
-#define MI_SEGMENT_MASK ((uintptr_t)MI_SEGMENT_SIZE - 1)
-
-#define MI_SMALL_PAGE_SIZE (1UL<<MI_SMALL_PAGE_SHIFT)
-#define MI_MEDIUM_PAGE_SIZE (1UL<<MI_MEDIUM_PAGE_SHIFT)
-#define MI_LARGE_PAGE_SIZE (1UL<<MI_LARGE_PAGE_SHIFT)
-
-#define MI_SMALL_PAGES_PER_SEGMENT (MI_SEGMENT_SIZE/MI_SMALL_PAGE_SIZE)
-#define MI_MEDIUM_PAGES_PER_SEGMENT (MI_SEGMENT_SIZE/MI_MEDIUM_PAGE_SIZE)
-#define MI_LARGE_PAGES_PER_SEGMENT (MI_SEGMENT_SIZE/MI_LARGE_PAGE_SIZE)
-
-// The max object size are checked to not waste more than 12.5% internally over the page sizes.
-// (Except for large pages since huge objects are allocated in 4MiB chunks)
-#define MI_SMALL_OBJ_SIZE_MAX (MI_SMALL_PAGE_SIZE/4) // 16kb
-#define MI_MEDIUM_OBJ_SIZE_MAX (MI_MEDIUM_PAGE_SIZE/4) // 128kb
-#define MI_LARGE_OBJ_SIZE_MAX (MI_LARGE_PAGE_SIZE/2) // 2mb
+#define MI_SEGMENT_SIZE (MI_ZU(1)<<MI_SEGMENT_SHIFT)
+#define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE
+#define MI_SEGMENT_MASK (MI_SEGMENT_SIZE - 1)
+#define MI_SEGMENT_SLICE_SIZE (MI_ZU(1)<< MI_SEGMENT_SLICE_SHIFT)
+#define MI_SLICES_PER_SEGMENT (MI_SEGMENT_SIZE / MI_SEGMENT_SLICE_SIZE) // 1024
+
+#define MI_SMALL_PAGE_SIZE (MI_ZU(1)<<MI_SMALL_PAGE_SHIFT)
+#define MI_MEDIUM_PAGE_SIZE (MI_ZU(1)<<MI_MEDIUM_PAGE_SHIFT)
+
+#define MI_SMALL_OBJ_SIZE_MAX (MI_SMALL_PAGE_SIZE/4) // 8KiB on 64-bit
+#define MI_MEDIUM_OBJ_SIZE_MAX (MI_MEDIUM_PAGE_SIZE/4) // 128KiB on 64-bit
+#define MI_MEDIUM_OBJ_WSIZE_MAX (MI_MEDIUM_OBJ_SIZE_MAX/MI_INTPTR_SIZE)
+#define MI_LARGE_OBJ_SIZE_MAX (MI_SEGMENT_SIZE/2) // 32MiB on 64-bit
#define MI_LARGE_OBJ_WSIZE_MAX (MI_LARGE_OBJ_SIZE_MAX/MI_INTPTR_SIZE)
-#define MI_HUGE_OBJ_SIZE_MAX (2*MI_INTPTR_SIZE*MI_SEGMENT_SIZE) // (must match MI_REGION_MAX_ALLOC_SIZE in memory.c)
// Maximum number of size classes. (spaced exponentially in 12.5% increments)
#define MI_BIN_HUGE (73U)
-#if (MI_LARGE_OBJ_WSIZE_MAX >= 655360)
-#error "define more bins"
+#if (MI_MEDIUM_OBJ_WSIZE_MAX >= 655360)
+#error "mimalloc internal: define more bins"
+#endif
+#if (MI_ALIGNMENT_MAX > MI_SEGMENT_SIZE/2)
+#error "mimalloc internal: the max aligned boundary is too large for the segment size"
#endif
+#if (MI_ALIGNED_MAX % MI_SEGMENT_SLICE_SIZE != 0)
+#error "mimalloc internal: the max aligned boundary must be an integral multiple of the segment slice size"
+#endif
+
+// Maximum slice offset (15)
+#define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1)
// Used as a special value to encode block sizes in 32 bits.
-#define MI_HUGE_BLOCK_SIZE ((uint32_t)MI_HUGE_OBJ_SIZE_MAX)
+#define MI_HUGE_BLOCK_SIZE ((uint32_t)(2*MI_GiB))
+
+// blocks up to this size are always allocated aligned
+#define MI_MAX_ALIGN_GUARANTEE (8*MI_MAX_ALIGN_SIZE)
+
+
+
+
+// ------------------------------------------------------
+// Mimalloc pages contain allocated blocks
+// ------------------------------------------------------
// The free lists use encoded next fields
// (Only actually encodes when MI_ENCODED_FREELIST is defined.)
-typedef uintptr_t mi_encoded_t;
+typedef uintptr_t mi_encoded_t;
+
+// thread id's
+typedef size_t mi_threadid_t;
// free lists contain blocks
typedef struct mi_block_s {
// The `in_full` and `has_aligned` page flags are put in a union to efficiently
// test if both are false (`full_aligned == 0`) in the `mi_free` routine.
+#if !MI_TSAN
typedef union mi_page_flags_s {
uint8_t full_aligned;
struct {
uint8_t has_aligned : 1;
} x;
} mi_page_flags_t;
+#else
+// under thread sanitizer, use a byte for each flag to suppress warning, issue #130
+typedef union mi_page_flags_s {
+ uint16_t full_aligned;
+ struct {
+ uint8_t in_full;
+ uint8_t has_aligned;
+ } x;
+} mi_page_flags_t;
+#endif
// Thread free list.
// We use the bottom 2 bits of the pointer for mi_delayed_t flags
// will be freed correctly even if only other threads free blocks.
typedef struct mi_page_s {
// "owned" by the segment
- uint8_t segment_idx; // index in the segment `pages` array, `page == &segment->pages[page->segment_idx]`
- uint8_t segment_in_use:1; // `true` if the segment allocated this page
- uint8_t is_reset:1; // `true` if the page memory was reset
- uint8_t is_committed:1; // `true` if the page virtual memory is committed
- uint8_t is_zero_init:1; // `true` if the page was zero initialized
+ uint32_t slice_count; // slices in this page (0 if not a page)
+ uint32_t slice_offset; // distance from the actual page data slice (0 if a page)
+ uint8_t is_reset : 1; // `true` if the page memory was reset
+ uint8_t is_committed : 1; // `true` if the page virtual memory is committed
+ uint8_t is_zero_init : 1; // `true` if the page was zero initialized
// layout like this to optimize access in `mi_malloc` and `mi_free`
uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear`
uint16_t reserved; // number of blocks reserved in memory
mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits)
- uint8_t is_zero:1; // `true` if the blocks in the free list are zero initialized
- uint8_t retire_expire:7; // expiration count for retired blocks
+ uint8_t is_zero : 1; // `true` if the blocks in the free list are zero initialized
+ uint8_t retire_expire : 7; // expiration count for retired blocks
mi_block_t* free; // list of available free blocks (`malloc` allocates from this list)
#ifdef MI_ENCODE_FREELIST
uint32_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`)
uint32_t xblock_size; // size available in each block (always `>0`)
- mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`)
- volatile _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads
- volatile _Atomic(uintptr_t) xheap;
-
- struct mi_page_s* next; // next page owned by this thread with the same `block_size`
- struct mi_page_s* prev; // previous page owned by this thread with the same `block_size`
+ mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`)
+ _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads
+ _Atomic(uintptr_t) xheap;
+
+ struct mi_page_s* next; // next page owned by this thread with the same `block_size`
+ struct mi_page_s* prev; // previous page owned by this thread with the same `block_size`
+
+ // 64-bit 9 words, 32-bit 12 words, (+2 for secure)
+ #if MI_INTPTR_SIZE==8
+ uintptr_t padding[1];
+ #endif
} mi_page_t;
typedef enum mi_page_kind_e {
- MI_PAGE_SMALL, // small blocks go into 64kb pages inside a segment
- MI_PAGE_MEDIUM, // medium blocks go into 512kb pages inside a segment
- MI_PAGE_LARGE, // larger blocks go into a single page spanning a whole segment
- MI_PAGE_HUGE // huge blocks (>512kb) are put into a single page in a segment of the exact size (but still 2mb aligned)
+ MI_PAGE_SMALL, // small blocks go into 64KiB pages inside a segment
+ MI_PAGE_MEDIUM, // medium blocks go into medium pages inside a segment
+ MI_PAGE_LARGE, // larger blocks go into a page of just one block
+ MI_PAGE_HUGE, // huge blocks (> 16 MiB) are put into a single page in a single segment.
} mi_page_kind_t;
-// Segments are large allocated memory blocks (2mb on 64 bit) from
+typedef enum mi_segment_kind_e {
+ MI_SEGMENT_NORMAL, // MI_SEGMENT_SIZE size with pages inside.
+ MI_SEGMENT_HUGE, // > MI_LARGE_SIZE_MAX segment with just one huge page inside.
+} mi_segment_kind_t;
+
+// ------------------------------------------------------
+// A segment holds a commit mask where a bit is set if
+// the corresponding MI_COMMIT_SIZE area is committed.
+// The MI_COMMIT_SIZE must be a multiple of the slice
+// size. If it is equal we have the most fine grained
+// decommit (but setting it higher can be more efficient).
+// The MI_MINIMAL_COMMIT_SIZE is the minimal amount that will
+// be committed in one go which can be set higher than
+// MI_COMMIT_SIZE for efficiency (while the decommit mask
+// is still tracked in fine-grained MI_COMMIT_SIZE chunks)
+// ------------------------------------------------------
+
+#define MI_MINIMAL_COMMIT_SIZE (2*MI_MiB)
+#define MI_COMMIT_SIZE (MI_SEGMENT_SLICE_SIZE) // 64KiB
+#define MI_COMMIT_MASK_BITS (MI_SEGMENT_SIZE / MI_COMMIT_SIZE)
+#define MI_COMMIT_MASK_FIELD_BITS MI_SIZE_BITS
+#define MI_COMMIT_MASK_FIELD_COUNT (MI_COMMIT_MASK_BITS / MI_COMMIT_MASK_FIELD_BITS)
+
+#if (MI_COMMIT_MASK_BITS != (MI_COMMIT_MASK_FIELD_COUNT * MI_COMMIT_MASK_FIELD_BITS))
+#error "the segment size must be exactly divisible by the (commit size * size_t bits)"
+#endif
+
+typedef struct mi_commit_mask_s {
+ size_t mask[MI_COMMIT_MASK_FIELD_COUNT];
+} mi_commit_mask_t;
+
+typedef mi_page_t mi_slice_t;
+typedef int64_t mi_msecs_t;
+
+
+// Segments are large allocated memory blocks (8mb on 64 bit) from
// the OS. Inside segments we allocated fixed size _pages_ that
// contain blocks.
typedef struct mi_segment_s {
- // memory fields
- size_t memid; // id for the os-level memory manager
- bool mem_is_fixed; // `true` if we cannot decommit/reset/protect in this memory (i.e. when allocated using large OS pages)
- bool mem_is_committed; // `true` if the whole segment is eagerly committed
-
- // segment fields
- struct mi_segment_s* next; // must be the first segment field -- see `segment.c:segment_alloc`
- struct mi_segment_s* prev;
- struct mi_segment_s* abandoned_next;
- size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`)
- size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long)
-
- size_t used; // count of pages in use (`used <= capacity`)
- size_t capacity; // count of available pages (`#free + used`)
- size_t segment_size;// for huge pages this may be different from `MI_SEGMENT_SIZE`
- size_t segment_info_size; // space we are using from the first page for segment meta-data and possible guard pages.
- uintptr_t cookie; // verify addresses in secure mode: `_mi_ptr_cookie(segment) == segment->cookie`
+ size_t memid; // memory id for arena allocation
+ bool mem_is_pinned; // `true` if we cannot decommit/reset/protect in this memory (i.e. when allocated using large OS pages)
+ bool mem_is_large; // in large/huge os pages?
+ bool mem_is_committed; // `true` if the whole segment is eagerly committed
+
+ bool allow_decommit;
+ mi_msecs_t decommit_expire;
+ mi_commit_mask_t decommit_mask;
+ mi_commit_mask_t commit_mask;
+
+ _Atomic(struct mi_segment_s*) abandoned_next;
+
+ // from here is zero initialized
+ struct mi_segment_s* next; // the list of freed segments in the cache (must be first field, see `segment.c:mi_segment_init`)
+
+ size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`)
+ size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long)
+ size_t used; // count of pages in use
+ uintptr_t cookie; // verify addresses in debug mode: `mi_ptr_cookie(segment) == segment->cookie`
+
+ size_t segment_slices; // for huge segments this may be different from `MI_SLICES_PER_SEGMENT`
+ size_t segment_info_slices; // initial slices we are using segment info and possible guard pages.
// layout like this to optimize access in `mi_free`
- size_t page_shift; // `1 << page_shift` == the page sizes == `page->block_size * page->reserved` (unless the first page, then `-segment_info_size`).
- volatile _Atomic(uintptr_t) thread_id; // unique id of the thread owning this segment
- mi_page_kind_t page_kind; // kind of pages: small, large, or huge
- mi_page_t pages[1]; // up to `MI_SMALL_PAGES_PER_SEGMENT` pages
+ mi_segment_kind_t kind;
+ _Atomic(mi_threadid_t) thread_id; // unique id of the thread owning this segment
+ size_t slice_entries; // entries in the `slices` array, at most `MI_SLICES_PER_SEGMENT`
+ mi_slice_t slices[MI_SLICES_PER_SEGMENT];
} mi_segment_t;
} mi_random_ctx_t;
-// In debug mode there is a padding stucture at the end of the blocks to check for buffer overflows
+// In debug mode there is a padding structure at the end of the blocks to check for buffer overflows
#if (MI_PADDING)
typedef struct mi_padding_s {
uint32_t canary; // encoded block value to check validity of the padding (in case of overflow)
mi_tld_t* tld;
mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size.
mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin")
- volatile _Atomic(mi_block_t*) thread_delayed_free;
- uintptr_t thread_id; // thread this heap belongs too
+ _Atomic(mi_block_t*) thread_delayed_free;
+ mi_threadid_t thread_id; // thread this heap belongs too
uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`)
uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list
mi_random_ctx_t random; // random number context used for secure allocation
// Debug
// ------------------------------------------------------
+#if !defined(MI_DEBUG_UNINIT)
#define MI_DEBUG_UNINIT (0xD0)
+#endif
+#if !defined(MI_DEBUG_FREED)
#define MI_DEBUG_FREED (0xDF)
+#endif
+#if !defined(MI_DEBUG_PADDING)
#define MI_DEBUG_PADDING (0xDE)
+#endif
#if (MI_DEBUG)
// use our own assertion to print without memory allocation
mi_stat_count_t segments_abandoned;
mi_stat_count_t pages_abandoned;
mi_stat_count_t threads;
+ mi_stat_count_t normal;
mi_stat_count_t huge;
- mi_stat_count_t giant;
+ mi_stat_count_t large;
mi_stat_count_t malloc;
mi_stat_count_t segments_cache;
mi_stat_counter_t pages_extended;
mi_stat_counter_t commit_calls;
mi_stat_counter_t page_no_retire;
mi_stat_counter_t searches;
+ mi_stat_counter_t normal_count;
mi_stat_counter_t huge_count;
- mi_stat_counter_t giant_count;
+ mi_stat_counter_t large_count;
#if MI_STAT>1
- mi_stat_count_t normal[MI_BIN_HUGE+1];
+ mi_stat_count_t normal_bins[MI_BIN_HUGE+1];
#endif
} mi_stats_t;
#define mi_stat_counter_increase(stat,amount) (void)0
#endif
+#define mi_heap_stat_counter_increase(heap,stat,amount) mi_stat_counter_increase( (heap)->tld->stats.stat, amount)
#define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount)
#define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount)
// Thread Local data
// ------------------------------------------------------
-typedef int64_t mi_msecs_t;
+// A "span" is is an available range of slices. The span queues keep
+// track of slice spans of at most the given `slice_count` (but more than the previous size class).
+typedef struct mi_span_queue_s {
+ mi_slice_t* first;
+ mi_slice_t* last;
+ size_t slice_count;
+} mi_span_queue_t;
-// Queue of segments
-typedef struct mi_segment_queue_s {
- mi_segment_t* first;
- mi_segment_t* last;
-} mi_segment_queue_t;
+#define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT)
// OS thread local data
typedef struct mi_os_tld_s {
mi_stats_t* stats; // points to tld stats
} mi_os_tld_t;
+
// Segments thread local data
typedef struct mi_segments_tld_s {
- mi_segment_queue_t small_free; // queue of segments with free small pages
- mi_segment_queue_t medium_free; // queue of segments with free medium pages
- mi_page_queue_t pages_reset; // queue of freed pages that can be reset
+ mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments
size_t count; // current number of segments;
size_t peak_count; // peak number of segments
size_t current_size; // current size of all segments
size_t peak_size; // peak size of all segments
- size_t cache_count; // number of segments in the cache
- size_t cache_size; // total size of all segments in the cache
- mi_segment_t* cache; // (small) cache of segments
mi_stats_t* stats; // points to tld stats
mi_os_tld_t* os; // points to os stats
} mi_segments_tld_t;
/* ----------------------------------------------------------------------------
-Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2022, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#ifndef MIMALLOC_H
#define MIMALLOC_H
-#define MI_MALLOC_VERSION 164 // major + 2 digits minor
+#define MI_MALLOC_VERSION 206 // major + 2 digits minor
// ------------------------------------------------------
// Compiler specific attributes
#define mi_attr_noexcept
#endif
-#if (__cplusplus >= 201703)
+#if defined(__cplusplus) && (__cplusplus >= 201703)
#define mi_decl_nodiscard [[nodiscard]]
-#elif (__GNUC__ >= 4) || defined(__clang__) // includes clang, icc, and clang-cl
+#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // includes clang, icc, and clang-cl
#define mi_decl_nodiscard __attribute__((warn_unused_result))
#elif (_MSC_VER >= 1700)
#define mi_decl_nodiscard _Check_return_
#define mi_attr_alloc_size2(s1,s2)
#define mi_attr_alloc_align(p)
#elif defined(__GNUC__) // includes clang and icc
+ #if defined(MI_SHARED_LIB) && defined(MI_SHARED_LIB_EXPORT)
+ #define mi_decl_export __attribute__((visibility("default")))
+ #else
+ #define mi_decl_export
+ #endif
#define mi_cdecl // leads to warnings... __attribute__((cdecl))
- #define mi_decl_export __attribute__((visibility("default")))
#define mi_decl_restrict
#define mi_attr_malloc __attribute__((malloc))
#if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5)
mi_decl_export void mi_thread_done(void) mi_attr_noexcept;
mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;
+mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs,
+ size_t* current_rss, size_t* peak_rss,
+ size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept;
// -------------------------------------------------------------------------------------
// Aligned allocation
// Note that `alignment` always follows `size` for consistency with unaligned
// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`.
// -------------------------------------------------------------------------------------
+#define MI_ALIGNMENT_MAX (1024*1024UL) // maximum supported alignment is 1MiB
mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);
mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
mi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3);
-mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4);;
+mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4);
mi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3);
mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept mi_attr_malloc;
void* blocks; // start of the area containing heap blocks
size_t reserved; // bytes reserved for this area (virtual)
size_t committed; // current available bytes for this area
- size_t used; // bytes in use by allocated blocks
+ size_t used; // number of allocated blocks
size_t block_size; // size in bytes of each block
+ size_t full_block_size; // size in bytes of a full block including padding and metadata.
} mi_heap_area_t;
typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);
// Experimental
mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;
-mi_decl_nodiscard mi_decl_export bool mi_is_redirected() mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept;
mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept;
mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept;
+mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept;
+mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept;
+
+mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept;
+
// deprecated
mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept;
// ------------------------------------------------------
-// Options, all `false` by default
+// Options
// ------------------------------------------------------
typedef enum mi_option_e {
mi_option_show_errors,
mi_option_show_stats,
mi_option_verbose,
- // the following options are experimental
+ // some of the following options are experimental
+ // (deprecated options are kept for binary backward compatibility with v1.x versions)
mi_option_eager_commit,
- mi_option_eager_region_commit,
- mi_option_reset_decommits,
- mi_option_large_os_pages, // implies eager commit
- mi_option_reserve_huge_os_pages,
- mi_option_segment_cache,
+ mi_option_deprecated_eager_region_commit,
+ mi_option_deprecated_reset_decommits,
+ mi_option_large_os_pages, // use large (2MiB) OS pages, implies eager commit
+ mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB) at startup
+ mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node
+ mi_option_reserve_os_memory, // reserve specified amount of OS memory at startup
+ mi_option_deprecated_segment_cache,
mi_option_page_reset,
- mi_option_abandoned_page_reset,
- mi_option_segment_reset,
+ mi_option_abandoned_page_decommit,
+ mi_option_deprecated_segment_reset,
mi_option_eager_commit_delay,
- mi_option_reset_delay,
- mi_option_use_numa_nodes,
+ mi_option_decommit_delay,
+ mi_option_use_numa_nodes, // 0 = use available numa nodes, otherwise use at most N nodes.
+ mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only reserved arenas)
mi_option_os_tag,
mi_option_max_errors,
+ mi_option_max_warnings,
+ mi_option_max_segment_reclaim,
+ mi_option_allow_decommit,
+ mi_option_segment_decommit_delay,
+ mi_option_decommit_extend_delay,
_mi_option_last
} mi_option_t;
mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable);
mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option);
+mi_decl_nodiscard mi_decl_export long mi_option_get_clamp(mi_option_t option, long min, long max);
mi_decl_export void mi_option_set(mi_option_t option, long value);
mi_decl_export void mi_option_set_default(mi_option_t option, long value);
mi_decl_export void mi_cfree(void* p) mi_attr_noexcept;
mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept;
mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export size_t mi_malloc_good_size(size_t size) mi_attr_noexcept;
mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;
mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept;
mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);
mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3);
+mi_decl_nodiscard mi_decl_export int mi_reallocarr(void* p, size_t count, size_t size) mi_attr_noexcept;
mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept;
mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept;
// ---------------------------------------------------------------------------------------------
#ifdef __cplusplus
+#include <cstddef> // std::size_t
#include <cstdint> // PTRDIFF_MAX
#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11
#include <type_traits> // std::true_type
mimalloc (pronounced "me-malloc")
is a general purpose allocator with excellent [performance](#performance) characteristics.
Initially developed by Daan Leijen for the run-time systems of the
-[Koka](https://github.com/koka-lang/koka) and [Lean](https://github.com/leanprover/lean) languages.
-Latest release:`v1.6.4` (2020-08-06).
+[Koka](https://koka-lang.github.io) and [Lean](https://github.com/leanprover/lean) languages.
-It is a drop-in replacement for `malloc` and can be used in other programs
+Latest release tag: `v2.0.5` (alpha, 2022-02-14).
+Latest stable tag: `v1.7.5` (2022-02-14).
+
+mimalloc is a drop-in replacement for `malloc` and can be used in other programs
without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as:
```
-> LD_PRELOAD=/usr/bin/libmimalloc.so myprogram
+> LD_PRELOAD=/usr/lib/libmimalloc.so myprogram
```
-It also has an easy way to override the allocator in [Windows](#override_on_windows). Notable aspects of the design include:
+It also has an easy way to override the default allocator in [Windows](#override_on_windows). Notable aspects of the design include:
-- __small and consistent__: the library is about 6k LOC using simple and
+- __small and consistent__: the library is about 8k LOC using simple and
consistent data structures. This makes it very suitable
to integrate and adapt in other projects. For runtime systems it
provides hooks for a monotonic _heartbeat_ and deferred freeing (for
bounded worst-case times with reference counting).
-- __free list sharding__: the big idea: instead of one big free list (per size class) we have
- many smaller lists per memory "page" which both reduces fragmentation
- and increases locality --
+- __free list sharding__: instead of one big free list (per size class) we have
+ many smaller lists per "mimalloc page" which reduces fragmentation and
+ increases locality --
things that are allocated close in time get allocated close in memory.
- (A memory "page" in _mimalloc_ contains blocks of one size class and is
- usually 64KiB on a 64-bit system).
+ (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system).
+- __free list multi-sharding__: the big idea! Not only do we shard the free list
+ per mimalloc page, but for each page we have multiple free lists. In particular, there
+ is one list for thread-local `free` operations, and another one for concurrent `free`
+ operations. Free-ing from another thread can now be a single CAS without needing
+ sophisticated coordination between threads. Since there will be
+ thousands of separate free lists, contention is naturally distributed over the heap,
+ and the chance of contending on a single location will be low -- this is quite
+ similar to randomized algorithms like skip lists where adding
+ a random oracle removes the need for a more complex algorithm.
- __eager page reset__: when a "page" becomes empty (with increased chance
due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged")
reducing (real) memory pressure and fragmentation, especially in long running
and has no internal points of contention using only atomic operations.
- __fast__: In our benchmarks (see [below](#performance)),
_mimalloc_ outperforms other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc),
- and usually uses less memory (up to 25% more in the worst case). A nice property
+ and often uses less memory. A nice property
is that it does consistently well over a wide range of benchmarks. There is also good huge OS page
support for larger server programs.
Enjoy!
+### Branches
+
+* `master`: latest stable release.
+* `dev`: development branch for mimalloc v1.
+* `dev-slice`: development branch for mimalloc v2 with a new algorithm for managing internal mimalloc pages.
+
### Releases
-* 2020-08-06, `v1.6.4`: stable release 1.6: improved error recovery in low-memory situations,
- support for IllumOS and Haiku, NUMA support for Vista/XP, improved NUMA detection for AMD Ryzen, ubsan support.
-* 2020-05-05, `v1.6.3`: stable release 1.6: improved behavior in out-of-memory situations, improved malloc zones on macOS,
- build PIC static libraries by default, add option to abort on out-of-memory, line buffered statistics.
-* 2020-04-20, `v1.6.2`: stable release 1.6: fix compilation on Android, MingW, Raspberry, and Conda,
- stability fix for Windows 7, fix multiple mimalloc instances in one executable, fix `strnlen` overload,
- fix aligned debug padding.
-* 2020-02-17, `v1.6.1`: stable release 1.6: minor updates (build with clang-cl, fix alignment issue for small objects).
-* 2020-02-09, `v1.6.0`: stable release 1.6: fixed potential memory leak, improved overriding
- and thread local support on FreeBSD, NetBSD, DragonFly, and macOSX. New byte-precise
- heap block overflow detection in debug mode (besides the double-free detection and free-list
- corruption detection). Add `nodiscard` attribute to most allocation functions.
- Enable `MIMALLOC_PAGE_RESET` by default. New reclamation strategy for abandoned heap pages
- for better memory footprint.
-* 2020-02-09, `v1.5.0`: stable release 1.5: improved free performance, small bug fixes.
-* 2020-01-22, `v1.4.0`: stable release 1.4: improved performance for delayed OS page reset,
-more eager concurrent free, addition of STL allocator, fixed potential memory leak.
-* 2020-01-15, `v1.3.0`: stable release 1.3: bug fixes, improved randomness and [stronger
-free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) in secure mode.
-* 2019-12-22, `v1.2.2`: stable release 1.2: minor updates.
-* 2019-11-22, `v1.2.0`: stable release 1.2: bug fixes, improved secure mode (free list corruption checks, double free mitigation). Improved dynamic overriding on Windows.
-* 2019-10-07, `v1.1.0`: stable release 1.1.
-* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support.
-* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements.
+Note: the `v2.x` beta has a new algorithm for managing internal mimalloc pages that tends to use reduce memory usage
+ and fragmentation compared to mimalloc `v1.x` (especially for large workloads). Should otherwise have similar performance
+ (see [below](#performance)); please report if you observe any significant performance regression.
+
+* 2022-02-14, `v1.7.5`, `v2.0.5` (alpha): fix malloc override on
+ Windows 11, fix compilation with musl, potentially reduced
+ committed memory, add `bin/minject` for Windows,
+ improved wasm support, faster aligned allocation,
+ various small fixes.
+
+* 2021-11-14, `v1.7.3`, `v2.0.3` (beta): improved WASM support, improved macOS support and performance (including
+ M1), improved performance for v2 for large objects, Python integration improvements, more standard
+ installation directories, various small fixes.
+
+* 2021-06-17, `v1.7.2`, `v2.0.2` (beta): support M1, better installation layout on Linux, fix
+ thread_id on Android, prefer 2-6TiB area for aligned allocation to work better on pre-windows 8, various small fixes.
+
+* 2021-04-06, `v1.7.1`, `v2.0.1` (beta): fix bug in arena allocation for huge pages, improved aslr on large allocations, initial M1 support (still experimental).
+
+* 2021-01-31, `v2.0.0`: beta release 2.0: new slice algorithm for managing internal mimalloc pages.
+
+* 2021-01-31, `v1.7.0`: stable release 1.7: support explicit user provided memory regions, more precise statistics,
+ improve macOS overriding, initial support for Apple M1, improved DragonFly support, faster memcpy on Windows, various small fixes.
+
+* [Older release notes](#older-release-notes)
Special thanks to:
-* Jason Gibson (@jasongibson) for exhaustive testing on large workloads and server environments and finding complex bugs in (early versions of) `mimalloc`.
-* Manuel Pöter (@mpoeter) and Sam Gross (@colesbury) for finding an ABA concurrency issue in abandoned segment reclamation.
+* [David Carlier](https://devnexen.blogspot.com/) (@devnexen) for his many contributions, and making
+ mimalloc work better on many less common operating systems, like Haiku, Dragonfly, etc.
+* Mary Feofanova (@mary3000), Evgeniy Moiseenko, and Manuel Pöter (@mpoeter) for making mimalloc TSAN checkable, and finding
+ memory model bugs using the [genMC] model checker.
+* Weipeng Liu (@pongba), Zhuowei Li, Junhua Wang, and Jakub Szymanski, for their early support of mimalloc and deployment
+ at large scale services, leading to many improvements in the mimalloc algorithms for large workloads.
+* Jason Gibson (@jasongibson) for exhaustive testing on large scale workloads and server environments, and finding complex bugs
+ in (early versions of) `mimalloc`.
+* Manuel Pöter (@mpoeter) and Sam Gross(@colesbury) for finding an ABA concurrency issue in abandoned segment reclamation. Sam also created the [no GIL](https://github.com/colesbury/nogil) Python fork which
+ uses mimalloc internally.
+
+
+[genMC]: https://plv.mpi-sws.org/genmc/
+
+### Usage
+
+mimalloc is used in various large scale low-latency services and programs, for example:
+
+<a href="https://www.bing.com"><img height="50" align="left" src="https://upload.wikimedia.org/wikipedia/commons/e/e9/Bing_logo.svg"></a>
+<a href="https://azure.microsoft.com/"><img height="50" align="left" src="https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg"></a>
+<a href="https://deathstrandingpc.505games.com"><img height="100" src="doc/ds-logo.png"></a>
+<a href="https://docs.unrealengine.com/4.26/en-US/WhatsNew/Builds/ReleaseNotes/4_25/"><img height="100" src="doc/unreal-logo.svg"></a>
+<a href="https://cab.spbu.ru/software/spades/"><img height="100" src="doc/spades-logo.png"></a>
+
# Building
## Windows
-Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build (or `ide/vs2017/mimalloc.sln`).
+Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build.
The `mimalloc` project builds a static library (in `out/msvc-x64`), while the
`mimalloc-override` project builds a DLL for overriding malloc
in the entire program.
2. Install CCMake: `sudo apt-get install cmake-curses-gui`
+## Single source
+
+You can also directly build the single `src/static.c` file as part of your project without
+needing `cmake` at all. Make sure to also add the mimalloc `include` directory to the include path.
+
# Using the library
## Environment Options
You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)),
-or via environment variables.
+or via environment variables:
- `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates.
- `MIMALLOC_VERBOSE=1`: show verbose messages.
`MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB)
of a thread to not allocate in the huge OS pages; this prevents threads that are short lived
and allocate just a little to take up space in the huge OS page area (which cannot be reset).
+ The huge pages are usually allocated evenly among NUMA nodes.
+ We can use `MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N` where `N` is the numa node (starting at 0) to allocate all
+ the huge pages at a specific numa node instead.
Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write
for all pages in the original process including the huge OS pages. When any memory is now written in that area, the
to make mimalloc more robust against exploits. In particular:
- All internal mimalloc pages are surrounded by guard pages and the heap metadata is behind a guard page as well (so a buffer overflow
- exploit cannot reach into the metadata),
+ exploit cannot reach into the metadata).
- All free list pointers are
[encoded](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396)
- with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption,
-- Double free's are detected (and ignored),
+ with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption.
+- Double free's are detected (and ignored).
- The free lists are initialized in a random order and allocation randomly chooses between extension and reuse within a page to
mitigate against attacks that rely on a predicable allocation order. Similarly, the larger heap blocks allocated by mimalloc
from the OS are also address randomized.
- Corrupted free-lists and some forms of use-after-free are detected.
-# Overriding Malloc
+# Overriding Standard Malloc
-Overriding the standard `malloc` can be done either _dynamically_ or _statically_.
+Overriding the standard `malloc` (and `new`) can be done either _dynamically_ or _statically_.
## Dynamic override
library so all calls to the standard `malloc` interface are
resolved to the _mimalloc_ library.
```
-> env DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram
+> env DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram
```
Note that certain security restrictions may apply when doing this from
the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash).
-(Note: macOS support for dynamic overriding is recent, please report any issues.)
### Override on Windows
The overriding on Windows requires that you link your program explicitly with
the mimalloc DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch).
-Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be available
+Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be put
in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency).
The redirection DLL ensures that all calls to the C runtime malloc API get redirected to
mimalloc (in `mimalloc-override.dll`).
# Performance
-Last update: 2020-01-20
+Last update: 2021-01-30
We tested _mimalloc_ against many other top allocators over a wide
range of benchmarks, ranging from various real world programs to
As always, interpret these results with care since some benchmarks test synthetic
or uncommon situations that may never apply to your workloads. For example, most
-allocators do not do well on `xmalloc-testN` but that includes the best
+allocators do not do well on `xmalloc-testN` but that includes even the best
industrial allocators like _jemalloc_ and _tcmalloc_ that are used in some of
the world's largest systems (like Chrome or FreeBSD).
+Also, the benchmarks here do not measure the behaviour on very large and long-running server workloads,
+or worst-case latencies of allocation. Much work has gone into `mimalloc` to work well on such
+workloads (for example, to reduce virtual memory fragmentation on long-running services)
+but such optimizations are not always reflected in the current benchmark suite.
+
We show here only an overview -- for
more specific details and further benchmarks we refer to the
[technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action).
as [mimalloc-bench](https://github.com/daanx/mimalloc-bench).
-## Benchmark Results on 36-core Intel
+## Benchmark Results on a 16-core AMD 5950x (Zen3)
-Testing on a big Amazon EC2 compute instance
-([c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized))
-consisting of a 72 processor Intel Xeon at 3GHz
-with 144GiB ECC memory, running Ubuntu 18.04.1 with glibc 2.27 and GCC 7.4.0.
-The measured allocators are _mimalloc_ (xmi, tag:v1.4.0, page reset enabled)
-and its secure build as _smi_,
-Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (tc, tag:gperftools-2.7) used in Chrome,
-Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (je, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD,
-the Intel thread building blocks [allocator](https://github.com/intel/tbb) (tbb, tag:2020),
-[rpmalloc](https://github.com/mjansson/rpmalloc) (rp,tag:1.4.0) by Mattias Jansson,
-the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (tag:3.13) allocator by Emery Berger \[1],
-the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:51222e7) allocator by
+Testing on the 16-core AMD 5950x processor at 3.4Ghz (4.9Ghz boost), with
+with 32GiB memory at 3600Mhz, running Ubuntu 20.04 with glibc 2.31 and GCC 9.3.0.
+
+We measure three versions of _mimalloc_: the main version `mi` (tag:v1.7.0),
+the new v2.0 beta version as `xmi` (tag:v2.0.0), and the main version in secure mode as `smi` (tag:v1.7.0).
+
+The other allocators are
+Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (`tc`, tag:gperftools-2.8.1) used in Chrome,
+Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (`je`, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD,
+the Intel thread building blocks [allocator](https://github.com/intel/tbb) (`tbb`, tag:v2020.3),
+[rpmalloc](https://github.com/mjansson/rpmalloc) (`rp`,tag:1.4.1) by Mattias Jansson,
+the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (git:d880f72) allocator by Emery Berger \[1],
+the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:67ff31a) allocator by
Bobby Powers _et al_ \[8],
-and finally the default system allocator (glibc, 2.27) (based on _PtMalloc2_).
+and finally the default system allocator (`glibc`, 2.31) (based on _PtMalloc2_).
-<img width="90%" src="doc/bench-c5-18xlarge-2020-01-20-a.svg"/>
-<img width="90%" src="doc/bench-c5-18xlarge-2020-01-20-b.svg"/>
+<img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-a.svg"/>
+<img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-b.svg"/>
-Any benchmarks ending in `N` run on all processors in parallel.
+Any benchmarks ending in `N` run on all 32 logical cores in parallel.
Results are averaged over 10 runs and reported relative
to mimalloc (where 1.2 means it took 1.2× longer to run).
The legend also contains the _overall relative score_ between the
The _leanN_ program is interesting as a large realistic and
concurrent workload of the [Lean](https://github.com/leanprover/lean)
-theorem prover compiling its own standard library, and there is a 7%
+theorem prover compiling its own standard library, and there is a 13%
speedup over _tcmalloc_. This is
quite significant: if Lean spends 20% of its time in the
-allocator that means that _mimalloc_ is 1.3× faster than _tcmalloc_
+allocator that means that _mimalloc_ is 1.6× faster than _tcmalloc_
here. (This is surprising as that is not measured in a pure
allocation benchmark like _alloc-test_. We conjecture that we see this
outsized improvement here because _mimalloc_ has better locality in
the allocation which improves performance for the *other* computations
in a program as well).
-The single threaded _redis_ benchmark again show that most allocators do well on such workloads where _tcmalloc_
-did best this time.
+The single threaded _redis_ benchmark again show that most allocators do well on such workloads.
The _larsonN_ server benchmark by Larson and Krishnan \[2] allocates and frees between threads. They observed this
behavior (which they call _bleeding_) in actual server applications, and the benchmark simulates this.
[OLogN Technologies AG](http://ithare.com/testing-memory-allocators-ptmalloc2-tcmalloc-hoard-jemalloc-while-trying-to-simulate-real-world-loads/), is a very allocation intensive benchmark doing millions of
allocations in various size classes. The test is scaled such that when an
allocator performs almost identically on _alloc-test1_ as _alloc-testN_ it
-means that it scales linearly. Here, _tcmalloc_, and
-_Hoard_ seem to scale less well and do more than 10% worse on the multi-core version. Even the best industrial
-allocators (_tcmalloc_, _jemalloc_, and _tbb_) are more than 10% slower as _mimalloc_ here.
+means that it scales linearly.
The _sh6bench_ and _sh8bench_ benchmarks are
developed by [MicroQuill](http://www.microquill.com/) as part of SmartHeap.
In _sh6bench_ _mimalloc_ does much
-better than the others (more than 1.5× faster than _jemalloc_).
+better than the others (more than 2.5× faster than _jemalloc_).
We cannot explain this well but believe it is
caused in part by the "reverse" free-ing pattern in _sh6bench_.
The _sh8bench_ is a variation with object migration
some threads only allocate, and others only free -- they observed this pattern in
larger server applications. Here we see that
the _mimalloc_ technique of having non-contended sharded thread free
-lists pays off as it outperforms others by a very large margin. Only _rpmalloc_ and _tbb_ also scale well on this benchmark.
+lists pays off as it outperforms others by a very large margin. Only _rpmalloc_, _tbb_, and _glibc_ also scale well on this benchmark.
The _cache-scratch_ benchmark by Emery Berger \[1], and introduced with
the Hoard allocator to test for _passive-false_ sharing of cache lines.
the effects. Kukanov and Voss \[7] describe in detail
how the design of _tbb_ avoids the false cache line sharing.
-## On 24-core AMD Epyc
-For completeness, here are the results on a
-[r5a.12xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance
-having a 48 processor AMD Epyc 7000 at 2.5GHz with 384GiB of memory.
-The results are similar to the Intel results but it is interesting to
+## On a 36-core Intel Xeon
+
+For completeness, here are the results on a big Amazon
+[c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized) instance
+consisting of a 2×18-core Intel Xeon (Cascade Lake) at 3.4GHz (boost 3.5GHz)
+with 144GiB ECC memory, running Ubuntu 20.04 with glibc 2.31, GCC 9.3.0, and
+Clang 10.0.0. This time, the mimalloc allocators (mi, xmi, and smi) were
+compiled with the Clang compiler instead of GCC.
+The results are similar to the AMD results but it is interesting to
see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks.
-<img width="90%" src="doc/bench-r5a-12xlarge-2020-01-16-a.svg"/>
-<img width="90%" src="doc/bench-r5a-12xlarge-2020-01-16-b.svg"/>
+<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg"/>
+<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg"/>
## Peak Working Set
The following figure shows the peak working set (rss) of the allocators
on the benchmarks (on the c5.18xlarge instance).
-<img width="90%" src="doc/bench-c5-18xlarge-2020-01-20-rss-a.svg"/>
-<img width="90%" src="doc/bench-c5-18xlarge-2020-01-20-rss-b.svg"/>
+<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg"/>
+<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg"/>
Note that the _xmalloc-testN_ memory usage should be disregarded as it
allocates more the faster the program runs. Similarly, memory usage of
-_mstressN_, _rptestN_ and _sh8bench_ can vary depending on scheduling and
-speed. Nevertheless, even though _mimalloc_ is fast on these benchmarks we
-believe the memory usage is too high and hope to improve.
+_larsonN_, _mstressN_, _rptestN_ and _sh8bench_ can vary depending on scheduling and
+speed. Nevertheless, we hope to improve the memory usage on _mstressN_
+and _rptestN_ (just as _cfrac_, _larsonN_ and _sh8bench_ have a small working set which skews the results).
+
+<!--
+# Previous Benchmarks
+
+Todo: should we create a separate page for this?
+
+## Benchmark Results on 36-core Intel: 2020-01-20
+
+Testing on a big Amazon EC2 compute instance
+([c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized))
+consisting of a 72 processor Intel Xeon at 3GHz
+with 144GiB ECC memory, running Ubuntu 18.04.1 with glibc 2.27 and GCC 7.4.0.
+The measured allocators are _mimalloc_ (xmi, tag:v1.4.0, page reset enabled)
+and its secure build as _smi_,
+Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (tc, tag:gperftools-2.7) used in Chrome,
+Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (je, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD,
+the Intel thread building blocks [allocator](https://github.com/intel/tbb) (tbb, tag:2020),
+[rpmalloc](https://github.com/mjansson/rpmalloc) (rp,tag:1.4.0) by Mattias Jansson,
+the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (tag:3.13) allocator by Emery Berger \[1],
+the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:51222e7) allocator by
+Bobby Powers _et al_ \[8],
+and finally the default system allocator (glibc, 2.27) (based on _PtMalloc2_).
+
+<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg"/>
+<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg"/>
+
+The following figure shows the peak working set (rss) of the allocators
+on the benchmarks (on the c5.18xlarge instance).
+
+<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg"/>
+<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg"/>
+
+
+## On 24-core AMD Epyc, 2020-01-16
+
+For completeness, here are the results on a
+[r5a.12xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance
+having a 48 processor AMD Epyc 7000 at 2.5GHz with 384GiB of memory.
+The results are similar to the Intel results but it is interesting to
+see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks.
+
+<img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg"/>
+<img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg"/>
+
+-->
# References
In Proceedings of the 2019 ACM SIGPLAN International Symposium on Memory Management, 122–135. ACM. 2019.
-->
-
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
+
+
+# Older Release Notes
+
+* 2020-09-24, `v1.6.7`: stable release 1.6: using standard C atomics, passing tsan testing, improved
+ handling of failing to commit on Windows, add [`mi_process_info`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc.h#L156) api call.
+* 2020-08-06, `v1.6.4`: stable release 1.6: improved error recovery in low-memory situations,
+ support for IllumOS and Haiku, NUMA support for Vista/XP, improved NUMA detection for AMD Ryzen, ubsan support.
+* 2020-05-05, `v1.6.3`: stable release 1.6: improved behavior in out-of-memory situations, improved malloc zones on macOS,
+ build PIC static libraries by default, add option to abort on out-of-memory, line buffered statistics.
+* 2020-04-20, `v1.6.2`: stable release 1.6: fix compilation on Android, MingW, Raspberry, and Conda,
+ stability fix for Windows 7, fix multiple mimalloc instances in one executable, fix `strnlen` overload,
+ fix aligned debug padding.
+* 2020-02-17, `v1.6.1`: stable release 1.6: minor updates (build with clang-cl, fix alignment issue for small objects).
+* 2020-02-09, `v1.6.0`: stable release 1.6: fixed potential memory leak, improved overriding
+ and thread local support on FreeBSD, NetBSD, DragonFly, and macOSX. New byte-precise
+ heap block overflow detection in debug mode (besides the double-free detection and free-list
+ corruption detection). Add `nodiscard` attribute to most allocation functions.
+ Enable `MIMALLOC_PAGE_RESET` by default. New reclamation strategy for abandoned heap pages
+ for better memory footprint.
+* 2020-02-09, `v1.5.0`: stable release 1.5: improved free performance, small bug fixes.
+* 2020-01-22, `v1.4.0`: stable release 1.4: improved performance for delayed OS page reset,
+more eager concurrent free, addition of STL allocator, fixed potential memory leak.
+* 2020-01-15, `v1.3.0`: stable release 1.3: bug fixes, improved randomness and [stronger
+free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) in secure mode.
+* 2019-12-22, `v1.2.2`: stable release 1.2: minor updates.
+* 2019-11-22, `v1.2.0`: stable release 1.2: bug fixes, improved secure mode (free list corruption checks, double free mitigation). Improved dynamic overriding on Windows.
+* 2019-10-07, `v1.1.0`: stable release 1.1.
+* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support.
+* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements.
+
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include "mimalloc.h"
#include "mimalloc-internal.h"
-#include <string.h> // memset, memcpy
+#include <string.h> // memset
// ------------------------------------------------------
// Aligned Allocation
// ------------------------------------------------------
-static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept {
- // note: we don't require `size > offset`, we just guarantee that
- // the address at offset is aligned regardless of the allocated size.
- mi_assert(alignment > 0);
- if (mi_unlikely(size > PTRDIFF_MAX)) return NULL; // we don't allocate more than PTRDIFF_MAX (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)
- if (mi_unlikely(alignment==0 || !_mi_is_power_of_two(alignment))) return NULL; // require power-of-two (see <https://en.cppreference.com/w/c/memory/aligned_alloc>)
+// Fallback primitive aligned allocation -- split out for better codegen
+static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept
+{
+ mi_assert_internal(size <= PTRDIFF_MAX);
+ mi_assert_internal(alignment!=0 && _mi_is_power_of_two(alignment) && alignment <= MI_ALIGNMENT_MAX);
+
const uintptr_t align_mask = alignment-1; // for any x, `(x & align_mask) == (x % alignment)`
-
- // try if there is a small block available with just the right alignment
const size_t padsize = size + MI_PADDING_SIZE;
- if (mi_likely(padsize <= MI_SMALL_SIZE_MAX)) {
- mi_page_t* page = _mi_heap_get_free_small_page(heap,padsize);
- const bool is_aligned = (((uintptr_t)page->free+offset) & align_mask)==0;
- if (mi_likely(page->free != NULL && is_aligned))
- {
- #if MI_STAT>1
- mi_heap_stat_increase( heap, malloc, size);
- #endif
- void* p = _mi_page_malloc(heap,page,padsize); // TODO: inline _mi_page_malloc
- mi_assert_internal(p != NULL);
- mi_assert_internal(((uintptr_t)p + offset) % alignment == 0);
- if (zero) _mi_block_zero_init(page,p,size);
- return p;
- }
- }
// use regular allocation if it is guaranteed to fit the alignment constraints
- if (offset==0 && alignment<=padsize && padsize<=MI_MEDIUM_OBJ_SIZE_MAX && (padsize&align_mask)==0) {
+ if (offset==0 && alignment<=padsize && padsize<=MI_MAX_ALIGN_GUARANTEE && (padsize&align_mask)==0) {
void* p = _mi_heap_malloc_zero(heap, size, zero);
mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0);
return p;
}
-
+
// otherwise over-allocate
void* p = _mi_heap_malloc_zero(heap, size + alignment - 1, zero);
if (p == NULL) return NULL;
uintptr_t adjust = alignment - (((uintptr_t)p + offset) & align_mask);
mi_assert_internal(adjust <= alignment);
void* aligned_p = (adjust == alignment ? p : (void*)((uintptr_t)p + adjust));
- if (aligned_p != p) mi_page_set_has_aligned(_mi_ptr_page(p), true);
+ if (aligned_p != p) mi_page_set_has_aligned(_mi_ptr_page(p), true);
mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0);
- mi_assert_internal( p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p),_mi_ptr_page(aligned_p),aligned_p) );
+ mi_assert_internal(p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p), _mi_ptr_page(aligned_p), aligned_p));
return aligned_p;
}
+// Primitive aligned allocation
+static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept
+{
+ // note: we don't require `size > offset`, we just guarantee that the address at offset is aligned regardless of the allocated size.
+ mi_assert(alignment > 0);
+ if (mi_unlikely(alignment==0 || !_mi_is_power_of_two(alignment))) { // require power-of-two (see <https://en.cppreference.com/w/c/memory/aligned_alloc>)
+ #if MI_DEBUG > 0
+ _mi_error_message(EOVERFLOW, "aligned allocation requires the alignment to be a power-of-two (size %zu, alignment %zu)\n", size, alignment);
+ #endif
+ return NULL;
+ }
+ if (mi_unlikely(alignment > MI_ALIGNMENT_MAX)) { // we cannot align at a boundary larger than this (or otherwise we cannot find segment headers)
+ #if MI_DEBUG > 0
+ _mi_error_message(EOVERFLOW, "aligned allocation has a maximum alignment of %zu (size %zu, alignment %zu)\n", MI_ALIGNMENT_MAX, size, alignment);
+ #endif
+ return NULL;
+ }
+ if (mi_unlikely(size > PTRDIFF_MAX)) { // we don't allocate more than PTRDIFF_MAX (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)
+ #if MI_DEBUG > 0
+ _mi_error_message(EOVERFLOW, "aligned allocation request is too large (size %zu, alignment %zu)\n", size, alignment);
+ #endif
+ return NULL;
+ }
+ const uintptr_t align_mask = alignment-1; // for any x, `(x & align_mask) == (x % alignment)`
+ const size_t padsize = size + MI_PADDING_SIZE; // note: cannot overflow due to earlier size > PTRDIFF_MAX check
+
+ // try first if there happens to be a small block available with just the right alignment
+ if (mi_likely(padsize <= MI_SMALL_SIZE_MAX)) {
+ mi_page_t* page = _mi_heap_get_free_small_page(heap, padsize);
+ const bool is_aligned = (((uintptr_t)page->free+offset) & align_mask)==0;
+ if (mi_likely(page->free != NULL && is_aligned))
+ {
+ #if MI_STAT>1
+ mi_heap_stat_increase(heap, malloc, size);
+ #endif
+ void* p = _mi_page_malloc(heap, page, padsize); // TODO: inline _mi_page_malloc
+ mi_assert_internal(p != NULL);
+ mi_assert_internal(((uintptr_t)p + offset) % alignment == 0);
+ if (zero) { _mi_block_zero_init(page, p, size); }
+ return p;
+ }
+ }
+ // fallback
+ return mi_heap_malloc_zero_aligned_at_fallback(heap, size, alignment, offset, zero);
+}
+
+
+// ------------------------------------------------------
+// Optimized mi_heap_malloc_aligned / mi_malloc_aligned
+// ------------------------------------------------------
mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false);
}
mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {
- return mi_heap_malloc_aligned_at(heap, size, alignment, 0);
+ #if !MI_PADDING
+ // without padding, any small sized allocation is naturally aligned (see also `_mi_segment_page_start`)
+ if (!_mi_is_power_of_two(alignment)) return NULL;
+ if (mi_likely(_mi_is_power_of_two(size) && size >= alignment && size <= MI_SMALL_SIZE_MAX))
+ #else
+ // with padding, we can only guarantee this for fixed alignments
+ if (mi_likely((alignment == sizeof(void*) || (alignment == MI_MAX_ALIGN_SIZE && size > (MI_MAX_ALIGN_SIZE/2)))
+ && size <= MI_SMALL_SIZE_MAX))
+ #endif
+ {
+ // fast path for common alignment and size
+ return mi_heap_malloc_small(heap, size);
+ }
+ else {
+ return mi_heap_malloc_aligned_at(heap, size, alignment, 0);
+ }
}
+// ------------------------------------------------------
+// Aligned Allocation
+// ------------------------------------------------------
+
mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true);
}
}
+// ------------------------------------------------------
+// Aligned re-allocation
+// ------------------------------------------------------
+
static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept {
mi_assert(alignment > 0);
if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero);
memset((uint8_t*)newp + start, 0, newsize - start);
}
}
- memcpy(newp, p, (newsize > size ? size : newsize));
+ _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize));
mi_free(p); // only free if successful
}
return newp;
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2022, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
/* ------------------------------------------------------
Override system malloc on macOS
This is done through the malloc zone interface.
- It seems we also need to interpose (see `alloc-override.c`)
- or otherwise we get zone errors as there are usually
- already allocations done by the time we take over the
- zone. Unfortunately, that means we need to replace
- the `free` with a checked free (`cfree`) impacting
- performance.
+ It seems to be most robust in combination with interposing
+ though or otherwise we may get zone errors as there are could
+ be allocations done by the time we take over the
+ zone.
------------------------------------------------------ */
#include <AvailabilityMacros.h>
#include <malloc/malloc.h>
#include <string.h> // memset
+#include <stdlib.h>
-#if defined(MAC_OS_X_VERSION_10_6) && \
- MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
// only available from OSX 10.6
extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import));
#endif
-
/* ------------------------------------------------------
malloc zone members
------------------------------------------------------ */
static size_t zone_size(malloc_zone_t* zone, const void* p) {
- UNUSED(zone);
- if (!mi_is_in_heap_region(p))
- return 0; // not our pointer, bail out
-
+ MI_UNUSED(zone);
+ if (!mi_is_in_heap_region(p)){ return 0; } // not our pointer, bail out
return mi_usable_size(p);
}
static void* zone_malloc(malloc_zone_t* zone, size_t size) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return mi_malloc(size);
}
static void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return mi_calloc(count, size);
}
static void* zone_valloc(malloc_zone_t* zone, size_t size) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return mi_malloc_aligned(size, _mi_os_page_size());
}
static void zone_free(malloc_zone_t* zone, void* p) {
- UNUSED(zone);
- return mi_free(p);
+ MI_UNUSED(zone);
+ mi_cfree(p);
}
static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return mi_realloc(p, newsize);
}
static void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return mi_malloc_aligned(size,alignment);
}
static void zone_destroy(malloc_zone_t* zone) {
- UNUSED(zone);
+ MI_UNUSED(zone);
// todo: ignore for now?
}
}
static size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) {
- UNUSED(zone); UNUSED(size);
+ MI_UNUSED(zone); MI_UNUSED(size);
mi_collect(false);
return 0;
}
static void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) {
- UNUSED(size);
+ MI_UNUSED(size);
zone_free(zone,p);
}
+static boolean_t zone_claimed_address(malloc_zone_t* zone, void* p) {
+ MI_UNUSED(zone);
+ return mi_is_in_heap_region(p);
+}
+
/* ------------------------------------------------------
Introspection members
vm_range_recorder_t recorder)
{
// todo: enumerate all memory
- UNUSED(task); UNUSED(p); UNUSED(type_mask); UNUSED(zone_address);
- UNUSED(reader); UNUSED(recorder);
+ MI_UNUSED(task); MI_UNUSED(p); MI_UNUSED(type_mask); MI_UNUSED(zone_address);
+ MI_UNUSED(reader); MI_UNUSED(recorder);
return KERN_SUCCESS;
}
static size_t intro_good_size(malloc_zone_t* zone, size_t size) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return mi_good_size(size);
}
static boolean_t intro_check(malloc_zone_t* zone) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return true;
}
static void intro_print(malloc_zone_t* zone, boolean_t verbose) {
- UNUSED(zone); UNUSED(verbose);
+ MI_UNUSED(zone); MI_UNUSED(verbose);
mi_stats_print(NULL);
}
static void intro_log(malloc_zone_t* zone, void* p) {
- UNUSED(zone); UNUSED(p);
+ MI_UNUSED(zone); MI_UNUSED(p);
// todo?
}
static void intro_force_lock(malloc_zone_t* zone) {
- UNUSED(zone);
+ MI_UNUSED(zone);
// todo?
}
static void intro_force_unlock(malloc_zone_t* zone) {
- UNUSED(zone);
+ MI_UNUSED(zone);
// todo?
}
static void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) {
- UNUSED(zone);
+ MI_UNUSED(zone);
// todo...
stats->blocks_in_use = 0;
stats->size_in_use = 0;
}
static boolean_t intro_zone_locked(malloc_zone_t* zone) {
- UNUSED(zone);
+ MI_UNUSED(zone);
return false;
}
At process start, override the default allocator
------------------------------------------------------ */
-static malloc_zone_t* mi_get_default_zone()
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wc99-extensions"
+#endif
+
+static malloc_introspection_t mi_introspect = {
+ .enumerator = &intro_enumerator,
+ .good_size = &intro_good_size,
+ .check = &intro_check,
+ .print = &intro_print,
+ .log = &intro_log,
+ .force_lock = &intro_force_lock,
+ .force_unlock = &intro_force_unlock,
+#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+ .statistics = &intro_statistics,
+ .zone_locked = &intro_zone_locked,
+#endif
+};
+
+static malloc_zone_t mi_malloc_zone = {
+ // note: even with designators, the order is important for C++ compilation
+ //.reserved1 = NULL,
+ //.reserved2 = NULL,
+ .size = &zone_size,
+ .malloc = &zone_malloc,
+ .calloc = &zone_calloc,
+ .valloc = &zone_valloc,
+ .free = &zone_free,
+ .realloc = &zone_realloc,
+ .destroy = &zone_destroy,
+ .zone_name = "mimalloc",
+ .batch_malloc = &zone_batch_malloc,
+ .batch_free = &zone_batch_free,
+ .introspect = &mi_introspect,
+#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+ #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14)
+ .version = 10,
+ #else
+ .version = 9,
+ #endif
+ // switch to version 9+ on OSX 10.6 to support memalign.
+ .memalign = &zone_memalign,
+ .free_definite_size = &zone_free_definite_size,
+ .pressure_relief = &zone_pressure_relief,
+ #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14)
+ .claimed_address = &zone_claimed_address,
+ #endif
+#else
+ .version = 4,
+#endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined(MI_OSX_INTERPOSE) && defined(MI_SHARED_LIB_EXPORT)
+
+// ------------------------------------------------------
+// Override malloc_xxx and malloc_zone_xxx api's to use only
+// our mimalloc zone. Since even the loader uses malloc
+// on macOS, this ensures that all allocations go through
+// mimalloc (as all calls are interposed).
+// The main `malloc`, `free`, etc calls are interposed in `alloc-override.c`,
+// Here, we also override macOS specific API's like
+// `malloc_zone_calloc` etc. see <https://github.com/aosm/libmalloc/blob/master/man/malloc_zone_malloc.3>
+// ------------------------------------------------------
+
+static inline malloc_zone_t* mi_get_default_zone(void)
+{
+ static bool init;
+ if (mi_unlikely(!init)) {
+ init = true;
+ malloc_zone_register(&mi_malloc_zone); // by calling register we avoid a zone error on free (see <http://eatmyrandom.blogspot.com/2010/03/mallocfree-interception-on-mac-os-x.html>)
+ }
+ return &mi_malloc_zone;
+}
+
+mi_decl_externc int malloc_jumpstart(uintptr_t cookie);
+mi_decl_externc void _malloc_fork_prepare(void);
+mi_decl_externc void _malloc_fork_parent(void);
+mi_decl_externc void _malloc_fork_child(void);
+
+
+static malloc_zone_t* mi_malloc_create_zone(vm_size_t size, unsigned flags) {
+ MI_UNUSED(size); MI_UNUSED(flags);
+ return mi_get_default_zone();
+}
+
+static malloc_zone_t* mi_malloc_default_zone (void) {
+ return mi_get_default_zone();
+}
+
+static malloc_zone_t* mi_malloc_default_purgeable_zone(void) {
+ return mi_get_default_zone();
+}
+
+static void mi_malloc_destroy_zone(malloc_zone_t* zone) {
+ MI_UNUSED(zone);
+ // nothing.
+}
+
+static kern_return_t mi_malloc_get_all_zones (task_t task, memory_reader_t mr, vm_address_t** addresses, unsigned* count) {
+ MI_UNUSED(task); MI_UNUSED(mr);
+ if (addresses != NULL) *addresses = NULL;
+ if (count != NULL) *count = 0;
+ return KERN_SUCCESS;
+}
+
+static const char* mi_malloc_get_zone_name(malloc_zone_t* zone) {
+ return (zone == NULL ? mi_malloc_zone.zone_name : zone->zone_name);
+}
+
+static void mi_malloc_set_zone_name(malloc_zone_t* zone, const char* name) {
+ MI_UNUSED(zone); MI_UNUSED(name);
+}
+
+static int mi_malloc_jumpstart(uintptr_t cookie) {
+ MI_UNUSED(cookie);
+ return 1; // or 0 for no error?
+}
+
+static void mi__malloc_fork_prepare(void) {
+ // nothing
+}
+static void mi__malloc_fork_parent(void) {
+ // nothing
+}
+static void mi__malloc_fork_child(void) {
+ // nothing
+}
+
+static void mi_malloc_printf(const char* fmt, ...) {
+ MI_UNUSED(fmt);
+}
+
+static bool zone_check(malloc_zone_t* zone) {
+ MI_UNUSED(zone);
+ return true;
+}
+
+static malloc_zone_t* zone_from_ptr(const void* p) {
+ MI_UNUSED(p);
+ return mi_get_default_zone();
+}
+
+static void zone_log(malloc_zone_t* zone, void* p) {
+ MI_UNUSED(zone); MI_UNUSED(p);
+}
+
+static void zone_print(malloc_zone_t* zone, bool b) {
+ MI_UNUSED(zone); MI_UNUSED(b);
+}
+
+static void zone_print_ptr_info(void* p) {
+ MI_UNUSED(p);
+}
+
+static void zone_register(malloc_zone_t* zone) {
+ MI_UNUSED(zone);
+}
+
+static void zone_unregister(malloc_zone_t* zone) {
+ MI_UNUSED(zone);
+}
+
+// use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1`
+// See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73>
+struct mi_interpose_s {
+ const void* replacement;
+ const void* target;
+};
+#define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun }
+#define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun)
+#define MI_INTERPOSE_ZONE(fun) MI_INTERPOSE_FUN(malloc_##fun,fun)
+__attribute__((used)) static const struct mi_interpose_s _mi_zone_interposes[] __attribute__((section("__DATA, __interpose"))) =
+{
+
+ MI_INTERPOSE_MI(malloc_create_zone),
+ MI_INTERPOSE_MI(malloc_default_purgeable_zone),
+ MI_INTERPOSE_MI(malloc_default_zone),
+ MI_INTERPOSE_MI(malloc_destroy_zone),
+ MI_INTERPOSE_MI(malloc_get_all_zones),
+ MI_INTERPOSE_MI(malloc_get_zone_name),
+ MI_INTERPOSE_MI(malloc_jumpstart),
+ MI_INTERPOSE_MI(malloc_printf),
+ MI_INTERPOSE_MI(malloc_set_zone_name),
+ MI_INTERPOSE_MI(_malloc_fork_child),
+ MI_INTERPOSE_MI(_malloc_fork_parent),
+ MI_INTERPOSE_MI(_malloc_fork_prepare),
+
+ MI_INTERPOSE_ZONE(zone_batch_free),
+ MI_INTERPOSE_ZONE(zone_batch_malloc),
+ MI_INTERPOSE_ZONE(zone_calloc),
+ MI_INTERPOSE_ZONE(zone_check),
+ MI_INTERPOSE_ZONE(zone_free),
+ MI_INTERPOSE_ZONE(zone_from_ptr),
+ MI_INTERPOSE_ZONE(zone_log),
+ MI_INTERPOSE_ZONE(zone_malloc),
+ MI_INTERPOSE_ZONE(zone_memalign),
+ MI_INTERPOSE_ZONE(zone_print),
+ MI_INTERPOSE_ZONE(zone_print_ptr_info),
+ MI_INTERPOSE_ZONE(zone_realloc),
+ MI_INTERPOSE_ZONE(zone_register),
+ MI_INTERPOSE_ZONE(zone_unregister),
+ MI_INTERPOSE_ZONE(zone_valloc)
+};
+
+
+#else
+
+// ------------------------------------------------------
+// hook into the zone api's without interposing
+// This is the official way of adding an allocator but
+// it seems less robust than using interpose.
+// ------------------------------------------------------
+
+static inline malloc_zone_t* mi_get_default_zone(void)
{
// The first returned zone is the real default
malloc_zone_t** zones = NULL;
}
}
-static void __attribute__((constructor)) _mi_macos_override_malloc()
-{
- static malloc_introspection_t intro;
- memset(&intro, 0, sizeof(intro));
-
- intro.enumerator = &intro_enumerator;
- intro.good_size = &intro_good_size;
- intro.check = &intro_check;
- intro.print = &intro_print;
- intro.log = &intro_log;
- intro.force_lock = &intro_force_lock;
- intro.force_unlock = &intro_force_unlock;
-
- static malloc_zone_t zone;
- memset(&zone, 0, sizeof(zone));
-
- zone.version = 4;
- zone.zone_name = "mimalloc";
- zone.size = &zone_size;
- zone.introspect = &intro;
- zone.malloc = &zone_malloc;
- zone.calloc = &zone_calloc;
- zone.valloc = &zone_valloc;
- zone.free = &zone_free;
- zone.realloc = &zone_realloc;
- zone.destroy = &zone_destroy;
- zone.batch_malloc = &zone_batch_malloc;
- zone.batch_free = &zone_batch_free;
-
+#if defined(__clang__)
+__attribute__((constructor(0)))
+#else
+__attribute__((constructor)) // seems not supported by g++-11 on the M1
+#endif
+static void _mi_macos_override_malloc() {
malloc_zone_t* purgeable_zone = NULL;
-#if defined(MAC_OS_X_VERSION_10_6) && \
- MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
- // switch to version 9 on OSX 10.6 to support memalign.
- zone.version = 9;
- zone.memalign = &zone_memalign;
- zone.free_definite_size = &zone_free_definite_size;
- zone.pressure_relief = &zone_pressure_relief;
- intro.zone_locked = &intro_zone_locked;
- intro.statistics = &intro_statistics;
-
+ #if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
// force the purgeable zone to exist to avoid strange bugs
if (malloc_default_purgeable_zone) {
purgeable_zone = malloc_default_purgeable_zone();
}
-#endif
-
- // Register our zone
- malloc_zone_register(&zone);
+ #endif
+ // Register our zone.
+ // thomcc: I think this is still needed to put us in the zone list.
+ malloc_zone_register(&mi_malloc_zone);
// Unregister the default zone, this makes our zone the new default
// as that was the last registered.
malloc_zone_t *default_zone = mi_get_default_zone();
- malloc_zone_unregister(default_zone);
+ // thomcc: Unsure if the next test is *always* false or just false in the
+ // cases I've tried. I'm also unsure if the code inside is needed. at all
+ if (default_zone != &mi_malloc_zone) {
+ malloc_zone_unregister(default_zone);
- // Reregister the default zone so free and realloc in that zone keep working.
- malloc_zone_register(default_zone);
+ // Reregister the default zone so free and realloc in that zone keep working.
+ malloc_zone_register(default_zone);
+ }
// Unregister, and re-register the purgeable_zone to avoid bugs if it occurs
// earlier than the default zone.
}
}
+#endif // MI_OSX_INTERPOSE
#endif // MI_MALLOC_OVERRIDE
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#error "It is only possible to override "malloc" on Windows when building as a DLL (and linking the C runtime as a DLL)"
#endif
-#if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) // || (defined(__MACH__) && !defined(MI_INTERPOSE)))
+#if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32))
+
+#if defined(__APPLE__)
+#include <AvailabilityMacros.h>
+mi_decl_externc void vfree(void* p);
+mi_decl_externc size_t malloc_size(const void* p);
+mi_decl_externc size_t malloc_good_size(size_t size);
+#endif
+
+// helper definition for C override of C++ new
+typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t;
// ------------------------------------------------------
// Override system malloc
// ------------------------------------------------------
-#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__)
- // use aliasing to alias the exported function to one of our `mi_` functions
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) && !defined(MI_VALGRIND)
+ // gcc, clang: use aliasing to alias the exported function to one of our `mi_` functions
#if (defined(__GNUC__) && __GNUC__ >= 9)
- #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun)))
+ #pragma GCC diagnostic ignored "-Wattributes" // or we get warnings that nodiscard is ignored on a forward
+ #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun)));
#else
- #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default")))
+ #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default")));
#endif
#define MI_FORWARD1(fun,x) MI_FORWARD(fun)
#define MI_FORWARD2(fun,x,y) MI_FORWARD(fun)
#define MI_FORWARD0(fun,x) MI_FORWARD(fun)
#define MI_FORWARD02(fun,x,y) MI_FORWARD(fun)
#else
- // use forwarding by calling our `mi_` function
+ // otherwise use forwarding by calling our `mi_` function
#define MI_FORWARD1(fun,x) { return fun(x); }
#define MI_FORWARD2(fun,x,y) { return fun(x,y); }
#define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); }
#define MI_FORWARD02(fun,x,y) { fun(x,y); }
#endif
-#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE)
+#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_OSX_INTERPOSE)
+ // define MI_OSX_IS_INTERPOSED as we should not provide forwarding definitions for
+ // functions that are interposed (or the interposing does not work)
+ #define MI_OSX_IS_INTERPOSED
+
// use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1`
// See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73>
struct mi_interpose_s {
};
#define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun }
#define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun)
+
__attribute__((used)) static struct mi_interpose_s _mi_interposes[] __attribute__((section("__DATA, __interpose"))) =
{
MI_INTERPOSE_MI(malloc),
MI_INTERPOSE_MI(posix_memalign),
MI_INTERPOSE_MI(reallocf),
MI_INTERPOSE_MI(valloc),
- // some code allocates from a zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)
+ MI_INTERPOSE_MI(malloc_size),
+ MI_INTERPOSE_MI(malloc_good_size),
+ #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15
+ MI_INTERPOSE_MI(aligned_alloc),
+ #endif
+ #ifdef MI_OSX_ZONE
+ // we interpose malloc_default_zone in alloc-override-osx.c so we can use mi_free safely
+ MI_INTERPOSE_MI(free),
+ MI_INTERPOSE_FUN(vfree,mi_free),
+ #else
+ // sometimes code allocates from default zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)
MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us
+ MI_INTERPOSE_FUN(vfree,mi_cfree),
+ #endif
+ };
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ void _ZdlPv(void* p); // delete
+ void _ZdaPv(void* p); // delete[]
+ void _ZdlPvm(void* p, size_t n); // delete
+ void _ZdaPvm(void* p, size_t n); // delete[]
+ void* _Znwm(size_t n); // new
+ void* _Znam(size_t n); // new[]
+ void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow
+ void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow
+ #ifdef __cplusplus
+ }
+ #endif
+ __attribute__((used)) static struct mi_interpose_s _mi_cxx_interposes[] __attribute__((section("__DATA, __interpose"))) =
+ {
+ MI_INTERPOSE_FUN(_ZdlPv,mi_free),
+ MI_INTERPOSE_FUN(_ZdaPv,mi_free),
+ MI_INTERPOSE_FUN(_ZdlPvm,mi_free_size),
+ MI_INTERPOSE_FUN(_ZdaPvm,mi_free_size),
+ MI_INTERPOSE_FUN(_Znwm,mi_new),
+ MI_INTERPOSE_FUN(_Znam,mi_new),
+ MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow),
+ MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow),
};
+
#elif defined(_MSC_VER)
// cannot override malloc unless using a dll.
// we just override new/delete which does work in a static library.
#else
- // On all other systems forward to our API
- void* malloc(size_t size) MI_FORWARD1(mi_malloc, size);
- void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n);
- void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize);
- void free(void* p) MI_FORWARD0(mi_free, p);
+ // On all other systems forward to our API
+ void* malloc(size_t size) MI_FORWARD1(mi_malloc, size)
+ void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n)
+ void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize)
+ void free(void* p) MI_FORWARD0(mi_free, p)
#endif
-#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__)
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__)
#pragma GCC visibility push(default)
#endif
// see <https://en.cppreference.com/w/cpp/memory/new/operator_new>
// ------------------------------------------------------
#include <new>
- void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p);
- void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p);
- void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n);
- void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n);
+ #ifndef MI_OSX_IS_INTERPOSED
+ void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p)
+ void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p)
+
+ void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n)
+ void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n)
- void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); }
- void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); }
+ void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); }
+ void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); }
- #if (__cplusplus >= 201402L || _MSC_VER >= 1916)
- void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n);
- void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n);
+ #if (__cplusplus >= 201402L || _MSC_VER >= 1916)
+ void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n)
+ void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n)
+ #endif
#endif
#if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5))
void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
-
+ void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
+ void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
+
void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
#endif
-#elif (defined(__GNUC__) || defined(__clang__))
+#elif (defined(__GNUC__) || defined(__clang__))
// ------------------------------------------------------
// Override by defining the mangled C++ names of the operators (as
// used by GCC and CLang).
// See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling>
// ------------------------------------------------------
- void _ZdlPv(void* p) MI_FORWARD0(mi_free,p); // delete
- void _ZdaPv(void* p) MI_FORWARD0(mi_free,p); // delete[]
- void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n);
- void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n);
+
+ void _ZdlPv(void* p) MI_FORWARD0(mi_free,p) // delete
+ void _ZdaPv(void* p) MI_FORWARD0(mi_free,p) // delete[]
+ void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n)
+ void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n)
void _ZdlPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); }
void _ZdaPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); }
void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); }
void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); }
-
- typedef struct mi_nothrow_s { } mi_nothrow_t;
+
#if (MI_INTPTR_SIZE==8)
- void* _Znwm(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit
- void* _Znam(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit
- void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al);
- void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al);
- void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); }
- void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); }
- void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
- void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
+ void* _Znwm(size_t n) MI_FORWARD1(mi_new,n) // new 64-bit
+ void* _Znam(size_t n) MI_FORWARD1(mi_new,n) // new[] 64-bit
+ void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }
+ void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }
+ void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al)
+ void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al)
+ void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
+ void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
#elif (MI_INTPTR_SIZE==4)
- void* _Znwj(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit
- void* _Znaj(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit
- void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al);
- void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al);
- void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); }
- void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); }
- void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
- void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
+ void* _Znwj(size_t n) MI_FORWARD1(mi_new,n) // new 64-bit
+ void* _Znaj(size_t n) MI_FORWARD1(mi_new,n) // new[] 64-bit
+ void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }
+ void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }
+ void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al)
+ void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al)
+ void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
+ void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }
#else
- #error "define overloads for new/delete for this platform (just for performance, can be skipped)"
+ #error "define overloads for new/delete for this platform (just for performance, can be skipped)"
#endif
#endif // __cplusplus
+// ------------------------------------------------------
+// Further Posix & Unix functions definitions
+// ------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
-// ------------------------------------------------------
-// Posix & Unix functions definitions
-// ------------------------------------------------------
+#ifndef MI_OSX_IS_INTERPOSED
+ // Forward Posix/Unix calls as well
+ void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize)
+ size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p)
+ #if !defined(__ANDROID__) && !defined(__FreeBSD__)
+ size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p)
+ #else
+ size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p)
+ #endif
-void cfree(void* p) MI_FORWARD0(mi_free, p);
-void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize);
-size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p);
-#if !defined(__ANDROID__)
-size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p);
-#else
-size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p);
+ // No forwarding here due to aliasing/name mangling issues
+ void* valloc(size_t size) { return mi_valloc(size); }
+ void vfree(void* p) { mi_free(p); }
+ size_t malloc_good_size(size_t size) { return mi_malloc_good_size(size); }
+ int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); }
+
+ // `aligned_alloc` is only available when __USE_ISOC11 is defined.
+ // Note: Conda has a custom glibc where `aligned_alloc` is declared `static inline` and we cannot
+ // override it, but both _ISOC11_SOURCE and __USE_ISOC11 are undefined in Conda GCC7 or GCC9.
+ // Fortunately, in the case where `aligned_alloc` is declared as `static inline` it
+ // uses internally `memalign`, `posix_memalign`, or `_aligned_malloc` so we can avoid overriding it ourselves.
+ #if __USE_ISOC11
+ void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }
+ #endif
#endif
// no forwarding here due to aliasing/name mangling issues
-void* valloc(size_t size) { return mi_valloc(size); }
-void* pvalloc(size_t size) { return mi_pvalloc(size); }
-void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); }
-void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); }
-int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); }
-void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }
-
-// on some glibc `aligned_alloc` is declared `static inline` so we cannot override it (e.g. Conda). This happens
-// when _GLIBCXX_HAVE_ALIGNED_ALLOC is not defined. However, in those cases it will use `memalign`, `posix_memalign`,
-// or `_aligned_malloc` and we can avoid overriding it ourselves.
-// We should always override if using C compilation. (issue #276)
-#if _GLIBCXX_HAVE_ALIGNED_ALLOC || !defined(__cplusplus)
-void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }
-#endif
-
+void cfree(void* p) { mi_free(p); }
+void* pvalloc(size_t size) { return mi_pvalloc(size); }
+void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); }
+int reallocarr(void* p, size_t count, size_t size) { return mi_reallocarr(p, count, size); }
+void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); }
+void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }
#if defined(__GLIBC__) && defined(__linux__)
// forward __libc interface (needed for glibc-based Linux distributions)
- void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size);
- void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size);
- void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size);
- void __libc_free(void* p) MI_FORWARD0(mi_free,p);
- void __libc_cfree(void* p) MI_FORWARD0(mi_free,p);
-
- void* __libc_valloc(size_t size) { return mi_valloc(size); }
- void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); }
- void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); }
+ void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size)
+ void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size)
+ void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size)
+ void __libc_free(void* p) MI_FORWARD0(mi_free,p)
+ void __libc_cfree(void* p) MI_FORWARD0(mi_free,p)
+
+ void* __libc_valloc(size_t size) { return mi_valloc(size); }
+ void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); }
+ void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); }
int __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); }
#endif
}
#endif
-#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__)
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__)
#pragma GCC visibility pop
#endif
/* ----------------------------------------------------------------------------
-Copyright (c) 2018,2019, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
// ------------------------------------------------------
#include <errno.h>
-#include <string.h> // memcpy
+#include <string.h> // memset
#include <stdlib.h> // getenv
+#ifdef _MSC_VER
+#pragma warning(disable:4996) // getenv _wgetenv
+#endif
+
#ifndef EINVAL
#define EINVAL 22
#endif
#endif
-size_t mi_malloc_size(const void* p) mi_attr_noexcept {
+mi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept {
+ //if (!mi_is_in_heap_region(p)) return 0;
return mi_usable_size(p);
}
-size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept {
+mi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept {
+ //if (!mi_is_in_heap_region(p)) return 0;
return mi_usable_size(p);
}
+mi_decl_nodiscard size_t mi_malloc_good_size(size_t size) mi_attr_noexcept {
+ return mi_good_size(size);
+}
+
void mi_cfree(void* p) mi_attr_noexcept {
if (mi_is_in_heap_region(p)) {
mi_free(p);
// Note: The spec dictates we should not modify `*p` on an error. (issue#27)
// <http://man7.org/linux/man-pages/man3/posix_memalign.3.html>
if (p == NULL) return EINVAL;
- if (alignment % sizeof(void*) != 0) return EINVAL; // natural alignment
- if (!_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2
- void* q = (mi_malloc_satisfies_alignment(alignment, size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment));
+ if (alignment % sizeof(void*) != 0) return EINVAL; // natural alignment
+ if (alignment==0 || !_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2
+ void* q = mi_malloc_aligned(size, alignment);
if (q==NULL && size != 0) return ENOMEM;
mi_assert_internal(((uintptr_t)q % alignment) == 0);
*p = q;
return 0;
}
-mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept {
- void* p = (mi_malloc_satisfies_alignment(alignment,size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment));
+mi_decl_nodiscard mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept {
+ void* p = mi_malloc_aligned(size, alignment);
mi_assert_internal(((uintptr_t)p % alignment) == 0);
return p;
}
-mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept {
+mi_decl_nodiscard mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept {
return mi_memalign( _mi_os_page_size(), size );
}
-mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept {
+mi_decl_nodiscard mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept {
size_t psize = _mi_os_page_size();
if (size >= SIZE_MAX - psize) return NULL; // overflow
size_t asize = _mi_align_up(size, psize);
return mi_malloc_aligned(asize, psize);
}
-mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {
- if (alignment==0 || !_mi_is_power_of_two(alignment)) return NULL;
- if ((size&(alignment-1)) != 0) return NULL; // C11 requires integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>
- void* p = (mi_malloc_satisfies_alignment(alignment, size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment));
+mi_decl_nodiscard mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {
+ if (mi_unlikely((size&(alignment-1)) != 0)) { // C11 requires alignment>0 && integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>
+ #if MI_DEBUG > 0
+ _mi_error_message(EOVERFLOW, "(mi_)aligned_alloc requires the size to be an integral multiple of the alignment (size %zu, alignment %zu)\n", size, alignment);
+ #endif
+ return NULL;
+ }
+ // C11 also requires alignment to be a power-of-two which is checked in mi_malloc_aligned
+ void* p = mi_malloc_aligned(size, alignment);
mi_assert_internal(((uintptr_t)p % alignment) == 0);
return p;
}
-void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD
+mi_decl_nodiscard void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD
void* newp = mi_reallocn(p,count,size);
- if (newp==NULL) errno = ENOMEM;
+ if (newp==NULL) { errno = ENOMEM; }
return newp;
}
+mi_decl_nodiscard int mi_reallocarr( void* p, size_t count, size_t size ) mi_attr_noexcept { // NetBSD
+ mi_assert(p != NULL);
+ if (p == NULL) {
+ errno = EINVAL;
+ return EINVAL;
+ }
+ void** op = (void**)p;
+ void* newp = mi_reallocarray(*op, count, size);
+ if (mi_unlikely(newp == NULL)) return errno;
+ *op = newp;
+ return 0;
+}
+
void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft
void* res = mi_expand(p, newsize);
- if (res == NULL) errno = ENOMEM;
+ if (res == NULL) { errno = ENOMEM; }
return res;
}
-mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept {
+mi_decl_nodiscard mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept {
if (s==NULL) return NULL;
size_t len;
for(len = 0; s[len] != 0; len++) { }
size_t size = (len+1)*sizeof(unsigned short);
unsigned short* p = (unsigned short*)mi_malloc(size);
if (p != NULL) {
- memcpy(p,s,size);
+ _mi_memcpy(p,s,size);
}
return p;
}
-mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept {
+mi_decl_nodiscard mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept {
return (unsigned char*)mi_strdup((const char*)s);
}
int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept {
if (buf==NULL || name==NULL) return EINVAL;
if (size != NULL) *size = 0;
- #pragma warning(suppress:4996)
- char* p = getenv(name);
+ char* p = getenv(name); // mscver warning 4996
if (p==NULL) {
*buf = NULL;
}
*buf = NULL;
return EINVAL;
#else
- #pragma warning(suppress:4996)
- unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name);
+ unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name); // msvc warning 4996
if (p==NULL) {
*buf = NULL;
}
#endif
}
-void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft
+mi_decl_nodiscard void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft
return mi_recalloc_aligned_at(p, newcount, size, alignment, offset);
}
-void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft
+mi_decl_nodiscard void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft
return mi_recalloc_aligned(p, newcount, size, alignment);
}
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2022, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE // for realpath() on Linux
+#endif
+
#include "mimalloc.h"
#include "mimalloc-internal.h"
#include "mimalloc-atomic.h"
-#include <string.h> // memset, memcpy, strlen
+#include <string.h> // memset, strlen
#include <stdlib.h> // malloc, exit
#define MI_IN_ALLOC_C
// Fall back to generic allocation only if the list is empty.
extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept {
mi_assert_internal(page->xblock_size==0||mi_page_block_size(page) >= size);
- mi_block_t* block = page->free;
+ mi_block_t* const block = page->free;
if (mi_unlikely(block == NULL)) {
return _mi_malloc_generic(heap, size);
}
mi_assert_internal(block != NULL && _mi_ptr_page(block) == page);
// pop from the free list
- page->free = mi_block_next(page, block);
page->used++;
+ page->free = mi_block_next(page, block);
mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page);
+
#if (MI_DEBUG>0)
if (!page->is_zero) { memset(block, MI_DEBUG_UNINIT, size); }
#elif (MI_SECURE!=0)
block->next = 0; // don't leak internal data
#endif
-#if (MI_STAT>1)
+
+#if (MI_STAT>0)
const size_t bsize = mi_page_usable_block_size(page);
- if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
+ if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) {
+ mi_heap_stat_increase(heap, normal, bsize);
+ mi_heap_stat_counter_increase(heap, normal_count, 1);
+#if (MI_STAT>1)
const size_t bin = _mi_bin(bsize);
- mi_heap_stat_increase(heap, normal[bin], 1);
+ mi_heap_stat_increase(heap, normal_bins[bin], 1);
+#endif
}
#endif
+
#if (MI_PADDING > 0) && defined(MI_ENCODE_FREELIST)
mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page));
ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE));
const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes
for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; }
#endif
+
return block;
}
void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size) {
// note: we need to initialize the whole usable block size to zero, not just the requested size,
// or the recalloc/rezalloc functions cannot safely expand in place (see issue #63)
- UNUSED(size);
+ MI_UNUSED(size);
mi_assert_internal(p != NULL);
mi_assert_internal(mi_usable_size(p) >= size); // size can be zero
mi_assert_internal(_mi_ptr_page(p)==page);
return p;
}
-void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) {
+void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept {
void* p = mi_heap_malloc(heap,size);
if (zero && p != NULL) {
_mi_block_zero_init(_mi_ptr_page(p),p,size); // todo: can we avoid getting the page again?
}
#else
static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {
- UNUSED(page);
- UNUSED(block);
+ MI_UNUSED(page);
+ MI_UNUSED(block);
return false;
}
#endif
}
#else
static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {
- UNUSED(page);
- UNUSED(block);
+ MI_UNUSED(page);
+ MI_UNUSED(block);
}
static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) {
- UNUSED(block);
+ MI_UNUSED(block);
return mi_page_usable_block_size(page);
}
static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {
- UNUSED(page);
- UNUSED(block);
- UNUSED(min_size);
+ MI_UNUSED(page);
+ MI_UNUSED(block);
+ MI_UNUSED(min_size);
+}
+#endif
+
+// only maintain stats for smaller objects if requested
+#if (MI_STAT>0)
+static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {
+ #if (MI_STAT < 2)
+ MI_UNUSED(block);
+ #endif
+ mi_heap_t* const heap = mi_heap_get_default();
+ const size_t bsize = mi_page_usable_block_size(page);
+ #if (MI_STAT>1)
+ const size_t usize = mi_page_usable_size_of(page, block);
+ mi_heap_stat_decrease(heap, malloc, usize);
+ #endif
+ if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) {
+ mi_heap_stat_decrease(heap, normal, bsize);
+ #if (MI_STAT > 1)
+ mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], 1);
+ #endif
+ }
+ else if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
+ mi_heap_stat_decrease(heap, large, bsize);
+ }
+ else {
+ mi_heap_stat_decrease(heap, huge, bsize);
+ }
+}
+#else
+static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {
+ MI_UNUSED(page); MI_UNUSED(block);
+}
+#endif
+
+#if (MI_STAT>0)
+// maintain stats for huge objects
+static void mi_stat_huge_free(const mi_page_t* page) {
+ mi_heap_t* const heap = mi_heap_get_default();
+ const size_t bsize = mi_page_block_size(page); // to match stats in `page.c:mi_page_huge_alloc`
+ if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
+ mi_heap_stat_decrease(heap, large, bsize);
+ }
+ else {
+ mi_heap_stat_decrease(heap, huge, bsize);
+ }
+}
+#else
+static void mi_stat_huge_free(const mi_page_t* page) {
+ MI_UNUSED(page);
}
#endif
#endif
// huge page segments are always abandoned and can be freed immediately
- mi_segment_t* const segment = _mi_page_segment(page);
- if (segment->page_kind==MI_PAGE_HUGE) {
+ mi_segment_t* segment = _mi_page_segment(page);
+ if (segment->kind==MI_SEGMENT_HUGE) {
+ mi_stat_huge_free(page);
_mi_segment_huge_page_free(segment, page, block);
return;
}
// Try to put the block on either the page-local thread free list, or the heap delayed free list.
- mi_thread_free_t tfree;
mi_thread_free_t tfreex;
bool use_delayed;
+ mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free);
do {
- tfree = mi_atomic_read_relaxed(&page->xthread_free);
use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE);
if (mi_unlikely(use_delayed)) {
// unlikely: this only happens on the first concurrent free in a page that is in the full list
mi_block_set_next(page, block, mi_tf_block(tfree));
tfreex = mi_tf_set_block(tfree,block);
}
- } while (!mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree));
+ } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));
if (mi_unlikely(use_delayed)) {
// racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`)
- mi_heap_t* const heap = mi_page_heap(page);
+ mi_heap_t* const heap = (mi_heap_t*)(mi_atomic_load_acquire(&page->xheap)); //mi_page_heap(page);
mi_assert_internal(heap != NULL);
if (heap != NULL) {
// add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity)
- mi_block_t* dfree;
+ mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);
do {
- dfree = mi_atomic_read_ptr_relaxed(mi_block_t,&heap->thread_delayed_free);
mi_block_set_nextx(heap,block,dfree, heap->keys);
- } while (!mi_atomic_cas_ptr_weak(mi_block_t,&heap->thread_delayed_free, block, dfree));
+ } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block));
}
// and reset the MI_DELAYED_FREEING flag
+ tfree = mi_atomic_load_relaxed(&page->xthread_free);
do {
- tfreex = tfree = mi_atomic_read_relaxed(&page->xthread_free);
+ tfreex = tfree;
mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING);
tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE);
- } while (!mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree));
+ } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));
}
}
-
// regular free
static inline void _mi_free_block(mi_page_t* page, bool local, mi_block_t* block)
{
}
-static void mi_decl_noinline mi_free_generic(const mi_segment_t* segment, bool local, void* p) {
+static void mi_decl_noinline mi_free_generic(const mi_segment_t* segment, bool local, void* p) mi_attr_noexcept {
mi_page_t* const page = _mi_segment_page_of(segment, p);
mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p);
+ mi_stat_free(page, block);
_mi_free_block(page, local, block);
}
// (and secure mode) if this was a valid pointer.
static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg)
{
- UNUSED(msg);
+ MI_UNUSED(msg);
#if (MI_DEBUG>0)
if (mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0)) {
_mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p);
#endif
#if (MI_DEBUG>0 || MI_SECURE>=4)
if (mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie)) {
- _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", p);
+ _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", msg, p);
+ return NULL;
}
#endif
return segment;
}
-
-// Free a block
+// Free a block
void mi_free(void* p) mi_attr_noexcept
{
- const mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free");
+ mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free");
if (mi_unlikely(segment == NULL)) return;
- const uintptr_t tid = _mi_thread_id();
+ mi_threadid_t tid = _mi_thread_id();
mi_page_t* const page = _mi_segment_page_of(segment, p);
- mi_block_t* const block = (mi_block_t*)p;
-
-#if (MI_STAT>1)
- mi_heap_t* const heap = mi_heap_get_default();
- const size_t bsize = mi_page_usable_block_size(page);
- mi_heap_stat_decrease(heap, malloc, bsize);
- if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { // huge page stats are accounted for in `_mi_page_retire`
- mi_heap_stat_decrease(heap, normal[_mi_bin(bsize)], 1);
- }
-#endif
-
- if (mi_likely(tid == segment->thread_id && page->flags.full_aligned == 0)) { // the thread id matches and it is not a full page, nor has aligned blocks
+
+ if (mi_likely(tid == mi_atomic_load_relaxed(&segment->thread_id) && page->flags.full_aligned == 0)) { // the thread id matches and it is not a full page, nor has aligned blocks
// local, and not full or aligned
+ mi_block_t* block = (mi_block_t*)(p);
if (mi_unlikely(mi_check_is_double_free(page,block))) return;
mi_check_padding(page, block);
+ mi_stat_free(page, block);
#if (MI_DEBUG!=0)
memset(block, MI_DEBUG_FREED, mi_page_block_size(page));
#endif
mi_block_set_next(page, block, page->local_free);
page->local_free = block;
- page->used--;
- if (mi_unlikely(mi_page_all_free(page))) {
+ if (mi_unlikely(--page->used == 0)) { // using this expression generates better code than: page->used--; if (mi_page_all_free(page))
_mi_page_retire(page);
}
}
}
// Bytes available in a block
-static size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept {
- const mi_segment_t* const segment = mi_checked_ptr_segment(p,msg);
- if (segment==NULL) return 0;
- const mi_page_t* const page = _mi_segment_page_of(segment, p);
- const mi_block_t* block = (const mi_block_t*)p;
- if (mi_unlikely(mi_page_has_aligned(page))) {
- block = _mi_page_ptr_unalign(segment, page, p);
- size_t size = mi_page_usable_size_of(page, block);
- ptrdiff_t const adjust = (uint8_t*)p - (uint8_t*)block;
- mi_assert_internal(adjust >= 0 && (size_t)adjust <= size);
- return (size - adjust);
+mi_decl_noinline static size_t mi_page_usable_aligned_size_of(const mi_segment_t* segment, const mi_page_t* page, const void* p) mi_attr_noexcept {
+ const mi_block_t* block = _mi_page_ptr_unalign(segment, page, p);
+ const size_t size = mi_page_usable_size_of(page, block);
+ const ptrdiff_t adjust = (uint8_t*)p - (uint8_t*)block;
+ mi_assert_internal(adjust >= 0 && (size_t)adjust <= size);
+ return (size - adjust);
+}
+
+static inline size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept {
+ const mi_segment_t* const segment = mi_checked_ptr_segment(p, msg);
+ if (segment==NULL) return 0; // also returns 0 if `p == NULL`
+ const mi_page_t* const page = _mi_segment_page_of(segment, p);
+ if (mi_likely(!mi_page_has_aligned(page))) {
+ const mi_block_t* block = (const mi_block_t*)p;
+ return mi_page_usable_size_of(page, block);
}
else {
- return mi_page_usable_size_of(page, block);
+ // split out to separate routine for improved code generation
+ return mi_page_usable_aligned_size_of(segment, page, p);
}
}
(void*)&_mi_page_malloc,
(void*)&mi_malloc,
(void*)&mi_malloc_small,
+ (void*)&mi_zalloc_small,
(void*)&mi_heap_malloc,
(void*)&mi_heap_zalloc,
(void*)&mi_heap_malloc_small
// ------------------------------------------------------
void mi_free_size(void* p, size_t size) mi_attr_noexcept {
- UNUSED_RELEASE(size);
+ MI_UNUSED_RELEASE(size);
mi_assert(p == NULL || size <= _mi_usable_size(p,"mi_free_size"));
mi_free(p);
}
void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept {
- UNUSED_RELEASE(alignment);
+ MI_UNUSED_RELEASE(alignment);
mi_assert(((uintptr_t)p % alignment) == 0);
mi_free_size(p,size);
}
void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept {
- UNUSED_RELEASE(alignment);
+ MI_UNUSED_RELEASE(alignment);
mi_assert(((uintptr_t)p % alignment) == 0);
mi_free(p);
}
return mi_heap_mallocn(mi_get_default_heap(),count,size);
}
-// Expand in place or fail
+// Expand (or shrink) in place (or fail)
void* mi_expand(void* p, size_t newsize) mi_attr_noexcept {
+ #if MI_PADDING
+ // we do not shrink/expand with padding enabled
+ MI_UNUSED(p); MI_UNUSED(newsize);
+ return NULL;
+ #else
if (p == NULL) return NULL;
- size_t size = _mi_usable_size(p,"mi_expand");
+ const size_t size = _mi_usable_size(p,"mi_expand");
if (newsize > size) return NULL;
return p; // it fits
+ #endif
}
-void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) {
- if (p == NULL) return _mi_heap_malloc_zero(heap,newsize,zero);
- size_t size = _mi_usable_size(p,"mi_realloc");
- if (newsize <= size && newsize >= (size / 2)) {
+void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept {
+ const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL
+ if (mi_unlikely(newsize <= size && newsize >= (size / 2))) {
+ // todo: adjust potential padding to reflect the new size?
return p; // reallocation still fits and not more than 50% waste
}
void* newp = mi_heap_malloc(heap,newsize);
if (mi_likely(newp != NULL)) {
if (zero && newsize > size) {
// also set last word in the previous allocation to zero to ensure any padding is zero-initialized
- size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);
+ const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);
memset((uint8_t*)newp + start, 0, newsize - start);
}
- memcpy(newp, p, (newsize > size ? size : newsize));
- mi_free(p); // only free if successful
+ if (mi_likely(p != NULL)) {
+ _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize));
+ mi_free(p); // only free the original pointer if successful
+ }
}
return newp;
}
void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
- return _mi_heap_realloc_zero(heap, p, newsize, false);
+ return _mi_heap_realloc_zero(heap, p, newsize, false);
}
void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {
if (s == NULL) return NULL;
size_t n = strlen(s);
char* t = (char*)mi_heap_malloc(heap,n+1);
- if (t != NULL) memcpy(t, s, n + 1);
+ if (t != NULL) _mi_memcpy(t, s, n + 1);
return t;
}
mi_assert_internal(m <= n);
char* t = (char*)mi_heap_malloc(heap, m+1);
if (t == NULL) return NULL;
- memcpy(t, s, m);
+ _mi_memcpy(t, s, m);
t[m] = 0;
return t;
}
}
#else
#include <unistd.h> // pathconf
-static size_t mi_path_max() {
+static size_t mi_path_max(void) {
static size_t path_max = 0;
if (path_max <= 0) {
long m = pathconf("/",_PC_PATH_MAX);
#ifdef __cplusplus
#include <new>
static bool mi_try_new_handler(bool nothrow) {
- std::new_handler h = std::get_new_handler();
+ #if defined(_MSC_VER) || (__cplusplus >= 201103L)
+ std::new_handler h = std::get_new_handler();
+ #else
+ std::new_handler h = std::set_new_handler();
+ std::set_new_handler(h);
+ #endif
if (h==NULL) {
- if (!nothrow) throw std::bad_alloc();
+ _mi_error_message(ENOMEM, "out of memory in 'new'");
+ if (!nothrow) {
+ throw std::bad_alloc();
+ }
return false;
}
else {
}
}
#else
-typedef void (*std_new_handler_t)();
+typedef void (*std_new_handler_t)(void);
#if (defined(__GNUC__) || defined(__clang__))
-std_new_handler_t __attribute((weak)) _ZSt15get_new_handlerv() {
+std_new_handler_t __attribute((weak)) _ZSt15get_new_handlerv(void) {
return NULL;
}
-std_new_handler_t mi_get_new_handler() {
+static std_new_handler_t mi_get_new_handler(void) {
return _ZSt15get_new_handlerv();
}
#else
// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`.
-std_new_handler_t mi_get_new_handler() {
+static std_new_handler_t mi_get_new_handler() {
return NULL;
}
#endif
static bool mi_try_new_handler(bool nothrow) {
std_new_handler_t h = mi_get_new_handler();
if (h==NULL) {
- if (!nothrow) exit(ENOMEM); // cannot throw in plain C, use exit as we are out of memory anyway.
+ _mi_error_message(ENOMEM, "out of memory in 'new'");
+ if (!nothrow) {
+ abort(); // cannot throw in plain C, use abort
+ }
return false;
}
else {
/* ----------------------------------------------------------------------------
-Copyright (c) 2019, Microsoft Research, Daan Leijen
+Copyright (c) 2019-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
/* ----------------------------------------------------------------------------
"Arenas" are fixed area's of OS memory from which we can allocate
-large blocks (>= MI_ARENA_BLOCK_SIZE, 32MiB).
+large blocks (>= MI_ARENA_MIN_BLOCK_SIZE, 4MiB).
In contrast to the rest of mimalloc, the arenas are shared between
threads and need to be accessed using atomic operations.
Currently arenas are only used to for huge OS page (1GiB) reservations,
-otherwise it delegates to direct allocation from the OS.
+or direct OS memory reservations -- otherwise it delegates to direct allocation from the OS.
In the future, we can expose an API to manually add more kinds of arenas
which is sometimes needed for embedded devices or shared memory for example.
(We can also employ this with WASI or `sbrk` systems to reserve large arenas
on demand and be able to reuse them efficiently).
-The arena allocation needs to be thread safe and we use an atomic
-bitmap to allocate. The current implementation of the bitmap can
-only do this within a field (`uintptr_t`) so we can allocate at most
-blocks of 2GiB (64*32MiB) and no object can cross the boundary. This
-can lead to fragmentation but fortunately most objects will be regions
-of 256MiB in practice.
+The arena allocation needs to be thread safe and we use an atomic bitmap to allocate.
-----------------------------------------------------------------------------*/
#include "mimalloc.h"
#include "mimalloc-internal.h"
#include "mimalloc-atomic.h"
#include <string.h> // memset
+#include <errno.h> // ENOMEM
-#include "bitmap.inc.c" // atomic bitmap
+#include "bitmap.h" // atomic bitmap
// os.c
-void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld);
+void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_stats_t* stats);
void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* stats);
-void _mi_os_free(void* p, size_t size, mi_stats_t* stats);
void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize);
void _mi_os_free_huge_pages(void* p, size_t size, mi_stats_t* stats);
bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats);
+bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats);
+
/* -----------------------------------------------------------
Arena allocation
----------------------------------------------------------- */
-#define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE
-#define MI_ARENA_BLOCK_SIZE (8*MI_SEGMENT_ALIGN) // 32MiB
-#define MI_ARENA_MAX_OBJ_SIZE (MI_BITMAP_FIELD_BITS * MI_ARENA_BLOCK_SIZE) // 2GiB
-#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2) // 16MiB
+
+// Block info: bit 0 contains the `in_use` bit, the upper bits the
+// size in count of arena blocks.
+typedef uintptr_t mi_block_info_t;
+#define MI_ARENA_BLOCK_SIZE (MI_SEGMENT_SIZE) // 8MiB (must be at least MI_SEGMENT_ALIGN)
+#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2) // 4MiB
#define MI_MAX_ARENAS (64) // not more than 256 (since we use 8 bits in the memid)
// A memory arena descriptor
size_t field_count; // number of bitmap fields (where `field_count * MI_BITMAP_FIELD_BITS >= block_count`)
int numa_node; // associated NUMA node
bool is_zero_init; // is the arena zero initialized?
- bool is_committed; // is the memory committed
- bool is_large; // large OS page allocated
- volatile _Atomic(uintptr_t) search_idx; // optimization to start the search for free blocks
+ bool allow_decommit; // is decommit allowed? if true, is_large should be false and blocks_committed != NULL
+ bool is_large; // large- or huge OS pages (always committed)
+ _Atomic(size_t) search_idx; // optimization to start the search for free blocks
mi_bitmap_field_t* blocks_dirty; // are the blocks potentially non-zero?
- mi_bitmap_field_t* blocks_committed; // if `!is_committed`, are the blocks committed?
- mi_bitmap_field_t blocks_inuse[1]; // in-place bitmap of in-use blocks (of size `field_count`)
+ mi_bitmap_field_t* blocks_committed; // are the blocks committed? (can be NULL for memory that cannot be decommitted)
+ mi_bitmap_field_t blocks_inuse[1]; // in-place bitmap of in-use blocks (of size `field_count`)
} mi_arena_t;
// The available arenas
static mi_decl_cache_align _Atomic(mi_arena_t*) mi_arenas[MI_MAX_ARENAS];
-static mi_decl_cache_align _Atomic(uintptr_t) mi_arena_count; // = 0
+static mi_decl_cache_align _Atomic(size_t) mi_arena_count; // = 0
/* -----------------------------------------------------------
----------------------------------------------------------- */
static bool mi_arena_alloc(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx)
{
- const size_t fcount = arena->field_count;
- size_t idx = mi_atomic_read(&arena->search_idx); // start from last search
- for (size_t visited = 0; visited < fcount; visited++, idx++) {
- if (idx >= fcount) idx = 0; // wrap around
- // try to atomically claim a range of bits
- if (mi_bitmap_try_find_claim_field(arena->blocks_inuse, idx, blocks, bitmap_idx)) {
- mi_atomic_write(&arena->search_idx, idx); // start search from here next time
- return true;
- }
- }
+ size_t idx = 0; // mi_atomic_load_relaxed(&arena->search_idx); // start from last search; ok to be relaxed as the exact start does not matter
+ if (_mi_bitmap_try_find_from_claim_across(arena->blocks_inuse, arena->field_count, idx, blocks, bitmap_idx)) {
+ mi_atomic_store_relaxed(&arena->search_idx, mi_bitmap_index_field(*bitmap_idx)); // start search from found location next time around
+ return true;
+ };
return false;
}
Arena Allocation
----------------------------------------------------------- */
-static void* mi_arena_alloc_from(mi_arena_t* arena, size_t arena_index, size_t needed_bcount,
- bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
+static mi_decl_noinline void* mi_arena_alloc_from(mi_arena_t* arena, size_t arena_index, size_t needed_bcount,
+ bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
{
mi_bitmap_index_t bitmap_index;
if (!mi_arena_alloc(arena, needed_bcount, &bitmap_index)) return NULL;
// claimed it! set the dirty bits (todo: no need for an atomic op here?)
- void* p = arena->start + (mi_bitmap_index_bit(bitmap_index)*MI_ARENA_BLOCK_SIZE);
- *memid = mi_arena_id_create(arena_index, bitmap_index);
- *is_zero = mi_bitmap_claim(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL);
- *large = arena->is_large;
- if (arena->is_committed) {
+ void* p = arena->start + (mi_bitmap_index_bit(bitmap_index)*MI_ARENA_BLOCK_SIZE);
+ *memid = mi_arena_id_create(arena_index, bitmap_index);
+ *is_zero = _mi_bitmap_claim_across(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL);
+ *large = arena->is_large;
+ *is_pinned = (arena->is_large || !arena->allow_decommit);
+ if (arena->blocks_committed == NULL) {
// always committed
*commit = true;
}
else if (*commit) {
// arena not committed as a whole, but commit requested: ensure commit now
bool any_uncommitted;
- mi_bitmap_claim(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted);
+ _mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted);
if (any_uncommitted) {
bool commit_zero;
_mi_os_commit(p, needed_bcount * MI_ARENA_BLOCK_SIZE, &commit_zero, tld->stats);
}
else {
// no need to commit, but check if already fully committed
- *commit = mi_bitmap_is_claimed(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index);
+ *commit = _mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index);
}
return p;
}
-void* _mi_arena_alloc_aligned(size_t size, size_t alignment,
- bool* commit, bool* large, bool* is_zero,
+static mi_decl_noinline void* mi_arena_allocate(int numa_node, size_t size, size_t alignment, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
+{
+ MI_UNUSED_RELEASE(alignment);
+ mi_assert_internal(alignment <= MI_SEGMENT_ALIGN);
+ const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count);
+ const size_t bcount = mi_block_count_of_size(size);
+ if (mi_likely(max_arena == 0)) return NULL;
+ mi_assert_internal(size <= bcount*MI_ARENA_BLOCK_SIZE);
+
+ // try numa affine allocation
+ for (size_t i = 0; i < max_arena; i++) {
+ mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]);
+ if (arena==NULL) break; // end reached
+ if ((arena->numa_node<0 || arena->numa_node==numa_node) && // numa local?
+ (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages
+ {
+ void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_pinned, is_zero, memid, tld);
+ mi_assert_internal((uintptr_t)p % alignment == 0);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ }
+
+ // try from another numa node instead..
+ for (size_t i = 0; i < max_arena; i++) {
+ mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]);
+ if (arena==NULL) break; // end reached
+ if ((arena->numa_node>=0 && arena->numa_node!=numa_node) && // not numa local!
+ (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages
+ {
+ void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_pinned, is_zero, memid, tld);
+ mi_assert_internal((uintptr_t)p % alignment == 0);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_pinned, bool* is_zero,
size_t* memid, mi_os_tld_t* tld)
{
- mi_assert_internal(commit != NULL && large != NULL && is_zero != NULL && memid != NULL && tld != NULL);
+ mi_assert_internal(commit != NULL && is_pinned != NULL && is_zero != NULL && memid != NULL && tld != NULL);
mi_assert_internal(size > 0);
*memid = MI_MEMID_OS;
*is_zero = false;
+ *is_pinned = false;
- // try to allocate in an arena if the alignment is small enough
- // and the object is not too large or too small.
- if (alignment <= MI_SEGMENT_ALIGN &&
- size <= MI_ARENA_MAX_OBJ_SIZE &&
- size >= MI_ARENA_MIN_OBJ_SIZE)
- {
- const size_t bcount = mi_block_count_of_size(size);
- const int numa_node = _mi_os_numa_node(tld); // current numa node
-
- mi_assert_internal(size <= bcount*MI_ARENA_BLOCK_SIZE);
- // try numa affine allocation
- for (size_t i = 0; i < MI_MAX_ARENAS; i++) {
- mi_arena_t* arena = mi_atomic_read_ptr_relaxed(mi_arena_t, &mi_arenas[i]);
- if (arena==NULL) break; // end reached
- if ((arena->numa_node<0 || arena->numa_node==numa_node) && // numa local?
- (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages
- {
- void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_zero, memid, tld);
- mi_assert_internal((uintptr_t)p % alignment == 0);
- if (p != NULL) return p;
- }
- }
- // try from another numa node instead..
- for (size_t i = 0; i < MI_MAX_ARENAS; i++) {
- mi_arena_t* arena = mi_atomic_read_ptr_relaxed(mi_arena_t, &mi_arenas[i]);
- if (arena==NULL) break; // end reached
- if ((arena->numa_node>=0 && arena->numa_node!=numa_node) && // not numa local!
- (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages
- {
- void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_zero, memid, tld);
- mi_assert_internal((uintptr_t)p % alignment == 0);
- if (p != NULL) return p;
- }
- }
+ bool default_large = false;
+ if (large==NULL) large = &default_large; // ensure `large != NULL`
+ const int numa_node = _mi_os_numa_node(tld); // current numa node
+
+ // try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data)
+ if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN) {
+ void* p = mi_arena_allocate(numa_node, size, alignment, commit, large, is_pinned, is_zero, memid, tld);
+ if (p != NULL) return p;
}
// finally, fall back to the OS
+ if (mi_option_is_enabled(mi_option_limit_os_alloc)) {
+ errno = ENOMEM;
+ return NULL;
+ }
*is_zero = true;
- *memid = MI_MEMID_OS;
- return _mi_os_alloc_aligned(size, alignment, *commit, large, tld);
+ *memid = MI_MEMID_OS;
+ void* p = _mi_os_alloc_aligned(size, alignment, *commit, large, tld->stats);
+ if (p != NULL) *is_pinned = *large;
+ return p;
}
-void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
+void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
{
- return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, commit, large, is_zero, memid, tld);
+ return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, commit, large, is_pinned, is_zero, memid, tld);
}
/* -----------------------------------------------------------
Arena free
----------------------------------------------------------- */
-void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_stats_t* stats) {
- mi_assert_internal(size > 0 && stats != NULL);
+void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_os_tld_t* tld) {
+ mi_assert_internal(size > 0 && tld->stats != NULL);
if (p==NULL) return;
if (size==0) return;
+
if (memid == MI_MEMID_OS) {
// was a direct OS allocation, pass through
- _mi_os_free_ex(p, size, all_committed, stats);
+ _mi_os_free_ex(p, size, all_committed, tld->stats);
}
else {
// allocated in an arena
size_t bitmap_idx;
mi_arena_id_indices(memid, &arena_idx, &bitmap_idx);
mi_assert_internal(arena_idx < MI_MAX_ARENAS);
- mi_arena_t* arena = mi_atomic_read_ptr_relaxed(mi_arena_t,&mi_arenas[arena_idx]);
+ mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t,&mi_arenas[arena_idx]);
mi_assert_internal(arena != NULL);
+ const size_t blocks = mi_block_count_of_size(size);
+ // checks
if (arena == NULL) {
_mi_error_message(EINVAL, "trying to free from non-existent arena: %p, size %zu, memid: 0x%zx\n", p, size, memid);
return;
_mi_error_message(EINVAL, "trying to free from non-existent arena block: %p, size %zu, memid: 0x%zx\n", p, size, memid);
return;
}
- const size_t blocks = mi_block_count_of_size(size);
- bool ones = mi_bitmap_unclaim(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx);
- if (!ones) {
+ // potentially decommit
+ if (!arena->allow_decommit || arena->blocks_committed == NULL) {
+ mi_assert_internal(all_committed); // note: may be not true as we may "pretend" to be not committed (in segment.c)
+ }
+ else {
+ mi_assert_internal(arena->blocks_committed != NULL);
+ _mi_os_decommit(p, blocks * MI_ARENA_BLOCK_SIZE, tld->stats); // ok if this fails
+ _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx);
+ }
+ // and make it available to others again
+ bool all_inuse = _mi_bitmap_unclaim_across(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx);
+ if (!all_inuse) {
_mi_error_message(EAGAIN, "trying to free an already freed block: %p, size %zu\n", p, size);
return;
};
static bool mi_arena_add(mi_arena_t* arena) {
mi_assert_internal(arena != NULL);
- mi_assert_internal((uintptr_t)mi_atomic_read_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0);
+ mi_assert_internal((uintptr_t)mi_atomic_load_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0);
mi_assert_internal(arena->block_count > 0);
- uintptr_t i = mi_atomic_increment(&mi_arena_count);
+ size_t i = mi_atomic_increment_acq_rel(&mi_arena_count);
if (i >= MI_MAX_ARENAS) {
- mi_atomic_decrement(&mi_arena_count);
+ mi_atomic_decrement_acq_rel(&mi_arena_count);
return false;
}
- mi_atomic_write_ptr(mi_arena_t,&mi_arenas[i], arena);
+ mi_atomic_store_ptr_release(mi_arena_t,&mi_arenas[i], arena);
return true;
}
+bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept
+{
+ if (size < MI_ARENA_BLOCK_SIZE) return false;
+
+ if (is_large) {
+ mi_assert_internal(is_committed);
+ is_committed = true;
+ }
+
+ const size_t bcount = size / MI_ARENA_BLOCK_SIZE;
+ const size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS);
+ const size_t bitmaps = (is_committed ? 2 : 3);
+ const size_t asize = sizeof(mi_arena_t) + (bitmaps*fields*sizeof(mi_bitmap_field_t));
+ mi_arena_t* arena = (mi_arena_t*)_mi_os_alloc(asize, &_mi_stats_main); // TODO: can we avoid allocating from the OS?
+ if (arena == NULL) return false;
+
+ arena->block_count = bcount;
+ arena->field_count = fields;
+ arena->start = (uint8_t*)start;
+ arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1)
+ arena->is_large = is_large;
+ arena->is_zero_init = is_zero;
+ arena->allow_decommit = !is_large && !is_committed; // only allow decommit for initially uncommitted memory
+ arena->search_idx = 0;
+ arena->blocks_dirty = &arena->blocks_inuse[fields]; // just after inuse bitmap
+ arena->blocks_committed = (!arena->allow_decommit ? NULL : &arena->blocks_inuse[2*fields]); // just after dirty bitmap
+ // the bitmaps are already zero initialized due to os_alloc
+ // initialize committed bitmap?
+ if (arena->blocks_committed != NULL && is_committed) {
+ memset((void*)arena->blocks_committed, 0xFF, fields*sizeof(mi_bitmap_field_t)); // cast to void* to avoid atomic warning
+ }
+ // and claim leftover blocks if needed (so we never allocate there)
+ ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount;
+ mi_assert_internal(post >= 0);
+ if (post > 0) {
+ // don't use leftover bits at the end
+ mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post);
+ _mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL);
+ }
+
+ mi_arena_add(arena);
+ return true;
+}
+
+// Reserve a range of regular OS memory
+int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept
+{
+ size = _mi_align_up(size, MI_ARENA_BLOCK_SIZE); // at least one block
+ bool large = allow_large;
+ void* start = _mi_os_alloc_aligned(size, MI_SEGMENT_ALIGN, commit, &large, &_mi_stats_main);
+ if (start==NULL) return ENOMEM;
+ if (!mi_manage_os_memory(start, size, (large || commit), large, true, -1)) {
+ _mi_os_free_ex(start, size, commit, &_mi_stats_main);
+ _mi_verbose_message("failed to reserve %zu k memory\n", _mi_divide_up(size,1024));
+ return ENOMEM;
+ }
+ _mi_verbose_message("reserved %zu KiB memory%s\n", _mi_divide_up(size,1024), large ? " (in large os pages)" : "");
+ return 0;
+}
+
+static size_t mi_debug_show_bitmap(const char* prefix, mi_bitmap_field_t* fields, size_t field_count ) {
+ size_t inuse_count = 0;
+ for (size_t i = 0; i < field_count; i++) {
+ char buf[MI_BITMAP_FIELD_BITS + 1];
+ uintptr_t field = mi_atomic_load_relaxed(&fields[i]);
+ for (size_t bit = 0; bit < MI_BITMAP_FIELD_BITS; bit++) {
+ bool inuse = ((((uintptr_t)1 << bit) & field) != 0);
+ if (inuse) inuse_count++;
+ buf[MI_BITMAP_FIELD_BITS - 1 - bit] = (inuse ? 'x' : '.');
+ }
+ buf[MI_BITMAP_FIELD_BITS] = 0;
+ _mi_verbose_message("%s%s\n", prefix, buf);
+ }
+ return inuse_count;
+}
+
+void mi_debug_show_arenas(void) mi_attr_noexcept {
+ size_t max_arenas = mi_atomic_load_relaxed(&mi_arena_count);
+ for (size_t i = 0; i < max_arenas; i++) {
+ mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]);
+ if (arena == NULL) break;
+ size_t inuse_count = 0;
+ _mi_verbose_message("arena %zu: %zu blocks with %zu fields\n", i, arena->block_count, arena->field_count);
+ inuse_count += mi_debug_show_bitmap(" ", arena->blocks_inuse, arena->field_count);
+ _mi_verbose_message(" blocks in use ('x'): %zu\n", inuse_count);
+ }
+}
/* -----------------------------------------------------------
Reserve a huge page arena.
----------------------------------------------------------- */
-#include <errno.h> // ENOMEM
-
// reserve at a specific numa node
int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept {
if (pages==0) return 0;
size_t pages_reserved = 0;
void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize);
if (p==NULL || pages_reserved==0) {
- _mi_warning_message("failed to reserve %zu gb huge pages\n", pages);
+ _mi_warning_message("failed to reserve %zu GiB huge pages\n", pages);
return ENOMEM;
}
- _mi_verbose_message("numa node %i: reserved %zu gb huge pages (of the %zu gb requested)\n", numa_node, pages_reserved, pages);
+ _mi_verbose_message("numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\n", numa_node, pages_reserved, pages);
- size_t bcount = mi_block_count_of_size(hsize);
- size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS);
- size_t asize = sizeof(mi_arena_t) + (2*fields*sizeof(mi_bitmap_field_t));
- mi_arena_t* arena = (mi_arena_t*)_mi_os_alloc(asize, &_mi_stats_main); // TODO: can we avoid allocating from the OS?
- if (arena == NULL) {
+ if (!mi_manage_os_memory(p, hsize, true, true, true, numa_node)) {
_mi_os_free_huge_pages(p, hsize, &_mi_stats_main);
return ENOMEM;
}
- arena->block_count = bcount;
- arena->field_count = fields;
- arena->start = (uint8_t*)p;
- arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1)
- arena->is_large = true;
- arena->is_zero_init = true;
- arena->is_committed = true;
- arena->search_idx = 0;
- arena->blocks_dirty = &arena->blocks_inuse[fields]; // just after inuse bitmap
- arena->blocks_committed = NULL;
- // the bitmaps are already zero initialized due to os_alloc
- // just claim leftover blocks if needed
- ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount;
- mi_assert_internal(post >= 0);
- if (post > 0) {
- // don't use leftover bits at the end
- mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post);
- mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL);
- }
-
- mi_arena_add(arena);
return 0;
}
}
int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept {
- UNUSED(max_secs);
+ MI_UNUSED(max_secs);
_mi_warning_message("mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\n");
if (pages_reserved != NULL) *pages_reserved = 0;
int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0));
--- /dev/null
+/* ----------------------------------------------------------------------------
+Copyright (c) 2019-2021 Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+
+/* ----------------------------------------------------------------------------
+Concurrent bitmap that can set/reset sequences of bits atomically,
+represeted as an array of fields where each field is a machine word (`size_t`)
+
+There are two api's; the standard one cannot have sequences that cross
+between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS).
+(this is used in region allocation)
+
+The `_across` postfixed functions do allow sequences that can cross over
+between the fields. (This is used in arena allocation)
+---------------------------------------------------------------------------- */
+
+#include "mimalloc.h"
+#include "mimalloc-internal.h"
+#include "bitmap.h"
+
+/* -----------------------------------------------------------
+ Bitmap definition
+----------------------------------------------------------- */
+
+// The bit mask for a given number of blocks at a specified bit index.
+static inline size_t mi_bitmap_mask_(size_t count, size_t bitidx) {
+ mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS);
+ mi_assert_internal(count > 0);
+ if (count >= MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL;
+ if (count == 0) return 0;
+ return ((((size_t)1 << count) - 1) << bitidx);
+}
+
+
+/* -----------------------------------------------------------
+ Claim a bit sequence atomically
+----------------------------------------------------------- */
+
+// Try to atomically claim a sequence of `count` bits in a single
+// field at `idx` in `bitmap`. Returns `true` on success.
+inline bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx)
+{
+ mi_assert_internal(bitmap_idx != NULL);
+ mi_assert_internal(count <= MI_BITMAP_FIELD_BITS);
+ mi_assert_internal(count > 0);
+ mi_bitmap_field_t* field = &bitmap[idx];
+ size_t map = mi_atomic_load_relaxed(field);
+ if (map==MI_BITMAP_FIELD_FULL) return false; // short cut
+
+ // search for 0-bit sequence of length count
+ const size_t mask = mi_bitmap_mask_(count, 0);
+ const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count;
+
+#ifdef MI_HAVE_FAST_BITSCAN
+ size_t bitidx = mi_ctz(~map); // quickly find the first zero bit if possible
+#else
+ size_t bitidx = 0; // otherwise start at 0
+#endif
+ size_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx
+
+ // scan linearly for a free range of zero bits
+ while (bitidx <= bitidx_max) {
+ const size_t mapm = map & m;
+ if (mapm == 0) { // are the mask bits free at bitidx?
+ mi_assert_internal((m >> bitidx) == mask); // no overflow?
+ const size_t newmap = map | m;
+ mi_assert_internal((newmap^map) >> bitidx == mask);
+ if (!mi_atomic_cas_weak_acq_rel(field, &map, newmap)) { // TODO: use strong cas here?
+ // no success, another thread claimed concurrently.. keep going (with updated `map`)
+ continue;
+ }
+ else {
+ // success, we claimed the bits!
+ *bitmap_idx = mi_bitmap_index_create(idx, bitidx);
+ return true;
+ }
+ }
+ else {
+ // on to the next bit range
+#ifdef MI_HAVE_FAST_BITSCAN
+ const size_t shift = (count == 1 ? 1 : mi_bsr(mapm) - bitidx + 1);
+ mi_assert_internal(shift > 0 && shift <= count);
+#else
+ const size_t shift = 1;
+#endif
+ bitidx += shift;
+ m <<= shift;
+ }
+ }
+ // no bits found
+ return false;
+}
+
+// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success.
+// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
+// `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields.
+bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {
+ size_t idx = start_field_idx;
+ for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {
+ if (idx >= bitmap_fields) idx = 0; // wrap
+ if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success.
+// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never span fields.
+bool _mi_bitmap_try_find_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t count, mi_bitmap_index_t* bitmap_idx) {
+ return _mi_bitmap_try_find_from_claim(bitmap, bitmap_fields, 0, count, bitmap_idx);
+}
+*/
+
+// Set `count` bits at `bitmap_idx` to 0 atomically
+// Returns `true` if all `count` bits were 1 previously.
+bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
+ // mi_assert_internal((bitmap[idx] & mask) == mask);
+ size_t prev = mi_atomic_and_acq_rel(&bitmap[idx], ~mask);
+ return ((prev & mask) == mask);
+}
+
+
+// Set `count` bits at `bitmap_idx` to 1 atomically
+// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
+bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) {
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
+ //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0);
+ size_t prev = mi_atomic_or_acq_rel(&bitmap[idx], mask);
+ if (any_zero != NULL) *any_zero = ((prev & mask) != mask);
+ return ((prev & mask) == 0);
+}
+
+// Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one.
+static bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) {
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
+ size_t field = mi_atomic_load_relaxed(&bitmap[idx]);
+ if (any_ones != NULL) *any_ones = ((field & mask) != 0);
+ return ((field & mask) == mask);
+}
+
+bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
+ return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL);
+}
+
+bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
+ bool any_ones;
+ mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones);
+ return any_ones;
+}
+
+
+//--------------------------------------------------------------------------
+// the `_across` functions work on bitmaps where sequences can cross over
+// between the fields. This is used in arena allocation
+//--------------------------------------------------------------------------
+
+// Try to atomically claim a sequence of `count` bits starting from the field
+// at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success.
+static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx)
+{
+ mi_assert_internal(bitmap_idx != NULL);
+
+ // check initial trailing zeros
+ mi_bitmap_field_t* field = &bitmap[idx];
+ size_t map = mi_atomic_load_relaxed(field);
+ const size_t initial = mi_clz(map); // count of initial zeros starting at idx
+ mi_assert_internal(initial <= MI_BITMAP_FIELD_BITS);
+ if (initial == 0) return false;
+ if (initial >= count) return _mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx); // no need to cross fields
+ if (_mi_divide_up(count - initial, MI_BITMAP_FIELD_BITS) >= (bitmap_fields - idx)) return false; // not enough entries
+
+ // scan ahead
+ size_t found = initial;
+ size_t mask = 0; // mask bits for the final field
+ while(found < count) {
+ field++;
+ map = mi_atomic_load_relaxed(field);
+ const size_t mask_bits = (found + MI_BITMAP_FIELD_BITS <= count ? MI_BITMAP_FIELD_BITS : (count - found));
+ mask = mi_bitmap_mask_(mask_bits, 0);
+ if ((map & mask) != 0) return false;
+ found += mask_bits;
+ }
+ mi_assert_internal(field < &bitmap[bitmap_fields]);
+
+ // found range of zeros up to the final field; mask contains mask in the final field
+ // now claim it atomically
+ mi_bitmap_field_t* const final_field = field;
+ const size_t final_mask = mask;
+ mi_bitmap_field_t* const initial_field = &bitmap[idx];
+ const size_t initial_mask = mi_bitmap_mask_(initial, MI_BITMAP_FIELD_BITS - initial);
+
+ // initial field
+ size_t newmap;
+ field = initial_field;
+ map = mi_atomic_load_relaxed(field);
+ do {
+ newmap = map | initial_mask;
+ if ((map & initial_mask) != 0) { goto rollback; };
+ } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
+
+ // intermediate fields
+ while (++field < final_field) {
+ newmap = MI_BITMAP_FIELD_FULL;
+ map = 0;
+ if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { goto rollback; }
+ }
+
+ // final field
+ mi_assert_internal(field == final_field);
+ map = mi_atomic_load_relaxed(field);
+ do {
+ newmap = map | final_mask;
+ if ((map & final_mask) != 0) { goto rollback; }
+ } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
+
+ // claimed!
+ *bitmap_idx = mi_bitmap_index_create(idx, MI_BITMAP_FIELD_BITS - initial);
+ return true;
+
+rollback:
+ // roll back intermediate fields
+ while (--field > initial_field) {
+ newmap = 0;
+ map = MI_BITMAP_FIELD_FULL;
+ mi_assert_internal(mi_atomic_load_relaxed(field) == map);
+ mi_atomic_store_release(field, newmap);
+ }
+ if (field == initial_field) {
+ map = mi_atomic_load_relaxed(field);
+ do {
+ mi_assert_internal((map & initial_mask) == initial_mask);
+ newmap = map & ~initial_mask;
+ } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
+ }
+ // retry? (we make a recursive call instead of goto to be able to use const declarations)
+ if (retries < 4) {
+ return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx);
+ }
+ else {
+ return false;
+ }
+}
+
+
+// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
+// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
+bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {
+ mi_assert_internal(count > 0);
+ if (count==1) return _mi_bitmap_try_find_from_claim(bitmap, bitmap_fields, start_field_idx, count, bitmap_idx);
+ size_t idx = start_field_idx;
+ for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {
+ if (idx >= bitmap_fields) idx = 0; // wrap
+ // try to claim inside the field
+ if (count <= MI_BITMAP_FIELD_BITS) {
+ if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {
+ return true;
+ }
+ }
+ // try to claim across fields
+ if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Helper for masks across fields; returns the mid count, post_mask may be 0
+static size_t mi_bitmap_mask_across(mi_bitmap_index_t bitmap_idx, size_t bitmap_fields, size_t count, size_t* pre_mask, size_t* mid_mask, size_t* post_mask) {
+ MI_UNUSED_RELEASE(bitmap_fields);
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
+ if (mi_likely(bitidx + count <= MI_BITMAP_FIELD_BITS)) {
+ *pre_mask = mi_bitmap_mask_(count, bitidx);
+ *mid_mask = 0;
+ *post_mask = 0;
+ mi_assert_internal(mi_bitmap_index_field(bitmap_idx) < bitmap_fields);
+ return 0;
+ }
+ else {
+ const size_t pre_bits = MI_BITMAP_FIELD_BITS - bitidx;
+ mi_assert_internal(pre_bits < count);
+ *pre_mask = mi_bitmap_mask_(pre_bits, bitidx);
+ count -= pre_bits;
+ const size_t mid_count = (count / MI_BITMAP_FIELD_BITS);
+ *mid_mask = MI_BITMAP_FIELD_FULL;
+ count %= MI_BITMAP_FIELD_BITS;
+ *post_mask = (count==0 ? 0 : mi_bitmap_mask_(count, 0));
+ mi_assert_internal(mi_bitmap_index_field(bitmap_idx) + mid_count + (count==0 ? 0 : 1) < bitmap_fields);
+ return mid_count;
+ }
+}
+
+// Set `count` bits at `bitmap_idx` to 0 atomically
+// Returns `true` if all `count` bits were 1 previously.
+bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
+ size_t idx = mi_bitmap_index_field(bitmap_idx);
+ size_t pre_mask;
+ size_t mid_mask;
+ size_t post_mask;
+ size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);
+ bool all_one = true;
+ mi_bitmap_field_t* field = &bitmap[idx];
+ size_t prev = mi_atomic_and_acq_rel(field++, ~pre_mask);
+ if ((prev & pre_mask) != pre_mask) all_one = false;
+ while(mid_count-- > 0) {
+ prev = mi_atomic_and_acq_rel(field++, ~mid_mask);
+ if ((prev & mid_mask) != mid_mask) all_one = false;
+ }
+ if (post_mask!=0) {
+ prev = mi_atomic_and_acq_rel(field, ~post_mask);
+ if ((prev & post_mask) != post_mask) all_one = false;
+ }
+ return all_one;
+}
+
+// Set `count` bits at `bitmap_idx` to 1 atomically
+// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
+bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero) {
+ size_t idx = mi_bitmap_index_field(bitmap_idx);
+ size_t pre_mask;
+ size_t mid_mask;
+ size_t post_mask;
+ size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);
+ bool all_zero = true;
+ bool any_zero = false;
+ _Atomic(size_t)*field = &bitmap[idx];
+ size_t prev = mi_atomic_or_acq_rel(field++, pre_mask);
+ if ((prev & pre_mask) != 0) all_zero = false;
+ if ((prev & pre_mask) != pre_mask) any_zero = true;
+ while (mid_count-- > 0) {
+ prev = mi_atomic_or_acq_rel(field++, mid_mask);
+ if ((prev & mid_mask) != 0) all_zero = false;
+ if ((prev & mid_mask) != mid_mask) any_zero = true;
+ }
+ if (post_mask!=0) {
+ prev = mi_atomic_or_acq_rel(field, post_mask);
+ if ((prev & post_mask) != 0) all_zero = false;
+ if ((prev & post_mask) != post_mask) any_zero = true;
+ }
+ if (pany_zero != NULL) *pany_zero = any_zero;
+ return all_zero;
+}
+
+
+// Returns `true` if all `count` bits were 1.
+// `any_ones` is `true` if there was at least one bit set to one.
+static bool mi_bitmap_is_claimedx_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_ones) {
+ size_t idx = mi_bitmap_index_field(bitmap_idx);
+ size_t pre_mask;
+ size_t mid_mask;
+ size_t post_mask;
+ size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);
+ bool all_ones = true;
+ bool any_ones = false;
+ mi_bitmap_field_t* field = &bitmap[idx];
+ size_t prev = mi_atomic_load_relaxed(field++);
+ if ((prev & pre_mask) != pre_mask) all_ones = false;
+ if ((prev & pre_mask) != 0) any_ones = true;
+ while (mid_count-- > 0) {
+ prev = mi_atomic_load_relaxed(field++);
+ if ((prev & mid_mask) != mid_mask) all_ones = false;
+ if ((prev & mid_mask) != 0) any_ones = true;
+ }
+ if (post_mask!=0) {
+ prev = mi_atomic_load_relaxed(field);
+ if ((prev & post_mask) != post_mask) all_ones = false;
+ if ((prev & post_mask) != 0) any_ones = true;
+ }
+ if (pany_ones != NULL) *pany_ones = any_ones;
+ return all_ones;
+}
+
+bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
+ return mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, NULL);
+}
+
+bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
+ bool any_ones;
+ mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, &any_ones);
+ return any_ones;
+}
--- /dev/null
+/* ----------------------------------------------------------------------------
+Copyright (c) 2019-2020 Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+
+/* ----------------------------------------------------------------------------
+Concurrent bitmap that can set/reset sequences of bits atomically,
+represeted as an array of fields where each field is a machine word (`size_t`)
+
+There are two api's; the standard one cannot have sequences that cross
+between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS).
+(this is used in region allocation)
+
+The `_across` postfixed functions do allow sequences that can cross over
+between the fields. (This is used in arena allocation)
+---------------------------------------------------------------------------- */
+#pragma once
+#ifndef MI_BITMAP_H
+#define MI_BITMAP_H
+
+/* -----------------------------------------------------------
+ Bitmap definition
+----------------------------------------------------------- */
+
+#define MI_BITMAP_FIELD_BITS (8*MI_SIZE_SIZE)
+#define MI_BITMAP_FIELD_FULL (~((size_t)0)) // all bits set
+
+// An atomic bitmap of `size_t` fields
+typedef _Atomic(size_t) mi_bitmap_field_t;
+typedef mi_bitmap_field_t* mi_bitmap_t;
+
+// A bitmap index is the index of the bit in a bitmap.
+typedef size_t mi_bitmap_index_t;
+
+// Create a bit index.
+static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) {
+ mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS);
+ return (idx*MI_BITMAP_FIELD_BITS) + bitidx;
+}
+
+// Create a bit index.
+static inline mi_bitmap_index_t mi_bitmap_index_create_from_bit(size_t full_bitidx) {
+ return mi_bitmap_index_create(full_bitidx / MI_BITMAP_FIELD_BITS, full_bitidx % MI_BITMAP_FIELD_BITS);
+}
+
+// Get the field index from a bit index.
+static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) {
+ return (bitmap_idx / MI_BITMAP_FIELD_BITS);
+}
+
+// Get the bit index in a bitmap field
+static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) {
+ return (bitmap_idx % MI_BITMAP_FIELD_BITS);
+}
+
+// Get the full bit index
+static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) {
+ return bitmap_idx;
+}
+
+/* -----------------------------------------------------------
+ Claim a bit sequence atomically
+----------------------------------------------------------- */
+
+// Try to atomically claim a sequence of `count` bits in a single
+// field at `idx` in `bitmap`. Returns `true` on success.
+bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
+
+// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
+// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields.
+bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
+
+// Set `count` bits at `bitmap_idx` to 0 atomically
+// Returns `true` if all `count` bits were 1 previously.
+bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
+
+// Set `count` bits at `bitmap_idx` to 1 atomically
+// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
+bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero);
+
+bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
+bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
+
+
+//--------------------------------------------------------------------------
+// the `_across` functions work on bitmaps where sequences can cross over
+// between the fields. This is used in arena allocation
+//--------------------------------------------------------------------------
+
+// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
+// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
+bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
+
+// Set `count` bits at `bitmap_idx` to 0 atomically
+// Returns `true` if all `count` bits were 1 previously.
+bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
+
+// Set `count` bits at `bitmap_idx` to 1 atomically
+// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
+bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero);
+
+bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
+bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
+
+#endif
+++ /dev/null
-/* ----------------------------------------------------------------------------
-Copyright (c) 2019, Microsoft Research, Daan Leijen
-This is free software; you can redistribute it and/or modify it under the
-terms of the MIT license. A copy of the license can be found in the file
-"LICENSE" at the root of this distribution.
------------------------------------------------------------------------------*/
-
-/* ----------------------------------------------------------------------------
-This file is meant to be included in other files for efficiency.
-It implements a bitmap that can set/reset sequences of bits atomically
-and is used to concurrently claim memory ranges.
-
-A bitmap is an array of fields where each field is a machine word (`uintptr_t`)
-
-A current limitation is that the bit sequences cannot cross fields
-and that the sequence must be smaller or equal to the bits in a field.
----------------------------------------------------------------------------- */
-#pragma once
-#ifndef MI_BITMAP_C
-#define MI_BITMAP_C
-
-#include "mimalloc.h"
-#include "mimalloc-internal.h"
-
-/* -----------------------------------------------------------
- Bitmap definition
------------------------------------------------------------ */
-
-#define MI_BITMAP_FIELD_BITS (8*MI_INTPTR_SIZE)
-#define MI_BITMAP_FIELD_FULL (~((uintptr_t)0)) // all bits set
-
-// An atomic bitmap of `uintptr_t` fields
-typedef volatile _Atomic(uintptr_t) mi_bitmap_field_t;
-typedef mi_bitmap_field_t* mi_bitmap_t;
-
-// A bitmap index is the index of the bit in a bitmap.
-typedef size_t mi_bitmap_index_t;
-
-// Create a bit index.
-static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) {
- mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS);
- return (idx*MI_BITMAP_FIELD_BITS) + bitidx;
-}
-
-// Get the field index from a bit index.
-static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) {
- return (bitmap_idx / MI_BITMAP_FIELD_BITS);
-}
-
-// Get the bit index in a bitmap field
-static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) {
- return (bitmap_idx % MI_BITMAP_FIELD_BITS);
-}
-
-// Get the full bit index
-static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) {
- return bitmap_idx;
-}
-
-
-// The bit mask for a given number of blocks at a specified bit index.
-static inline uintptr_t mi_bitmap_mask_(size_t count, size_t bitidx) {
- mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS);
- if (count == MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL;
- return ((((uintptr_t)1 << count) - 1) << bitidx);
-}
-
-
-/* -----------------------------------------------------------
- Use bit scan forward/reverse to quickly find the first zero bit if it is available
------------------------------------------------------------ */
-#if defined(_MSC_VER)
-#define MI_HAVE_BITSCAN
-#include <intrin.h>
-static inline size_t mi_bsf(uintptr_t x) {
- if (x==0) return 8*MI_INTPTR_SIZE;
- DWORD idx;
- MI_64(_BitScanForward)(&idx, x);
- return idx;
-}
-static inline size_t mi_bsr(uintptr_t x) {
- if (x==0) return 8*MI_INTPTR_SIZE;
- DWORD idx;
- MI_64(_BitScanReverse)(&idx, x);
- return idx;
-}
-#elif defined(__GNUC__) || defined(__clang__)
-#include <limits.h> // LONG_MAX
-#define MI_HAVE_BITSCAN
-#if (INTPTR_MAX == LONG_MAX)
-# define MI_L(x) x##l
-#else
-# define MI_L(x) x##ll
-#endif
-static inline size_t mi_bsf(uintptr_t x) {
- return (x==0 ? 8*MI_INTPTR_SIZE : MI_L(__builtin_ctz)(x));
-}
-static inline size_t mi_bsr(uintptr_t x) {
- return (x==0 ? 8*MI_INTPTR_SIZE : (8*MI_INTPTR_SIZE - 1) - MI_L(__builtin_clz)(x));
-}
-#endif
-
-/* -----------------------------------------------------------
- Claim a bit sequence atomically
------------------------------------------------------------ */
-
-// Try to atomically claim a sequence of `count` bits at in `idx`
-// in the bitmap field. Returns `true` on success.
-static inline bool mi_bitmap_try_claim_field(mi_bitmap_t bitmap, size_t bitmap_fields, const size_t count, mi_bitmap_index_t bitmap_idx) {
- const size_t idx = mi_bitmap_index_field(bitmap_idx);
- const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
- const uintptr_t mask = mi_bitmap_mask_(count, bitidx);
- mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields);
- mi_assert_internal(bitidx + count <= MI_BITMAP_FIELD_BITS);
-
- uintptr_t field = mi_atomic_read_relaxed(&bitmap[idx]);
- if ((field & mask) == 0) { // free?
- if (mi_atomic_cas_strong(&bitmap[idx], (field|mask), field)) {
- // claimed!
- return true;
- }
- }
- return false;
-}
-
-
-// Try to atomically claim a sequence of `count` bits in a single
-// field at `idx` in `bitmap`. Returns `true` on success.
-static inline bool mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx)
-{
- mi_assert_internal(bitmap_idx != NULL);
- volatile _Atomic(uintptr_t)* field = &bitmap[idx];
- uintptr_t map = mi_atomic_read(field);
- if (map==MI_BITMAP_FIELD_FULL) return false; // short cut
-
- // search for 0-bit sequence of length count
- const uintptr_t mask = mi_bitmap_mask_(count, 0);
- const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count;
-
-#ifdef MI_HAVE_BITSCAN
- size_t bitidx = mi_bsf(~map); // quickly find the first zero bit if possible
-#else
- size_t bitidx = 0; // otherwise start at 0
-#endif
- uintptr_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx
-
- // scan linearly for a free range of zero bits
- while (bitidx <= bitidx_max) {
- if ((map & m) == 0) { // are the mask bits free at bitidx?
- mi_assert_internal((m >> bitidx) == mask); // no overflow?
- const uintptr_t newmap = map | m;
- mi_assert_internal((newmap^map) >> bitidx == mask);
- if (!mi_atomic_cas_weak(field, newmap, map)) { // TODO: use strong cas here?
- // no success, another thread claimed concurrently.. keep going
- map = mi_atomic_read(field);
- continue;
- }
- else {
- // success, we claimed the bits!
- *bitmap_idx = mi_bitmap_index_create(idx, bitidx);
- return true;
- }
- }
- else {
- // on to the next bit range
-#ifdef MI_HAVE_BITSCAN
- const size_t shift = (count == 1 ? 1 : mi_bsr(map & m) - bitidx + 1);
- mi_assert_internal(shift > 0 && shift <= count);
-#else
- const size_t shift = 1;
-#endif
- bitidx += shift;
- m <<= shift;
- }
- }
- // no bits found
- return false;
-}
-
-
-// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success.
-// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never span fields.
-static inline bool mi_bitmap_try_find_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t* bitmap_idx) {
- for (size_t idx = 0; idx < bitmap_fields; idx++) {
- if (mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {
- return true;
- }
- }
- return false;
-}
-
-// Set `count` bits at `bitmap_idx` to 0 atomically
-// Returns `true` if all `count` bits were 1 previously.
-static inline bool mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
- const size_t idx = mi_bitmap_index_field(bitmap_idx);
- const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
- const uintptr_t mask = mi_bitmap_mask_(count, bitidx);
- mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields);
- // mi_assert_internal((bitmap[idx] & mask) == mask);
- uintptr_t prev = mi_atomic_and(&bitmap[idx], ~mask);
- return ((prev & mask) == mask);
-}
-
-
-// Set `count` bits at `bitmap_idx` to 1 atomically
-// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
-static inline bool mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) {
- const size_t idx = mi_bitmap_index_field(bitmap_idx);
- const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
- const uintptr_t mask = mi_bitmap_mask_(count, bitidx);
- mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields);
- //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0);
- uintptr_t prev = mi_atomic_or(&bitmap[idx], mask);
- if (any_zero != NULL) *any_zero = ((prev & mask) != mask);
- return ((prev & mask) == 0);
-}
-
-// Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one.
-static inline bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) {
- const size_t idx = mi_bitmap_index_field(bitmap_idx);
- const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
- const uintptr_t mask = mi_bitmap_mask_(count, bitidx);
- mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields);
- uintptr_t field = mi_atomic_read_relaxed(&bitmap[idx]);
- if (any_ones != NULL) *any_ones = ((field & mask) != 0);
- return ((field & mask) == mask);
-}
-
-static inline bool mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
- return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL);
-}
-
-static inline bool mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
- bool any_ones;
- mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones);
- return any_ones;
-}
-
-
-#endif
/*----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include <string.h> // memset, memcpy
+#if defined(_MSC_VER) && (_MSC_VER < 1920)
+#pragma warning(disable:4204) // non-constant aggregate initializer
+#endif
/* -----------------------------------------------------------
Helpers
#if MI_DEBUG>=2
static bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {
- UNUSED(arg1);
- UNUSED(arg2);
- UNUSED(pq);
+ MI_UNUSED(arg1);
+ MI_UNUSED(arg2);
+ MI_UNUSED(pq);
mi_assert_internal(mi_page_heap(page) == heap);
mi_segment_t* segment = _mi_page_segment(page);
mi_assert_internal(segment->thread_id == heap->thread_id);
static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) {
- UNUSED(arg2);
- UNUSED(heap);
+ MI_UNUSED(arg2);
+ MI_UNUSED(heap);
mi_assert_internal(mi_heap_page_is_valid(heap, pq, page, NULL, NULL));
mi_collect_t collect = *((mi_collect_t*)arg_collect);
_mi_page_free_collect(page, collect >= MI_FORCE);
}
static bool mi_heap_page_never_delayed_free(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {
- UNUSED(arg1);
- UNUSED(arg2);
- UNUSED(heap);
- UNUSED(pq);
+ MI_UNUSED(arg1);
+ MI_UNUSED(arg2);
+ MI_UNUSED(heap);
+ MI_UNUSED(pq);
_mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false);
return true; // don't break
}
static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect)
{
- if (!mi_heap_is_initialized(heap)) return;
- _mi_deferred_free(heap, collect >= MI_FORCE);
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return;
+
+ const bool force = collect >= MI_FORCE;
+ _mi_deferred_free(heap, force);
// note: never reclaim on collect but leave it to threads that need storage to reclaim
- if (
- #ifdef NDEBUG
+ const bool force_main =
+ #ifdef NDEBUG
collect == MI_FORCE
- #else
+ #else
collect >= MI_FORCE
- #endif
- && _mi_is_main_thread() && mi_heap_is_backing(heap) && !heap->no_reclaim)
- {
+ #endif
+ && _mi_is_main_thread() && mi_heap_is_backing(heap) && !heap->no_reclaim;
+
+ if (force_main) {
// the main thread is abandoned (end-of-program), try to reclaim all abandoned segments.
// if all memory is freed by now, all segments should be freed.
_mi_abandoned_reclaim_all(heap, &heap->tld->segments);
_mi_heap_delayed_free(heap);
// collect retired pages
- _mi_heap_collect_retired(heap, collect >= MI_FORCE);
+ _mi_heap_collect_retired(heap, force);
// collect all pages owned by this thread
mi_heap_visit_pages(heap, &mi_heap_page_collect, &collect, NULL);
- mi_assert_internal( collect != MI_ABANDON || mi_atomic_read_ptr(mi_block_t,&heap->thread_delayed_free) == NULL );
+ mi_assert_internal( collect != MI_ABANDON || mi_atomic_load_ptr_acquire(mi_block_t,&heap->thread_delayed_free) == NULL );
+
+ // collect abandoned segments (in particular, decommit expired parts of segments in the abandoned segment list)
+ // note: forced decommit can be quite expensive if many threads are created/destroyed so we do not force on abandonment
+ _mi_abandoned_collect(heap, collect == MI_FORCE /* force? */, &heap->tld->segments);
- // collect segment caches
- if (collect >= MI_FORCE) {
+ // collect segment local caches
+ if (force) {
_mi_segment_thread_collect(&heap->tld->segments);
}
+ // decommit in global segment caches
+ // note: forced decommit can be quite expensive if many threads are created/destroyed so we do not force on abandonment
+ _mi_segment_cache_collect( collect == MI_FORCE, &heap->tld->os);
+
// collect regions on program-exit (or shared library unload)
- if (collect >= MI_FORCE && _mi_is_main_thread() && mi_heap_is_backing(heap)) {
- _mi_mem_collect(&heap->tld->os);
+ if (force && _mi_is_main_thread() && mi_heap_is_backing(heap)) {
+ //_mi_mem_collect(&heap->tld->os);
}
}
mi_heap_t* bheap = mi_heap_get_backing();
mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t); // todo: OS allocate in secure mode?
if (heap==NULL) return NULL;
- memcpy(heap, &_mi_heap_empty, sizeof(mi_heap_t));
+ _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(mi_heap_t));
heap->tld = bheap->tld;
heap->thread_id = _mi_thread_id();
_mi_random_split(&bheap->random, &heap->random);
// zero out the page queues
static void mi_heap_reset_pages(mi_heap_t* heap) {
+ mi_assert_internal(heap != NULL);
mi_assert_internal(mi_heap_is_initialized(heap));
// TODO: copy full empty heap instead?
memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct));
#ifdef MI_MEDIUM_DIRECT
memset(&heap->pages_free_medium, 0, sizeof(heap->pages_free_medium));
#endif
- memcpy(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages));
+ _mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages));
heap->thread_delayed_free = NULL;
heap->page_count = 0;
}
static void mi_heap_free(mi_heap_t* heap) {
mi_assert(heap != NULL);
mi_assert_internal(mi_heap_is_initialized(heap));
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return;
if (mi_heap_is_backing(heap)) return; // dont free the backing heap
// reset default
----------------------------------------------------------- */
static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {
- UNUSED(arg1);
- UNUSED(arg2);
- UNUSED(heap);
- UNUSED(pq);
+ MI_UNUSED(arg1);
+ MI_UNUSED(arg2);
+ MI_UNUSED(heap);
+ MI_UNUSED(pq);
// ensure no more thread_delayed_free will be added
_mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false);
// stats
const size_t bsize = mi_page_block_size(page);
- if (bsize > MI_LARGE_OBJ_SIZE_MAX) {
- if (bsize > MI_HUGE_OBJ_SIZE_MAX) {
- _mi_stat_decrease(&heap->tld->stats.giant, bsize);
+ if (bsize > MI_MEDIUM_OBJ_SIZE_MAX) {
+ if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
+ mi_heap_stat_decrease(heap, large, bsize);
}
else {
- _mi_stat_decrease(&heap->tld->stats.huge, bsize);
+ mi_heap_stat_decrease(heap, huge, bsize);
}
}
-#if (MI_STAT>1)
+#if (MI_STAT)
_mi_page_free_collect(page, false); // update used count
const size_t inuse = page->used;
if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
- mi_heap_stat_decrease(heap, normal[_mi_bin(bsize)], inuse);
+ mi_heap_stat_decrease(heap, normal, bsize * inuse);
+#if (MI_STAT>1)
+ mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], inuse);
+#endif
}
mi_heap_stat_decrease(heap, malloc, bsize * inuse); // todo: off for aligned blocks...
#endif
mi_assert(mi_heap_is_initialized(heap));
mi_assert(heap->no_reclaim);
mi_assert_expensive(mi_heap_is_valid(heap));
- if (!mi_heap_is_initialized(heap)) return;
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return;
if (!heap->no_reclaim) {
// don't free in case it may contain reclaimed pages
mi_heap_delete(heap);
Safe Heap delete
----------------------------------------------------------- */
-// Tranfer the pages from one heap to the other
+// Transfer the pages from one heap to the other
static void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) {
mi_assert_internal(heap!=NULL);
if (from==NULL || from->page_count == 0) return;
// turns out to be ok as `_mi_heap_delayed_free` only visits the list and calls a
// the regular `_mi_free_delayed_block` which is safe.
_mi_heap_delayed_free(from);
- mi_assert_internal(from->thread_delayed_free == NULL);
+ #if !defined(_MSC_VER) || (_MSC_VER > 1900) // somehow the following line gives an error in VS2015, issue #353
+ mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_block_t,&from->thread_delayed_free) == NULL);
+ #endif
// and reset the `from` heap
mi_heap_reset_pages(from);
mi_assert(heap != NULL);
mi_assert(mi_heap_is_initialized(heap));
mi_assert_expensive(mi_heap_is_valid(heap));
- if (!mi_heap_is_initialized(heap)) return;
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return;
if (!mi_heap_is_backing(heap)) {
// tranfer still used pages to the backing heap
}
mi_heap_t* mi_heap_set_default(mi_heap_t* heap) {
+ mi_assert(heap != NULL);
mi_assert(mi_heap_is_initialized(heap));
- if (!mi_heap_is_initialized(heap)) return NULL;
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return NULL;
mi_assert_expensive(mi_heap_is_valid(heap));
mi_heap_t* old = mi_get_default_heap();
_mi_heap_set_default_direct(heap);
bool mi_heap_contains_block(mi_heap_t* heap, const void* p) {
mi_assert(heap != NULL);
- if (!mi_heap_is_initialized(heap)) return false;
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return false;
return (heap == mi_heap_of_block(p));
}
static bool mi_heap_page_check_owned(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* p, void* vfound) {
- UNUSED(heap);
- UNUSED(pq);
+ MI_UNUSED(heap);
+ MI_UNUSED(pq);
bool* found = (bool*)vfound;
mi_segment_t* segment = _mi_page_segment(page);
void* start = _mi_page_start(segment, page, NULL);
bool mi_heap_check_owned(mi_heap_t* heap, const void* p) {
mi_assert(heap != NULL);
- if (!mi_heap_is_initialized(heap)) return false;
+ if (heap==NULL || !mi_heap_is_initialized(heap)) return false;
if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false; // only aligned pointers
bool found = false;
mi_heap_visit_pages(heap, &mi_heap_page_check_owned, (void*)p, &found);
if (page->used == 0) return true;
const size_t bsize = mi_page_block_size(page);
+ const size_t ubsize = mi_page_usable_block_size(page); // without padding
size_t psize;
uint8_t* pstart = _mi_page_start(_mi_page_segment(page), page, &psize);
if (page->capacity == 1) {
// optimize page with one block
mi_assert_internal(page->used == 1 && page->free == NULL);
- return visitor(mi_page_heap(page), area, pstart, bsize, arg);
+ return visitor(mi_page_heap(page), area, pstart, ubsize, arg);
}
// create a bitmap of free blocks.
else if ((m & ((uintptr_t)1 << bit)) == 0) {
used_count++;
uint8_t* block = pstart + (i * bsize);
- if (!visitor(mi_page_heap(page), area, block, bsize, arg)) return false;
+ if (!visitor(mi_page_heap(page), area, block, ubsize, arg)) return false;
}
}
mi_assert_internal(page->used == used_count);
static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) {
- UNUSED(heap);
- UNUSED(pq);
+ MI_UNUSED(heap);
+ MI_UNUSED(pq);
mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun;
mi_heap_area_ex_t xarea;
const size_t bsize = mi_page_block_size(page);
+ const size_t ubsize = mi_page_usable_block_size(page);
xarea.page = page;
xarea.area.reserved = page->reserved * bsize;
xarea.area.committed = page->capacity * bsize;
xarea.area.blocks = _mi_page_start(_mi_page_segment(page), page, NULL);
- xarea.area.used = page->used;
- xarea.area.block_size = bsize;
+ xarea.area.used = page->used * bsize;
+ xarea.area.block_size = ubsize;
+ xarea.area.full_block_size = bsize;
return fun(heap, &xarea, arg);
}
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2022, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
0, // used
0, // xblock_size
NULL, // local_free
- ATOMIC_VAR_INIT(0), // xthread_free
- ATOMIC_VAR_INIT(0), // xheap
+ MI_ATOMIC_VAR_INIT(0), // xthread_free
+ MI_ATOMIC_VAR_INIT(0), // xheap
NULL, NULL
+ #if MI_INTPTR_SIZE==8
+ , { 0 } // padding
+ #endif
};
#define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty)
QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \
QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \
QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \
- QNULL(MI_LARGE_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \
- QNULL(MI_LARGE_OBJ_WSIZE_MAX + 2) /* Full queue */ }
+ QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \
+ QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 2) /* Full queue */ }
#define MI_STAT_COUNT_NULL() {0,0,0,0}
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
- MI_STAT_COUNT_NULL(), \
- { 0, 0 }, { 0, 0 }, { 0, 0 }, \
+ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \
MI_STAT_COUNT_END_NULL()
+
+// Empty slice span queues for every bin
+#define SQNULL(sz) { NULL, NULL, sz }
+#define MI_SEGMENT_SPAN_QUEUES_EMPTY \
+ { SQNULL(1), \
+ SQNULL( 1), SQNULL( 2), SQNULL( 3), SQNULL( 4), SQNULL( 5), SQNULL( 6), SQNULL( 7), SQNULL( 10), /* 8 */ \
+ SQNULL( 12), SQNULL( 14), SQNULL( 16), SQNULL( 20), SQNULL( 24), SQNULL( 28), SQNULL( 32), SQNULL( 40), /* 16 */ \
+ SQNULL( 48), SQNULL( 56), SQNULL( 64), SQNULL( 80), SQNULL( 96), SQNULL( 112), SQNULL( 128), SQNULL( 160), /* 24 */ \
+ SQNULL( 192), SQNULL( 224), SQNULL( 256), SQNULL( 320), SQNULL( 384), SQNULL( 448), SQNULL( 512), SQNULL( 640), /* 32 */ \
+ SQNULL( 768), SQNULL( 896), SQNULL( 1024) /* 35 */ }
+
+
// --------------------------------------------------------
// Statically allocate an empty heap as the initial
// thread local value for the default heap,
// may lead to allocation itself on some platforms)
// --------------------------------------------------------
-const mi_heap_t _mi_heap_empty = {
+mi_decl_cache_align const mi_heap_t _mi_heap_empty = {
NULL,
MI_SMALL_PAGES_EMPTY,
MI_PAGE_QUEUES_EMPTY,
- ATOMIC_VAR_INIT(NULL),
+ MI_ATOMIC_VAR_INIT(NULL),
0, // tid
0, // cookie
{ 0, 0 }, // keys
false
};
+#define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats)))
+#define tld_empty_os ((mi_os_tld_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,os)))
+
+mi_decl_cache_align static const mi_tld_t tld_empty = {
+ 0,
+ false,
+ NULL, NULL,
+ { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, tld_empty_stats, tld_empty_os }, // segments
+ { 0, tld_empty_stats }, // os
+ { MI_STATS_NULL } // stats
+};
+
// the thread-local default heap for allocation
mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;
static mi_tld_t tld_main = {
0, false,
- &_mi_heap_main, &_mi_heap_main,
- { { NULL, NULL }, {NULL ,NULL}, {NULL ,NULL, 0},
- 0, 0, 0, 0, 0, 0, NULL,
- &tld_main.stats, &tld_main.os
- }, // segments
+ &_mi_heap_main, & _mi_heap_main,
+ { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, &tld_main.stats, &tld_main.os }, // segments
{ 0, &tld_main.stats }, // os
{ MI_STATS_NULL } // stats
};
&tld_main,
MI_SMALL_PAGES_EMPTY,
MI_PAGE_QUEUES_EMPTY,
- ATOMIC_VAR_INIT(NULL),
+ MI_ATOMIC_VAR_INIT(NULL),
0, // thread id
0, // initial cookie
{ 0, 0 }, // the key of the main heap can be fixed (unlike page keys that need to be secure!)
static void mi_heap_main_init(void) {
if (_mi_heap_main.cookie == 0) {
_mi_heap_main.thread_id = _mi_thread_id();
- _mi_heap_main.cookie = _os_random_weak((uintptr_t)&mi_heap_main_init);
+ _mi_heap_main.cookie = _mi_os_random_weak((uintptr_t)&mi_heap_main_init);
_mi_random_init(&_mi_heap_main.random);
_mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main);
_mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main);
mi_tld_t tld;
} mi_thread_data_t;
+
+// Thread meta-data is allocated directly from the OS. For
+// some programs that do not use thread pools and allocate and
+// destroy many OS threads, this may causes too much overhead
+// per thread so we maintain a small cache of recently freed metadata.
+
+#define TD_CACHE_SIZE (8)
+static _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE];
+
+static mi_thread_data_t* mi_thread_data_alloc(void) {
+ // try to find thread metadata in the cache
+ mi_thread_data_t* td;
+ for (int i = 0; i < TD_CACHE_SIZE; i++) {
+ td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
+ if (td != NULL) {
+ td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
+ if (td != NULL) {
+ return td;
+ }
+ }
+ }
+ // if that fails, allocate directly from the OS
+ td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main);
+ if (td == NULL) {
+ // if this fails, try once more. (issue #257)
+ td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main);
+ if (td == NULL) {
+ // really out of memory
+ _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
+ }
+ }
+ return td;
+}
+
+static void mi_thread_data_free( mi_thread_data_t* tdfree ) {
+ // try to add the thread metadata to the cache
+ for (int i = 0; i < TD_CACHE_SIZE; i++) {
+ mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
+ if (td == NULL) {
+ mi_thread_data_t* expected = NULL;
+ if (mi_atomic_cas_ptr_weak_acq_rel(mi_thread_data_t, &td_cache[i], &expected, tdfree)) {
+ return;
+ }
+ }
+ }
+ // if that fails, just free it directly
+ _mi_os_free(tdfree, sizeof(mi_thread_data_t), &_mi_stats_main);
+}
+
+static void mi_thread_data_collect(void) {
+ // free all thread metadata from the cache
+ for (int i = 0; i < TD_CACHE_SIZE; i++) {
+ mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
+ if (td != NULL) {
+ td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
+ if (td != NULL) {
+ _mi_os_free( td, sizeof(mi_thread_data_t), &_mi_stats_main );
+ }
+ }
+ }
+}
+
// Initialize the thread local default heap, called from `mi_thread_init`
static bool _mi_heap_init(void) {
if (mi_heap_is_initialized(mi_get_default_heap())) return true;
}
else {
// use `_mi_os_alloc` to allocate directly from the OS
- mi_thread_data_t* td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); // Todo: more efficient allocation?
- if (td == NULL) {
- // if this fails, try once more. (issue #257)
- td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main);
- if (td == NULL) {
- // really out of memory
- _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
- return false;
- }
- }
+ mi_thread_data_t* td = mi_thread_data_alloc();
+ if (td == NULL) return false;
+
// OS allocated so already zero initialized
mi_tld_t* tld = &td->tld;
mi_heap_t* heap = &td->heap;
- memcpy(heap, &_mi_heap_empty, sizeof(*heap));
+ _mi_memcpy_aligned(tld, &tld_empty, sizeof(*tld));
+ _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(*heap));
heap->thread_id = _mi_thread_id();
_mi_random_init(&heap->random);
heap->cookie = _mi_heap_random_next(heap) | 1;
tld->segments.stats = &tld->stats;
tld->segments.os = &tld->os;
tld->os.stats = &tld->stats;
- _mi_heap_set_default_direct(heap);
+ _mi_heap_set_default_direct(heap);
}
return false;
}
_mi_heap_collect_abandon(heap);
}
-
// merge stats
- _mi_stats_done(&heap->tld->stats);
+ _mi_stats_done(&heap->tld->stats);
// free if not the main thread
if (heap != &_mi_heap_main) {
- mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id());
- _mi_os_free(heap, sizeof(mi_thread_data_t), &_mi_stats_main);
+ // the following assertion does not always hold for huge segments as those are always treated
+ // as abondened: one may allocate it in one thread, but deallocate in another in which case
+ // the count can be too large or negative. todo: perhaps not count huge segments? see issue #363
+ // mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id());
+ mi_thread_data_free((mi_thread_data_t*)heap);
}
-#if 0
- // never free the main thread even in debug mode; if a dll is linked statically with mimalloc,
- // there may still be delete/free calls after the mi_fls_done is called. Issue #207
else {
+ mi_thread_data_collect(); // free cached thread metadata
+ #if 0
+ // never free the main thread even in debug mode; if a dll is linked statically with mimalloc,
+ // there may still be delete/free calls after the mi_fls_done is called. Issue #207
_mi_heap_destroy_pages(heap);
mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main);
+ #endif
}
-#endif
return false;
}
static void _mi_thread_done(mi_heap_t* default_heap);
-#ifdef __wasi__
-// no pthreads in the WebAssembly Standard Interface
-#elif !defined(_WIN32)
-#define MI_USE_PTHREADS
-#endif
-
#if defined(_WIN32) && defined(MI_SHARED_LIB)
// nothing to do as it is done in DllMain
#elif defined(_WIN32) && !defined(MI_SHARED_LIB)
#elif defined(MI_USE_PTHREADS)
// use pthread local storage keys to detect thread ending
// (and used with MI_TLS_PTHREADS for the default heap)
- #include <pthread.h>
pthread_key_t _mi_heap_default_key = (pthread_key_t)(-1);
static void mi_pthread_done(void* value) {
if (value!=NULL) _mi_thread_done((mi_heap_t*)value);
return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id());
}
+static _Atomic(size_t) thread_count = MI_ATOMIC_VAR_INIT(1);
+
+size_t _mi_current_thread_count(void) {
+ return mi_atomic_load_relaxed(&thread_count);
+}
+
// This is called from the `mi_malloc_generic`
void mi_thread_init(void) mi_attr_noexcept
{
// ensure our process has started already
mi_process_init();
-
+
// initialize the thread local default heap
// (this will call `_mi_heap_set_default_direct` and thus set the
// fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called)
if (_mi_heap_init()) return; // returns true if already initialized
- // don't further initialize for the main thread
- if (_mi_is_main_thread()) return;
-
- mi_heap_t* const heap = mi_get_default_heap();
- if (mi_heap_is_initialized(heap)) { _mi_stat_increase(&heap->tld->stats.threads, 1); }
-
+ _mi_stat_increase(&_mi_stats_main.threads, 1);
+ mi_atomic_increment_relaxed(&thread_count);
//_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id());
}
}
static void _mi_thread_done(mi_heap_t* heap) {
+ mi_atomic_decrement_relaxed(&thread_count);
+ _mi_stat_decrease(&_mi_stats_main.threads, 1);
+
// check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps...
if (heap->thread_id != _mi_thread_id()) return;
-
- // stats
- if (!_mi_is_main_thread() && mi_heap_is_initialized(heap)) {
- _mi_stat_decrease(&heap->tld->stats.threads, 1);
- }
-
+
// abandon the thread local heap
if (_mi_heap_done(heap)) return; // returns true if already ran
}
static bool mi_redirected = false; // true if malloc redirects to mi_malloc
// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false.
-bool _mi_preloading() {
+bool _mi_preloading(void) {
return os_preloading;
}
-bool mi_is_redirected() mi_attr_noexcept {
+mi_decl_nodiscard bool mi_is_redirected(void) mi_attr_noexcept {
return mi_redirected;
}
}
}
__declspec(dllimport) bool mi_allocator_init(const char** message);
-__declspec(dllimport) void mi_allocator_done();
+__declspec(dllimport) void mi_allocator_done(void);
#ifdef __cplusplus
}
#endif
if (message != NULL) *message = NULL;
return true;
}
-static void mi_allocator_done() {
+static void mi_allocator_done(void) {
// nothing to do
}
#endif
mi_heap_main_init();
#if defined(MI_TLS_RECURSE_GUARD)
volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true;
- UNUSED(dummy);
+ MI_UNUSED(dummy);
#endif
os_preloading = false;
- atexit(&mi_process_done);
+ #if !(defined(_WIN32) && defined(MI_SHARED_LIB)) // use Dll process detach (see below) instead of atexit (issue #521)
+ atexit(&mi_process_done);
+ #endif
_mi_options_init();
mi_process_init();
//mi_stats_reset();-
}
}
+#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
+#include <intrin.h>
+mi_decl_cache_align bool _mi_cpu_has_fsrm = false;
+
+static void mi_detect_cpu_features(void) {
+ // FSRM for fast rep movsb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017))
+ int32_t cpu_info[4];
+ __cpuid(cpu_info, 7);
+ _mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https ://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>
+}
+#else
+static void mi_detect_cpu_features(void) {
+ // nothing
+}
+#endif
+
// Initialize the process; called by thread_init or the process loader
void mi_process_init(void) mi_attr_noexcept {
// ensure we are called once
if (_mi_process_is_initialized) return;
+ _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id());
_mi_process_is_initialized = true;
mi_process_setup_auto_thread_done();
- _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id());
+
+ mi_detect_cpu_features();
_mi_os_init();
mi_heap_main_init();
#if (MI_DEBUG)
#endif
_mi_verbose_message("secure level: %d\n", MI_SECURE);
mi_thread_init();
+
+ #if defined(_WIN32) && !defined(MI_SHARED_LIB)
+ // When building as a static lib the FLS cleanup happens to early for the main thread.
+ // To avoid this, set the FLS value for the main thread to NULL so the fls cleanup
+ // will not call _mi_thread_done on the (still executing) main thread. See issue #508.
+ FlsSetValue(mi_fls_key, NULL);
+ #endif
+
mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL)
if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
- size_t pages = mi_option_get(mi_option_reserve_huge_os_pages);
- mi_reserve_huge_os_pages_interleave(pages, 0, pages*500);
+ size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024);
+ long reserve_at = mi_option_get(mi_option_reserve_huge_os_pages_at);
+ if (reserve_at != -1) {
+ mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500);
+ } else {
+ mi_reserve_huge_os_pages_interleave(pages, 0, pages*500);
+ }
+ }
+ if (mi_option_is_enabled(mi_option_reserve_os_memory)) {
+ long ksize = mi_option_get(mi_option_reserve_os_memory);
+ if (ksize > 0) {
+ mi_reserve_os_memory((size_t)ksize*MI_KiB, true /* commit? */, true /* allow large pages? */);
+ }
}
}
process_done = true;
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
- FlsSetValue(mi_fls_key, NULL); // don't call main-thread callback
- FlsFree(mi_fls_key); // call thread-done on all threads to prevent dangling callback pointer if statically linked with a DLL; Issue #208
+ FlsFree(mi_fls_key); // call thread-done on all threads (except the main thread) to prevent dangling callback pointer if statically linked with a DLL; Issue #208
#endif
- #if (MI_DEBUG != 0) || !defined(MI_SHARED_LIB)
- // free all memory if possible on process exit. This is not needed for a stand-alone process
- // but should be done if mimalloc is statically linked into another shared library which
- // is repeatedly loaded/unloaded, see issue #281.
- mi_collect(true /* force */ );
+ #ifndef MI_SKIP_COLLECT_ON_EXIT
+ #if (MI_DEBUG != 0) || !defined(MI_SHARED_LIB)
+ // free all memory if possible on process exit. This is not needed for a stand-alone process
+ // but should be done if mimalloc is statically linked into another shared library which
+ // is repeatedly loaded/unloaded, see issue #281.
+ mi_collect(true /* force */ );
+ #endif
#endif
if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {
#if defined(_WIN32) && defined(MI_SHARED_LIB)
// Windows DLL: easy to hook into process_init and thread_done
__declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {
- UNUSED(reserved);
- UNUSED(inst);
+ MI_UNUSED(reserved);
+ MI_UNUSED(inst);
if (reason==DLL_PROCESS_ATTACH) {
mi_process_load();
}
- else if (reason==DLL_THREAD_DETACH) {
- if (!mi_is_redirected()) mi_thread_done();
+ else if (reason==DLL_PROCESS_DETACH) {
+ mi_process_done();
}
+ else if (reason==DLL_THREAD_DETACH) {
+ if (!mi_is_redirected()) {
+ mi_thread_done();
+ }
+ }
return TRUE;
}
-#elif defined(__cplusplus)
- // C++: use static initialization to detect process start
- static bool _mi_process_init(void) {
- mi_process_load();
- return (_mi_heap_main.thread_id != 0);
- }
- static bool mi_initialized = _mi_process_init();
-
-#elif defined(__GNUC__) || defined(__clang__)
- // GCC,Clang: use the constructor attribute
- static void __attribute__((constructor)) _mi_process_init(void) {
- mi_process_load();
- }
-
#elif defined(_MSC_VER)
// MSVC: use data section magic for static libraries
// See <https://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm>
mi_process_load();
return 0;
}
- typedef int(*_crt_cb)(void);
- #ifdef _M_X64
+ typedef int(*_mi_crt_callback_t)(void);
+ #if defined(_M_X64) || defined(_M_ARM64)
__pragma(comment(linker, "/include:" "_mi_msvc_initu"))
#pragma section(".CRT$XIU", long, read)
#else
__pragma(comment(linker, "/include:" "__mi_msvc_initu"))
#endif
#pragma data_seg(".CRT$XIU")
- _crt_cb _mi_msvc_initu[] = { &_mi_process_init };
+ mi_decl_externc _mi_crt_callback_t _mi_msvc_initu[] = { &_mi_process_init };
#pragma data_seg()
+#elif defined(__cplusplus)
+ // C++: use static initialization to detect process start
+ static bool _mi_process_init(void) {
+ mi_process_load();
+ return (_mi_heap_main.thread_id != 0);
+ }
+ static bool mi_initialized = _mi_process_init();
+
+#elif defined(__GNUC__) || defined(__clang__)
+ // GCC,Clang: use the constructor attribute
+ static void __attribute__((constructor)) _mi_process_init(void) {
+ mi_process_load();
+ }
+
#else
#pragma message("define a way to call mi_process_load on your platform")
#endif
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include <ctype.h> // toupper
#include <stdarg.h>
-static uintptr_t mi_max_error_count = 16; // stop outputting errors after this
+#ifdef _MSC_VER
+#pragma warning(disable:4996) // strncpy, strncat
+#endif
+
-static void mi_add_stderr_output();
+static long mi_max_error_count = 16; // stop outputting errors after this (use < 0 for no limit)
+static long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit)
+
+static void mi_add_stderr_output(void);
int mi_version(void) mi_attr_noexcept {
return MI_MALLOC_VERSION;
mi_init_t init; // is it initialized yet? (from the environment)
mi_option_t option; // for debugging: the option index should match the option
const char* name; // option name without `mimalloc_` prefix
+ const char* legacy_name; // potential legacy v1.x option name
} mi_option_desc_t;
-#define MI_OPTION(opt) mi_option_##opt, #opt
-#define MI_OPTION_DESC(opt) {0, UNINIT, MI_OPTION(opt) }
+#define MI_OPTION(opt) mi_option_##opt, #opt, NULL
+#define MI_OPTION_LEGACY(opt,legacy) mi_option_##opt, #opt, #legacy
static mi_option_desc_t options[_mi_option_last] =
{
// stable options
-#if MI_DEBUG || defined(MI_SHOW_ERRORS)
+ #if MI_DEBUG || defined(MI_SHOW_ERRORS)
{ 1, UNINIT, MI_OPTION(show_errors) },
-#else
+ #else
{ 0, UNINIT, MI_OPTION(show_errors) },
-#endif
+ #endif
{ 0, UNINIT, MI_OPTION(show_stats) },
{ 0, UNINIT, MI_OPTION(verbose) },
- // the following options are experimental and not all combinations make sense.
- { 1, UNINIT, MI_OPTION(eager_commit) }, // commit on demand
- #if defined(_WIN32) || (MI_INTPTR_SIZE <= 4) // and other OS's without overcommit?
- { 0, UNINIT, MI_OPTION(eager_region_commit) },
- { 1, UNINIT, MI_OPTION(reset_decommits) }, // reset decommits memory
- #else
- { 1, UNINIT, MI_OPTION(eager_region_commit) },
- { 0, UNINIT, MI_OPTION(reset_decommits) }, // reset uses MADV_FREE/MADV_DONTNEED
- #endif
+ // Some of the following options are experimental and not all combinations are valid. Use with care.
+ { 1, UNINIT, MI_OPTION(eager_commit) }, // commit per segment directly (8MiB) (but see also `eager_commit_delay`)
+ { 0, UNINIT, MI_OPTION(deprecated_eager_region_commit) },
+ { 0, UNINIT, MI_OPTION(deprecated_reset_decommits) },
{ 0, UNINIT, MI_OPTION(large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's
- { 0, UNINIT, MI_OPTION(reserve_huge_os_pages) },
- { 0, UNINIT, MI_OPTION(segment_cache) }, // cache N segments per thread
- { 1, UNINIT, MI_OPTION(page_reset) }, // reset page memory on free
- { 0, UNINIT, MI_OPTION(abandoned_page_reset) },// reset free page memory when a thread terminates
- { 0, UNINIT, MI_OPTION(segment_reset) }, // reset segment memory on free (needs eager commit)
-#if defined(__NetBSD__)
+ { 0, UNINIT, MI_OPTION(reserve_huge_os_pages) }, // per 1GiB huge pages
+ { -1, UNINIT, MI_OPTION(reserve_huge_os_pages_at) }, // reserve huge pages at node N
+ { 0, UNINIT, MI_OPTION(reserve_os_memory) },
+ { 0, UNINIT, MI_OPTION(deprecated_segment_cache) }, // cache N segments per thread
+ { 0, UNINIT, MI_OPTION(page_reset) }, // reset page memory on free
+ { 0, UNINIT, MI_OPTION_LEGACY(abandoned_page_decommit, abandoned_page_reset) },// decommit free page memory when a thread terminates
+ { 0, UNINIT, MI_OPTION(deprecated_segment_reset) },
+ #if defined(__NetBSD__)
{ 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed
-#else
- { 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed
-#endif
- { 100, UNINIT, MI_OPTION(reset_delay) }, // reset delay in milli-seconds
- { 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes.
- { 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose
- { 16, UNINIT, MI_OPTION(max_errors) } // maximum errors that are output
+ #elif defined(_WIN32)
+ { 4, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed (but per page in the segment on demand)
+ #else
+ { 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed (but per page in the segment on demand)
+ #endif
+ { 25, UNINIT, MI_OPTION_LEGACY(decommit_delay, reset_delay) }, // page decommit delay in milli-seconds
+ { 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes.
+ { 0, UNINIT, MI_OPTION(limit_os_alloc) }, // 1 = do not use OS memory for allocation (but only reserved arenas)
+ { 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose
+ { 16, UNINIT, MI_OPTION(max_errors) }, // maximum errors that are output
+ { 16, UNINIT, MI_OPTION(max_warnings) }, // maximum warnings that are output
+ { 8, UNINIT, MI_OPTION(max_segment_reclaim)},// max. number of segment reclaims from the abandoned segments per try.
+ { 1, UNINIT, MI_OPTION(allow_decommit) }, // decommit slices when no longer used (after decommit_delay milli-seconds)
+ { 500, UNINIT, MI_OPTION(segment_decommit_delay) }, // decommit delay in milli-seconds for freed segments
+ { 2, UNINIT, MI_OPTION(decommit_extend_delay) }
};
static void mi_option_init(mi_option_desc_t* desc);
mi_add_stderr_output(); // now it safe to use stderr for output
for(int i = 0; i < _mi_option_last; i++ ) {
mi_option_t option = (mi_option_t)i;
- long l = mi_option_get(option); UNUSED(l); // initialize
+ long l = mi_option_get(option); MI_UNUSED(l); // initialize
if (option != mi_option_verbose) {
mi_option_desc_t* desc = &options[option];
_mi_verbose_message("option '%s': %ld\n", desc->name, desc->value);
}
}
mi_max_error_count = mi_option_get(mi_option_max_errors);
+ mi_max_warning_count = mi_option_get(mi_option_max_warnings);
}
-long mi_option_get(mi_option_t option) {
+mi_decl_nodiscard long mi_option_get(mi_option_t option) {
mi_assert(option >= 0 && option < _mi_option_last);
+ if (option < 0 || option >= _mi_option_last) return 0;
mi_option_desc_t* desc = &options[option];
mi_assert(desc->option == option); // index should match the option
if (mi_unlikely(desc->init == UNINIT)) {
return desc->value;
}
+mi_decl_nodiscard long mi_option_get_clamp(mi_option_t option, long min, long max) {
+ long x = mi_option_get(option);
+ return (x < min ? min : (x > max ? max : x));
+}
+
void mi_option_set(mi_option_t option, long value) {
mi_assert(option >= 0 && option < _mi_option_last);
+ if (option < 0 || option >= _mi_option_last) return;
mi_option_desc_t* desc = &options[option];
mi_assert(desc->option == option); // index should match the option
desc->value = value;
void mi_option_set_default(mi_option_t option, long value) {
mi_assert(option >= 0 && option < _mi_option_last);
+ if (option < 0 || option >= _mi_option_last) return;
mi_option_desc_t* desc = &options[option];
if (desc->init != INITIALIZED) {
desc->value = value;
}
}
-bool mi_option_is_enabled(mi_option_t option) {
+mi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option) {
return (mi_option_get(option) != 0);
}
static void mi_out_stderr(const char* msg, void* arg) {
- UNUSED(arg);
+ MI_UNUSED(arg);
+ if (msg == NULL) return;
#ifdef _WIN32
// on windows with redirection, the C runtime cannot handle locale dependent output
// after the main thread closes so we use direct console output.
- if (!_mi_preloading()) { _cputs(msg); }
+ if (!_mi_preloading()) {
+ // _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console
+ static HANDLE hcon = INVALID_HANDLE_VALUE;
+ if (hcon == INVALID_HANDLE_VALUE) {
+ hcon = GetStdHandle(STD_ERROR_HANDLE);
+ }
+ const size_t len = strlen(msg);
+ if (hcon != INVALID_HANDLE_VALUE && len > 0 && len < UINT32_MAX) {
+ DWORD written = 0;
+ WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);
+ }
+ }
#else
fputs(msg, stderr);
#endif
// an output function is registered it is called immediately with
// the output up to that point.
#ifndef MI_MAX_DELAY_OUTPUT
-#define MI_MAX_DELAY_OUTPUT (32*1024)
+#define MI_MAX_DELAY_OUTPUT ((size_t)(32*1024))
#endif
static char out_buf[MI_MAX_DELAY_OUTPUT+1];
-static _Atomic(uintptr_t) out_len;
+static _Atomic(size_t) out_len;
static void mi_out_buf(const char* msg, void* arg) {
- UNUSED(arg);
+ MI_UNUSED(arg);
if (msg==NULL) return;
- if (mi_atomic_read_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return;
+ if (mi_atomic_load_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return;
size_t n = strlen(msg);
if (n==0) return;
// claim space
- uintptr_t start = mi_atomic_add(&out_len, n);
+ size_t start = mi_atomic_add_acq_rel(&out_len, n);
if (start >= MI_MAX_DELAY_OUTPUT) return;
// check bound
if (start+n >= MI_MAX_DELAY_OUTPUT) {
n = MI_MAX_DELAY_OUTPUT-start-1;
}
- memcpy(&out_buf[start], msg, n);
+ _mi_memcpy(&out_buf[start], msg, n);
}
static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) {
if (out==NULL) return;
// claim (if `no_more_buf == true`, no more output will be added after this point)
- size_t count = mi_atomic_add(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1));
+ size_t count = mi_atomic_add_acq_rel(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1));
// and output the current contents
if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT;
out_buf[count] = 0;
// Should be atomic but gives errors on many platforms as generally we cannot cast a function pointer to a uintptr_t.
// For now, don't register output from multiple threads.
-#pragma warning(suppress:4180)
static mi_output_fun* volatile mi_out_default; // = NULL
-static volatile _Atomic(void*) mi_out_arg; // = NULL
+static _Atomic(void*) mi_out_arg; // = NULL
static mi_output_fun* mi_out_get_default(void** parg) {
- if (parg != NULL) { *parg = mi_atomic_read_ptr(void,&mi_out_arg); }
+ if (parg != NULL) { *parg = mi_atomic_load_ptr_acquire(void,&mi_out_arg); }
mi_output_fun* out = mi_out_default;
return (out == NULL ? &mi_out_buf : out);
}
void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept {
mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer
- mi_atomic_write_ptr(void,&mi_out_arg, arg);
+ mi_atomic_store_ptr_release(void,&mi_out_arg, arg);
if (out!=NULL) mi_out_buf_flush(out,true,arg); // output all the delayed output now
}
// --------------------------------------------------------
// Messages, all end up calling `_mi_fputs`.
// --------------------------------------------------------
-static volatile _Atomic(uintptr_t) error_count; // = 0; // when MAX_ERROR_COUNT stop emitting errors and warnings
+static _Atomic(size_t) error_count; // = 0; // when >= max_error_count stop emitting errors
+static _Atomic(size_t) warning_count; // = 0; // when >= max_warning_count stop emitting warnings
// When overriding malloc, we may recurse into mi_vfprintf if an allocation
// inside the C runtime causes another message.
+// In some cases (like on macOS) the loader already allocates which
+// calls into mimalloc; if we then access thread locals (like `recurse`)
+// this may crash as the access may call _tlv_bootstrap that tries to
+// (recursively) invoke malloc again to allocate space for the thread local
+// variables on demand. This is why we use a _mi_preloading test on such
+// platforms. However, C code generator may move the initial thread local address
+// load before the `if` and we therefore split it out in a separate funcion.
static mi_decl_thread bool recurse = false;
-static bool mi_recurse_enter(void) {
- #ifdef MI_TLS_RECURSE_GUARD
- if (_mi_preloading()) return true;
- #endif
+static mi_decl_noinline bool mi_recurse_enter_prim(void) {
if (recurse) return false;
recurse = true;
return true;
}
+static mi_decl_noinline void mi_recurse_exit_prim(void) {
+ recurse = false;
+}
+
+static bool mi_recurse_enter(void) {
+ #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD)
+ if (_mi_preloading()) return true;
+ #endif
+ return mi_recurse_enter_prim();
+}
+
static void mi_recurse_exit(void) {
- #ifdef MI_TLS_RECURSE_GUARD
+ #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD)
if (_mi_preloading()) return;
#endif
- recurse = false;
+ mi_recurse_exit_prim();
}
void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) {
va_end(args);
}
+static void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) {
+ if (prefix != NULL && strlen(prefix) <= 32 && !_mi_is_main_thread()) {
+ char tprefix[64];
+ snprintf(tprefix, sizeof(tprefix), "%sthread 0x%zx: ", prefix, _mi_thread_id());
+ mi_vfprintf(out, arg, tprefix, fmt, args);
+ }
+ else {
+ mi_vfprintf(out, arg, prefix, fmt, args);
+ }
+}
+
void _mi_trace_message(const char* fmt, ...) {
if (mi_option_get(mi_option_verbose) <= 1) return; // only with verbose level 2 or higher
va_list args;
va_start(args, fmt);
- mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args);
+ mi_vfprintf_thread(NULL, NULL, "mimalloc: ", fmt, args);
va_end(args);
}
}
static void mi_show_error_message(const char* fmt, va_list args) {
- if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return;
- if (mi_atomic_increment(&error_count) > mi_max_error_count) return;
- mi_vfprintf(NULL, NULL, "mimalloc: error: ", fmt, args);
+ if (!mi_option_is_enabled(mi_option_verbose)) {
+ if (!mi_option_is_enabled(mi_option_show_errors)) return;
+ if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return;
+ }
+ mi_vfprintf_thread(NULL, NULL, "mimalloc: error: ", fmt, args);
}
void _mi_warning_message(const char* fmt, ...) {
- if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return;
- if (mi_atomic_increment(&error_count) > mi_max_error_count) return;
+ if (!mi_option_is_enabled(mi_option_verbose)) {
+ if (!mi_option_is_enabled(mi_option_show_errors)) return;
+ if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return;
+ }
va_list args;
va_start(args,fmt);
- mi_vfprintf(NULL, NULL, "mimalloc: warning: ", fmt, args);
+ mi_vfprintf_thread(NULL, NULL, "mimalloc: warning: ", fmt, args);
va_end(args);
}
// --------------------------------------------------------
static mi_error_fun* volatile mi_error_handler; // = NULL
-static volatile _Atomic(void*) mi_error_arg; // = NULL
+static _Atomic(void*) mi_error_arg; // = NULL
static void mi_error_default(int err) {
- UNUSED(err);
+ MI_UNUSED(err);
#if (MI_DEBUG>0)
if (err==EFAULT) {
#ifdef _MSC_VER
void mi_register_error(mi_error_fun* fun, void* arg) {
mi_error_handler = fun; // can be NULL
- mi_atomic_write_ptr(void,&mi_error_arg, arg);
+ mi_atomic_store_ptr_release(void,&mi_error_arg, arg);
}
void _mi_error_message(int err, const char* fmt, ...) {
va_end(args);
// and call the error handler which may abort (or return normally)
if (mi_error_handler != NULL) {
- mi_error_handler(err, mi_atomic_read_ptr(void,&mi_error_arg));
+ mi_error_handler(err, mi_atomic_load_ptr_acquire(void,&mi_error_arg));
}
else {
mi_error_default(err);
// --------------------------------------------------------
static void mi_strlcpy(char* dest, const char* src, size_t dest_size) {
- dest[0] = 0;
- #pragma warning(suppress:4996)
- strncpy(dest, src, dest_size - 1);
- dest[dest_size - 1] = 0;
+ if (dest==NULL || src==NULL || dest_size == 0) return;
+ // copy until end of src, or when dest is (almost) full
+ while (*src != 0 && dest_size > 1) {
+ *dest++ = *src++;
+ dest_size--;
+ }
+ // always zero terminate
+ *dest = 0;
}
static void mi_strlcat(char* dest, const char* src, size_t dest_size) {
- #pragma warning(suppress:4996)
- strncat(dest, src, dest_size - 1);
- dest[dest_size - 1] = 0;
+ if (dest==NULL || src==NULL || dest_size == 0) return;
+ // find end of string in the dest buffer
+ while (*dest != 0 && dest_size > 1) {
+ dest++;
+ dest_size--;
+ }
+ // and catenate
+ mi_strlcpy(dest, src, dest_size);
}
+#ifdef MI_NO_GETENV
+static bool mi_getenv(const char* name, char* result, size_t result_size) {
+ MI_UNUSED(name);
+ MI_UNUSED(result);
+ MI_UNUSED(result_size);
+ return false;
+}
+#else
static inline int mi_strnicmp(const char* s, const char* t, size_t n) {
if (n==0) return 0;
for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) {
}
return (n==0 ? 0 : *s - *t);
}
-
#if defined _WIN32
// On Windows use GetEnvironmentVariable instead of getenv to work
// reliably even when this is invoked before the C runtime is initialized.
#elif !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0)
// On Posix systemsr use `environ` to acces environment variables
// even before the C runtime is initialized.
-#if defined(__APPLE__)
+#if defined(__APPLE__) && defined(__has_include) && __has_include(<crt_externs.h>)
#include <crt_externs.h>
static char** mi_get_environ(void) {
return (*_NSGetEnviron());
return false;
}
}
-#endif
+#endif // !MI_USE_ENVIRON
+#endif // !MI_NO_GETENV
static void mi_option_init(mi_option_desc_t* desc) {
// Read option value from the environment
+ char s[64+1];
char buf[64+1];
mi_strlcpy(buf, "mimalloc_", sizeof(buf));
mi_strlcat(buf, desc->name, sizeof(buf));
- char s[64+1];
- if (mi_getenv(buf, s, sizeof(s))) {
+ bool found = mi_getenv(buf,s,sizeof(s));
+ if (!found && desc->legacy_name != NULL) {
+ mi_strlcpy(buf, "mimalloc_", sizeof(buf));
+ mi_strlcat(buf, desc->legacy_name, sizeof(buf));
+ found = mi_getenv(buf,s,sizeof(s));
+ if (found) {
+ _mi_warning_message("environment option \"mimalloc_%s\" is deprecated -- use \"mimalloc_%s\" instead.\n", desc->legacy_name, desc->name );
+ }
+ }
+
+ if (found) {
size_t len = strlen(s);
if (len >= sizeof(buf)) len = sizeof(buf) - 1;
for (size_t i = 0; i < len; i++) {
else {
char* end = buf;
long value = strtol(buf, &end, 10);
+ if (desc->option == mi_option_reserve_os_memory) {
+ // this option is interpreted in KiB to prevent overflow of `long`
+ if (*end == 'K') { end++; }
+ else if (*end == 'M') { value *= MI_KiB; end++; }
+ else if (*end == 'G') { value *= MI_MiB; end++; }
+ else { value = (value + MI_KiB - 1) / MI_KiB; }
+ if (end[0] == 'I' && end[1] == 'B') { end += 2; }
+ else if (*end == 'B') { end++; }
+ }
if (*end == 0) {
desc->value = value;
desc->init = INITIALIZED;
}
else {
- _mi_warning_message("environment option mimalloc_%s has an invalid value: %s\n", desc->name, buf);
+ // set `init` first to avoid recursion through _mi_warning_message on mimalloc_verbose.
desc->init = DEFAULTED;
+ if (desc->option == mi_option_verbose && desc->value == 0) {
+ // if the 'mimalloc_verbose' env var has a bogus value we'd never know
+ // (since the value defaults to 'off') so in that case briefly enable verbose
+ desc->value = 1;
+ _mi_warning_message("environment option mimalloc_%s has an invalid value.\n", desc->name );
+ desc->value = 0;
+ }
+ else {
+ _mi_warning_message("environment option mimalloc_%s has an invalid value.\n", desc->name );
+ }
}
}
mi_assert_internal(desc->init != UNINIT);
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include <string.h> // strerror
+#ifdef _MSC_VER
+#pragma warning(disable:4996) // strerror
+#endif
+
+#if defined(__wasi__)
+#define MI_USE_SBRK
+#endif
#if defined(_WIN32)
#include <windows.h>
#elif defined(__wasi__)
-// stdlib.h is all we need, and has already been included in mimalloc.h
+#include <unistd.h> // sbrk
#else
#include <sys/mman.h> // mmap
#include <unistd.h> // sysconf
#if defined(__linux__)
#include <features.h>
+#include <fcntl.h>
#if defined(__GLIBC__)
#include <linux/mman.h> // linux mmap flags
#else
#include <mach/vm_statistics.h>
#endif
#endif
-#if defined(__HAIKU__)
-#define madvise posix_madvise
-#define MADV_DONTNEED POSIX_MADV_DONTNEED
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#if __FreeBSD_version >= 1200000
+#include <sys/cpuset.h>
+#include <sys/domainset.h>
+#endif
+#include <sys/sysctl.h>
#endif
#endif
On windows initializes support for aligned allocation and
large OS pages (if MIMALLOC_LARGE_OS_PAGES is true).
----------------------------------------------------------- */
-bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats);
+bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats);
+bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats);
static void* mi_align_up_ptr(void* p, size_t alignment) {
return (void*)_mi_align_up((uintptr_t)p, alignment);
}
-static uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
- return (sz / alignment) * alignment;
-}
-
static void* mi_align_down_ptr(void* p, size_t alignment) {
return (void*)_mi_align_down((uintptr_t)p, alignment);
}
+
// page size (initialized properly in `os_init`)
static size_t os_page_size = 4096;
// if non-zero, use large page allocation
static size_t large_os_page_size = 0;
+// is memory overcommit allowed?
+// set dynamically in _mi_os_init (and if true we use MAP_NORESERVE)
+static bool os_overcommit = true;
+
+bool _mi_os_has_overcommit(void) {
+ return os_overcommit;
+}
+
// OS (small) page size
-size_t _mi_os_page_size() {
+size_t _mi_os_page_size(void) {
return os_page_size;
}
// if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB)
-size_t _mi_os_large_page_size() {
+size_t _mi_os_large_page_size(void) {
return (large_os_page_size != 0 ? large_os_page_size : _mi_os_page_size());
}
+#if !defined(MI_USE_SBRK) && !defined(__wasi__)
static bool use_large_os_page(size_t size, size_t alignment) {
// if we have access, check the size and alignment requirements
if (large_os_page_size == 0 || !mi_option_is_enabled(mi_option_large_os_pages)) return false;
return ((size % large_os_page_size) == 0 && (alignment % large_os_page_size) == 0);
}
+#endif
// round to a good OS allocation size (bounded by max 12.5% waste)
size_t _mi_os_good_alloc_size(size_t size) {
size_t align_size;
- if (size < 512*KiB) align_size = _mi_os_page_size();
- else if (size < 2*MiB) align_size = 64*KiB;
- else if (size < 8*MiB) align_size = 256*KiB;
- else if (size < 32*MiB) align_size = 1*MiB;
- else align_size = 4*MiB;
- if (size >= (SIZE_MAX - align_size)) return size; // possible overflow?
+ if (size < 512*MI_KiB) align_size = _mi_os_page_size();
+ else if (size < 2*MI_MiB) align_size = 64*MI_KiB;
+ else if (size < 8*MI_MiB) align_size = 256*MI_KiB;
+ else if (size < 32*MI_MiB) align_size = 1*MI_MiB;
+ else align_size = 4*MI_MiB;
+ if (mi_unlikely(size >= (SIZE_MAX - align_size))) return size; // possible overflow?
return _mi_align_up(size, align_size);
}
// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016.
// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility)
// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB)
-//
-// We hide MEM_EXTENDED_PARAMETER to compile with older SDK's.
+// We define a minimal MEM_EXTENDED_PARAMETER ourselves in order to be able to compile with older SDK's.
+typedef enum MI_MEM_EXTENDED_PARAMETER_TYPE_E {
+ MiMemExtendedParameterInvalidType = 0,
+ MiMemExtendedParameterAddressRequirements,
+ MiMemExtendedParameterNumaNode,
+ MiMemExtendedParameterPartitionHandle,
+ MiMemExtendedParameterUserPhysicalHandle,
+ MiMemExtendedParameterAttributeFlags,
+ MiMemExtendedParameterMax
+} MI_MEM_EXTENDED_PARAMETER_TYPE;
+
+typedef struct DECLSPEC_ALIGN(8) MI_MEM_EXTENDED_PARAMETER_S {
+ struct { DWORD64 Type : 8; DWORD64 Reserved : 56; } Type;
+ union { DWORD64 ULong64; PVOID Pointer; SIZE_T Size; HANDLE Handle; DWORD ULong; } Arg;
+} MI_MEM_EXTENDED_PARAMETER;
+
+typedef struct MI_MEM_ADDRESS_REQUIREMENTS_S {
+ PVOID LowestStartingAddress;
+ PVOID HighestEndingAddress;
+ SIZE_T Alignment;
+} MI_MEM_ADDRESS_REQUIREMENTS;
+
+#define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010
+
#include <winternl.h>
-typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ void*, ULONG);
-typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ PVOID, ULONG);
+typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);
+typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);
static PVirtualAlloc2 pVirtualAlloc2 = NULL;
static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;
// Similarly, GetNumaProcesorNodeEx is only supported since Windows 7
-#if (_WIN32_WINNT < 0x601) // before Win7
-typedef struct _PROCESSOR_NUMBER { WORD Group; BYTE Number; BYTE Reserved; } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
-#endif
-typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(PPROCESSOR_NUMBER ProcNumber);
-typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(PPROCESSOR_NUMBER Processor, PUSHORT NodeNumber);
+typedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER;
+
+typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);
+typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);
typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);
static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;
static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL;
static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL;
-static bool mi_win_enable_large_os_pages()
+static bool mi_win_enable_large_os_pages(void)
{
if (large_os_page_size > 0) return true;
return (ok!=0);
}
-void _mi_os_init(void) {
+void _mi_os_init(void)
+{
+ os_overcommit = false;
// get the page size
SYSTEM_INFO si;
GetSystemInfo(&si);
}
}
#elif defined(__wasi__)
-void _mi_os_init() {
- os_page_size = 0x10000; // WebAssembly has a fixed page size: 64KB
+void _mi_os_init(void) {
+ os_overcommit = false;
+ os_page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB
os_alloc_granularity = 16;
}
+
+#else // generic unix
+
+static void os_detect_overcommit(void) {
+#if defined(__linux__)
+ int fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY);
+ if (fd < 0) return;
+ char buf[32];
+ ssize_t nread = read(fd, &buf, sizeof(buf));
+ close(fd);
+ // <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>
+ // 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE)
+ if (nread >= 1) {
+ os_overcommit = (buf[0] == '0' || buf[0] == '1');
+ }
+#elif defined(__FreeBSD__)
+ int val = 0;
+ size_t olen = sizeof(val);
+ if (sysctlbyname("vm.overcommit", &val, &olen, NULL, 0) == 0) {
+ os_overcommit = (val != 0);
+ }
#else
-void _mi_os_init() {
+ // default: overcommit is true
+#endif
+}
+
+void _mi_os_init(void) {
// get the page size
long result = sysconf(_SC_PAGESIZE);
if (result > 0) {
os_page_size = (size_t)result;
os_alloc_granularity = os_page_size;
}
- large_os_page_size = 2*MiB; // TODO: can we query the OS for this?
+ large_os_page_size = 2*MI_MiB; // TODO: can we query the OS for this?
+ os_detect_overcommit();
+}
+#endif
+
+
+#if defined(MADV_NORMAL)
+static int mi_madvise(void* addr, size_t length, int advice) {
+ #if defined(__sun)
+ return madvise((caddr_t)addr, length, advice); // Solaris needs cast (issue #520)
+ #else
+ return madvise(addr, length, advice);
+ #endif
}
#endif
/* -----------------------------------------------------------
- Raw allocation on Windows (VirtualAlloc) and Unix's (mmap).
------------------------------------------------------------ */
+ aligned hinting
+-------------------------------------------------------------- */
+
+// On 64-bit systems, we can do efficient aligned allocation by using
+// the 2TiB to 30TiB area to allocate those.
+#if (MI_INTPTR_SIZE >= 8)
+static mi_decl_cache_align _Atomic(uintptr_t)aligned_base;
+
+// Return a MI_SEGMENT_SIZE aligned address that is probably available.
+// If this returns NULL, the OS will determine the address but on some OS's that may not be
+// properly aligned which can be more costly as it needs to be adjusted afterwards.
+// For a size > 1GiB this always returns NULL in order to guarantee good ASLR randomization;
+// (otherwise an initial large allocation of say 2TiB has a 50% chance to include (known) addresses
+// in the middle of the 2TiB - 6TiB address range (see issue #372))
+
+#define MI_HINT_BASE ((uintptr_t)2 << 40) // 2TiB start
+#define MI_HINT_AREA ((uintptr_t)4 << 40) // upto 6TiB (since before win8 there is "only" 8TiB available to processes)
+#define MI_HINT_MAX ((uintptr_t)30 << 40) // wrap after 30TiB (area after 32TiB is used for huge OS pages)
+
+static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size)
+{
+ if (try_alignment <= 1 || try_alignment > MI_SEGMENT_SIZE) return NULL;
+ size = _mi_align_up(size, MI_SEGMENT_SIZE);
+ if (size > 1*MI_GiB) return NULL; // guarantee the chance of fixed valid address is at most 1/(MI_HINT_AREA / 1<<30) = 1/4096.
+ #if (MI_SECURE>0)
+ size += MI_SEGMENT_SIZE; // put in `MI_SEGMENT_SIZE` virtual gaps between hinted blocks; this splits VLA's but increases guarded areas.
+ #endif
+
+ uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size);
+ if (hint == 0 || hint > MI_HINT_MAX) { // wrap or initialize
+ uintptr_t init = MI_HINT_BASE;
+ #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of aligned allocations unless in debug mode
+ uintptr_t r = _mi_heap_random_next(mi_get_default_heap());
+ init = init + ((MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)) % MI_HINT_AREA); // (randomly 20 bits)*4MiB == 0 to 4TiB
+ #endif
+ uintptr_t expected = hint + size;
+ mi_atomic_cas_strong_acq_rel(&aligned_base, &expected, init);
+ hint = mi_atomic_add_acq_rel(&aligned_base, size); // this may still give 0 or > MI_HINT_MAX but that is ok, it is a hint after all
+ }
+ if (hint%try_alignment != 0) return NULL;
+ return (void*)hint;
+}
+#else
+static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) {
+ MI_UNUSED(try_alignment); MI_UNUSED(size);
+ return NULL;
+}
+#endif
+
+/* -----------------------------------------------------------
+ Free memory
+-------------------------------------------------------------- */
static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats_t* stats)
{
if (addr == NULL || size == 0) return true; // || _mi_os_is_huge_reserved(addr)
bool err = false;
#if defined(_WIN32)
+ DWORD errcode = 0;
err = (VirtualFree(addr, 0, MEM_RELEASE) == 0);
-#elif defined(__wasi__)
- err = 0; // WebAssembly's heap cannot be shrunk
+ if (err) { errcode = GetLastError(); }
+ if (errcode == ERROR_INVALID_ADDRESS) {
+ // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside
+ // the memory region returned by VirtualAlloc; in that case we need to free using
+ // the start of the region.
+ MEMORY_BASIC_INFORMATION info = { 0, 0 };
+ VirtualQuery(addr, &info, sizeof(info));
+ if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < MI_SEGMENT_SIZE) {
+ errcode = 0;
+ err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0);
+ if (err) { errcode = GetLastError(); }
+ }
+ }
+ if (errcode != 0) {
+ _mi_warning_message("unable to release OS memory: error code 0x%x, addr: %p, size: %zu\n", errcode, addr, size);
+ }
+#elif defined(MI_USE_SBRK) || defined(__wasi__)
+ err = false; // sbrk heap cannot be shrunk
#else
err = (munmap(addr, size) == -1);
-#endif
- if (was_committed) _mi_stat_decrease(&stats->committed, size);
- _mi_stat_decrease(&stats->reserved, size);
if (err) {
- #pragma warning(suppress:4996)
- _mi_warning_message("munmap failed: %s, addr 0x%8li, size %lu\n", strerror(errno), (size_t)addr, size);
- return false;
- }
- else {
- return true;
+ _mi_warning_message("unable to release OS memory: %s, addr: %p, size: %zu\n", strerror(errno), addr, size);
}
+#endif
+ if (was_committed) { _mi_stat_decrease(&stats->committed, size); }
+ _mi_stat_decrease(&stats->reserved, size);
+ return !err;
}
-static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size);
+
+/* -----------------------------------------------------------
+ Raw allocation on Windows (VirtualAlloc)
+-------------------------------------------------------------- */
#ifdef _WIN32
+
+#define MEM_COMMIT_RESERVE (MEM_COMMIT|MEM_RESERVE)
+
static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment, DWORD flags) {
#if (MI_INTPTR_SIZE >= 8)
- // on 64-bit systems, try to use the virtual address area after 4TiB for 4MiB aligned allocations
- void* hint;
- if (addr == NULL && (hint = mi_os_get_aligned_hint(try_alignment,size)) != NULL) {
- void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE);
- if (p != NULL) return p;
- DWORD err = GetLastError();
- if (err != ERROR_INVALID_ADDRESS && // If linked with multiple instances, we may have tried to allocate at an already allocated area (#210)
- err != ERROR_INVALID_PARAMETER) { // Windows7 instability (#230)
- return NULL;
+ // on 64-bit systems, try to use the virtual address area after 2TiB for 4MiB aligned allocations
+ if (addr == NULL) {
+ void* hint = mi_os_get_aligned_hint(try_alignment,size);
+ if (hint != NULL) {
+ void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE);
+ if (p != NULL) return p;
+ _mi_verbose_message("warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags);
+ // fall through on error
}
- // fall through
}
#endif
-#if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS)
// on modern Windows try use VirtualAlloc2 for aligned allocation
- if (try_alignment > 0 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) {
- MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 };
+ if (try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) {
+ MI_MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 };
reqs.Alignment = try_alignment;
- MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} };
- param.Type = MemExtendedParameterAddressRequirements;
- param.Pointer = &reqs;
- return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1);
+ MI_MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} };
+ param.Type.Type = MiMemExtendedParameterAddressRequirements;
+ param.Arg.Pointer = &reqs;
+ void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1);
+ if (p != NULL) return p;
+ _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags);
+ // fall through on error
}
-#endif
// last resort
return VirtualAlloc(addr, size, flags, PAGE_READWRITE);
}
static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) {
mi_assert_internal(!(large_only && !allow_large));
- static volatile _Atomic(uintptr_t) large_page_try_ok; // = 0;
+ static _Atomic(size_t) large_page_try_ok; // = 0;
void* p = NULL;
+ // Try to allocate large OS pages (2MiB) if allowed or required.
if ((large_only || use_large_os_page(size, try_alignment))
&& allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) {
- uintptr_t try_ok = mi_atomic_read(&large_page_try_ok);
+ size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);
if (!large_only && try_ok > 0) {
// if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive.
// therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times.
- mi_atomic_cas_weak(&large_page_try_ok, try_ok - 1, try_ok);
+ mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);
}
else {
// large OS pages must always reserve and commit.
if (large_only) return p;
// fall back to non-large page allocation on error (`p == NULL`).
if (p == NULL) {
- mi_atomic_write(&large_page_try_ok,10); // on error, don't try again for the next N allocations
+ mi_atomic_store_release(&large_page_try_ok,10UL); // on error, don't try again for the next N allocations
}
}
}
+ // Fall back to regular page allocation
if (p == NULL) {
*is_large = ((flags&MEM_LARGE_PAGES) != 0);
p = mi_win_virtual_allocx(addr, size, try_alignment, flags);
}
if (p == NULL) {
- _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, GetLastError(), addr, large_only, allow_large);
+ _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large);
}
return p;
}
+/* -----------------------------------------------------------
+ Raw allocation using `sbrk` or `wasm_memory_grow`
+-------------------------------------------------------------- */
+
+#elif defined(MI_USE_SBRK) || defined(__wasi__)
+#if defined(MI_USE_SBRK)
+ static void* mi_memory_grow( size_t size ) {
+ void* p = sbrk(size);
+ if (p == (void*)(-1)) return NULL;
+ #if !defined(__wasi__) // on wasi this is always zero initialized already (?)
+ memset(p,0,size);
+ #endif
+ return p;
+ }
#elif defined(__wasi__)
-static void* mi_wasm_heap_grow(size_t size, size_t try_alignment) {
- uintptr_t base = __builtin_wasm_memory_size(0) * _mi_os_page_size();
- uintptr_t aligned_base = _mi_align_up(base, (uintptr_t) try_alignment);
- size_t alloc_size = _mi_align_up( aligned_base - base + size, _mi_os_page_size());
- mi_assert(alloc_size >= size && (alloc_size % _mi_os_page_size()) == 0);
- if (alloc_size < size) return NULL;
- if (__builtin_wasm_memory_grow(0, alloc_size / _mi_os_page_size()) == SIZE_MAX) {
+ static void* mi_memory_grow( size_t size ) {
+ size_t base = (size > 0 ? __builtin_wasm_memory_grow(0,_mi_divide_up(size, _mi_os_page_size()))
+ : __builtin_wasm_memory_size(0));
+ if (base == SIZE_MAX) return NULL;
+ return (void*)(base * _mi_os_page_size());
+ }
+#endif
+
+#if defined(MI_USE_PTHREADS)
+static pthread_mutex_t mi_heap_grow_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+static void* mi_heap_grow(size_t size, size_t try_alignment) {
+ void* p = NULL;
+ if (try_alignment <= 1) {
+ // `sbrk` is not thread safe in general so try to protect it (we could skip this on WASM but leave it in for now)
+ #if defined(MI_USE_PTHREADS)
+ pthread_mutex_lock(&mi_heap_grow_mutex);
+ #endif
+ p = mi_memory_grow(size);
+ #if defined(MI_USE_PTHREADS)
+ pthread_mutex_unlock(&mi_heap_grow_mutex);
+ #endif
+ }
+ else {
+ void* base = NULL;
+ size_t alloc_size = 0;
+ // to allocate aligned use a lock to try to avoid thread interaction
+ // between getting the current size and actual allocation
+ // (also, `sbrk` is not thread safe in general)
+ #if defined(MI_USE_PTHREADS)
+ pthread_mutex_lock(&mi_heap_grow_mutex);
+ #endif
+ {
+ void* current = mi_memory_grow(0); // get current size
+ if (current != NULL) {
+ void* aligned_current = mi_align_up_ptr(current, try_alignment); // and align from there to minimize wasted space
+ alloc_size = _mi_align_up( ((uint8_t*)aligned_current - (uint8_t*)current) + size, _mi_os_page_size());
+ base = mi_memory_grow(alloc_size);
+ }
+ }
+ #if defined(MI_USE_PTHREADS)
+ pthread_mutex_unlock(&mi_heap_grow_mutex);
+ #endif
+ if (base != NULL) {
+ p = mi_align_up_ptr(base, try_alignment);
+ if ((uint8_t*)p + size > (uint8_t*)base + alloc_size) {
+ // another thread used wasm_memory_grow/sbrk in-between and we do not have enough
+ // space after alignment. Give up (and waste the space as we cannot shrink :-( )
+ // (in `mi_os_mem_alloc_aligned` this will fall back to overallocation to align)
+ p = NULL;
+ }
+ }
+ }
+ if (p == NULL) {
+ _mi_warning_message("unable to allocate sbrk/wasm_memory_grow OS memory (%zu bytes, %zu alignment)\n", size, try_alignment);
errno = ENOMEM;
return NULL;
}
- return (void*)aligned_base;
+ mi_assert_internal( try_alignment == 0 || (uintptr_t)p % try_alignment == 0 );
+ return p;
}
-#else
+
+/* -----------------------------------------------------------
+ Raw allocation on Unix's (mmap)
+-------------------------------------------------------------- */
+#else
#define MI_OS_USE_MMAP
static void* mi_unix_mmapx(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) {
- void* p = NULL;
- #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED)
- // on 64-bit systems, use the virtual address area after 4TiB for 4MiB aligned allocations
- void* hint;
- if (addr == NULL && (hint = mi_os_get_aligned_hint(try_alignment, size)) != NULL) {
- p = mmap(hint,size,protect_flags,flags,fd,0);
- if (p==MAP_FAILED) p = NULL; // fall back to regular mmap
+ MI_UNUSED(try_alignment);
+ #if defined(MAP_ALIGNED) // BSD
+ if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {
+ size_t n = mi_bsr(try_alignment);
+ if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB
+ flags |= MAP_ALIGNED(n);
+ void* p = mmap(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd, 0);
+ if (p!=MAP_FAILED) return p;
+ // fall back to regular mmap
+ }
+ }
+ #elif defined(MAP_ALIGN) // Solaris
+ if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {
+ void* p = mmap((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd, 0); // addr parameter is the required alignment
+ if (p!=MAP_FAILED) return p;
+ // fall back to regular mmap
}
- #else
- UNUSED(try_alignment);
- UNUSED(mi_os_get_aligned_hint);
#endif
- if (p==NULL) {
- p = mmap(addr,size,protect_flags,flags,fd,0);
- if (p==MAP_FAILED) p = NULL;
+ #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED)
+ // on 64-bit systems, use the virtual address area after 2TiB for 4MiB aligned allocations
+ if (addr == NULL) {
+ void* hint = mi_os_get_aligned_hint(try_alignment, size);
+ if (hint != NULL) {
+ void* p = mmap(hint, size, protect_flags, flags, fd, 0);
+ if (p!=MAP_FAILED) return p;
+ // fall back to regular mmap
+ }
}
- return p;
+ #endif
+ // regular mmap
+ void* p = mmap(addr, size, protect_flags, flags, fd, 0);
+ if (p!=MAP_FAILED) return p;
+ // failed to allocate
+ return NULL;
+}
+
+static int mi_unix_mmap_fd(void) {
+#if defined(VM_MAKE_TAG)
+ // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99)
+ int os_tag = (int)mi_option_get(mi_option_os_tag);
+ if (os_tag < 100 || os_tag > 255) os_tag = 100;
+ return VM_MAKE_TAG(os_tag);
+#else
+ return -1;
+#endif
}
static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) {
#if !defined(MAP_NORESERVE)
#define MAP_NORESERVE 0
#endif
- int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
- int fd = -1;
- #if defined(MAP_ALIGNED) // BSD
- if (try_alignment > 0) {
- size_t n = _mi_bsr(try_alignment);
- if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB
- flags |= MAP_ALIGNED(n);
- }
- }
- #endif
+ const int fd = mi_unix_mmap_fd();
+ int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ if (_mi_os_has_overcommit()) {
+ flags |= MAP_NORESERVE;
+ }
#if defined(PROT_MAX)
protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD
- #endif
- #if defined(VM_MAKE_TAG)
- // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99)
- int os_tag = (int)mi_option_get(mi_option_os_tag);
- if (os_tag < 100 || os_tag > 255) os_tag = 100;
- fd = VM_MAKE_TAG(os_tag);
- #endif
+ #endif
+ // huge page allocation
if ((large_only || use_large_os_page(size, try_alignment)) && allow_large) {
- static volatile _Atomic(uintptr_t) large_page_try_ok; // = 0;
- uintptr_t try_ok = mi_atomic_read(&large_page_try_ok);
+ static _Atomic(size_t) large_page_try_ok; // = 0;
+ size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);
if (!large_only && try_ok > 0) {
// If the OS is not configured for large OS pages, or the user does not have
// enough permission, the `mmap` will always fail (but it might also fail for other reasons).
// Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times
// to avoid too many failing calls to mmap.
- mi_atomic_cas_weak(&large_page_try_ok, try_ok - 1, try_ok);
+ mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);
}
else {
int lflags = flags & ~MAP_NORESERVE; // using NORESERVE on huge pages seems to fail on Linux
#endif
#ifdef MAP_HUGE_1GB
static bool mi_huge_pages_available = true;
- if ((size % GiB) == 0 && mi_huge_pages_available) {
+ if ((size % MI_GiB) == 0 && mi_huge_pages_available) {
lflags |= MAP_HUGE_1GB;
}
else
#endif
if (large_only) return p;
if (p == NULL) {
- mi_atomic_write(&large_page_try_ok, 10); // on error, don't try again for the next N allocations
+ mi_atomic_store_release(&large_page_try_ok, (size_t)8); // on error, don't try again for the next N allocations
}
}
}
}
+ // regular allocation
if (p == NULL) {
*is_large = false;
p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, flags, fd);
- #if defined(MADV_HUGEPAGE)
- // Many Linux systems don't allow MAP_HUGETLB but they support instead
- // transparent huge pages (THP). It is not required to call `madvise` with MADV_HUGE
- // though since properly aligned allocations will already use large pages if available
- // in that case -- in particular for our large regions (in `memory.c`).
- // However, some systems only allow THP if called with explicit `madvise`, so
- // when large OS pages are enabled for mimalloc, we call `madvice` anyways.
- if (allow_large && use_large_os_page(size, try_alignment)) {
- if (madvise(p, size, MADV_HUGEPAGE) == 0) {
- *is_large = true; // possibly
- };
- }
- #endif
- #if defined(__sun)
- if (allow_large && use_large_os_page(size, try_alignment)) {
- struct memcntl_mha cmd = {0};
- cmd.mha_pagesize = large_os_page_size;
- cmd.mha_cmd = MHA_MAPSIZE_VA;
- if (memcntl(p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {
- *is_large = true;
+ if (p != NULL) {
+ #if defined(MADV_HUGEPAGE)
+ // Many Linux systems don't allow MAP_HUGETLB but they support instead
+ // transparent huge pages (THP). Generally, it is not required to call `madvise` with MADV_HUGE
+ // though since properly aligned allocations will already use large pages if available
+ // in that case -- in particular for our large regions (in `memory.c`).
+ // However, some systems only allow THP if called with explicit `madvise`, so
+ // when large OS pages are enabled for mimalloc, we call `madvise` anyways.
+ if (allow_large && use_large_os_page(size, try_alignment)) {
+ if (mi_madvise(p, size, MADV_HUGEPAGE) == 0) {
+ *is_large = true; // possibly
+ };
}
+ #elif defined(__sun)
+ if (allow_large && use_large_os_page(size, try_alignment)) {
+ struct memcntl_mha cmd = {0};
+ cmd.mha_pagesize = large_os_page_size;
+ cmd.mha_cmd = MHA_MAPSIZE_VA;
+ if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {
+ *is_large = true;
+ }
+ }
+ #endif
}
- #endif
}
if (p == NULL) {
_mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, errno, addr, large_only, allow_large);
}
#endif
-// On 64-bit systems, we can do efficient aligned allocation by using
-// the 4TiB to 30TiB area to allocate them.
-#if (MI_INTPTR_SIZE >= 8) && (defined(_WIN32) || (defined(MI_OS_USE_MMAP) && !defined(MAP_ALIGNED)))
-static volatile mi_decl_cache_align _Atomic(uintptr_t) aligned_base;
-
-// Return a 4MiB aligned address that is probably available
-static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) {
- if (try_alignment == 0 || try_alignment > MI_SEGMENT_SIZE) return NULL;
- if ((size%MI_SEGMENT_SIZE) != 0) return NULL;
- uintptr_t hint = mi_atomic_add(&aligned_base, size);
- if (hint == 0 || hint > ((intptr_t)30<<40)) { // try to wrap around after 30TiB (area after 32TiB is used for huge OS pages)
- uintptr_t init = ((uintptr_t)4 << 40); // start at 4TiB area
- #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of aligned allocations unless in debug mode
- uintptr_t r = _mi_heap_random_next(mi_get_default_heap());
- init = init + (MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)); // (randomly 20 bits)*4MiB == 0 to 4TiB
- #endif
- mi_atomic_cas_strong(&aligned_base, init, hint + size);
- hint = mi_atomic_add(&aligned_base, size); // this may still give 0 or > 30TiB but that is ok, it is a hint after all
- }
- if (hint%try_alignment != 0) return NULL;
- return (void*)hint;
-}
-#else
-static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) {
- UNUSED(try_alignment); UNUSED(size);
- return NULL;
-}
-#endif
+/* -----------------------------------------------------------
+ Primitive allocation from the OS.
+-------------------------------------------------------------- */
-// Primitive allocation from the OS.
// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.
static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) {
mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
if (size == 0) return NULL;
if (!commit) allow_large = false;
+ if (try_alignment == 0) try_alignment = 1; // avoid 0 to ensure there will be no divide by zero when aligning
void* p = NULL;
/*
#if defined(_WIN32)
int flags = MEM_RESERVE;
- if (commit) flags |= MEM_COMMIT;
+ if (commit) { flags |= MEM_COMMIT; }
p = mi_win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large);
- #elif defined(__wasi__)
+ #elif defined(MI_USE_SBRK) || defined(__wasi__)
+ MI_UNUSED(allow_large);
*is_large = false;
- p = mi_wasm_heap_grow(size, try_alignment);
+ p = mi_heap_grow(size, try_alignment);
#else
int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE);
p = mi_unix_mmap(NULL, size, try_alignment, protect_flags, false, allow_large, is_large);
static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) {
mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0));
mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
+ mi_assert_internal(is_large != NULL);
if (!commit) allow_large = false;
if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL;
size = _mi_align_up(size, _mi_os_page_size());
// try first with a hint (this will be aligned directly on Win 10+ or BSD)
void* p = mi_os_mem_alloc(size, alignment, commit, allow_large, is_large, stats);
if (p == NULL) return NULL;
-
+
// if not aligned, free it, overallocate, and unmap around it
if (((uintptr_t)p % alignment != 0)) {
mi_os_mem_free(p, size, commit, stats);
+ _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (%zu bytes, address: %p, alignment: %zu, commit: %d)\n", size, p, alignment, commit);
if (size >= (SIZE_MAX - alignment)) return NULL; // overflow
- size_t over_size = size + alignment;
+ const size_t over_size = size + alignment;
#if _WIN32
- // over-allocate and than re-allocate exactly at an aligned address in there.
- // this may fail due to threads allocating at the same time so we
- // retry this at most 3 times before giving up.
- // (we can not decommit around the overallocation on Windows, because we can only
- // free the original pointer, not one pointing inside the area)
- int flags = MEM_RESERVE;
- if (commit) flags |= MEM_COMMIT;
- for (int tries = 0; tries < 3; tries++) {
- // over-allocate to determine a virtual memory range
- p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats);
- if (p == NULL) return NULL; // error
- if (((uintptr_t)p % alignment) == 0) {
- // if p happens to be aligned, just decommit the left-over area
- _mi_os_decommit((uint8_t*)p + size, over_size - size, stats);
- break;
- }
- else {
- // otherwise free and allocate at an aligned address in there
- mi_os_mem_free(p, over_size, commit, stats);
- void* aligned_p = mi_align_up_ptr(p, alignment);
- p = mi_win_virtual_alloc(aligned_p, size, alignment, flags, false, allow_large, is_large);
- if (p == aligned_p) break; // success!
- if (p != NULL) { // should not happen?
- mi_os_mem_free(p, size, commit, stats);
- p = NULL;
- }
- }
+ // over-allocate uncommitted (virtual) memory
+ p = mi_os_mem_alloc(over_size, 0 /*alignment*/, false /* commit? */, false /* allow_large */, is_large, stats);
+ if (p == NULL) return NULL;
+
+ // set p to the aligned part in the full region
+ // note: this is dangerous on Windows as VirtualFree needs the actual region pointer
+ // but in mi_os_mem_free we handle this (hopefully exceptional) situation.
+ p = mi_align_up_ptr(p, alignment);
+
+ // explicitly commit only the aligned part
+ if (commit) {
+ _mi_os_commit(p, size, NULL, stats);
}
#else
// overallocate...
- p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats);
+ p = mi_os_mem_alloc(over_size, 1, commit, false, is_large, stats);
if (p == NULL) return NULL;
- // and selectively unmap parts around the over-allocated area.
+ // and selectively unmap parts around the over-allocated area. (noop on sbrk)
void* aligned_p = mi_align_up_ptr(p, alignment);
size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p;
size_t mid_size = _mi_align_up(size, _mi_os_page_size());
mi_assert_internal(pre_size < over_size && post_size < over_size && mid_size >= size);
if (pre_size > 0) mi_os_mem_free(p, pre_size, commit, stats);
if (post_size > 0) mi_os_mem_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats);
- // we can return the aligned pointer on `mmap` systems
+ // we can return the aligned pointer on `mmap` (and sbrk) systems
p = aligned_p;
#endif
}
return p;
}
+
/* -----------------------------------------------------------
OS API: alloc, free, alloc_aligned
----------------------------------------------------------- */
-void* _mi_os_alloc(size_t size, mi_stats_t* stats) {
+void* _mi_os_alloc(size_t size, mi_stats_t* tld_stats) {
+ MI_UNUSED(tld_stats);
+ mi_stats_t* stats = &_mi_stats_main;
if (size == 0) return NULL;
size = _mi_os_good_alloc_size(size);
bool is_large = false;
return mi_os_mem_alloc(size, 0, true, false, &is_large, stats);
}
-void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* stats) {
+void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* tld_stats) {
+ MI_UNUSED(tld_stats);
+ mi_stats_t* stats = &_mi_stats_main;
if (size == 0 || p == NULL) return;
size = _mi_os_good_alloc_size(size);
mi_os_mem_free(p, size, was_committed, stats);
_mi_os_free_ex(p, size, true, stats);
}
-void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld)
+void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_stats_t* tld_stats)
{
+ MI_UNUSED(&mi_os_get_aligned_hint); // suppress unused warnings
+ MI_UNUSED(tld_stats);
if (size == 0) return NULL;
size = _mi_os_good_alloc_size(size);
alignment = _mi_align_up(alignment, _mi_os_page_size());
allow_large = *large;
*large = false;
}
- return mi_os_mem_alloc_aligned(size, alignment, commit, allow_large, (large!=NULL?large:&allow_large), tld->stats);
+ return mi_os_mem_alloc_aligned(size, alignment, commit, allow_large, (large!=NULL?large:&allow_large), &_mi_stats_main /*tld->stats*/ );
}
" > sudo sysctl -w vm.max_map_count=262144\n");
}
#else
- UNUSED(err);
+ MI_UNUSED(err);
#endif
}
if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr))
int err = 0;
if (commit) {
- _mi_stat_increase(&stats->committed, csize);
+ _mi_stat_increase(&stats->committed, size); // use size for precise commit vs. decommit
_mi_stat_counter_increase(&stats->commit_calls, 1);
}
else {
- _mi_stat_decrease(&stats->committed, csize);
+ _mi_stat_decrease(&stats->committed, size);
}
#if defined(_WIN32)
if (commit) {
- // if the memory was already committed, the call succeeds but it is not zero'd
- // *is_zero = true;
+ // *is_zero = true; // note: if the memory was already committed, the call succeeds but the memory is not zero'd
void* p = VirtualAlloc(start, csize, MEM_COMMIT, PAGE_READWRITE);
err = (p == start ? 0 : GetLastError());
}
}
#elif defined(__wasi__)
// WebAssembly guests can't control memory protection
- #elif defined(MAP_FIXED)
- if (!commit) {
- // use mmap with MAP_FIXED to discard the existing memory (and reduce commit charge)
- void* p = mmap(start, csize, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), -1, 0);
+ #elif 0 && defined(MAP_FIXED) && !defined(__APPLE__)
+ // Linux: disabled for now as mmap fixed seems much more expensive than MADV_DONTNEED (and splits VMA's?)
+ if (commit) {
+ // commit: just change the protection
+ err = mprotect(start, csize, (PROT_READ | PROT_WRITE));
+ if (err != 0) { err = errno; }
+ }
+ else {
+ // decommit: use mmap with MAP_FIXED to discard the existing memory (and reduce rss)
+ const int fd = mi_unix_mmap_fd();
+ void* p = mmap(start, csize, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), fd, 0);
if (p != start) { err = errno; }
}
- else {
- // for commit, just change the protection
+ #else
+ // Linux, macOSX and others.
+ if (commit) {
+ // commit: ensure we can access the area
err = mprotect(start, csize, (PROT_READ | PROT_WRITE));
if (err != 0) { err = errno; }
+ }
+ else {
+ #if defined(MADV_DONTNEED) && MI_DEBUG == 0 && MI_SECURE == 0
+ // decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE)
+ // (on the other hand, MADV_FREE would be good enough.. it is just not reflected in the stats :-( )
+ err = madvise(start, csize, MADV_DONTNEED);
+ #else
+ // decommit: just disable access (also used in debug and secure mode to trap on illegal access)
+ err = mprotect(start, csize, PROT_NONE);
+ if (err != 0) { err = errno; }
+ #endif
+ //#if defined(MADV_FREE_REUSE)
+ // while ((err = mi_madvise(start, csize, MADV_FREE_REUSE)) != 0 && errno == EAGAIN) { errno = 0; }
+ //#endif
}
- #else
- err = mprotect(start, csize, (commit ? (PROT_READ | PROT_WRITE) : PROT_NONE));
- if (err != 0) { err = errno; }
#endif
if (err != 0) {
- _mi_warning_message("%s error: start: %p, csize: 0x%x, err: %i\n", commit ? "commit" : "decommit", start, csize, err);
+ _mi_warning_message("%s error: start: %p, csize: 0x%zx, err: %i\n", commit ? "commit" : "decommit", start, csize, err);
mi_mprotect_hint(err);
}
mi_assert_internal(err == 0);
return (err == 0);
}
-bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) {
+bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) {
+ MI_UNUSED(tld_stats);
+ mi_stats_t* stats = &_mi_stats_main;
return mi_os_commitx(addr, size, true, false /* liberal */, is_zero, stats);
}
-bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats) {
+bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* tld_stats) {
+ MI_UNUSED(tld_stats);
+ mi_stats_t* stats = &_mi_stats_main;
bool is_zero;
return mi_os_commitx(addr, size, false, true /* conservative */, &is_zero, stats);
}
-bool _mi_os_commit_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) {
- return mi_os_commitx(addr, size, true, true /* conservative */, is_zero, stats);
+/*
+static bool mi_os_commit_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) {
+ return mi_os_commitx(addr, size, true, true // conservative
+ , is_zero, stats);
}
+*/
// Signal to the OS that the address range is no longer in use
// but may be used later again. This will release physical memory
if (p != start) return false;
#else
#if defined(MADV_FREE)
- static int advice = MADV_FREE;
- int err = madvise(start, csize, advice);
- if (err != 0 && errno == EINVAL && advice == MADV_FREE) {
+ static _Atomic(size_t) advice = MI_ATOMIC_VAR_INIT(MADV_FREE);
+ int oadvice = (int)mi_atomic_load_relaxed(&advice);
+ int err;
+ while ((err = mi_madvise(start, csize, oadvice)) != 0 && errno == EAGAIN) { errno = 0; };
+ if (err != 0 && errno == EINVAL && oadvice == MADV_FREE) {
// if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on
- advice = MADV_DONTNEED;
- err = madvise(start, csize, advice);
+ mi_atomic_store_release(&advice, (size_t)MADV_DONTNEED);
+ err = mi_madvise(start, csize, MADV_DONTNEED);
}
#elif defined(__wasi__)
int err = 0;
#else
- int err = madvise(start, csize, MADV_DONTNEED);
+ int err = mi_madvise(start, csize, MADV_DONTNEED);
#endif
if (err != 0) {
- _mi_warning_message("madvise reset error: start: %p, csize: 0x%x, errno: %i\n", start, csize, errno);
+ _mi_warning_message("madvise reset error: start: %p, csize: 0x%zx, errno: %i\n", start, csize, errno);
}
//mi_assert(err == 0);
if (err != 0) return false;
// but may be used later again. This will release physical memory
// pages and reduce swapping while keeping the memory committed.
// We page align to a conservative area inside the range to reset.
-bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) {
- if (mi_option_is_enabled(mi_option_reset_decommits)) {
- return _mi_os_decommit(addr, size, stats);
- }
- else {
- return mi_os_resetx(addr, size, true, stats);
- }
+bool _mi_os_reset(void* addr, size_t size, mi_stats_t* tld_stats) {
+ MI_UNUSED(tld_stats);
+ mi_stats_t* stats = &_mi_stats_main;
+ return mi_os_resetx(addr, size, true, stats);
}
-bool _mi_os_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) {
+/*
+bool _mi_os_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) {
+ MI_UNUSED(tld_stats);
+ mi_stats_t* stats = &_mi_stats_main;
if (mi_option_is_enabled(mi_option_reset_decommits)) {
- return _mi_os_commit_unreset(addr, size, is_zero, stats); // re-commit it (conservatively!)
+ return mi_os_commit_unreset(addr, size, is_zero, stats); // re-commit it (conservatively!)
}
else {
*is_zero = false;
return mi_os_resetx(addr, size, false, stats);
}
}
-
+*/
// Protect a region in memory to be not accessible.
static bool mi_os_protectx(void* addr, size_t size, bool protect) {
if (err != 0) { err = errno; }
#endif
if (err != 0) {
- _mi_warning_message("mprotect error: start: %p, csize: 0x%x, err: %i\n", start, csize, err);
+ _mi_warning_message("mprotect error: start: %p, csize: 0x%zx, err: %i\n", start, csize, err);
mi_mprotect_hint(err);
}
return (err == 0);
Support for allocating huge OS pages (1Gib) that are reserved up-front
and possibly associated with a specific NUMA node. (use `numa_node>=0`)
-----------------------------------------------------------------------------*/
-#define MI_HUGE_OS_PAGE_SIZE (GiB)
+#define MI_HUGE_OS_PAGE_SIZE (MI_GiB)
#if defined(_WIN32) && (MI_INTPTR_SIZE >= 8)
static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node)
{
- mi_assert_internal(size%GiB == 0);
+ mi_assert_internal(size%MI_GiB == 0);
mi_assert_internal(addr != NULL);
const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE;
mi_win_enable_large_os_pages();
- #if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS)
- MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };
+ MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };
// on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages
static bool mi_huge_pages_available = true;
if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) {
- #ifndef MEM_EXTENDED_PARAMETER_NONPAGED_HUGE
- #define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE (0x10)
- #endif
- params[0].Type = 5; // == MemExtendedParameterAttributeFlags;
- params[0].ULong64 = MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;
+ params[0].Type.Type = MiMemExtendedParameterAttributeFlags;
+ params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;
ULONG param_count = 1;
if (numa_node >= 0) {
param_count++;
- params[1].Type = MemExtendedParameterNumaNode;
- params[1].ULong = (unsigned)numa_node;
+ params[1].Type.Type = MiMemExtendedParameterNumaNode;
+ params[1].Arg.ULong = (unsigned)numa_node;
}
SIZE_T psize = size;
void* base = addr;
else {
// fall back to regular large pages
mi_huge_pages_available = false; // don't try further huge pages
- _mi_warning_message("unable to allocate using huge (1gb) pages, trying large (2mb) pages instead (status 0x%lx)\n", err);
+ _mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err);
}
}
// on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation
if (pVirtualAlloc2 != NULL && numa_node >= 0) {
- params[0].Type = MemExtendedParameterNumaNode;
- params[0].ULong = (unsigned)numa_node;
+ params[0].Type.Type = MiMemExtendedParameterNumaNode;
+ params[0].Arg.ULong = (unsigned)numa_node;
return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, params, 1);
}
- #else
- UNUSED(numa_node);
- #endif
+
// otherwise use regular virtual alloc on older windows
return VirtualAlloc(addr, size, flags, PAGE_READWRITE);
}
}
#else
static long mi_os_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) {
- UNUSED(start); UNUSED(len); UNUSED(mode); UNUSED(nmask); UNUSED(maxnode); UNUSED(flags);
+ MI_UNUSED(start); MI_UNUSED(len); MI_UNUSED(mode); MI_UNUSED(nmask); MI_UNUSED(maxnode); MI_UNUSED(flags);
return 0;
}
#endif
static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) {
- mi_assert_internal(size%GiB == 0);
+ mi_assert_internal(size%MI_GiB == 0);
bool is_large = true;
void* p = mi_unix_mmap(addr, size, MI_SEGMENT_SIZE, PROT_READ | PROT_WRITE, true, true, &is_large);
if (p == NULL) return NULL;
if (numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes
- uintptr_t numa_mask = (1UL << numa_node);
+ unsigned long numa_mask = (1UL << numa_node);
// TODO: does `mbind` work correctly for huge OS pages? should we
// use `set_mempolicy` before calling mmap instead?
// see: <https://lkml.org/lkml/2017/2/9/875>
long err = mi_os_mbind(p, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0);
if (err != 0) {
- _mi_warning_message("failed to bind huge (1gb) pages to numa node %d: %s\n", numa_node, strerror(errno));
+ _mi_warning_message("failed to bind huge (1GiB) pages to numa node %d: %s\n", numa_node, strerror(errno));
}
}
return p;
}
#else
static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) {
- UNUSED(addr); UNUSED(size); UNUSED(numa_node);
+ MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(numa_node);
return NULL;
}
#endif
uintptr_t start = 0;
uintptr_t end = 0;
- uintptr_t expected;
+ uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start);
do {
- start = expected = mi_atomic_read_relaxed(&mi_huge_start);
+ start = huge_start;
if (start == 0) {
// Initialize the start address after the 32TiB area
start = ((uintptr_t)32 << 40); // 32TiB virtual start address
}
end = start + size;
mi_assert_internal(end % MI_SEGMENT_SIZE == 0);
- } while (!mi_atomic_cas_strong(&mi_huge_start, end, expected));
+ } while (!mi_atomic_cas_strong_acq_rel(&mi_huge_start, &huge_start, end));
if (total_size != NULL) *total_size = size;
return (uint8_t*)start;
}
#else
static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) {
- UNUSED(pages);
+ MI_UNUSED(pages);
if (total_size != NULL) *total_size = 0;
return NULL;
}
}
}
mi_assert_internal(page*MI_HUGE_OS_PAGE_SIZE <= size);
- if (pages_reserved != NULL) *pages_reserved = page;
- if (psize != NULL) *psize = page * MI_HUGE_OS_PAGE_SIZE;
+ if (pages_reserved != NULL) { *pages_reserved = page; }
+ if (psize != NULL) { *psize = page * MI_HUGE_OS_PAGE_SIZE; }
return (page == 0 ? NULL : start);
}
while (size >= MI_HUGE_OS_PAGE_SIZE) {
_mi_os_free(base, MI_HUGE_OS_PAGE_SIZE, stats);
size -= MI_HUGE_OS_PAGE_SIZE;
+ base += MI_HUGE_OS_PAGE_SIZE;
}
}
Support NUMA aware allocation
-----------------------------------------------------------------------------*/
#ifdef _WIN32
-static size_t mi_os_numa_nodex() {
+static size_t mi_os_numa_nodex(void) {
USHORT numa_node = 0;
if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) {
// Extended API is supported
- PROCESSOR_NUMBER pnum;
+ MI_PROCESSOR_NUMBER pnum;
(*pGetCurrentProcessorNumberEx)(&pnum);
USHORT nnode = 0;
BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);
}
return (node+1);
}
+#elif defined(__FreeBSD__) && __FreeBSD_version >= 1200000
+static size_t mi_os_numa_nodex(void) {
+ domainset_t dom;
+ size_t node;
+ int policy;
+ if (cpuset_getdomain(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(dom), &dom, &policy) == -1) return 0ul;
+ for (node = 0; node < MAXMEMDOM; node++) {
+ if (DOMAINSET_ISSET(node, &dom)) return node;
+ }
+ return 0ul;
+}
+static size_t mi_os_numa_node_countx(void) {
+ size_t ndomains = 0;
+ size_t len = sizeof(ndomains);
+ if (sysctlbyname("vm.ndomains", &ndomains, &len, NULL, 0) == -1) return 0ul;
+ return ndomains;
+}
+#elif defined(__DragonFly__)
+static size_t mi_os_numa_nodex(void) {
+ // TODO: DragonFly does not seem to provide any userland means to get this information.
+ return 0ul;
+}
+static size_t mi_os_numa_node_countx(void) {
+ size_t ncpus = 0, nvirtcoresperphys = 0;
+ size_t len = sizeof(size_t);
+ if (sysctlbyname("hw.ncpu", &ncpus, &len, NULL, 0) == -1) return 0ul;
+ if (sysctlbyname("hw.cpu_topology_ht_ids", &nvirtcoresperphys, &len, NULL, 0) == -1) return 0ul;
+ return nvirtcoresperphys * ncpus;
+}
#else
static size_t mi_os_numa_nodex(void) {
return 0;
}
#endif
-size_t _mi_numa_node_count = 0; // cache the node count
+_Atomic(size_t) _mi_numa_node_count; // = 0 // cache the node count
size_t _mi_os_numa_node_count_get(void) {
- if (mi_unlikely(_mi_numa_node_count <= 0)) {
+ size_t count = mi_atomic_load_acquire(&_mi_numa_node_count);
+ if (count <= 0) {
long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly?
- if (ncount <= 0) ncount = (long)mi_os_numa_node_countx(); // or detect dynamically
- _mi_numa_node_count = (size_t)(ncount <= 0 ? 1 : ncount);
- _mi_verbose_message("using %zd numa regions\n", _mi_numa_node_count);
+ if (ncount > 0) {
+ count = (size_t)ncount;
+ }
+ else {
+ count = mi_os_numa_node_countx(); // or detect dynamically
+ if (count == 0) count = 1;
+ }
+ mi_atomic_store_release(&_mi_numa_node_count, count); // save it
+ _mi_verbose_message("using %zd numa regions\n", count);
}
- mi_assert_internal(_mi_numa_node_count >= 1);
- return _mi_numa_node_count;
+ return count;
}
int _mi_os_numa_node_get(mi_os_tld_t* tld) {
- UNUSED(tld);
+ MI_UNUSED(tld);
size_t numa_count = _mi_os_numa_node_count();
if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0
// never more than the node count and >= 0
/*----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
static inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) {
- return (pq->block_size == (MI_LARGE_OBJ_SIZE_MAX+sizeof(uintptr_t)));
+ return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+sizeof(uintptr_t)));
}
static inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) {
- return (pq->block_size == (MI_LARGE_OBJ_SIZE_MAX+(2*sizeof(uintptr_t))));
+ return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+(2*sizeof(uintptr_t))));
}
static inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) {
- return (pq->block_size > MI_LARGE_OBJ_SIZE_MAX);
+ return (pq->block_size > MI_MEDIUM_OBJ_SIZE_MAX);
}
/* -----------------------------------------------------------
Bins
----------------------------------------------------------- */
-// Bit scan reverse: return the index of the highest bit.
-static inline uint8_t mi_bsr32(uint32_t x);
-
-#if defined(_MSC_VER)
-#include <intrin.h>
-static inline uint8_t mi_bsr32(uint32_t x) {
- uint32_t idx;
- _BitScanReverse((DWORD*)&idx, x);
- return (uint8_t)idx;
-}
-#elif defined(__GNUC__) || defined(__clang__)
-static inline uint8_t mi_bsr32(uint32_t x) {
- return (31 - __builtin_clz(x));
-}
-#else
-static inline uint8_t mi_bsr32(uint32_t x) {
- // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
- static const uint8_t debruijn[32] = {
- 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12,
- 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13,
- };
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- x++;
- return debruijn[(x*0x076be629) >> 27];
-}
-#endif
-
-// Bit scan reverse: return the index of the highest bit.
-uint8_t _mi_bsr(uintptr_t x) {
- if (x == 0) return 0;
-#if MI_INTPTR_SIZE==8
- uint32_t hi = (x >> 32);
- return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi));
-#elif MI_INTPTR_SIZE==4
- return mi_bsr32(x);
-#else
-# error "define bsr for non-32 or 64-bit platforms"
-#endif
-}
-
// Return the bin for a given field size.
// Returns MI_BIN_HUGE if the size is too large.
// We use `wsize` for the size in "machine word sizes",
// i.e. byte size == `wsize*sizeof(void*)`.
-extern inline uint8_t _mi_bin(size_t size) {
+static inline uint8_t mi_bin(size_t size) {
size_t wsize = _mi_wsize_from_size(size);
uint8_t bin;
if (wsize <= 1) {
bin = (uint8_t)wsize;
}
#endif
- else if (wsize > MI_LARGE_OBJ_WSIZE_MAX) {
+ else if (wsize > MI_MEDIUM_OBJ_WSIZE_MAX) {
bin = MI_BIN_HUGE;
}
else {
- #if defined(MI_ALIGN4W)
+ #if defined(MI_ALIGN4W)
if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes
#endif
wsize--;
// find the highest bit
- uint8_t b = mi_bsr32((uint32_t)wsize);
+ uint8_t b = (uint8_t)mi_bsr(wsize); // note: wsize != 0
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
// - adjust with 3 because we use do not round the first 8 sizes
// which each get an exact bin
Queue of pages with free blocks
----------------------------------------------------------- */
+uint8_t _mi_bin(size_t size) {
+ return mi_bin(size);
+}
+
size_t _mi_bin_size(uint8_t bin) {
return _mi_heap_empty.pages[bin].block_size;
}
// Good size for allocation
size_t mi_good_size(size_t size) mi_attr_noexcept {
- if (size <= MI_LARGE_OBJ_SIZE_MAX) {
- return _mi_bin_size(_mi_bin(size));
+ if (size <= MI_MEDIUM_OBJ_SIZE_MAX) {
+ return _mi_bin_size(mi_bin(size));
}
else {
return _mi_align_up(size,_mi_os_page_size());
#endif
static mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) {
- uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size));
+ uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : mi_bin(page->xblock_size));
mi_heap_t* heap = mi_page_heap(page);
mi_assert_internal(heap != NULL && bin <= MI_BIN_FULL);
mi_page_queue_t* pq = &heap->pages[bin];
}
static mi_page_queue_t* mi_heap_page_queue_of(mi_heap_t* heap, const mi_page_t* page) {
- uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size));
+ uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : mi_bin(page->xblock_size));
mi_assert_internal(bin <= MI_BIN_FULL);
mi_page_queue_t* pq = &heap->pages[bin];
mi_assert_internal(mi_page_is_in_full(page) || page->xblock_size == pq->block_size);
}
else {
// find previous size; due to minimal alignment upto 3 previous bins may need to be skipped
- uint8_t bin = _mi_bin(size);
+ uint8_t bin = mi_bin(size);
const mi_page_queue_t* prev = pq - 1;
- while( bin == _mi_bin(prev->block_size) && prev > &heap->pages[0]) {
+ while( bin == mi_bin(prev->block_size) && prev > &heap->pages[0]) {
prev--;
}
start = 1 + _mi_wsize_from_size(prev->block_size);
static void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) {
mi_assert_internal(page != NULL);
mi_assert_expensive(mi_page_queue_contains(queue, page));
- mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));
+ mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_MEDIUM_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));
mi_heap_t* heap = mi_page_heap(page);
+
if (page->prev != NULL) page->prev->next = page->next;
if (page->next != NULL) page->next->prev = page->prev;
if (page == queue->last) queue->last = page->prev;
heap->page_count--;
page->next = NULL;
page->prev = NULL;
- // mi_atomic_write_ptr(mi_atomic_cast(void*, &page->heap), NULL);
+ // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), NULL);
mi_page_set_in_full(page,false);
}
static void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) {
mi_assert_internal(mi_page_heap(page) == heap);
mi_assert_internal(!mi_page_queue_contains(queue, page));
- mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE);
+
+ mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE);
mi_assert_internal(page->xblock_size == queue->block_size ||
- (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) ||
+ (page->xblock_size > MI_MEDIUM_OBJ_SIZE_MAX) ||
(mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));
mi_page_set_in_full(page, mi_page_queue_is_full(queue));
- // mi_atomic_write_ptr(mi_atomic_cast(void*, &page->heap), heap);
+ // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), heap);
page->next = queue->first;
page->prev = NULL;
if (queue->first != NULL) {
mi_assert_internal(page != NULL);
mi_assert_expensive(mi_page_queue_contains(from, page));
mi_assert_expensive(!mi_page_queue_contains(to, page));
+
mi_assert_internal((page->xblock_size == to->block_size && page->xblock_size == from->block_size) ||
(page->xblock_size == to->block_size && mi_page_queue_is_full(from)) ||
(page->xblock_size == from->block_size && mi_page_queue_is_full(to)) ||
for (mi_page_t* page = append->first; page != NULL; page = page->next) {
// inline `mi_page_set_heap` to avoid wrong assertion during absorption;
// in this case it is ok to be delayed freeing since both "to" and "from" heap are still alive.
- mi_atomic_write(&page->xheap, (uintptr_t)heap);
+ mi_atomic_store_release(&page->xheap, (uintptr_t)heap);
// set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a
// side effect that it spins until any DELAYED_FREEING is finished. This ensures
// that after appending only the new heap will be used for delayed free operations.
/*----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
/* -----------------------------------------------------------
The core of the allocator. Every segment contains
- pages of a {certain block size. The main function
+ pages of a certain block size. The main function
exported is `mi_malloc_generic`.
----------------------------------------------------------- */
// Index a block in a page
static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) {
- UNUSED(page);
+ MI_UNUSED(page);
mi_assert_internal(page != NULL);
mi_assert_internal(i <= page->reserved);
return (mi_block_t*)((uint8_t*)page_start + (i * block_size));
mi_assert_internal(page->used <= page->capacity);
mi_assert_internal(page->capacity <= page->reserved);
- const size_t bsize = mi_page_block_size(page);
mi_segment_t* segment = _mi_page_segment(page);
uint8_t* start = _mi_page_start(segment,page,NULL);
- mi_assert_internal(start == _mi_segment_page_start(segment,page,bsize,NULL,NULL));
+ mi_assert_internal(start == _mi_segment_page_start(segment,page,NULL));
+ //const size_t bsize = mi_page_block_size(page);
//mi_assert_internal(start + page->capacity*page->block_size == page->top);
mi_assert_internal(mi_page_list_is_valid(page,page->free));
mi_assert_internal(mi_page_list_is_valid(page,page->local_free));
#if MI_DEBUG>3 // generally too expensive to check this
- if (page->flags.is_zero) {
- for(mi_block_t* block = page->free; block != NULL; mi_block_next(page,block)) {
- mi_assert_expensive(mi_mem_is_zero(block + 1, page->block_size - sizeof(mi_block_t)));
+ if (page->is_zero) {
+ const size_t ubsize = mi_page_usable_block_size(page);
+ for(mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) {
+ mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t)));
}
}
#endif
#endif
if (mi_page_heap(page)!=NULL) {
mi_segment_t* segment = _mi_page_segment(page);
- mi_assert_internal(!_mi_process_is_initialized || segment->thread_id == mi_page_heap(page)->thread_id || segment->thread_id==0);
- if (segment->page_kind != MI_PAGE_HUGE) {
+
+ mi_assert_internal(!_mi_process_is_initialized || segment->thread_id==0 || segment->thread_id == mi_page_heap(page)->thread_id);
+ if (segment->kind != MI_SEGMENT_HUGE) {
mi_page_queue_t* pq = mi_page_queue_of(page);
mi_assert_internal(mi_page_queue_contains(pq, page));
- mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_LARGE_OBJ_SIZE_MAX || mi_page_is_in_full(page));
+ mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_MEDIUM_OBJ_SIZE_MAX || mi_page_is_in_full(page));
mi_assert_internal(mi_heap_contains_queue(mi_page_heap(page),pq));
}
}
#endif
void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) {
- mi_thread_free_t tfree;
mi_thread_free_t tfreex;
mi_delayed_t old_delay;
+ mi_thread_free_t tfree;
do {
- tfree = mi_atomic_read(&page->xthread_free); // note: must acquire as we can break this loop and not do a CAS
+ tfree = mi_atomic_load_acquire(&page->xthread_free); // note: must acquire as we can break/repeat this loop and not do a CAS;
tfreex = mi_tf_set_delayed(tfree, delay);
old_delay = mi_tf_delayed(tfree);
if (mi_unlikely(old_delay == MI_DELAYED_FREEING)) {
break; // leave never-delayed flag set
}
} while ((old_delay == MI_DELAYED_FREEING) ||
- !mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree));
+ !mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));
}
/* -----------------------------------------------------------
static void _mi_page_thread_free_collect(mi_page_t* page)
{
mi_block_t* head;
- mi_thread_free_t tfree;
mi_thread_free_t tfreex;
+ mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free);
do {
- tfree = mi_atomic_read_relaxed(&page->xthread_free);
head = mi_tf_block(tfree);
tfreex = mi_tf_set_block(tfree,NULL);
- } while (!mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree));
+ } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tfree, tfreex));
// return if the list is empty
if (head == NULL) return;
// called from segments when reclaiming abandoned pages
void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page) {
mi_assert_expensive(mi_page_is_valid_init(page));
+
mi_assert_internal(mi_page_heap(page) == heap);
mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE);
- mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE);
+ mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE);
mi_assert_internal(!page->is_reset);
// TODO: push on full queue immediately if it is full?
mi_page_queue_t* pq = mi_page_queue(heap, mi_page_block_size(page));
// allocate a fresh page from a segment
static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size_t block_size) {
mi_assert_internal(pq==NULL||mi_heap_contains_queue(heap, pq));
- mi_assert_internal(pq==NULL||block_size == pq->block_size);
mi_page_t* page = _mi_segment_page_alloc(heap, block_size, &heap->tld->segments, &heap->tld->os);
if (page == NULL) {
// this may be out-of-memory, or an abandoned page was reclaimed (and in our queue)
return NULL;
}
- // a fresh page was found, initialize it
- mi_assert_internal(pq==NULL || _mi_page_segment(page)->page_kind != MI_PAGE_HUGE);
+ mi_assert_internal(pq==NULL || _mi_page_segment(page)->kind != MI_SEGMENT_HUGE);
mi_page_init(heap, page, block_size, heap->tld);
- _mi_stat_increase(&heap->tld->stats.pages, 1);
+ mi_heap_stat_increase(heap, pages, 1);
if (pq!=NULL) mi_page_queue_push(heap, pq, page); // huge pages use pq==NULL
mi_assert_expensive(_mi_page_is_valid(page));
return page;
(put there by other threads if they deallocated in a full page)
----------------------------------------------------------- */
void _mi_heap_delayed_free(mi_heap_t* heap) {
- // take over the list (note: no atomic exchange is it is often NULL)
- mi_block_t* block;
- do {
- block = mi_atomic_read_ptr_relaxed(mi_block_t,&heap->thread_delayed_free);
- } while (block != NULL && !mi_atomic_cas_ptr_weak(mi_block_t,&heap->thread_delayed_free, NULL, block));
+ // take over the list (note: no atomic exchange since it is often NULL)
+ mi_block_t* block = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);
+ while (block != NULL && !mi_atomic_cas_ptr_weak_acq_rel(mi_block_t, &heap->thread_delayed_free, &block, NULL)) { /* nothing */ };
// and free them all
while(block != NULL) {
if (!_mi_free_delayed_block(block)) {
// we might already start delayed freeing while another thread has not yet
// reset the delayed_freeing flag; in that case delay it further by reinserting.
- mi_block_t* dfree;
+ mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);
do {
- dfree = mi_atomic_read_ptr_relaxed(mi_block_t,&heap->thread_delayed_free);
mi_block_set_nextx(heap, block, dfree, heap->keys);
- } while (!mi_atomic_cas_ptr_weak(mi_block_t,&heap->thread_delayed_free, block, dfree));
+ } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block));
}
block = next;
}
// no more aligned blocks in here
mi_page_set_has_aligned(page, false);
+ mi_heap_t* heap = mi_page_heap(page);
+
// remove from the page list
// (no need to do _mi_heap_delayed_free first as all blocks are already free)
- mi_segments_tld_t* segments_tld = &mi_page_heap(page)->tld->segments;
+ mi_segments_tld_t* segments_tld = &heap->tld->segments;
mi_page_queue_remove(pq, page);
// and free it
_mi_segment_page_free(page, force, segments_tld);
}
-#define MI_MAX_RETIRE_SIZE MI_LARGE_OBJ_SIZE_MAX
+// Retire parameters
+#define MI_MAX_RETIRE_SIZE MI_MEDIUM_OBJ_SIZE_MAX
#define MI_RETIRE_CYCLES (8)
// Retire a page with no more used blocks
// Note: called from `mi_free` and benchmarks often
// trigger this due to freeing everything and then
// allocating again so careful when changing this.
-void _mi_page_retire(mi_page_t* page) {
+void _mi_page_retire(mi_page_t* page) mi_attr_noexcept {
mi_assert_internal(page != NULL);
mi_assert_expensive(_mi_page_is_valid(page));
mi_assert_internal(mi_page_all_free(page));
-
+
mi_page_set_has_aligned(page, false);
// don't retire too often..
if (mi_likely(page->xblock_size <= MI_MAX_RETIRE_SIZE && !mi_page_is_in_full(page))) {
if (pq->last==page && pq->first==page) { // the only page in the queue?
mi_stat_counter_increase(_mi_stats_main.page_no_retire,1);
- page->retire_expire = (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4);
+ page->retire_expire = 1 + (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4);
mi_heap_t* heap = mi_page_heap(page);
mi_assert_internal(pq >= heap->pages);
const size_t index = pq - heap->pages;
return; // dont't free after all
}
}
-
_mi_page_free(page, pq, false);
}
#define MI_MIN_SLICES (2)
static void mi_page_free_list_extend_secure(mi_heap_t* const heap, mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) {
- UNUSED(stats);
+ MI_UNUSED(stats);
#if (MI_SECURE<=2)
mi_assert_internal(page->free == NULL);
mi_assert_internal(page->local_free == NULL);
static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats)
{
- UNUSED(stats);
+ MI_UNUSED(stats);
#if (MI_SECURE <= 2)
mi_assert_internal(page->free == NULL);
mi_assert_internal(page->local_free == NULL);
// allocations but this did not speed up any benchmark (due to an
// extra test in malloc? or cache effects?)
static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) {
+ MI_UNUSED(tld);
mi_assert_expensive(mi_page_is_valid_init(page));
#if (MI_SECURE<=2)
mi_assert(page->free == NULL);
if (page->capacity >= page->reserved) return;
size_t page_size;
- //uint8_t* page_start =
_mi_page_start(_mi_page_segment(page), page, &page_size);
mi_stat_counter_increase(tld->stats.pages_extended, 1);
// calculate the extend count
const size_t bsize = (page->xblock_size < MI_HUGE_BLOCK_SIZE ? page->xblock_size : page_size);
size_t extend = page->reserved - page->capacity;
- size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/(uint32_t)bsize);
- if (max_extend < MI_MIN_EXTEND) max_extend = MI_MIN_EXTEND;
+ mi_assert_internal(extend > 0);
+ size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/(uint32_t)bsize);
+ if (max_extend < MI_MIN_EXTEND) { max_extend = MI_MIN_EXTEND; }
+ mi_assert_internal(max_extend > 0);
+
if (extend > max_extend) {
// ensure we don't touch memory beyond the page to reduce page commit.
// the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%.
- extend = (max_extend==0 ? 1 : max_extend);
+ extend = max_extend;
}
mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved);
mi_assert_internal(block_size > 0);
// set fields
mi_page_set_heap(page, heap);
+ page->xblock_size = (block_size < MI_HUGE_BLOCK_SIZE ? (uint32_t)block_size : MI_HUGE_BLOCK_SIZE); // initialize before _mi_segment_page_start
size_t page_size;
- _mi_segment_page_start(segment, page, block_size, &page_size, NULL);
- page->xblock_size = (block_size < MI_HUGE_BLOCK_SIZE ? (uint32_t)block_size : MI_HUGE_BLOCK_SIZE);
+ _mi_segment_page_start(segment, page, &page_size);
+ mi_assert_internal(mi_page_block_size(page) <= page_size);
+ mi_assert_internal(page_size <= page->slice_count*MI_SEGMENT_SLICE_SIZE);
mi_assert_internal(page_size / block_size < (1L<<16));
page->reserved = (uint16_t)(page_size / block_size);
#ifdef MI_ENCODE_FREELIST
page->keys[0] = _mi_heap_random_next(heap);
page->keys[1] = _mi_heap_random_next(heap);
#endif
+ #if MI_DEBUG > 0
+ page->is_zero = false; // ensure in debug mode we initialize with MI_DEBUG_UNINIT, see issue #501
+ #else
page->is_zero = page->is_zero_init;
+ #endif
+ mi_assert_internal(page->is_committed);
+ mi_assert_internal(!page->is_reset);
mi_assert_internal(page->capacity == 0);
mi_assert_internal(page->free == NULL);
mi_assert_internal(page->used == 0);
page = next;
} // for each page
- mi_stat_counter_increase(heap->tld->stats.searches, count);
+ mi_heap_stat_counter_increase(heap, searches, count);
if (page == NULL) {
- _mi_heap_collect_retired(heap, false); // perhaps make a page available
+ _mi_heap_collect_retired(heap, false); // perhaps make a page available?
page = mi_page_fresh(heap, pq);
if (page == NULL && first_try) {
// out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again
mi_page_queue_t* pq = mi_page_queue(heap,size);
mi_page_t* page = pq->first;
if (page != NULL) {
- if ((MI_SECURE >= 3) && page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) {
- // in secure mode, we extend half the time to increase randomness
+ #if (MI_SECURE>=3) // in secure mode, we extend half the time to increase randomness
+ if (page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) {
mi_page_extend_free(heap, page, heap->tld);
mi_assert_internal(mi_page_immediate_available(page));
}
- else {
+ else
+ #endif
+ {
_mi_page_free_collect(page,false);
}
+
if (mi_page_immediate_available(page)) {
page->retire_expire = 0;
return page; // fast path
----------------------------------------------------------- */
static mi_deferred_free_fun* volatile deferred_free = NULL;
-static volatile _Atomic(void*) deferred_arg; // = NULL
+static _Atomic(void*) deferred_arg; // = NULL
void _mi_deferred_free(mi_heap_t* heap, bool force) {
heap->tld->heartbeat++;
if (deferred_free != NULL && !heap->tld->recurse) {
heap->tld->recurse = true;
- deferred_free(force, heap->tld->heartbeat, mi_atomic_read_ptr_relaxed(void,&deferred_arg));
+ deferred_free(force, heap->tld->heartbeat, mi_atomic_load_ptr_relaxed(void,&deferred_arg));
heap->tld->recurse = false;
}
}
void mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept {
deferred_free = fn;
- mi_atomic_write_ptr(void,&deferred_arg, arg);
+ mi_atomic_store_ptr_release(void,&deferred_arg, arg);
}
General allocation
----------------------------------------------------------- */
-// A huge page is allocated directly without being in a queue.
+// Large and huge page allocation.
+// Huge pages are allocated directly without being in a queue.
// Because huge pages contain just one block, and the segment contains
// just that page, we always treat them as abandoned and any thread
// that frees the block can free the whole page and segment directly.
-static mi_page_t* mi_huge_page_alloc(mi_heap_t* heap, size_t size) {
+static mi_page_t* mi_large_huge_page_alloc(mi_heap_t* heap, size_t size) {
size_t block_size = _mi_os_good_alloc_size(size);
- mi_assert_internal(_mi_bin(block_size) == MI_BIN_HUGE);
- mi_page_t* page = mi_page_fresh_alloc(heap,NULL,block_size);
+ mi_assert_internal(mi_bin(block_size) == MI_BIN_HUGE);
+ bool is_huge = (block_size > MI_LARGE_OBJ_SIZE_MAX);
+ mi_page_queue_t* pq = (is_huge ? NULL : mi_page_queue(heap, block_size));
+ mi_page_t* page = mi_page_fresh_alloc(heap, pq, block_size);
if (page != NULL) {
- const size_t bsize = mi_page_block_size(page); // note: not `mi_page_usable_block_size` as `size` includes padding already
- mi_assert_internal(bsize >= size);
mi_assert_internal(mi_page_immediate_available(page));
- mi_assert_internal(_mi_page_segment(page)->page_kind==MI_PAGE_HUGE);
- mi_assert_internal(_mi_page_segment(page)->used==1);
- mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue
- mi_page_set_heap(page, NULL);
-
- if (bsize > MI_HUGE_OBJ_SIZE_MAX) {
- _mi_stat_increase(&heap->tld->stats.giant, bsize);
- _mi_stat_counter_increase(&heap->tld->stats.giant_count, 1);
+
+ if (pq == NULL) {
+ // huge pages are directly abandoned
+ mi_assert_internal(_mi_page_segment(page)->kind == MI_SEGMENT_HUGE);
+ mi_assert_internal(_mi_page_segment(page)->used==1);
+ mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue
+ mi_page_set_heap(page, NULL);
+ }
+ else {
+ mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE);
+ }
+
+ const size_t bsize = mi_page_usable_block_size(page); // note: not `mi_page_block_size` to account for padding
+ if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
+ mi_heap_stat_increase(heap, large, bsize);
+ mi_heap_stat_counter_increase(heap, large_count, 1);
}
else {
- _mi_stat_increase(&heap->tld->stats.huge, bsize);
- _mi_stat_counter_increase(&heap->tld->stats.huge_count, 1);
+ mi_heap_stat_increase(heap, huge, bsize);
+ mi_heap_stat_counter_increase(heap, huge_count, 1);
}
}
return page;
static mi_page_t* mi_find_page(mi_heap_t* heap, size_t size) mi_attr_noexcept {
// huge allocation?
const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size`
- if (mi_unlikely(req_size > (MI_LARGE_OBJ_SIZE_MAX - MI_PADDING_SIZE) )) {
+ if (mi_unlikely(req_size > (MI_MEDIUM_OBJ_SIZE_MAX - MI_PADDING_SIZE) )) {
if (mi_unlikely(req_size > PTRDIFF_MAX)) { // we don't allocate more than PTRDIFF_MAX (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)
_mi_error_message(EOVERFLOW, "allocation request is too large (%zu bytes)\n", req_size);
return NULL;
}
else {
- return mi_huge_page_alloc(heap,size);
+ return mi_large_huge_page_alloc(heap,size);
}
}
else {
/* ----------------------------------------------------------------------------
-Copyright (c) 2019, Microsoft Research, Daan Leijen
+Copyright (c) 2019-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE // for syscall() on Linux
+#endif
+
#include "mimalloc.h"
#include "mimalloc-internal.h"
static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) {
memset(ctx_new, 0, sizeof(*ctx_new));
- memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input));
+ _mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input));
ctx_new->input[12] = 0;
ctx_new->input[13] = 0;
ctx_new->input[14] = (uint32_t)nonce;
/* ----------------------------------------------------------------------------
To initialize a fresh random context we rely on the OS:
-- Windows : BCryptGenRandom
-- osX,bsd,wasi: arc4random_buf
+- Windows : BCryptGenRandom (or RtlGenRandom)
+- macOS : CCRandomGenerateBytes, arc4random_buf
+- bsd,wasi : arc4random_buf
- Linux : getrandom,/dev/urandom
If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR.
-----------------------------------------------------------------------------*/
#if defined(_WIN32)
+
+#if defined(MI_USE_RTLGENRANDOM) || defined(__cplusplus)
+// We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using
+// dynamic overriding, we observed it can raise an exception when compiled with C++, and
+// sometimes deadlocks when also running under the VS debugger.
+#pragma comment (lib,"advapi32.lib")
+#define RtlGenRandom SystemFunction036
+#ifdef __cplusplus
+extern "C" {
+#endif
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+#ifdef __cplusplus
+}
+#endif
+static bool os_random_buf(void* buf, size_t buf_len) {
+ return (RtlGenRandom(buf, (ULONG)buf_len) != 0);
+}
+#else
#pragma comment (lib,"bcrypt.lib")
#include <bcrypt.h>
static bool os_random_buf(void* buf, size_t buf_len) {
return (BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
}
-/*
-#define SystemFunction036 NTAPI SystemFunction036
-#include <NTSecAPI.h>
-#undef SystemFunction036
+#endif
+
+#elif defined(__APPLE__)
+#include <AvailabilityMacros.h>
+#if defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10
+#include <CommonCrypto/CommonCryptoError.h>
+#include <CommonCrypto/CommonRandom.h>
+#endif
static bool os_random_buf(void* buf, size_t buf_len) {
- RtlGenRandom(buf, (ULONG)buf_len);
- return true;
+ #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15
+ // We prefere CCRandomGenerateBytes as it returns an error code while arc4random_buf
+ // may fail silently on macOS. See PR #390, and <https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html>
+ return (CCRandomGenerateBytes(buf, buf_len) == kCCSuccess);
+ #else
+ // fall back on older macOS
+ arc4random_buf(buf, buf_len);
+ return true;
+ #endif
}
-*/
-#elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \
+
+#elif defined(__ANDROID__) || defined(__DragonFly__) || \
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
- defined(__sun) || defined(__wasi__)
+ defined(__sun) // todo: what to use with __wasi__?
#include <stdlib.h>
static bool os_random_buf(void* buf, size_t buf_len) {
arc4random_buf(buf, buf_len);
return true;
}
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__HAIKU__)
+#if defined(__linux__)
#include <sys/syscall.h>
+#endif
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef GRND_NONBLOCK
#define GRND_NONBLOCK (1)
#endif
- static volatile _Atomic(uintptr_t) no_getrandom; // = 0
- if (mi_atomic_read(&no_getrandom)==0) {
+ static _Atomic(uintptr_t) no_getrandom; // = 0
+ if (mi_atomic_load_acquire(&no_getrandom)==0) {
ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK);
if (ret >= 0) return (buf_len == (size_t)ret);
- if (ret != ENOSYS) return false;
- mi_atomic_write(&no_getrandom,1); // don't call again, and fall back to /dev/urandom
+ if (errno != ENOSYS) return false;
+ mi_atomic_store_release(&no_getrandom, 1UL); // don't call again, and fall back to /dev/urandom
}
#endif
int flags = O_RDONLY;
#include <time.h>
#endif
-uintptr_t _os_random_weak(uintptr_t extra_seed) {
- uintptr_t x = (uintptr_t)&_os_random_weak ^ extra_seed; // ASLR makes the address random
+uintptr_t _mi_os_random_weak(uintptr_t extra_seed) {
+ uintptr_t x = (uintptr_t)&_mi_os_random_weak ^ extra_seed; // ASLR makes the address random
+
#if defined(_WIN32)
LARGE_INTEGER pcount;
QueryPerformanceCounter(&pcount);
if (!os_random_buf(key, sizeof(key))) {
// if we fail to get random data from the OS, we fall back to a
// weak random source based on the current time
+ #if !defined(__wasi__)
_mi_warning_message("unable to use secure randomness\n");
- uintptr_t x = _os_random_weak(0);
+ #endif
+ uintptr_t x = _mi_os_random_weak(0);
for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words.
x = _mi_random_shuffle(x);
((uint32_t*)key)[i] = (uint32_t)x;
/* ----------------------------------------------------------------------------
-Copyright (c) 2019, Microsoft Research, Daan Leijen
+Copyright (c) 2019-2020, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include <string.h> // memset
-#include "bitmap.inc.c"
+#include "bitmap.h"
// Internal raw OS interface
-size_t _mi_os_large_page_size();
+size_t _mi_os_large_page_size(void);
bool _mi_os_protect(void* addr, size_t size);
bool _mi_os_unprotect(void* addr, size_t size);
bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats);
// arena.c
void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_stats_t* stats);
-void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
-void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
+void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
+void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
// Constants
#if (MI_INTPTR_SIZE==8)
-#define MI_HEAP_REGION_MAX_SIZE (256 * GiB) // 64KiB for the region map
+#define MI_HEAP_REGION_MAX_SIZE (256 * MI_GiB) // 64KiB for the region map
#elif (MI_INTPTR_SIZE==4)
-#define MI_HEAP_REGION_MAX_SIZE (3 * GiB) // ~ KiB for the region map
+#define MI_HEAP_REGION_MAX_SIZE (3 * MI_GiB) // ~ KiB for the region map
#else
#error "define the maximum heap space allowed for regions on this platform"
#endif
// Region info
typedef union mi_region_info_u {
- uintptr_t value;
+ size_t value;
struct {
bool valid; // initialized?
- bool is_large; // allocated in fixed large/huge OS pages
+ bool is_large:1; // allocated in fixed large/huge OS pages
+ bool is_pinned:1; // pinned memory cannot be decommitted
short numa_node; // the associated NUMA node (where -1 means no associated node)
} x;
} mi_region_info_t;
// A region owns a chunk of REGION_SIZE (256MiB) (virtual) memory with
// a bit map with one bit per MI_SEGMENT_SIZE (4MiB) block.
typedef struct mem_region_s {
- volatile _Atomic(uintptr_t) info; // mi_region_info_t.value
- volatile _Atomic(void*) start; // start of the memory area
- mi_bitmap_field_t in_use; // bit per in-use block
- mi_bitmap_field_t dirty; // track if non-zero per block
- mi_bitmap_field_t commit; // track if committed per block
- mi_bitmap_field_t reset; // track if reset per block
- volatile _Atomic(uintptr_t) arena_memid; // if allocated from a (huge page) arena
- uintptr_t padding; // round to 8 fields
+ _Atomic(size_t) info; // mi_region_info_t.value
+ _Atomic(void*) start; // start of the memory area
+ mi_bitmap_field_t in_use; // bit per in-use block
+ mi_bitmap_field_t dirty; // track if non-zero per block
+ mi_bitmap_field_t commit; // track if committed per block
+ mi_bitmap_field_t reset; // track if reset per block
+ _Atomic(size_t) arena_memid; // if allocated from a (huge page) arena
+ _Atomic(size_t) padding; // round to 8 fields (needs to be atomic for msvc, see issue #508)
} mem_region_t;
// The region map
static mem_region_t regions[MI_REGION_MAX];
// Allocated regions
-static volatile _Atomic(uintptr_t) regions_count; // = 0;
+static _Atomic(size_t) regions_count; // = 0;
/* ----------------------------------------------------------------------------
*/
// Return if a pointer points into a region reserved by us.
-bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {
+mi_decl_nodiscard bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {
if (p==NULL) return false;
- size_t count = mi_atomic_read_relaxed(®ions_count);
+ size_t count = mi_atomic_load_relaxed(®ions_count);
for (size_t i = 0; i < count; i++) {
- uint8_t* start = mi_atomic_read_ptr_relaxed(uint8_t,®ions[i].start);
+ uint8_t* start = (uint8_t*)mi_atomic_load_ptr_relaxed(uint8_t, ®ions[i].start);
if (start != NULL && (uint8_t*)p >= start && (uint8_t*)p < start + MI_REGION_SIZE) return true;
}
return false;
static void* mi_region_blocks_start(const mem_region_t* region, mi_bitmap_index_t bit_idx) {
- uint8_t* start = mi_atomic_read_ptr(uint8_t,®ion->start);
+ uint8_t* start = (uint8_t*)mi_atomic_load_ptr_acquire(uint8_t, &((mem_region_t*)region)->start);
mi_assert_internal(start != NULL);
return (start + (bit_idx * MI_SEGMENT_SIZE));
}
static bool mi_region_try_alloc_os(size_t blocks, bool commit, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld)
{
// not out of regions yet?
- if (mi_atomic_read_relaxed(®ions_count) >= MI_REGION_MAX - 1) return false;
+ if (mi_atomic_load_relaxed(®ions_count) >= MI_REGION_MAX - 1) return false;
// try to allocate a fresh region from the OS
bool region_commit = (commit && mi_option_is_enabled(mi_option_eager_region_commit));
bool region_large = (commit && allow_large);
bool is_zero = false;
+ bool is_pinned = false;
size_t arena_memid = 0;
- void* const start = _mi_arena_alloc_aligned(MI_REGION_SIZE, MI_SEGMENT_ALIGN, ®ion_commit, ®ion_large, &is_zero, &arena_memid, tld);
+ void* const start = _mi_arena_alloc_aligned(MI_REGION_SIZE, MI_SEGMENT_ALIGN, ®ion_commit, ®ion_large, &is_pinned, &is_zero, &arena_memid, tld);
if (start == NULL) return false;
mi_assert_internal(!(region_large && !allow_large));
mi_assert_internal(!region_large || region_commit);
// claim a fresh slot
- const uintptr_t idx = mi_atomic_increment(®ions_count);
+ const size_t idx = mi_atomic_increment_acq_rel(®ions_count);
if (idx >= MI_REGION_MAX) {
- mi_atomic_decrement(®ions_count);
+ mi_atomic_decrement_acq_rel(®ions_count);
_mi_arena_free(start, MI_REGION_SIZE, arena_memid, region_commit, tld->stats);
- _mi_warning_message("maximum regions used: %zu GiB (perhaps recompile with a larger setting for MI_HEAP_REGION_MAX_SIZE)", _mi_divide_up(MI_HEAP_REGION_MAX_SIZE, GiB));
+ _mi_warning_message("maximum regions used: %zu GiB (perhaps recompile with a larger setting for MI_HEAP_REGION_MAX_SIZE)", _mi_divide_up(MI_HEAP_REGION_MAX_SIZE, MI_GiB));
return false;
}
// allocated, initialize and claim the initial blocks
mem_region_t* r = ®ions[idx];
r->arena_memid = arena_memid;
- mi_atomic_write(&r->in_use, 0);
- mi_atomic_write(&r->dirty, (is_zero ? 0 : MI_BITMAP_FIELD_FULL));
- mi_atomic_write(&r->commit, (region_commit ? MI_BITMAP_FIELD_FULL : 0));
- mi_atomic_write(&r->reset, 0);
+ mi_atomic_store_release(&r->in_use, (size_t)0);
+ mi_atomic_store_release(&r->dirty, (is_zero ? 0 : MI_BITMAP_FIELD_FULL));
+ mi_atomic_store_release(&r->commit, (region_commit ? MI_BITMAP_FIELD_FULL : 0));
+ mi_atomic_store_release(&r->reset, (size_t)0);
*bit_idx = 0;
- mi_bitmap_claim(&r->in_use, 1, blocks, *bit_idx, NULL);
- mi_atomic_write_ptr(uint8_t*,&r->start, start);
+ _mi_bitmap_claim(&r->in_use, 1, blocks, *bit_idx, NULL);
+ mi_atomic_store_ptr_release(void,&r->start, start);
// and share it
mi_region_info_t info;
info.value = 0; // initialize the full union to zero
info.x.valid = true;
info.x.is_large = region_large;
+ info.x.is_pinned = is_pinned;
info.x.numa_node = (short)_mi_os_numa_node(tld);
- mi_atomic_write(&r->info, info.value); // now make it available to others
+ mi_atomic_store_release(&r->info, info.value); // now make it available to others
*region = r;
return true;
}
static bool mi_region_is_suitable(const mem_region_t* region, int numa_node, bool allow_large ) {
// initialized at all?
mi_region_info_t info;
- info.value = mi_atomic_read_relaxed(®ion->info);
+ info.value = mi_atomic_load_relaxed(&((mem_region_t*)region)->info);
if (info.value==0) return false;
// numa correct
static bool mi_region_try_claim(int numa_node, size_t blocks, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld)
{
// try all regions for a free slot
- const size_t count = mi_atomic_read(®ions_count);
+ const size_t count = mi_atomic_load_relaxed(®ions_count); // monotonic, so ok to be relaxed
size_t idx = tld->region_idx; // Or start at 0 to reuse low addresses? Starting at 0 seems to increase latency though
for (size_t visited = 0; visited < count; visited++, idx++) {
if (idx >= count) idx = 0; // wrap around
// if this region suits our demand (numa node matches, large OS page matches)
if (mi_region_is_suitable(r, numa_node, allow_large)) {
// then try to atomically claim a segment(s) in this region
- if (mi_bitmap_try_find_claim_field(&r->in_use, 0, blocks, bit_idx)) {
+ if (_mi_bitmap_try_find_claim_field(&r->in_use, 0, blocks, bit_idx)) {
tld->region_idx = idx; // remember the last found position
*region = r;
return true;
}
-static void* mi_region_try_alloc(size_t blocks, bool* commit, bool* is_large, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
+static void* mi_region_try_alloc(size_t blocks, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
{
mi_assert_internal(blocks <= MI_BITMAP_FIELD_BITS);
mem_region_t* region;
mi_bitmap_index_t bit_idx;
const int numa_node = (_mi_os_numa_node_count() <= 1 ? -1 : _mi_os_numa_node(tld));
// try to claim in existing regions
- if (!mi_region_try_claim(numa_node, blocks, *is_large, ®ion, &bit_idx, tld)) {
+ if (!mi_region_try_claim(numa_node, blocks, *large, ®ion, &bit_idx, tld)) {
// otherwise try to allocate a fresh region and claim in there
- if (!mi_region_try_alloc_os(blocks, *commit, *is_large, ®ion, &bit_idx, tld)) {
+ if (!mi_region_try_alloc_os(blocks, *commit, *large, ®ion, &bit_idx, tld)) {
// out of regions or memory
return NULL;
}
// ------------------------------------------------
// found a region and claimed `blocks` at `bit_idx`, initialize them now
mi_assert_internal(region != NULL);
- mi_assert_internal(mi_bitmap_is_claimed(®ion->in_use, 1, blocks, bit_idx));
+ mi_assert_internal(_mi_bitmap_is_claimed(®ion->in_use, 1, blocks, bit_idx));
mi_region_info_t info;
- info.value = mi_atomic_read(®ion->info);
- uint8_t* start = mi_atomic_read_ptr(uint8_t,®ion->start);
- mi_assert_internal(!(info.x.is_large && !*is_large));
+ info.value = mi_atomic_load_acquire(®ion->info);
+ uint8_t* start = (uint8_t*)mi_atomic_load_ptr_acquire(uint8_t,®ion->start);
+ mi_assert_internal(!(info.x.is_large && !*large));
mi_assert_internal(start != NULL);
- *is_zero = mi_bitmap_claim(®ion->dirty, 1, blocks, bit_idx, NULL);
- *is_large = info.x.is_large;
- *memid = mi_memid_create(region, bit_idx);
+ *is_zero = _mi_bitmap_claim(®ion->dirty, 1, blocks, bit_idx, NULL);
+ *large = info.x.is_large;
+ *is_pinned = info.x.is_pinned;
+ *memid = mi_memid_create(region, bit_idx);
void* p = start + (mi_bitmap_index_bit_in_field(bit_idx) * MI_SEGMENT_SIZE);
// commit
if (*commit) {
// ensure commit
bool any_uncommitted;
- mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, &any_uncommitted);
+ _mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, &any_uncommitted);
if (any_uncommitted) {
- mi_assert_internal(!info.x.is_large);
- bool commit_zero;
- _mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld);
- if (commit_zero) *is_zero = true;
+ mi_assert_internal(!info.x.is_large && !info.x.is_pinned);
+ bool commit_zero = false;
+ if (!_mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld)) {
+ // failed to commit! unclaim and return
+ mi_bitmap_unclaim(®ion->in_use, 1, blocks, bit_idx);
+ return NULL;
+ }
+ if (commit_zero) *is_zero = true;
}
}
else {
// no need to commit, but check if already fully committed
- *commit = mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx);
+ *commit = _mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx);
}
- mi_assert_internal(!*commit || mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx));
+ mi_assert_internal(!*commit || _mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx));
// unreset reset blocks
- if (mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx)) {
+ if (_mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx)) {
// some blocks are still reset
- mi_assert_internal(!info.x.is_large);
+ mi_assert_internal(!info.x.is_large && !info.x.is_pinned);
mi_assert_internal(!mi_option_is_enabled(mi_option_eager_commit) || *commit || mi_option_get(mi_option_eager_commit_delay) > 0);
mi_bitmap_unclaim(®ion->reset, 1, blocks, bit_idx);
if (*commit || !mi_option_is_enabled(mi_option_reset_decommits)) { // only if needed
if (reset_zero) *is_zero = true;
}
}
- mi_assert_internal(!mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx));
+ mi_assert_internal(!_mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx));
#if (MI_DEBUG>=2)
if (*commit) { ((uint8_t*)p)[0] = 0; }
// Allocate `size` memory aligned at `alignment`. Return non NULL on success, with a given memory `id`.
// (`id` is abstract, but `id = idx*MI_REGION_MAP_BITS + bitidx`)
-void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
+void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
{
mi_assert_internal(memid != NULL && tld != NULL);
mi_assert_internal(size > 0);
*memid = 0;
*is_zero = false;
+ *is_pinned = false;
bool default_large = false;
if (large==NULL) large = &default_large; // ensure `large != NULL`
if (size == 0) return NULL;
size_t arena_memid;
const size_t blocks = mi_region_block_count(size);
if (blocks <= MI_REGION_MAX_OBJ_BLOCKS && alignment <= MI_SEGMENT_ALIGN) {
- p = mi_region_try_alloc(blocks, commit, large, is_zero, memid, tld);
+ p = mi_region_try_alloc(blocks, commit, large, is_pinned, is_zero, memid, tld);
if (p == NULL) {
_mi_warning_message("unable to allocate from region: size %zu\n", size);
}
}
if (p == NULL) {
// and otherwise fall back to the OS
- p = _mi_arena_alloc_aligned(size, alignment, commit, large, is_zero, &arena_memid, tld);
+ p = _mi_arena_alloc_aligned(size, alignment, commit, large, is_pinned, is_zero, &arena_memid, tld);
*memid = mi_memid_create_from_arena(arena_memid);
}
const size_t blocks = mi_region_block_count(size);
mi_assert_internal(blocks + bit_idx <= MI_BITMAP_FIELD_BITS);
mi_region_info_t info;
- info.value = mi_atomic_read(®ion->info);
+ info.value = mi_atomic_load_acquire(®ion->info);
mi_assert_internal(info.value != 0);
void* blocks_start = mi_region_blocks_start(region, bit_idx);
mi_assert_internal(blocks_start == p); // not a pointer in our area?
// committed?
if (full_commit && (size % MI_SEGMENT_SIZE) == 0) {
- mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, NULL);
+ _mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, NULL);
}
if (any_reset) {
// set the is_reset bits if any pages were reset
- mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, NULL);
+ _mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, NULL);
}
// reset the blocks to reduce the working set.
- if (!info.x.is_large && mi_option_is_enabled(mi_option_segment_reset)
+ if (!info.x.is_large && !info.x.is_pinned && mi_option_is_enabled(mi_option_segment_reset)
&& (mi_option_is_enabled(mi_option_eager_commit) ||
mi_option_is_enabled(mi_option_reset_decommits))) // cannot reset halfway committed segments, use only `option_page_reset` instead
{
bool any_unreset;
- mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, &any_unreset);
+ _mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, &any_unreset);
if (any_unreset) {
_mi_abandoned_await_readers(); // ensure no more pending write (in case reset = decommit)
_mi_mem_reset(p, blocks * MI_SEGMENT_SIZE, tld);
// and unclaim
bool all_unclaimed = mi_bitmap_unclaim(®ion->in_use, 1, blocks, bit_idx);
- mi_assert_internal(all_unclaimed); UNUSED(all_unclaimed);
+ mi_assert_internal(all_unclaimed); MI_UNUSED(all_unclaimed);
}
}
-----------------------------------------------------------------------------*/
void _mi_mem_collect(mi_os_tld_t* tld) {
// free every region that has no segments in use.
- uintptr_t rcount = mi_atomic_read_relaxed(®ions_count);
+ size_t rcount = mi_atomic_load_relaxed(®ions_count);
for (size_t i = 0; i < rcount; i++) {
mem_region_t* region = ®ions[i];
- if (mi_atomic_read_relaxed(®ion->info) != 0) {
+ if (mi_atomic_load_relaxed(®ion->info) != 0) {
// if no segments used, try to claim the whole region
- uintptr_t m;
- do {
- m = mi_atomic_read_relaxed(®ion->in_use);
- } while(m == 0 && !mi_atomic_cas_weak(®ion->in_use, MI_BITMAP_FIELD_FULL, 0 ));
+ size_t m = mi_atomic_load_relaxed(®ion->in_use);
+ while (m == 0 && !mi_atomic_cas_weak_release(®ion->in_use, &m, MI_BITMAP_FIELD_FULL)) { /* nothing */ };
if (m == 0) {
// on success, free the whole region
- uint8_t* start = mi_atomic_read_ptr(uint8_t,®ions[i].start);
- size_t arena_memid = mi_atomic_read_relaxed(®ions[i].arena_memid);
- uintptr_t commit = mi_atomic_read_relaxed(®ions[i].commit);
- memset(®ions[i], 0, sizeof(mem_region_t));
+ uint8_t* start = (uint8_t*)mi_atomic_load_ptr_acquire(uint8_t,®ions[i].start);
+ size_t arena_memid = mi_atomic_load_relaxed(®ions[i].arena_memid);
+ size_t commit = mi_atomic_load_relaxed(®ions[i].commit);
+ memset((void*)®ions[i], 0, sizeof(mem_region_t)); // cast to void* to avoid atomic warning
// and release the whole region
- mi_atomic_write(®ion->info, 0);
+ mi_atomic_store_release(®ion->info, (size_t)0);
if (start != NULL) { // && !_mi_os_is_huge_reserved(start)) {
_mi_abandoned_await_readers(); // ensure no pending reads
_mi_arena_free(start, MI_REGION_SIZE, arena_memid, (~commit == 0), tld->stats);
--- /dev/null
+/* ----------------------------------------------------------------------------
+Copyright (c) 2020, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+
+/* ----------------------------------------------------------------------------
+ Implements a cache of segments to avoid expensive OS calls and to reuse
+ the commit_mask to optimize the commit/decommit calls.
+ The full memory map of all segments is also implemented here.
+-----------------------------------------------------------------------------*/
+#include "mimalloc.h"
+#include "mimalloc-internal.h"
+#include "mimalloc-atomic.h"
+
+#include "bitmap.h" // atomic bitmap
+
+//#define MI_CACHE_DISABLE 1 // define to completely disable the segment cache
+
+#define MI_CACHE_FIELDS (16)
+#define MI_CACHE_MAX (MI_BITMAP_FIELD_BITS*MI_CACHE_FIELDS) // 1024 on 64-bit
+
+#define BITS_SET() MI_ATOMIC_VAR_INIT(UINTPTR_MAX)
+#define MI_CACHE_BITS_SET MI_INIT16(BITS_SET) // note: update if MI_CACHE_FIELDS changes
+
+typedef struct mi_cache_slot_s {
+ void* p;
+ size_t memid;
+ bool is_pinned;
+ mi_commit_mask_t commit_mask;
+ mi_commit_mask_t decommit_mask;
+ _Atomic(mi_msecs_t) expire;
+} mi_cache_slot_t;
+
+static mi_decl_cache_align mi_cache_slot_t cache[MI_CACHE_MAX]; // = 0
+
+static mi_decl_cache_align mi_bitmap_field_t cache_available[MI_CACHE_FIELDS] = { MI_CACHE_BITS_SET }; // zero bit = available!
+static mi_decl_cache_align mi_bitmap_field_t cache_available_large[MI_CACHE_FIELDS] = { MI_CACHE_BITS_SET };
+static mi_decl_cache_align mi_bitmap_field_t cache_inuse[MI_CACHE_FIELDS]; // zero bit = free
+
+
+mi_decl_noinline void* _mi_segment_cache_pop(size_t size, mi_commit_mask_t* commit_mask, mi_commit_mask_t* decommit_mask, bool* large, bool* is_pinned, bool* is_zero, size_t* memid, mi_os_tld_t* tld)
+{
+#ifdef MI_CACHE_DISABLE
+ return NULL;
+#else
+
+ // only segment blocks
+ if (size != MI_SEGMENT_SIZE) return NULL;
+
+ // numa node determines start field
+ const int numa_node = _mi_os_numa_node(tld);
+ size_t start_field = 0;
+ if (numa_node > 0) {
+ start_field = (MI_CACHE_FIELDS / _mi_os_numa_node_count())*numa_node;
+ if (start_field >= MI_CACHE_FIELDS) start_field = 0;
+ }
+
+ // find an available slot
+ mi_bitmap_index_t bitidx = 0;
+ bool claimed = false;
+ if (*large) { // large allowed?
+ claimed = _mi_bitmap_try_find_from_claim(cache_available_large, MI_CACHE_FIELDS, start_field, 1, &bitidx);
+ if (claimed) *large = true;
+ }
+ if (!claimed) {
+ claimed = _mi_bitmap_try_find_from_claim(cache_available, MI_CACHE_FIELDS, start_field, 1, &bitidx);
+ if (claimed) *large = false;
+ }
+
+ if (!claimed) return NULL;
+
+ // found a slot
+ mi_cache_slot_t* slot = &cache[mi_bitmap_index_bit(bitidx)];
+ void* p = slot->p;
+ *memid = slot->memid;
+ *is_pinned = slot->is_pinned;
+ *is_zero = false;
+ *commit_mask = slot->commit_mask;
+ *decommit_mask = slot->decommit_mask;
+ slot->p = NULL;
+ mi_atomic_storei64_release(&slot->expire,(mi_msecs_t)0);
+
+ // mark the slot as free again
+ mi_assert_internal(_mi_bitmap_is_claimed(cache_inuse, MI_CACHE_FIELDS, 1, bitidx));
+ _mi_bitmap_unclaim(cache_inuse, MI_CACHE_FIELDS, 1, bitidx);
+ return p;
+#endif
+}
+
+static mi_decl_noinline void mi_commit_mask_decommit(mi_commit_mask_t* cmask, void* p, size_t total, mi_stats_t* stats)
+{
+ if (mi_commit_mask_is_empty(cmask)) {
+ // nothing
+ }
+ else if (mi_commit_mask_is_full(cmask)) {
+ _mi_os_decommit(p, total, stats);
+ }
+ else {
+ // todo: one call to decommit the whole at once?
+ mi_assert_internal((total%MI_COMMIT_MASK_BITS)==0);
+ size_t part = total/MI_COMMIT_MASK_BITS;
+ size_t idx;
+ size_t count;
+ mi_commit_mask_foreach(cmask, idx, count) {
+ void* start = (uint8_t*)p + (idx*part);
+ size_t size = count*part;
+ _mi_os_decommit(start, size, stats);
+ }
+ mi_commit_mask_foreach_end()
+ }
+ mi_commit_mask_create_empty(cmask);
+}
+
+#define MI_MAX_PURGE_PER_PUSH (4)
+
+static mi_decl_noinline void mi_segment_cache_purge(bool force, mi_os_tld_t* tld)
+{
+ MI_UNUSED(tld);
+ if (!mi_option_is_enabled(mi_option_allow_decommit)) return;
+ mi_msecs_t now = _mi_clock_now();
+ size_t purged = 0;
+ const size_t max_visits = (force ? MI_CACHE_MAX /* visit all */ : MI_CACHE_FIELDS /* probe at most N (=16) slots */);
+ size_t idx = (force ? 0 : _mi_random_shuffle((uintptr_t)now) % MI_CACHE_MAX /* random start */ );
+ for (size_t visited = 0; visited < max_visits; visited++,idx++) { // visit N slots
+ if (idx >= MI_CACHE_MAX) idx = 0; // wrap
+ mi_cache_slot_t* slot = &cache[idx];
+ mi_msecs_t expire = mi_atomic_loadi64_relaxed(&slot->expire);
+ if (expire != 0 && (force || now >= expire)) { // racy read
+ // seems expired, first claim it from available
+ purged++;
+ mi_bitmap_index_t bitidx = mi_bitmap_index_create_from_bit(idx);
+ if (_mi_bitmap_claim(cache_available, MI_CACHE_FIELDS, 1, bitidx, NULL)) {
+ // was available, we claimed it
+ expire = mi_atomic_loadi64_acquire(&slot->expire);
+ if (expire != 0 && (force || now >= expire)) { // safe read
+ // still expired, decommit it
+ mi_atomic_storei64_relaxed(&slot->expire,(mi_msecs_t)0);
+ mi_assert_internal(!mi_commit_mask_is_empty(&slot->commit_mask) && _mi_bitmap_is_claimed(cache_available_large, MI_CACHE_FIELDS, 1, bitidx));
+ _mi_abandoned_await_readers(); // wait until safe to decommit
+ // decommit committed parts
+ // TODO: instead of decommit, we could also free to the OS?
+ mi_commit_mask_decommit(&slot->commit_mask, slot->p, MI_SEGMENT_SIZE, tld->stats);
+ mi_commit_mask_create_empty(&slot->decommit_mask);
+ }
+ _mi_bitmap_unclaim(cache_available, MI_CACHE_FIELDS, 1, bitidx); // make it available again for a pop
+ }
+ if (!force && purged > MI_MAX_PURGE_PER_PUSH) break; // bound to no more than N purge tries per push
+ }
+ }
+}
+
+void _mi_segment_cache_collect(bool force, mi_os_tld_t* tld) {
+ mi_segment_cache_purge(force, tld );
+}
+
+mi_decl_noinline bool _mi_segment_cache_push(void* start, size_t size, size_t memid, const mi_commit_mask_t* commit_mask, const mi_commit_mask_t* decommit_mask, bool is_large, bool is_pinned, mi_os_tld_t* tld)
+{
+#ifdef MI_CACHE_DISABLE
+ return false;
+#else
+
+ // only for normal segment blocks
+ if (size != MI_SEGMENT_SIZE || ((uintptr_t)start % MI_SEGMENT_ALIGN) != 0) return false;
+
+ // numa node determines start field
+ int numa_node = _mi_os_numa_node(NULL);
+ size_t start_field = 0;
+ if (numa_node > 0) {
+ start_field = (MI_CACHE_FIELDS / _mi_os_numa_node_count())*numa_node;
+ if (start_field >= MI_CACHE_FIELDS) start_field = 0;
+ }
+
+ // purge expired entries
+ mi_segment_cache_purge(false /* force? */, tld);
+
+ // find an available slot
+ mi_bitmap_index_t bitidx;
+ bool claimed = _mi_bitmap_try_find_from_claim(cache_inuse, MI_CACHE_FIELDS, start_field, 1, &bitidx);
+ if (!claimed) return false;
+
+ mi_assert_internal(_mi_bitmap_is_claimed(cache_available, MI_CACHE_FIELDS, 1, bitidx));
+ mi_assert_internal(_mi_bitmap_is_claimed(cache_available_large, MI_CACHE_FIELDS, 1, bitidx));
+#if MI_DEBUG>1
+ if (is_pinned || is_large) {
+ mi_assert_internal(mi_commit_mask_is_full(commit_mask));
+ }
+#endif
+
+ // set the slot
+ mi_cache_slot_t* slot = &cache[mi_bitmap_index_bit(bitidx)];
+ slot->p = start;
+ slot->memid = memid;
+ slot->is_pinned = is_pinned;
+ mi_atomic_storei64_relaxed(&slot->expire,(mi_msecs_t)0);
+ slot->commit_mask = *commit_mask;
+ slot->decommit_mask = *decommit_mask;
+ if (!mi_commit_mask_is_empty(commit_mask) && !is_large && !is_pinned && mi_option_is_enabled(mi_option_allow_decommit)) {
+ long delay = mi_option_get(mi_option_segment_decommit_delay);
+ if (delay == 0) {
+ _mi_abandoned_await_readers(); // wait until safe to decommit
+ mi_commit_mask_decommit(&slot->commit_mask, start, MI_SEGMENT_SIZE, tld->stats);
+ mi_commit_mask_create_empty(&slot->decommit_mask);
+ }
+ else {
+ mi_atomic_storei64_release(&slot->expire, _mi_clock_now() + delay);
+ }
+ }
+
+ // make it available
+ _mi_bitmap_unclaim((is_large ? cache_available_large : cache_available), MI_CACHE_FIELDS, 1, bitidx);
+ return true;
+#endif
+}
+
+
+/* -----------------------------------------------------------
+ The following functions are to reliably find the segment or
+ block that encompasses any pointer p (or NULL if it is not
+ in any of our segments).
+ We maintain a bitmap of all memory with 1 bit per MI_SEGMENT_SIZE (64MiB)
+ set to 1 if it contains the segment meta data.
+----------------------------------------------------------- */
+
+
+#if (MI_INTPTR_SIZE==8)
+#define MI_MAX_ADDRESS ((size_t)20 << 40) // 20TB
+#else
+#define MI_MAX_ADDRESS ((size_t)2 << 30) // 2Gb
+#endif
+
+#define MI_SEGMENT_MAP_BITS (MI_MAX_ADDRESS / MI_SEGMENT_SIZE)
+#define MI_SEGMENT_MAP_SIZE (MI_SEGMENT_MAP_BITS / 8)
+#define MI_SEGMENT_MAP_WSIZE (MI_SEGMENT_MAP_SIZE / MI_INTPTR_SIZE)
+
+static _Atomic(uintptr_t) mi_segment_map[MI_SEGMENT_MAP_WSIZE + 1]; // 2KiB per TB with 64MiB segments
+
+static size_t mi_segment_map_index_of(const mi_segment_t* segment, size_t* bitidx) {
+ mi_assert_internal(_mi_ptr_segment(segment) == segment); // is it aligned on MI_SEGMENT_SIZE?
+ if ((uintptr_t)segment >= MI_MAX_ADDRESS) {
+ *bitidx = 0;
+ return MI_SEGMENT_MAP_WSIZE;
+ }
+ else {
+ const uintptr_t segindex = ((uintptr_t)segment) / MI_SEGMENT_SIZE;
+ *bitidx = segindex % MI_INTPTR_BITS;
+ const size_t mapindex = segindex / MI_INTPTR_BITS;
+ mi_assert_internal(mapindex < MI_SEGMENT_MAP_WSIZE);
+ return mapindex;
+ }
+}
+
+void _mi_segment_map_allocated_at(const mi_segment_t* segment) {
+ size_t bitidx;
+ size_t index = mi_segment_map_index_of(segment, &bitidx);
+ mi_assert_internal(index <= MI_SEGMENT_MAP_WSIZE);
+ if (index==MI_SEGMENT_MAP_WSIZE) return;
+ uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]);
+ uintptr_t newmask;
+ do {
+ newmask = (mask | ((uintptr_t)1 << bitidx));
+ } while (!mi_atomic_cas_weak_release(&mi_segment_map[index], &mask, newmask));
+}
+
+void _mi_segment_map_freed_at(const mi_segment_t* segment) {
+ size_t bitidx;
+ size_t index = mi_segment_map_index_of(segment, &bitidx);
+ mi_assert_internal(index <= MI_SEGMENT_MAP_WSIZE);
+ if (index == MI_SEGMENT_MAP_WSIZE) return;
+ uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]);
+ uintptr_t newmask;
+ do {
+ newmask = (mask & ~((uintptr_t)1 << bitidx));
+ } while (!mi_atomic_cas_weak_release(&mi_segment_map[index], &mask, newmask));
+}
+
+// Determine the segment belonging to a pointer or NULL if it is not in a valid segment.
+static mi_segment_t* _mi_segment_of(const void* p) {
+ mi_segment_t* segment = _mi_ptr_segment(p);
+ if (segment == NULL) return NULL;
+ size_t bitidx;
+ size_t index = mi_segment_map_index_of(segment, &bitidx);
+ // fast path: for any pointer to valid small/medium/large object or first MI_SEGMENT_SIZE in huge
+ const uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]);
+ if (mi_likely((mask & ((uintptr_t)1 << bitidx)) != 0)) {
+ return segment; // yes, allocated by us
+ }
+ if (index==MI_SEGMENT_MAP_WSIZE) return NULL;
+
+ // TODO: maintain max/min allocated range for efficiency for more efficient rejection of invalid pointers?
+
+ // search downwards for the first segment in case it is an interior pointer
+ // could be slow but searches in MI_INTPTR_SIZE * MI_SEGMENT_SIZE (512MiB) steps trough
+ // valid huge objects
+ // note: we could maintain a lowest index to speed up the path for invalid pointers?
+ size_t lobitidx;
+ size_t loindex;
+ uintptr_t lobits = mask & (((uintptr_t)1 << bitidx) - 1);
+ if (lobits != 0) {
+ loindex = index;
+ lobitidx = mi_bsr(lobits); // lobits != 0
+ }
+ else if (index == 0) {
+ return NULL;
+ }
+ else {
+ mi_assert_internal(index > 0);
+ uintptr_t lomask = mask;
+ loindex = index;
+ do {
+ loindex--;
+ lomask = mi_atomic_load_relaxed(&mi_segment_map[loindex]);
+ } while (lomask != 0 && loindex > 0);
+ if (lomask == 0) return NULL;
+ lobitidx = mi_bsr(lomask); // lomask != 0
+ }
+ mi_assert_internal(loindex < MI_SEGMENT_MAP_WSIZE);
+ // take difference as the addresses could be larger than the MAX_ADDRESS space.
+ size_t diff = (((index - loindex) * (8*MI_INTPTR_SIZE)) + bitidx - lobitidx) * MI_SEGMENT_SIZE;
+ segment = (mi_segment_t*)((uint8_t*)segment - diff);
+
+ if (segment == NULL) return NULL;
+ mi_assert_internal((void*)segment < p);
+ bool cookie_ok = (_mi_ptr_cookie(segment) == segment->cookie);
+ mi_assert_internal(cookie_ok);
+ if (mi_unlikely(!cookie_ok)) return NULL;
+ if (((uint8_t*)segment + mi_segment_size(segment)) <= (uint8_t*)p) return NULL; // outside the range
+ mi_assert_internal(p >= (void*)segment && (uint8_t*)p < (uint8_t*)segment + mi_segment_size(segment));
+ return segment;
+}
+
+// Is this a valid pointer in our heap?
+static bool mi_is_valid_pointer(const void* p) {
+ return (_mi_segment_of(p) != NULL);
+}
+
+mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {
+ return mi_is_valid_pointer(p);
+}
+
+/*
+// Return the full segment range belonging to a pointer
+static void* mi_segment_range_of(const void* p, size_t* size) {
+ mi_segment_t* segment = _mi_segment_of(p);
+ if (segment == NULL) {
+ if (size != NULL) *size = 0;
+ return NULL;
+ }
+ else {
+ if (size != NULL) *size = segment->segment_size;
+ return segment;
+ }
+ mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld));
+ mi_assert_internal(page == NULL || (mi_segment_page_size(_mi_page_segment(page)) - (MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= block_size);
+ mi_reset_delayed(tld);
+ mi_assert_internal(page == NULL || mi_page_not_in_queue(page, tld));
+ return page;
+}
+*/
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#define MI_PAGE_HUGE_ALIGN (256*1024)
-static uint8_t* mi_segment_raw_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size);
+static void mi_segment_delayed_decommit(mi_segment_t* segment, bool force, mi_stats_t* stats);
-/* --------------------------------------------------------------------------------
- Segment allocation
- We allocate pages inside bigger "segments" (4mb on 64-bit). This is to avoid
- splitting VMA's on Linux and reduce fragmentation on other OS's.
- Each thread owns its own segments.
-
- Currently we have:
- - small pages (64kb), 64 in one segment
- - medium pages (512kb), 8 in one segment
- - large pages (4mb), 1 in one segment
- - huge blocks > MI_LARGE_OBJ_SIZE_MAX become large segment with 1 page
- In any case the memory for a segment is virtual and usually committed on demand.
- (i.e. we are careful to not touch the memory until we actually allocate a block there)
-
- If a thread ends, it "abandons" pages with used blocks
- and there is an abandoned segment list whose segments can
- be reclaimed by still running threads, much like work-stealing.
--------------------------------------------------------------------------------- */
-
-
-/* -----------------------------------------------------------
- Queue of segments containing free pages
------------------------------------------------------------ */
+// -------------------------------------------------------------------
+// commit mask
+// -------------------------------------------------------------------
-#if (MI_DEBUG>=3)
-static bool mi_segment_queue_contains(const mi_segment_queue_t* queue, const mi_segment_t* segment) {
- mi_assert_internal(segment != NULL);
- mi_segment_t* list = queue->first;
- while (list != NULL) {
- if (list == segment) break;
- mi_assert_internal(list->next==NULL || list->next->prev == list);
- mi_assert_internal(list->prev==NULL || list->prev->next == list);
- list = list->next;
+static bool mi_commit_mask_all_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ if ((commit->mask[i] & cm->mask[i]) != cm->mask[i]) return false;
}
- return (list == segment);
-}
-#endif
-
-static bool mi_segment_queue_is_empty(const mi_segment_queue_t* queue) {
- return (queue->first == NULL);
-}
-
-static void mi_segment_queue_remove(mi_segment_queue_t* queue, mi_segment_t* segment) {
- mi_assert_expensive(mi_segment_queue_contains(queue, segment));
- if (segment->prev != NULL) segment->prev->next = segment->next;
- if (segment->next != NULL) segment->next->prev = segment->prev;
- if (segment == queue->first) queue->first = segment->next;
- if (segment == queue->last) queue->last = segment->prev;
- segment->next = NULL;
- segment->prev = NULL;
+ return true;
}
-static void mi_segment_enqueue(mi_segment_queue_t* queue, mi_segment_t* segment) {
- mi_assert_expensive(!mi_segment_queue_contains(queue, segment));
- segment->next = NULL;
- segment->prev = queue->last;
- if (queue->last != NULL) {
- mi_assert_internal(queue->last->next == NULL);
- queue->last->next = segment;
- queue->last = segment;
- }
- else {
- queue->last = queue->first = segment;
+static bool mi_commit_mask_any_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ if ((commit->mask[i] & cm->mask[i]) != 0) return true;
}
+ return false;
}
-static mi_segment_queue_t* mi_segment_free_queue_of_kind(mi_page_kind_t kind, mi_segments_tld_t* tld) {
- if (kind == MI_PAGE_SMALL) return &tld->small_free;
- else if (kind == MI_PAGE_MEDIUM) return &tld->medium_free;
- else return NULL;
-}
-
-static mi_segment_queue_t* mi_segment_free_queue(const mi_segment_t* segment, mi_segments_tld_t* tld) {
- return mi_segment_free_queue_of_kind(segment->page_kind, tld);
-}
-
-// remove from free queue if it is in one
-static void mi_segment_remove_from_free_queue(mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_segment_queue_t* queue = mi_segment_free_queue(segment, tld); // may be NULL
- bool in_queue = (queue!=NULL && (segment->next != NULL || segment->prev != NULL || queue->first == segment));
- if (in_queue) {
- mi_segment_queue_remove(queue, segment);
+static void mi_commit_mask_create_intersect(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm, mi_commit_mask_t* res) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ res->mask[i] = (commit->mask[i] & cm->mask[i]);
}
}
-static void mi_segment_insert_in_free_queue(mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_segment_enqueue(mi_segment_free_queue(segment, tld), segment);
+static void mi_commit_mask_clear(mi_commit_mask_t* res, const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ res->mask[i] &= ~(cm->mask[i]);
+ }
}
-
-/* -----------------------------------------------------------
- Invariant checking
------------------------------------------------------------ */
-
-#if (MI_DEBUG>=2)
-static bool mi_segment_is_in_free_queue(const mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_segment_queue_t* queue = mi_segment_free_queue(segment, tld);
- bool in_queue = (queue!=NULL && (segment->next != NULL || segment->prev != NULL || queue->first == segment));
- if (in_queue) {
- mi_assert_expensive(mi_segment_queue_contains(queue, segment));
+static void mi_commit_mask_set(mi_commit_mask_t* res, const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ res->mask[i] |= cm->mask[i];
}
- return in_queue;
}
-#endif
-static size_t mi_segment_page_size(const mi_segment_t* segment) {
- if (segment->capacity > 1) {
- mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM);
- return ((size_t)1 << segment->page_shift);
+static void mi_commit_mask_create(size_t bitidx, size_t bitcount, mi_commit_mask_t* cm) {
+ mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS);
+ mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS);
+ if (bitcount == MI_COMMIT_MASK_BITS) {
+ mi_assert_internal(bitidx==0);
+ mi_commit_mask_create_full(cm);
}
- else {
- mi_assert_internal(segment->page_kind >= MI_PAGE_LARGE);
- return segment->segment_size;
+ else if (bitcount == 0) {
+ mi_commit_mask_create_empty(cm);
}
-}
-
-
-#if (MI_DEBUG>=2)
-static bool mi_pages_reset_contains(const mi_page_t* page, mi_segments_tld_t* tld) {
- mi_page_t* p = tld->pages_reset.first;
- while (p != NULL) {
- if (p == page) return true;
- p = p->next;
+ else {
+ mi_commit_mask_create_empty(cm);
+ size_t i = bitidx / MI_COMMIT_MASK_FIELD_BITS;
+ size_t ofs = bitidx % MI_COMMIT_MASK_FIELD_BITS;
+ while (bitcount > 0) {
+ mi_assert_internal(i < MI_COMMIT_MASK_FIELD_COUNT);
+ size_t avail = MI_COMMIT_MASK_FIELD_BITS - ofs;
+ size_t count = (bitcount > avail ? avail : bitcount);
+ size_t mask = (count >= MI_COMMIT_MASK_FIELD_BITS ? ~((size_t)0) : (((size_t)1 << count) - 1) << ofs);
+ cm->mask[i] = mask;
+ bitcount -= count;
+ ofs = 0;
+ i++;
+ }
}
- return false;
}
-#endif
-#if (MI_DEBUG>=3)
-static bool mi_segment_is_valid(const mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_assert_internal(segment != NULL);
- mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);
- mi_assert_internal(segment->used <= segment->capacity);
- mi_assert_internal(segment->abandoned <= segment->used);
- size_t nfree = 0;
- for (size_t i = 0; i < segment->capacity; i++) {
- const mi_page_t* const page = &segment->pages[i];
- if (!page->segment_in_use) {
- nfree++;
+size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total) {
+ mi_assert_internal((total%MI_COMMIT_MASK_BITS)==0);
+ size_t count = 0;
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ size_t mask = cm->mask[i];
+ if (~mask == 0) {
+ count += MI_COMMIT_MASK_FIELD_BITS;
}
- if (page->segment_in_use || page->is_reset) {
- mi_assert_expensive(!mi_pages_reset_contains(page, tld));
+ else {
+ for (; mask != 0; mask >>= 1) { // todo: use popcount
+ if ((mask&1)!=0) count++;
+ }
}
}
- mi_assert_internal(nfree + segment->used == segment->capacity);
- // mi_assert_internal(segment->thread_id == _mi_thread_id() || (segment->thread_id==0)); // or 0
- mi_assert_internal(segment->page_kind == MI_PAGE_HUGE ||
- (mi_segment_page_size(segment) * segment->capacity == segment->segment_size));
- return true;
+ // we use total since for huge segments each commit bit may represent a larger size
+ return ((total / MI_COMMIT_MASK_BITS) * count);
}
-#endif
-static bool mi_page_not_in_queue(const mi_page_t* page, mi_segments_tld_t* tld) {
- mi_assert_internal(page != NULL);
- if (page->next != NULL || page->prev != NULL) {
- mi_assert_internal(mi_pages_reset_contains(page, tld));
- return false;
+
+size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx) {
+ size_t i = (*idx) / MI_COMMIT_MASK_FIELD_BITS;
+ size_t ofs = (*idx) % MI_COMMIT_MASK_FIELD_BITS;
+ size_t mask = 0;
+ // find first ones
+ while (i < MI_COMMIT_MASK_FIELD_COUNT) {
+ mask = cm->mask[i];
+ mask >>= ofs;
+ if (mask != 0) {
+ while ((mask&1) == 0) {
+ mask >>= 1;
+ ofs++;
+ }
+ break;
+ }
+ i++;
+ ofs = 0;
+ }
+ if (i >= MI_COMMIT_MASK_FIELD_COUNT) {
+ // not found
+ *idx = MI_COMMIT_MASK_BITS;
+ return 0;
}
else {
- // both next and prev are NULL, check for singleton list
- return (tld->pages_reset.first != page && tld->pages_reset.last != page);
+ // found, count ones
+ size_t count = 0;
+ *idx = (i*MI_COMMIT_MASK_FIELD_BITS) + ofs;
+ do {
+ mi_assert_internal(ofs < MI_COMMIT_MASK_FIELD_BITS && (mask&1) == 1);
+ do {
+ count++;
+ mask >>= 1;
+ } while ((mask&1) == 1);
+ if ((((*idx + count) % MI_COMMIT_MASK_FIELD_BITS) == 0)) {
+ i++;
+ if (i >= MI_COMMIT_MASK_FIELD_COUNT) break;
+ mask = cm->mask[i];
+ ofs = 0;
+ }
+ } while ((mask&1) == 1);
+ mi_assert_internal(count > 0);
+ return count;
}
}
+/* --------------------------------------------------------------------------------
+ Segment allocation
+
+ If a thread ends, it "abandons" pages with used blocks
+ and there is an abandoned segment list whose segments can
+ be reclaimed by still running threads, much like work-stealing.
+-------------------------------------------------------------------------------- */
+
+
/* -----------------------------------------------------------
- Guard pages
+ Slices
----------------------------------------------------------- */
-static void mi_segment_protect_range(void* p, size_t size, bool protect) {
- if (protect) {
- _mi_mem_protect(p, size);
- }
- else {
- _mi_mem_unprotect(p, size);
- }
-}
-
-static void mi_segment_protect(mi_segment_t* segment, bool protect, mi_os_tld_t* tld) {
- // add/remove guard pages
- if (MI_SECURE != 0) {
- // in secure mode, we set up a protected page in between the segment info and the page data
- const size_t os_page_size = _mi_os_page_size();
- mi_assert_internal((segment->segment_info_size - os_page_size) >= (sizeof(mi_segment_t) + ((segment->capacity - 1) * sizeof(mi_page_t))));
- mi_assert_internal(((uintptr_t)segment + segment->segment_info_size) % os_page_size == 0);
- mi_segment_protect_range((uint8_t*)segment + segment->segment_info_size - os_page_size, os_page_size, protect);
- if (MI_SECURE <= 1 || segment->capacity == 1) {
- // and protect the last (or only) page too
- mi_assert_internal(MI_SECURE <= 1 || segment->page_kind >= MI_PAGE_LARGE);
- uint8_t* start = (uint8_t*)segment + segment->segment_size - os_page_size;
- if (protect && !segment->mem_is_committed) {
- // ensure secure page is committed
- _mi_mem_commit(start, os_page_size, NULL, tld);
- }
- mi_segment_protect_range(start, os_page_size, protect);
- }
- else {
- // or protect every page
- const size_t page_size = mi_segment_page_size(segment);
- for (size_t i = 0; i < segment->capacity; i++) {
- if (segment->pages[i].is_committed) {
- mi_segment_protect_range((uint8_t*)segment + (i+1)*page_size - os_page_size, os_page_size, protect);
- }
- }
- }
- }
+
+static const mi_slice_t* mi_segment_slices_end(const mi_segment_t* segment) {
+ return &segment->slices[segment->slice_entries];
}
+static uint8_t* mi_slice_start(const mi_slice_t* slice) {
+ mi_segment_t* segment = _mi_ptr_segment(slice);
+ mi_assert_internal(slice >= segment->slices && slice < mi_segment_slices_end(segment));
+ return ((uint8_t*)segment + ((slice - segment->slices)*MI_SEGMENT_SLICE_SIZE));
+}
+
+
/* -----------------------------------------------------------
- Page reset
+ Bins
----------------------------------------------------------- */
+// Use bit scan forward to quickly find the first zero bit if it is available
+
+static inline size_t mi_slice_bin8(size_t slice_count) {
+ if (slice_count<=1) return slice_count;
+ mi_assert_internal(slice_count <= MI_SLICES_PER_SEGMENT);
+ slice_count--;
+ size_t s = mi_bsr(slice_count); // slice_count > 1
+ if (s <= 2) return slice_count + 1;
+ size_t bin = ((s << 2) | ((slice_count >> (s - 2))&0x03)) - 4;
+ return bin;
+}
-static void mi_page_reset(mi_segment_t* segment, mi_page_t* page, size_t size, mi_segments_tld_t* tld) {
- mi_assert_internal(page->is_committed);
- if (!mi_option_is_enabled(mi_option_page_reset)) return;
- if (segment->mem_is_fixed || page->segment_in_use || !page->is_committed || page->is_reset) return;
- size_t psize;
- void* start = mi_segment_raw_page_start(segment, page, &psize);
- page->is_reset = true;
- mi_assert_internal(size <= psize);
- size_t reset_size = ((size == 0 || size > psize) ? psize : size);
- if (reset_size > 0) _mi_mem_reset(start, reset_size, tld->os);
+static inline size_t mi_slice_bin(size_t slice_count) {
+ mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_SEGMENT_SIZE);
+ mi_assert_internal(mi_slice_bin8(MI_SLICES_PER_SEGMENT) <= MI_SEGMENT_BIN_MAX);
+ size_t bin = mi_slice_bin8(slice_count);
+ mi_assert_internal(bin <= MI_SEGMENT_BIN_MAX);
+ return bin;
}
-static bool mi_page_unreset(mi_segment_t* segment, mi_page_t* page, size_t size, mi_segments_tld_t* tld)
-{
- mi_assert_internal(page->is_reset);
- mi_assert_internal(page->is_committed);
- mi_assert_internal(!segment->mem_is_fixed);
- if (segment->mem_is_fixed || !page->is_committed || !page->is_reset) return true;
- page->is_reset = false;
- size_t psize;
- uint8_t* start = mi_segment_raw_page_start(segment, page, &psize);
- size_t unreset_size = (size == 0 || size > psize ? psize : size);
- bool is_zero = false;
- bool ok = true;
- if (unreset_size > 0) {
- ok = _mi_mem_unreset(start, unreset_size, &is_zero, tld->os);
- }
- if (is_zero) page->is_zero_init = true;
- return ok;
+static inline size_t mi_slice_index(const mi_slice_t* slice) {
+ mi_segment_t* segment = _mi_ptr_segment(slice);
+ ptrdiff_t index = slice - segment->slices;
+ mi_assert_internal(index >= 0 && index < (ptrdiff_t)segment->slice_entries);
+ return index;
}
/* -----------------------------------------------------------
- The free page queue
+ Slice span queues
----------------------------------------------------------- */
-// we re-use the `used` field for the expiration counter. Since this is a
-// a 32-bit field while the clock is always 64-bit we need to guard
-// against overflow, we use substraction to check for expiry which work
-// as long as the reset delay is under (2^30 - 1) milliseconds (~12 days)
-static void mi_page_reset_set_expire(mi_page_t* page) {
- uint32_t expire = (uint32_t)_mi_clock_now() + mi_option_get(mi_option_reset_delay);
- page->used = expire;
+static void mi_span_queue_push(mi_span_queue_t* sq, mi_slice_t* slice) {
+ // todo: or push to the end?
+ mi_assert_internal(slice->prev == NULL && slice->next==NULL);
+ slice->prev = NULL; // paranoia
+ slice->next = sq->first;
+ sq->first = slice;
+ if (slice->next != NULL) slice->next->prev = slice;
+ else sq->last = slice;
+ slice->xblock_size = 0; // free
}
-static bool mi_page_reset_is_expired(mi_page_t* page, mi_msecs_t now) {
- int32_t expire = (int32_t)(page->used);
- return (((int32_t)now - expire) >= 0);
+static mi_span_queue_t* mi_span_queue_for(size_t slice_count, mi_segments_tld_t* tld) {
+ size_t bin = mi_slice_bin(slice_count);
+ mi_span_queue_t* sq = &tld->spans[bin];
+ mi_assert_internal(sq->slice_count >= slice_count);
+ return sq;
}
-static void mi_pages_reset_add(mi_segment_t* segment, mi_page_t* page, mi_segments_tld_t* tld) {
- mi_assert_internal(!page->segment_in_use || !page->is_committed);
- mi_assert_internal(mi_page_not_in_queue(page,tld));
- mi_assert_expensive(!mi_pages_reset_contains(page, tld));
- mi_assert_internal(_mi_page_segment(page)==segment);
- if (!mi_option_is_enabled(mi_option_page_reset)) return;
- if (segment->mem_is_fixed || page->segment_in_use || !page->is_committed || page->is_reset) return;
+static void mi_span_queue_delete(mi_span_queue_t* sq, mi_slice_t* slice) {
+ mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0);
+ // should work too if the queue does not contain slice (which can happen during reclaim)
+ if (slice->prev != NULL) slice->prev->next = slice->next;
+ if (slice == sq->first) sq->first = slice->next;
+ if (slice->next != NULL) slice->next->prev = slice->prev;
+ if (slice == sq->last) sq->last = slice->prev;
+ slice->prev = NULL;
+ slice->next = NULL;
+ slice->xblock_size = 1; // no more free
+}
- if (mi_option_get(mi_option_reset_delay) == 0) {
- // reset immediately?
- mi_page_reset(segment, page, 0, tld);
- }
- else {
- // otherwise push on the delayed page reset queue
- mi_page_queue_t* pq = &tld->pages_reset;
- // push on top
- mi_page_reset_set_expire(page);
- page->next = pq->first;
- page->prev = NULL;
- if (pq->first == NULL) {
- mi_assert_internal(pq->last == NULL);
- pq->first = pq->last = page;
- }
- else {
- pq->first->prev = page;
- pq->first = page;
- }
- }
+
+/* -----------------------------------------------------------
+ Invariant checking
+----------------------------------------------------------- */
+
+static bool mi_slice_is_used(const mi_slice_t* slice) {
+ return (slice->xblock_size > 0);
}
-static void mi_pages_reset_remove(mi_page_t* page, mi_segments_tld_t* tld) {
- if (mi_page_not_in_queue(page,tld)) return;
- mi_page_queue_t* pq = &tld->pages_reset;
- mi_assert_internal(pq!=NULL);
- mi_assert_internal(!page->segment_in_use);
- mi_assert_internal(mi_pages_reset_contains(page, tld));
- if (page->prev != NULL) page->prev->next = page->next;
- if (page->next != NULL) page->next->prev = page->prev;
- if (page == pq->last) pq->last = page->prev;
- if (page == pq->first) pq->first = page->next;
- page->next = page->prev = NULL;
- page->used = 0;
+#if (MI_DEBUG>=3)
+static bool mi_span_queue_contains(mi_span_queue_t* sq, mi_slice_t* slice) {
+ for (mi_slice_t* s = sq->first; s != NULL; s = s->next) {
+ if (s==slice) return true;
+ }
+ return false;
}
-static void mi_pages_reset_remove_all_in_segment(mi_segment_t* segment, bool force_reset, mi_segments_tld_t* tld) {
- if (segment->mem_is_fixed) return; // never reset in huge OS pages
- for (size_t i = 0; i < segment->capacity; i++) {
- mi_page_t* page = &segment->pages[i];
- if (!page->segment_in_use && page->is_committed && !page->is_reset) {
- mi_pages_reset_remove(page, tld);
- if (force_reset) {
- mi_page_reset(segment, page, 0, tld);
+static bool mi_segment_is_valid(mi_segment_t* segment, mi_segments_tld_t* tld) {
+ mi_assert_internal(segment != NULL);
+ mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);
+ mi_assert_internal(segment->abandoned <= segment->used);
+ mi_assert_internal(segment->thread_id == 0 || segment->thread_id == _mi_thread_id());
+ mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask)); // can only decommit committed blocks
+ //mi_assert_internal(segment->segment_info_size % MI_SEGMENT_SLICE_SIZE == 0);
+ mi_slice_t* slice = &segment->slices[0];
+ const mi_slice_t* end = mi_segment_slices_end(segment);
+ size_t used_count = 0;
+ mi_span_queue_t* sq;
+ while(slice < end) {
+ mi_assert_internal(slice->slice_count > 0);
+ mi_assert_internal(slice->slice_offset == 0);
+ size_t index = mi_slice_index(slice);
+ size_t maxindex = (index + slice->slice_count >= segment->slice_entries ? segment->slice_entries : index + slice->slice_count) - 1;
+ if (mi_slice_is_used(slice)) { // a page in use, we need at least MAX_SLICE_OFFSET valid back offsets
+ used_count++;
+ for (size_t i = 0; i <= MI_MAX_SLICE_OFFSET && index + i <= maxindex; i++) {
+ mi_assert_internal(segment->slices[index + i].slice_offset == i*sizeof(mi_slice_t));
+ mi_assert_internal(i==0 || segment->slices[index + i].slice_count == 0);
+ mi_assert_internal(i==0 || segment->slices[index + i].xblock_size == 1);
+ }
+ // and the last entry as well (for coalescing)
+ const mi_slice_t* last = slice + slice->slice_count - 1;
+ if (last > slice && last < mi_segment_slices_end(segment)) {
+ mi_assert_internal(last->slice_offset == (slice->slice_count-1)*sizeof(mi_slice_t));
+ mi_assert_internal(last->slice_count == 0);
+ mi_assert_internal(last->xblock_size == 1);
}
}
- else {
- mi_assert_internal(mi_page_not_in_queue(page,tld));
+ else { // free range of slices; only last slice needs a valid back offset
+ mi_slice_t* last = &segment->slices[maxindex];
+ if (segment->kind != MI_SEGMENT_HUGE || slice->slice_count <= (segment->slice_entries - segment->segment_info_slices)) {
+ mi_assert_internal((uint8_t*)slice == (uint8_t*)last - last->slice_offset);
+ }
+ mi_assert_internal(slice == last || last->slice_count == 0 );
+ mi_assert_internal(last->xblock_size == 0 || (segment->kind==MI_SEGMENT_HUGE && last->xblock_size==1));
+ if (segment->kind != MI_SEGMENT_HUGE && segment->thread_id != 0) { // segment is not huge or abandoned
+ sq = mi_span_queue_for(slice->slice_count,tld);
+ mi_assert_internal(mi_span_queue_contains(sq,slice));
+ }
}
+ slice = &segment->slices[maxindex+1];
}
+ mi_assert_internal(slice == end);
+ mi_assert_internal(used_count == segment->used + 1);
+ return true;
}
-
-static void mi_reset_delayed(mi_segments_tld_t* tld) {
- if (!mi_option_is_enabled(mi_option_page_reset)) return;
- mi_msecs_t now = _mi_clock_now();
- mi_page_queue_t* pq = &tld->pages_reset;
- // from oldest up to the first that has not expired yet
- mi_page_t* page = pq->last;
- while (page != NULL && mi_page_reset_is_expired(page,now)) {
- mi_page_t* const prev = page->prev; // save previous field
- mi_page_reset(_mi_page_segment(page), page, 0, tld);
- page->used = 0;
- page->prev = page->next = NULL;
- page = prev;
- }
- // discard the reset pages from the queue
- pq->last = page;
- if (page != NULL){
- page->next = NULL;
- }
- else {
- pq->first = NULL;
- }
-}
-
+#endif
/* -----------------------------------------------------------
Segment size calculations
----------------------------------------------------------- */
-// Raw start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set)
-// The raw start is not taking aligned block allocation into consideration.
-static uint8_t* mi_segment_raw_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) {
- size_t psize = (segment->page_kind == MI_PAGE_HUGE ? segment->segment_size : (size_t)1 << segment->page_shift);
- uint8_t* p = (uint8_t*)segment + page->segment_idx * psize;
-
- if (page->segment_idx == 0) {
- // the first page starts after the segment info (and possible guard page)
- p += segment->segment_info_size;
- psize -= segment->segment_info_size;
- }
-
- if (MI_SECURE > 1 || (MI_SECURE == 1 && page->segment_idx == segment->capacity - 1)) {
- // secure == 1: the last page has an os guard page at the end
- // secure > 1: every page has an os guard page
- psize -= _mi_os_page_size();
- }
-
- if (page_size != NULL) *page_size = psize;
- mi_assert_internal(page->xblock_size == 0 || _mi_ptr_page(p) == page);
- mi_assert_internal(_mi_ptr_segment(p) == segment);
- return p;
+static size_t mi_segment_info_size(mi_segment_t* segment) {
+ return segment->segment_info_slices * MI_SEGMENT_SLICE_SIZE;
}
-// Start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set)
-uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size, size_t* pre_size)
+static uint8_t* _mi_segment_page_start_from_slice(const mi_segment_t* segment, const mi_slice_t* slice, size_t xblock_size, size_t* page_size)
{
- size_t psize;
- uint8_t* p = mi_segment_raw_page_start(segment, page, &psize);
- if (pre_size != NULL) *pre_size = 0;
- if (page->segment_idx == 0 && block_size > 0 && segment->page_kind <= MI_PAGE_MEDIUM) {
- // for small and medium objects, ensure the page start is aligned with the block size (PR#66 by kickunderscore)
- size_t adjust = block_size - ((uintptr_t)p % block_size);
- if (adjust < block_size) {
- p += adjust;
- psize -= adjust;
- if (pre_size != NULL) *pre_size = adjust;
- }
- mi_assert_internal((uintptr_t)p % block_size == 0);
- }
+ ptrdiff_t idx = slice - segment->slices;
+ size_t psize = (size_t)slice->slice_count * MI_SEGMENT_SLICE_SIZE;
+ // make the start not OS page aligned for smaller blocks to avoid page/cache effects
+ size_t start_offset = (xblock_size >= MI_INTPTR_SIZE && xblock_size <= 1024 ? MI_MAX_ALIGN_GUARANTEE : 0);
+ if (page_size != NULL) { *page_size = psize - start_offset; }
+ return (uint8_t*)segment + ((idx*MI_SEGMENT_SLICE_SIZE) + start_offset);
+}
- if (page_size != NULL) *page_size = psize;
- mi_assert_internal(page->xblock_size==0 || _mi_ptr_page(p) == page);
+// Start of the page available memory; can be used on uninitialized pages
+uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size)
+{
+ const mi_slice_t* slice = mi_page_to_slice((mi_page_t*)page);
+ uint8_t* p = _mi_segment_page_start_from_slice(segment, slice, page->xblock_size, page_size);
+ mi_assert_internal(page->xblock_size > 0 || _mi_ptr_page(p) == page);
mi_assert_internal(_mi_ptr_segment(p) == segment);
return p;
}
-static size_t mi_segment_size(size_t capacity, size_t required, size_t* pre_size, size_t* info_size)
-{
- const size_t minsize = sizeof(mi_segment_t) + ((capacity - 1) * sizeof(mi_page_t)) + 16 /* padding */;
+
+static size_t mi_segment_calculate_slices(size_t required, size_t* pre_size, size_t* info_slices) {
+ size_t page_size = _mi_os_page_size();
+ size_t isize = _mi_align_up(sizeof(mi_segment_t), page_size);
size_t guardsize = 0;
- size_t isize = 0;
- if (MI_SECURE == 0) {
- // normally no guard pages
- isize = _mi_align_up(minsize, 16 * MI_MAX_ALIGN_SIZE);
- }
- else {
+ if (MI_SECURE>0) {
// in secure mode, we set up a protected page in between the segment info
// and the page data (and one at the end of the segment)
- const size_t page_size = _mi_os_page_size();
- isize = _mi_align_up(minsize, page_size);
- guardsize = page_size;
- required = _mi_align_up(required, page_size);
+ guardsize = page_size;
+ required = _mi_align_up(required, page_size);
}
- if (info_size != NULL) *info_size = isize;
- if (pre_size != NULL) *pre_size = isize + guardsize;
- return (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + 2*guardsize, MI_PAGE_HUGE_ALIGN) );
+ if (pre_size != NULL) *pre_size = isize;
+ isize = _mi_align_up(isize + guardsize, MI_SEGMENT_SLICE_SIZE);
+ if (info_slices != NULL) *info_slices = isize / MI_SEGMENT_SLICE_SIZE;
+ size_t segment_size = (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + guardsize, MI_SEGMENT_SLICE_SIZE) );
+ mi_assert_internal(segment_size % MI_SEGMENT_SLICE_SIZE == 0);
+ return (segment_size / MI_SEGMENT_SLICE_SIZE);
}
if (tld->current_size > tld->peak_size) tld->peak_size = tld->current_size;
}
-static void mi_segment_os_free(mi_segment_t* segment, size_t segment_size, mi_segments_tld_t* tld) {
+static void mi_segment_os_free(mi_segment_t* segment, mi_segments_tld_t* tld) {
segment->thread_id = 0;
- mi_segments_track_size(-((long)segment_size),tld);
- if (MI_SECURE != 0) {
- mi_assert_internal(!segment->mem_is_fixed);
- mi_segment_protect(segment, false, tld->os); // ensure no more guard pages are set
+ _mi_segment_map_freed_at(segment);
+ mi_segments_track_size(-((long)mi_segment_size(segment)),tld);
+ if (MI_SECURE>0) {
+ // _mi_os_unprotect(segment, mi_segment_size(segment)); // ensure no more guard pages are set
+ // unprotect the guard pages; we cannot just unprotect the whole segment size as part may be decommitted
+ size_t os_pagesize = _mi_os_page_size();
+ _mi_os_unprotect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize);
+ uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize;
+ _mi_os_unprotect(end, os_pagesize);
+ }
+
+ // purge delayed decommits now? (no, leave it to the cache)
+ // mi_segment_delayed_decommit(segment,true,tld->stats);
+
+ // _mi_os_free(segment, mi_segment_size(segment), /*segment->memid,*/ tld->stats);
+ const size_t size = mi_segment_size(segment);
+ if (size != MI_SEGMENT_SIZE || !_mi_segment_cache_push(segment, size, segment->memid, &segment->commit_mask, &segment->decommit_mask, segment->mem_is_large, segment->mem_is_pinned, tld->os)) {
+ const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size);
+ if (csize > 0 && !segment->mem_is_pinned) _mi_stat_decrease(&_mi_stats_main.committed, csize);
+ _mi_abandoned_await_readers(); // wait until safe to free
+ _mi_arena_free(segment, mi_segment_size(segment), segment->memid, segment->mem_is_pinned /* pretend not committed to not double count decommits */, tld->os);
}
+}
- bool any_reset = false;
- bool fully_committed = true;
- for (size_t i = 0; i < segment->capacity; i++) {
- mi_page_t* page = &segment->pages[i];
- if (!page->is_committed) { fully_committed = false; }
- if (page->is_reset) { any_reset = true; }
+// called by threads that are terminating
+void _mi_segment_thread_collect(mi_segments_tld_t* tld) {
+ MI_UNUSED(tld);
+ // nothing to do
+}
+
+
+/* -----------------------------------------------------------
+ Span management
+----------------------------------------------------------- */
+
+static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uint8_t* p, size_t size, uint8_t** start_p, size_t* full_size, mi_commit_mask_t* cm) {
+ mi_assert_internal(_mi_ptr_segment(p) == segment);
+ mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);
+ mi_commit_mask_create_empty(cm);
+ if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return;
+ const size_t segstart = mi_segment_info_size(segment);
+ const size_t segsize = mi_segment_size(segment);
+ if (p >= (uint8_t*)segment + segsize) return;
+
+ size_t pstart = (p - (uint8_t*)segment);
+ mi_assert_internal(pstart + size <= segsize);
+
+ size_t start;
+ size_t end;
+ if (conservative) {
+ // decommit conservative
+ start = _mi_align_up(pstart, MI_COMMIT_SIZE);
+ end = _mi_align_down(pstart + size, MI_COMMIT_SIZE);
+ mi_assert_internal(start >= segstart);
+ mi_assert_internal(end <= segsize);
+ }
+ else {
+ // commit liberal
+ start = _mi_align_down(pstart, MI_MINIMAL_COMMIT_SIZE);
+ end = _mi_align_up(pstart + size, MI_MINIMAL_COMMIT_SIZE);
}
- if (any_reset && mi_option_is_enabled(mi_option_reset_decommits)) {
- fully_committed = false;
+ if (pstart >= segstart && start < segstart) { // note: the mask is also calculated for an initial commit of the info area
+ start = segstart;
}
+ if (end > segsize) {
+ end = segsize;
+ }
+
+ mi_assert_internal(start <= pstart && (pstart + size) <= end);
+ mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0);
+ *start_p = (uint8_t*)segment + start;
+ *full_size = (end > start ? end - start : 0);
+ if (*full_size == 0) return;
+
+ size_t bitidx = start / MI_COMMIT_SIZE;
+ mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS);
- _mi_mem_free(segment, segment_size, segment->memid, fully_committed, any_reset, tld->os);
+ size_t bitcount = *full_size / MI_COMMIT_SIZE; // can be 0
+ if (bitidx + bitcount > MI_COMMIT_MASK_BITS) {
+ _mi_warning_message("commit mask overflow: idx=%zu count=%zu start=%zx end=%zx p=0x%p size=%zu fullsize=%zu\n", bitidx, bitcount, start, end, p, size, *full_size);
+ }
+ mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS);
+ mi_commit_mask_create(bitidx, bitcount, cm);
}
-// The thread local segment cache is limited to be at most 1/8 of the peak size of segments in use,
-#define MI_SEGMENT_CACHE_FRACTION (8)
+static bool mi_segment_commitx(mi_segment_t* segment, bool commit, uint8_t* p, size_t size, mi_stats_t* stats) {
+ mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask));
-// note: returned segment may be partially reset
-static mi_segment_t* mi_segment_cache_pop(size_t segment_size, mi_segments_tld_t* tld) {
- if (segment_size != 0 && segment_size != MI_SEGMENT_SIZE) return NULL;
- mi_segment_t* segment = tld->cache;
- if (segment == NULL) return NULL;
- tld->cache_count--;
- tld->cache = segment->next;
- segment->next = NULL;
- mi_assert_internal(segment->segment_size == MI_SEGMENT_SIZE);
- _mi_stat_decrease(&tld->stats->segments_cache, 1);
- return segment;
+ // try to commit in at least MI_MINIMAL_COMMIT_SIZE sizes.
+ /*
+ if (commit && size > 0) {
+ const size_t csize = _mi_align_up(size, MI_MINIMAL_COMMIT_SIZE);
+ if (p + csize <= mi_segment_end(segment)) {
+ size = csize;
+ }
+ }
+ */
+ // commit liberal, but decommit conservative
+ uint8_t* start = NULL;
+ size_t full_size = 0;
+ mi_commit_mask_t mask;
+ mi_segment_commit_mask(segment, !commit/*conservative*/, p, size, &start, &full_size, &mask);
+ if (mi_commit_mask_is_empty(&mask) || full_size==0) return true;
+
+ if (commit && !mi_commit_mask_all_set(&segment->commit_mask, &mask)) {
+ bool is_zero = false;
+ mi_commit_mask_t cmask;
+ mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);
+ _mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap
+ if (!_mi_os_commit(start,full_size,&is_zero,stats)) return false;
+ mi_commit_mask_set(&segment->commit_mask, &mask);
+ }
+ else if (!commit && mi_commit_mask_any_set(&segment->commit_mask, &mask)) {
+ mi_assert_internal((void*)start != (void*)segment);
+ //mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &mask));
+
+ mi_commit_mask_t cmask;
+ mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);
+ _mi_stat_increase(&_mi_stats_main.committed, full_size - _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap
+ if (segment->allow_decommit) {
+ _mi_os_decommit(start, full_size, stats); // ok if this fails
+ }
+ mi_commit_mask_clear(&segment->commit_mask, &mask);
+ }
+ // increase expiration of reusing part of the delayed decommit
+ if (commit && mi_commit_mask_any_set(&segment->decommit_mask, &mask)) {
+ segment->decommit_expire = _mi_clock_now() + mi_option_get(mi_option_decommit_delay);
+ }
+ // always undo delayed decommits
+ mi_commit_mask_clear(&segment->decommit_mask, &mask);
+ return true;
}
-static bool mi_segment_cache_full(mi_segments_tld_t* tld)
-{
- // if (tld->count == 1 && tld->cache_count==0) return false; // always cache at least the final segment of a thread
- size_t max_cache = mi_option_get(mi_option_segment_cache);
- if (tld->cache_count < max_cache
- && tld->cache_count < (1 + (tld->peak_count / MI_SEGMENT_CACHE_FRACTION)) // at least allow a 1 element cache
- ) {
- return false;
- }
- // take the opportunity to reduce the segment cache if it is too large (now)
- // TODO: this never happens as we check against peak usage, should we use current usage instead?
- while (tld->cache_count > max_cache) { //(1 + (tld->peak_count / MI_SEGMENT_CACHE_FRACTION))) {
- mi_segment_t* segment = mi_segment_cache_pop(0,tld);
- mi_assert_internal(segment != NULL);
- if (segment != NULL) mi_segment_os_free(segment, segment->segment_size, tld);
+static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
+ mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask));
+ // note: assumes commit_mask is always full for huge segments as otherwise the commit mask bits can overflow
+ if (mi_commit_mask_is_full(&segment->commit_mask) && mi_commit_mask_is_empty(&segment->decommit_mask)) return true; // fully committed
+ return mi_segment_commitx(segment,true,p,size,stats);
+}
+
+static void mi_segment_perhaps_decommit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
+ if (!segment->allow_decommit) return;
+ if (mi_option_get(mi_option_decommit_delay) == 0) {
+ mi_segment_commitx(segment, false, p, size, stats);
}
- return true;
+ else {
+ // register for future decommit in the decommit mask
+ uint8_t* start = NULL;
+ size_t full_size = 0;
+ mi_commit_mask_t mask;
+ mi_segment_commit_mask(segment, true /*conservative*/, p, size, &start, &full_size, &mask);
+ if (mi_commit_mask_is_empty(&mask) || full_size==0) return;
+
+ // update delayed commit
+ mi_assert_internal(segment->decommit_expire > 0 || mi_commit_mask_is_empty(&segment->decommit_mask));
+ mi_commit_mask_t cmask;
+ mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); // only decommit what is committed; span_free may try to decommit more
+ mi_commit_mask_set(&segment->decommit_mask, &cmask);
+ mi_msecs_t now = _mi_clock_now();
+ if (segment->decommit_expire == 0) {
+ // no previous decommits, initialize now
+ segment->decommit_expire = now + mi_option_get(mi_option_decommit_delay);
+ }
+ else if (segment->decommit_expire <= now) {
+ // previous decommit mask already expired
+ // mi_segment_delayed_decommit(segment, true, stats);
+ segment->decommit_expire = now + mi_option_get(mi_option_decommit_extend_delay); // (mi_option_get(mi_option_decommit_delay) / 8); // wait a tiny bit longer in case there is a series of free's
+ }
+ else {
+ // previous decommit mask is not yet expired, increase the expiration by a bit.
+ segment->decommit_expire += mi_option_get(mi_option_decommit_extend_delay);
+ }
+ }
}
-static bool mi_segment_cache_push(mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_assert_internal(!mi_segment_is_in_free_queue(segment, tld));
- mi_assert_internal(segment->next == NULL);
- if (segment->segment_size != MI_SEGMENT_SIZE || mi_segment_cache_full(tld)) {
- return false;
- }
- mi_assert_internal(segment->segment_size == MI_SEGMENT_SIZE);
- segment->next = tld->cache;
- tld->cache = segment;
- tld->cache_count++;
- _mi_stat_increase(&tld->stats->segments_cache,1);
- return true;
+static void mi_segment_delayed_decommit(mi_segment_t* segment, bool force, mi_stats_t* stats) {
+ if (!segment->allow_decommit || mi_commit_mask_is_empty(&segment->decommit_mask)) return;
+ mi_msecs_t now = _mi_clock_now();
+ if (!force && now < segment->decommit_expire) return;
+
+ mi_commit_mask_t mask = segment->decommit_mask;
+ segment->decommit_expire = 0;
+ mi_commit_mask_create_empty(&segment->decommit_mask);
+
+ size_t idx;
+ size_t count;
+ mi_commit_mask_foreach(&mask, idx, count) {
+ // if found, decommit that sequence
+ if (count > 0) {
+ uint8_t* p = (uint8_t*)segment + (idx*MI_COMMIT_SIZE);
+ size_t size = count * MI_COMMIT_SIZE;
+ mi_segment_commitx(segment, false, p, size, stats);
+ }
+ }
+ mi_commit_mask_foreach_end()
+ mi_assert_internal(mi_commit_mask_is_empty(&segment->decommit_mask));
}
-// called by threads that are terminating to free cached segments
-void _mi_segment_thread_collect(mi_segments_tld_t* tld) {
- mi_segment_t* segment;
- while ((segment = mi_segment_cache_pop(0,tld)) != NULL) {
- mi_segment_os_free(segment, segment->segment_size, tld);
+
+static bool mi_segment_is_abandoned(mi_segment_t* segment) {
+ return (segment->thread_id == 0);
+}
+
+// note: can be called on abandoned segments
+static void mi_segment_span_free(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) {
+ mi_assert_internal(slice_index < segment->slice_entries);
+ mi_span_queue_t* sq = (segment->kind == MI_SEGMENT_HUGE || mi_segment_is_abandoned(segment)
+ ? NULL : mi_span_queue_for(slice_count,tld));
+ if (slice_count==0) slice_count = 1;
+ mi_assert_internal(slice_index + slice_count - 1 < segment->slice_entries);
+
+ // set first and last slice (the intermediates can be undetermined)
+ mi_slice_t* slice = &segment->slices[slice_index];
+ slice->slice_count = (uint32_t)slice_count;
+ mi_assert_internal(slice->slice_count == slice_count); // no overflow?
+ slice->slice_offset = 0;
+ if (slice_count > 1) {
+ mi_slice_t* last = &segment->slices[slice_index + slice_count - 1];
+ last->slice_count = 0;
+ last->slice_offset = (uint32_t)(sizeof(mi_page_t)*(slice_count - 1));
+ last->xblock_size = 0;
+ }
+
+ // perhaps decommit
+ mi_segment_perhaps_decommit(segment,mi_slice_start(slice),slice_count*MI_SEGMENT_SLICE_SIZE,tld->stats);
+
+ // and push it on the free page queue (if it was not a huge page)
+ if (sq != NULL) mi_span_queue_push( sq, slice );
+ else slice->xblock_size = 0; // mark huge page as free anyways
+}
+
+/*
+// called from reclaim to add existing free spans
+static void mi_segment_span_add_free(mi_slice_t* slice, mi_segments_tld_t* tld) {
+ mi_segment_t* segment = _mi_ptr_segment(slice);
+ mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0);
+ size_t slice_index = mi_slice_index(slice);
+ mi_segment_span_free(segment,slice_index,slice->slice_count,tld);
+}
+*/
+
+static void mi_segment_span_remove_from_queue(mi_slice_t* slice, mi_segments_tld_t* tld) {
+ mi_assert_internal(slice->slice_count > 0 && slice->slice_offset==0 && slice->xblock_size==0);
+ mi_assert_internal(_mi_ptr_segment(slice)->kind != MI_SEGMENT_HUGE);
+ mi_span_queue_t* sq = mi_span_queue_for(slice->slice_count, tld);
+ mi_span_queue_delete(sq, slice);
+}
+
+// note: can be called on abandoned segments
+static mi_slice_t* mi_segment_span_free_coalesce(mi_slice_t* slice, mi_segments_tld_t* tld) {
+ mi_assert_internal(slice != NULL && slice->slice_count > 0 && slice->slice_offset == 0);
+ mi_segment_t* segment = _mi_ptr_segment(slice);
+ bool is_abandoned = mi_segment_is_abandoned(segment);
+
+ // for huge pages, just mark as free but don't add to the queues
+ if (segment->kind == MI_SEGMENT_HUGE) {
+ mi_assert_internal(segment->used == 1); // decreased right after this call in `mi_segment_page_clear`
+ slice->xblock_size = 0; // mark as free anyways
+ // we should mark the last slice `xblock_size=0` now to maintain invariants but we skip it to
+ // avoid a possible cache miss (and the segment is about to be freed)
+ return slice;
+ }
+
+ // otherwise coalesce the span and add to the free span queues
+ size_t slice_count = slice->slice_count;
+ mi_slice_t* next = slice + slice->slice_count;
+ mi_assert_internal(next <= mi_segment_slices_end(segment));
+ if (next < mi_segment_slices_end(segment) && next->xblock_size==0) {
+ // free next block -- remove it from free and merge
+ mi_assert_internal(next->slice_count > 0 && next->slice_offset==0);
+ slice_count += next->slice_count; // extend
+ if (!is_abandoned) { mi_segment_span_remove_from_queue(next, tld); }
+ }
+ if (slice > segment->slices) {
+ mi_slice_t* prev = mi_slice_first(slice - 1);
+ mi_assert_internal(prev >= segment->slices);
+ if (prev->xblock_size==0) {
+ // free previous slice -- remove it from free and merge
+ mi_assert_internal(prev->slice_count > 0 && prev->slice_offset==0);
+ slice_count += prev->slice_count;
+ if (!is_abandoned) { mi_segment_span_remove_from_queue(prev, tld); }
+ slice = prev;
+ }
}
- mi_assert_internal(tld->cache_count == 0);
- mi_assert_internal(tld->cache == NULL);
-#if MI_DEBUG>=2
- if (!_mi_is_main_thread()) {
- mi_assert_internal(tld->pages_reset.first == NULL);
- mi_assert_internal(tld->pages_reset.last == NULL);
+
+ // and add the new free page
+ mi_segment_span_free(segment, mi_slice_index(slice), slice_count, tld);
+ return slice;
+}
+
+
+static void mi_segment_slice_split(mi_segment_t* segment, mi_slice_t* slice, size_t slice_count, mi_segments_tld_t* tld) {
+ mi_assert_internal(_mi_ptr_segment(slice)==segment);
+ mi_assert_internal(slice->slice_count >= slice_count);
+ mi_assert_internal(slice->xblock_size > 0); // no more in free queue
+ if (slice->slice_count <= slice_count) return;
+ mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);
+ size_t next_index = mi_slice_index(slice) + slice_count;
+ size_t next_count = slice->slice_count - slice_count;
+ mi_segment_span_free(segment, next_index, next_count, tld);
+ slice->slice_count = (uint32_t)slice_count;
+}
+
+// Note: may still return NULL if committing the memory failed
+static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) {
+ mi_assert_internal(slice_index < segment->slice_entries);
+ mi_slice_t* slice = &segment->slices[slice_index];
+ mi_assert_internal(slice->xblock_size==0 || slice->xblock_size==1);
+
+ // commit before changing the slice data
+ if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats)) {
+ return NULL; // commit failed!
+ }
+
+ // convert the slices to a page
+ slice->slice_offset = 0;
+ slice->slice_count = (uint32_t)slice_count;
+ mi_assert_internal(slice->slice_count == slice_count);
+ const size_t bsize = slice_count * MI_SEGMENT_SLICE_SIZE;
+ slice->xblock_size = (uint32_t)(bsize >= MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : bsize);
+ mi_page_t* page = mi_slice_to_page(slice);
+ mi_assert_internal(mi_page_block_size(page) == bsize);
+
+ // set slice back pointers for the first MI_MAX_SLICE_OFFSET entries
+ size_t extra = slice_count-1;
+ if (extra > MI_MAX_SLICE_OFFSET) extra = MI_MAX_SLICE_OFFSET;
+ if (slice_index + extra >= segment->slice_entries) extra = segment->slice_entries - slice_index - 1; // huge objects may have more slices than avaiable entries in the segment->slices
+ slice++;
+ for (size_t i = 1; i <= extra; i++, slice++) {
+ slice->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i);
+ slice->slice_count = 0;
+ slice->xblock_size = 1;
+ }
+
+ // and also for the last one (if not set already) (the last one is needed for coalescing)
+ // note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543)
+ mi_slice_t* last = &((mi_slice_t*)segment->slices)[slice_index + slice_count - 1];
+ if (last < mi_segment_slices_end(segment) && last >= slice) {
+ last->slice_offset = (uint32_t)(sizeof(mi_slice_t)*(slice_count-1));
+ last->slice_count = 0;
+ last->xblock_size = 1;
}
-#endif
+
+ // and initialize the page
+ page->is_reset = false;
+ page->is_committed = true;
+ segment->used++;
+ return page;
+}
+
+static mi_page_t* mi_segments_page_find_and_allocate(size_t slice_count, mi_segments_tld_t* tld) {
+ mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_LARGE_OBJ_SIZE_MAX);
+ // search from best fit up
+ mi_span_queue_t* sq = mi_span_queue_for(slice_count, tld);
+ if (slice_count == 0) slice_count = 1;
+ while (sq <= &tld->spans[MI_SEGMENT_BIN_MAX]) {
+ for (mi_slice_t* slice = sq->first; slice != NULL; slice = slice->next) {
+ if (slice->slice_count >= slice_count) {
+ // found one
+ mi_span_queue_delete(sq, slice);
+ mi_segment_t* segment = _mi_ptr_segment(slice);
+ if (slice->slice_count > slice_count) {
+ mi_segment_slice_split(segment, slice, slice_count, tld);
+ }
+ mi_assert_internal(slice != NULL && slice->slice_count == slice_count && slice->xblock_size > 0);
+ mi_page_t* page = mi_segment_span_allocate(segment, mi_slice_index(slice), slice->slice_count, tld);
+ if (page == NULL) {
+ // commit failed; return NULL but first restore the slice
+ mi_segment_span_free_coalesce(slice, tld);
+ return NULL;
+ }
+ return page;
+ }
+ }
+ sq++;
+ }
+ // could not find a page..
+ return NULL;
}
----------------------------------------------------------- */
// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .
-static mi_segment_t* mi_segment_init(mi_segment_t* segment, size_t required, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
+static mi_segment_t* mi_segment_init(mi_segment_t* segment, size_t required, mi_segments_tld_t* tld, mi_os_tld_t* os_tld, mi_page_t** huge_page)
{
- // the segment parameter is non-null if it came from our cache
- mi_assert_internal(segment==NULL || (required==0 && page_kind <= MI_PAGE_LARGE));
-
+ mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL));
+ mi_assert_internal((segment==NULL) || (segment!=NULL && required==0));
// calculate needed sizes first
- size_t capacity;
- if (page_kind == MI_PAGE_HUGE) {
- mi_assert_internal(page_shift == MI_SEGMENT_SHIFT && required > 0);
- capacity = 1;
- }
- else {
- mi_assert_internal(required == 0);
- size_t page_size = (size_t)1 << page_shift;
- capacity = MI_SEGMENT_SIZE / page_size;
- mi_assert_internal(MI_SEGMENT_SIZE % page_size == 0);
- mi_assert_internal(capacity >= 1 && capacity <= MI_SMALL_PAGES_PER_SEGMENT);
- }
- size_t info_size;
+ size_t info_slices;
size_t pre_size;
- size_t segment_size = mi_segment_size(capacity, required, &pre_size, &info_size);
- mi_assert_internal(segment_size >= required);
-
- // Initialize parameters
- const bool eager_delayed = (page_kind <= MI_PAGE_MEDIUM && tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay));
- const bool eager = !eager_delayed && mi_option_is_enabled(mi_option_eager_commit);
- bool commit = eager; // || (page_kind >= MI_PAGE_LARGE);
- bool pages_still_good = false;
+ const size_t segment_slices = mi_segment_calculate_slices(required, &pre_size, &info_slices);
+ const size_t slice_entries = (segment_slices > MI_SLICES_PER_SEGMENT ? MI_SLICES_PER_SEGMENT : segment_slices);
+ const size_t segment_size = segment_slices * MI_SEGMENT_SLICE_SIZE;
+
+ // Commit eagerly only if not the first N lazy segments (to reduce impact of many threads that allocate just a little)
+ const bool eager_delay = (// !_mi_os_has_overcommit() && // never delay on overcommit systems
+ _mi_current_thread_count() > 1 && // do not delay for the first N threads
+ tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay));
+ const bool eager = !eager_delay && mi_option_is_enabled(mi_option_eager_commit);
+ bool commit = eager || (required > 0);
+
+ // Try to get from our cache first
bool is_zero = false;
-
- // Try to get it from our thread local cache first
+ const bool commit_info_still_good = (segment != NULL);
+ mi_commit_mask_t commit_mask;
+ mi_commit_mask_t decommit_mask;
if (segment != NULL) {
- // came from cache
- mi_assert_internal(segment->segment_size == segment_size);
- if (page_kind <= MI_PAGE_MEDIUM && segment->page_kind == page_kind && segment->segment_size == segment_size) {
- pages_still_good = true;
- }
- else
- {
- if (MI_SECURE!=0) {
- mi_assert_internal(!segment->mem_is_fixed);
- mi_segment_protect(segment, false, tld->os); // reset protection if the page kind differs
- }
- // different page kinds; unreset any reset pages, and unprotect
- // TODO: optimize cache pop to return fitting pages if possible?
- for (size_t i = 0; i < segment->capacity; i++) {
- mi_page_t* page = &segment->pages[i];
- if (page->is_reset) {
- if (!commit && mi_option_is_enabled(mi_option_reset_decommits)) {
- page->is_reset = false;
- }
- else {
- mi_page_unreset(segment, page, 0, tld); // todo: only unreset the part that was reset? (instead of the full page)
- }
- }
- }
- // ensure the initial info is committed
- if (segment->capacity < capacity) {
- bool commit_zero = false;
- _mi_mem_commit(segment, pre_size, &commit_zero, tld->os);
- if (commit_zero) is_zero = true;
- }
- }
+ commit_mask = segment->commit_mask;
+ decommit_mask = segment->decommit_mask;
}
else {
+ mi_commit_mask_create_empty(&commit_mask);
+ mi_commit_mask_create_empty(&decommit_mask);
+ }
+ if (segment==NULL) {
// Allocate the segment from the OS
- size_t memid;
- bool mem_large = (!eager_delayed && (MI_SECURE==0)); // only allow large OS pages once we are no longer lazy
- segment = (mi_segment_t*)_mi_mem_alloc_aligned(segment_size, MI_SEGMENT_SIZE, &commit, &mem_large, &is_zero, &memid, os_tld);
- if (segment == NULL) return NULL; // failed to allocate
- if (!commit) {
- // ensure the initial info is committed
- bool commit_zero = false;
- bool ok = _mi_mem_commit(segment, pre_size, &commit_zero, tld->os);
- if (commit_zero) is_zero = true;
- if (!ok) {
- // commit failed; we cannot touch the memory: free the segment directly and return `NULL`
- _mi_mem_free(segment, MI_SEGMENT_SIZE, memid, false, false, os_tld);
- return NULL;
+ bool mem_large = (!eager_delay && (MI_SECURE==0)); // only allow large OS pages once we are no longer lazy
+ bool is_pinned = false;
+ size_t memid = 0;
+ segment = (mi_segment_t*)_mi_segment_cache_pop(segment_size, &commit_mask, &decommit_mask, &mem_large, &is_pinned, &is_zero, &memid, os_tld);
+ if (segment==NULL) {
+ segment = (mi_segment_t*)_mi_arena_alloc_aligned(segment_size, MI_SEGMENT_SIZE, &commit, &mem_large, &is_pinned, &is_zero, &memid, os_tld);
+ if (segment == NULL) return NULL; // failed to allocate
+ if (commit) {
+ mi_commit_mask_create_full(&commit_mask);
}
+ else {
+ mi_commit_mask_create_empty(&commit_mask);
+ }
+ }
+ mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0);
+
+ const size_t commit_needed = _mi_divide_up(info_slices*MI_SEGMENT_SLICE_SIZE, MI_COMMIT_SIZE);
+ mi_assert_internal(commit_needed>0);
+ mi_commit_mask_t commit_needed_mask;
+ mi_commit_mask_create(0, commit_needed, &commit_needed_mask);
+ if (!mi_commit_mask_all_set(&commit_mask, &commit_needed_mask)) {
+ // at least commit the info slices
+ mi_assert_internal(commit_needed*MI_COMMIT_SIZE >= info_slices*MI_SEGMENT_SLICE_SIZE);
+ bool ok = _mi_os_commit(segment, commit_needed*MI_COMMIT_SIZE, &is_zero, tld->stats);
+ if (!ok) return NULL; // failed to commit
+ mi_commit_mask_set(&commit_mask, &commit_needed_mask);
}
segment->memid = memid;
- segment->mem_is_fixed = mem_large;
- segment->mem_is_committed = commit;
- mi_segments_track_size((long)segment_size, tld);
- }
- mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0);
- mi_assert_internal(segment->mem_is_fixed ? segment->mem_is_committed : true);
- if (!pages_still_good) {
- // zero the segment info (but not the `mem` fields)
- ptrdiff_t ofs = offsetof(mi_segment_t, next);
- memset((uint8_t*)segment + ofs, 0, info_size - ofs);
-
- // initialize pages info
- for (uint8_t i = 0; i < capacity; i++) {
- segment->pages[i].segment_idx = i;
- segment->pages[i].is_reset = false;
- segment->pages[i].is_committed = commit;
- segment->pages[i].is_zero_init = is_zero;
- }
+ segment->mem_is_pinned = is_pinned;
+ segment->mem_is_large = mem_large;
+ segment->mem_is_committed = mi_commit_mask_is_full(&commit_mask);
+ mi_segments_track_size((long)(segment_size), tld);
+ _mi_segment_map_allocated_at(segment);
}
- else {
- // zero the segment info but not the pages info (and mem fields)
+
+ // zero the segment info? -- not always needed as it is zero initialized from the OS
+ mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); // tsan
+ if (!is_zero) {
ptrdiff_t ofs = offsetof(mi_segment_t, next);
- memset((uint8_t*)segment + ofs, 0, offsetof(mi_segment_t,pages) - ofs);
+ size_t prefix = offsetof(mi_segment_t, slices) - ofs;
+ memset((uint8_t*)segment+ofs, 0, prefix + sizeof(mi_slice_t)*segment_slices);
+ }
+
+ if (!commit_info_still_good) {
+ segment->commit_mask = commit_mask; // on lazy commit, the initial part is always committed
+ segment->allow_decommit = (mi_option_is_enabled(mi_option_allow_decommit) && !segment->mem_is_pinned && !segment->mem_is_large);
+ if (segment->allow_decommit) {
+ segment->decommit_expire = _mi_clock_now() + mi_option_get(mi_option_decommit_delay);
+ segment->decommit_mask = decommit_mask;
+ mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask));
+ #if MI_DEBUG>2
+ const size_t commit_needed = _mi_divide_up(info_slices*MI_SEGMENT_SLICE_SIZE, MI_COMMIT_SIZE);
+ mi_commit_mask_t commit_needed_mask;
+ mi_commit_mask_create(0, commit_needed, &commit_needed_mask);
+ mi_assert_internal(!mi_commit_mask_any_set(&segment->decommit_mask, &commit_needed_mask));
+ #endif
+ }
+ else {
+ mi_assert_internal(mi_commit_mask_is_empty(&decommit_mask));
+ segment->decommit_expire = 0;
+ mi_commit_mask_create_empty( &segment->decommit_mask );
+ mi_assert_internal(mi_commit_mask_is_empty(&segment->decommit_mask));
+ }
}
+
- // initialize
- segment->page_kind = page_kind;
- segment->capacity = capacity;
- segment->page_shift = page_shift;
- segment->segment_size = segment_size;
- segment->segment_info_size = pre_size;
- segment->thread_id = _mi_thread_id();
+ // initialize segment info
+ segment->segment_slices = segment_slices;
+ segment->segment_info_slices = info_slices;
+ segment->thread_id = _mi_thread_id();
segment->cookie = _mi_ptr_cookie(segment);
- // _mi_stat_increase(&tld->stats->page_committed, segment->segment_info_size);
+ segment->slice_entries = slice_entries;
+ segment->kind = (required == 0 ? MI_SEGMENT_NORMAL : MI_SEGMENT_HUGE);
- // set protection
- mi_segment_protect(segment, true, tld->os);
+ // memset(segment->slices, 0, sizeof(mi_slice_t)*(info_slices+1));
+ _mi_stat_increase(&tld->stats->page_committed, mi_segment_info_size(segment));
- // insert in free lists for small and medium pages
- if (page_kind <= MI_PAGE_MEDIUM) {
- mi_segment_insert_in_free_queue(segment, tld);
+ // set up guard pages
+ size_t guard_slices = 0;
+ if (MI_SECURE>0) {
+ // in secure mode, we set up a protected page in between the segment info
+ // and the page data, and at the end of the segment.
+ size_t os_pagesize = _mi_os_page_size();
+ mi_assert_internal(mi_segment_info_size(segment) - os_pagesize >= pre_size);
+ _mi_os_protect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize);
+ uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize;
+ mi_segment_ensure_committed(segment, end, os_pagesize, tld->stats);
+ _mi_os_protect(end, os_pagesize);
+ if (slice_entries == segment_slices) segment->slice_entries--; // don't use the last slice :-(
+ guard_slices = 1;
+ }
+
+ // reserve first slices for segment info
+ mi_page_t* page0 = mi_segment_span_allocate(segment, 0, info_slices, tld);
+ mi_assert_internal(page0!=NULL); if (page0==NULL) return NULL; // cannot fail as we always commit in advance
+ mi_assert_internal(segment->used == 1);
+ segment->used = 0; // don't count our internal slices towards usage
+
+ // initialize initial free pages
+ if (segment->kind == MI_SEGMENT_NORMAL) { // not a huge page
+ mi_assert_internal(huge_page==NULL);
+ mi_segment_span_free(segment, info_slices, segment->slice_entries - info_slices, tld);
+ }
+ else {
+ mi_assert_internal(huge_page!=NULL);
+ mi_assert_internal(mi_commit_mask_is_empty(&segment->decommit_mask));
+ mi_assert_internal(mi_commit_mask_is_full(&segment->commit_mask));
+ *huge_page = mi_segment_span_allocate(segment, info_slices, segment_slices - info_slices - guard_slices, tld);
+ mi_assert_internal(*huge_page != NULL); // cannot fail as we commit in advance
}
- //fprintf(stderr,"mimalloc: alloc segment at %p\n", (void*)segment);
+ mi_assert_expensive(mi_segment_is_valid(segment,tld));
return segment;
}
-static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
- return mi_segment_init(NULL, required, page_kind, page_shift, tld, os_tld);
-}
-static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) {
- UNUSED(force);
- mi_assert(segment != NULL);
- // note: don't reset pages even on abandon as the whole segment is freed? (and ready for reuse)
- bool force_reset = (force && mi_option_is_enabled(mi_option_abandoned_page_reset));
- mi_pages_reset_remove_all_in_segment(segment, force_reset, tld);
- mi_segment_remove_from_free_queue(segment,tld);
-
- mi_assert_expensive(!mi_segment_queue_contains(&tld->small_free, segment));
- mi_assert_expensive(!mi_segment_queue_contains(&tld->medium_free, segment));
- mi_assert(segment->next == NULL);
- mi_assert(segment->prev == NULL);
- _mi_stat_decrease(&tld->stats->page_committed, segment->segment_info_size);
-
- if (!force && mi_segment_cache_push(segment, tld)) {
- // it is put in our cache
- }
- else {
- // otherwise return it to the OS
- mi_segment_os_free(segment, segment->segment_size, tld);
- }
+// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .
+static mi_segment_t* mi_segment_alloc(size_t required, mi_segments_tld_t* tld, mi_os_tld_t* os_tld, mi_page_t** huge_page) {
+ return mi_segment_init(NULL, required, tld, os_tld, huge_page);
}
-/* -----------------------------------------------------------
- Free page management inside a segment
------------------------------------------------------------ */
-
-static bool mi_segment_has_free(const mi_segment_t* segment) {
- return (segment->used < segment->capacity);
-}
-
-static bool mi_segment_page_claim(mi_segment_t* segment, mi_page_t* page, mi_segments_tld_t* tld) {
- mi_assert_internal(_mi_page_segment(page) == segment);
- mi_assert_internal(!page->segment_in_use);
- mi_pages_reset_remove(page, tld);
- // check commit
- if (!page->is_committed) {
- mi_assert_internal(!segment->mem_is_fixed);
- mi_assert_internal(!page->is_reset);
- size_t psize;
- uint8_t* start = mi_segment_raw_page_start(segment, page, &psize);
- bool is_zero = false;
- const size_t gsize = (MI_SECURE >= 2 ? _mi_os_page_size() : 0);
- bool ok = _mi_mem_commit(start, psize + gsize, &is_zero, tld->os);
- if (!ok) return false; // failed to commit!
- if (gsize > 0) { mi_segment_protect_range(start + psize, gsize, true); }
- if (is_zero) { page->is_zero_init = true; }
- page->is_committed = true;
- }
- // set in-use before doing unreset to prevent delayed reset
- page->segment_in_use = true;
- segment->used++;
- // check reset
- if (page->is_reset) {
- mi_assert_internal(!segment->mem_is_fixed);
- bool ok = mi_page_unreset(segment, page, 0, tld);
- if (!ok) {
- page->segment_in_use = false;
- segment->used--;
- return false;
+static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) {
+ MI_UNUSED(force);
+ mi_assert_internal(segment != NULL);
+ mi_assert_internal(segment->next == NULL);
+ mi_assert_internal(segment->used == 0);
+
+ // Remove the free pages
+ mi_slice_t* slice = &segment->slices[0];
+ const mi_slice_t* end = mi_segment_slices_end(segment);
+ size_t page_count = 0;
+ while (slice < end) {
+ mi_assert_internal(slice->slice_count > 0);
+ mi_assert_internal(slice->slice_offset == 0);
+ mi_assert_internal(mi_slice_index(slice)==0 || slice->xblock_size == 0); // no more used pages ..
+ if (slice->xblock_size == 0 && segment->kind != MI_SEGMENT_HUGE) {
+ mi_segment_span_remove_from_queue(slice, tld);
}
+ page_count++;
+ slice = slice + slice->slice_count;
}
- mi_assert_internal(page->segment_in_use);
- mi_assert_internal(segment->used <= segment->capacity);
- if (segment->used == segment->capacity && segment->page_kind <= MI_PAGE_MEDIUM) {
- // if no more free pages, remove from the queue
- mi_assert_internal(!mi_segment_has_free(segment));
- mi_segment_remove_from_free_queue(segment, tld);
- }
- return true;
+ mi_assert_internal(page_count == 2); // first page is allocated by the segment itself
+
+ // stats
+ _mi_stat_decrease(&tld->stats->page_committed, mi_segment_info_size(segment));
+
+ // return it to the OS
+ mi_segment_os_free(segment, tld);
}
/* -----------------------------------------------------------
- Free
+ Page Free
----------------------------------------------------------- */
static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld);
-// clear page data; can be called on abandoned segments
-static void mi_segment_page_clear(mi_segment_t* segment, mi_page_t* page, bool allow_reset, mi_segments_tld_t* tld)
-{
- mi_assert_internal(page->segment_in_use);
+// note: can be called on abandoned pages
+static mi_slice_t* mi_segment_page_clear(mi_page_t* page, mi_segments_tld_t* tld) {
+ mi_assert_internal(page->xblock_size > 0);
mi_assert_internal(mi_page_all_free(page));
- mi_assert_internal(page->is_committed);
- mi_assert_internal(mi_page_not_in_queue(page, tld));
-
+ mi_segment_t* segment = _mi_ptr_segment(page);
+ mi_assert_internal(segment->used > 0);
+
size_t inuse = page->capacity * mi_page_block_size(page);
_mi_stat_decrease(&tld->stats->page_committed, inuse);
_mi_stat_decrease(&tld->stats->pages, 1);
- // calculate the used size from the raw (non-aligned) start of the page
- //size_t pre_size;
- //_mi_segment_page_start(segment, page, page->block_size, NULL, &pre_size);
- //size_t used_size = pre_size + (page->capacity * page->block_size);
+ // reset the page memory to reduce memory pressure?
+ if (!segment->mem_is_pinned && !page->is_reset && mi_option_is_enabled(mi_option_page_reset)) {
+ size_t psize;
+ uint8_t* start = _mi_page_start(segment, page, &psize);
+ page->is_reset = true;
+ _mi_os_reset(start, psize, tld->stats);
+ }
+ // zero the page data, but not the segment fields
page->is_zero_init = false;
- page->segment_in_use = false;
-
- // reset the page memory to reduce memory pressure?
- // note: must come after setting `segment_in_use` to false but before block_size becomes 0
- //mi_page_reset(segment, page, 0 /*used_size*/, tld);
-
- // zero the page data, but not the segment fields and capacity, and block_size (for page size calculations)
- uint32_t block_size = page->xblock_size;
- uint16_t capacity = page->capacity;
- uint16_t reserved = page->reserved;
- ptrdiff_t ofs = offsetof(mi_page_t,capacity);
+ ptrdiff_t ofs = offsetof(mi_page_t, capacity);
memset((uint8_t*)page + ofs, 0, sizeof(*page) - ofs);
- page->capacity = capacity;
- page->reserved = reserved;
- page->xblock_size = block_size;
- segment->used--;
+ page->xblock_size = 1;
- // add to the free page list for reuse/reset
- if (allow_reset) {
- mi_pages_reset_add(segment, page, tld);
- }
-
- page->capacity = 0; // after reset there can be zero'd now
- page->reserved = 0;
+ // and free it
+ mi_slice_t* slice = mi_segment_span_free_coalesce(mi_page_to_slice(page), tld);
+ segment->used--;
+ // cannot assert segment valid as it is called during reclaim
+ // mi_assert_expensive(mi_segment_is_valid(segment, tld));
+ return slice;
}
void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld)
{
mi_assert(page != NULL);
+
mi_segment_t* segment = _mi_page_segment(page);
mi_assert_expensive(mi_segment_is_valid(segment,tld));
- mi_reset_delayed(tld);
// mark it as free now
- mi_segment_page_clear(segment, page, true, tld);
+ mi_segment_page_clear(page, tld);
+ mi_assert_expensive(mi_segment_is_valid(segment, tld));
if (segment->used == 0) {
// no more used pages; remove from the free list and free the segment
mi_segment_free(segment, force, tld);
}
- else {
- if (segment->used == segment->abandoned) {
- // only abandoned pages; remove from free list and abandon
- mi_segment_abandon(segment,tld);
- }
- else if (segment->used + 1 == segment->capacity) {
- mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM); // for now we only support small and medium pages
- // move back to segments free list
- mi_segment_insert_in_free_queue(segment,tld);
- }
+ else if (segment->used == segment->abandoned) {
+ // only abandoned pages; remove from free list and abandon
+ mi_segment_abandon(segment,tld);
}
}
Abandonment
When threads terminate, they can leave segments with
-live blocks (reached through other threads). Such segments
+live blocks (reachable through other threads). Such segments
are "abandoned" and will be reclaimed by other threads to
reuse their pages and/or free them eventually
Note: the current implementation is one possible design;
another way might be to keep track of abandoned segments
-in the regions. This would have the advantage of keeping
+in the arenas/segment_cache's. This would have the advantage of keeping
all concurrent code in one place and not needing to deal
with ABA issues. The drawback is that it is unclear how to
scan abandoned segments efficiently in that case as they
-would be spread among all other segments in the regions.
+would be spread among all other segments in the arenas.
----------------------------------------------------------- */
// Use the bottom 20-bits (on 64-bit) of the aligned segment pointers
// This is a list of visited abandoned pages that were full at the time.
// this list migrates to `abandoned` when that becomes NULL. The use of
// this list reduces contention and the rate at which segments are visited.
-static mi_decl_cache_align volatile _Atomic(mi_segment_t*) abandoned_visited; // = NULL
+static mi_decl_cache_align _Atomic(mi_segment_t*) abandoned_visited; // = NULL
// The abandoned page list (tagged as it supports pop)
-static mi_decl_cache_align volatile _Atomic(mi_tagged_segment_t) abandoned; // = NULL
+static mi_decl_cache_align _Atomic(mi_tagged_segment_t) abandoned; // = NULL
+
+// Maintain these for debug purposes (these counts may be a bit off)
+static mi_decl_cache_align _Atomic(size_t) abandoned_count;
+static mi_decl_cache_align _Atomic(size_t) abandoned_visited_count;
// We also maintain a count of current readers of the abandoned list
// in order to prevent resetting/decommitting segment memory if it might
// still be read.
-static mi_decl_cache_align volatile _Atomic(uintptr_t) abandoned_readers; // = 0
+static mi_decl_cache_align _Atomic(size_t) abandoned_readers; // = 0
// Push on the visited list
static void mi_abandoned_visited_push(mi_segment_t* segment) {
mi_assert_internal(segment->thread_id == 0);
- mi_assert_internal(segment->abandoned_next == NULL);
- mi_assert_internal(segment->next == NULL && segment->prev == NULL);
+ mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t,&segment->abandoned_next) == NULL);
+ mi_assert_internal(segment->next == NULL);
mi_assert_internal(segment->used > 0);
- mi_segment_t* anext;
+ mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited);
do {
- anext = mi_atomic_read_ptr_relaxed(mi_segment_t, &abandoned_visited);
- segment->abandoned_next = anext;
- } while (!mi_atomic_cas_ptr_weak(mi_segment_t, &abandoned_visited, segment, anext));
+ mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, anext);
+ } while (!mi_atomic_cas_ptr_weak_release(mi_segment_t, &abandoned_visited, &anext, segment));
+ mi_atomic_increment_relaxed(&abandoned_visited_count);
}
// Move the visited list to the abandoned list.
static bool mi_abandoned_visited_revisit(void)
{
// quick check if the visited list is empty
- if (mi_atomic_read_ptr_relaxed(mi_segment_t,&abandoned_visited)==NULL) return false;
+ if (mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited) == NULL) return false;
// grab the whole visited list
- mi_segment_t* first = mi_atomic_exchange_ptr(mi_segment_t, &abandoned_visited, NULL);
+ mi_segment_t* first = mi_atomic_exchange_ptr_acq_rel(mi_segment_t, &abandoned_visited, NULL);
if (first == NULL) return false;
// first try to swap directly if the abandoned list happens to be NULL
- const mi_tagged_segment_t ts = mi_atomic_read_relaxed(&abandoned);
mi_tagged_segment_t afirst;
+ mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned);
if (mi_tagged_segment_ptr(ts)==NULL) {
+ size_t count = mi_atomic_load_relaxed(&abandoned_visited_count);
afirst = mi_tagged_segment(first, ts);
- if (mi_atomic_cas_strong(&abandoned, afirst, ts)) return true;
+ if (mi_atomic_cas_strong_acq_rel(&abandoned, &ts, afirst)) {
+ mi_atomic_add_relaxed(&abandoned_count, count);
+ mi_atomic_sub_relaxed(&abandoned_visited_count, count);
+ return true;
+ }
}
// find the last element of the visited list: O(n)
mi_segment_t* last = first;
- while (last->abandoned_next != NULL) {
- last = last->abandoned_next;
+ mi_segment_t* next;
+ while ((next = mi_atomic_load_ptr_relaxed(mi_segment_t, &last->abandoned_next)) != NULL) {
+ last = next;
}
// and atomically prepend to the abandoned list
// (no need to increase the readers as we don't access the abandoned segments)
- mi_tagged_segment_t anext;
+ mi_tagged_segment_t anext = mi_atomic_load_relaxed(&abandoned);
+ size_t count;
do {
- anext = mi_atomic_read_relaxed(&abandoned);
- last->abandoned_next = mi_tagged_segment_ptr(anext);
+ count = mi_atomic_load_relaxed(&abandoned_visited_count);
+ mi_atomic_store_ptr_release(mi_segment_t, &last->abandoned_next, mi_tagged_segment_ptr(anext));
afirst = mi_tagged_segment(first, anext);
- } while (!mi_atomic_cas_weak(&abandoned, afirst, anext));
+ } while (!mi_atomic_cas_weak_release(&abandoned, &anext, afirst));
+ mi_atomic_add_relaxed(&abandoned_count, count);
+ mi_atomic_sub_relaxed(&abandoned_visited_count, count);
return true;
}
// Push on the abandoned list.
static void mi_abandoned_push(mi_segment_t* segment) {
mi_assert_internal(segment->thread_id == 0);
- mi_assert_internal(segment->abandoned_next == NULL);
- mi_assert_internal(segment->next == NULL && segment->prev == NULL);
+ mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL);
+ mi_assert_internal(segment->next == NULL);
mi_assert_internal(segment->used > 0);
- mi_tagged_segment_t ts;
mi_tagged_segment_t next;
+ mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned);
do {
- ts = mi_atomic_read_relaxed(&abandoned);
- segment->abandoned_next = mi_tagged_segment_ptr(ts);
+ mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, mi_tagged_segment_ptr(ts));
next = mi_tagged_segment(segment, ts);
- } while (!mi_atomic_cas_weak(&abandoned, next, ts));
+ } while (!mi_atomic_cas_weak_release(&abandoned, &ts, next));
+ mi_atomic_increment_relaxed(&abandoned_count);
}
// Wait until there are no more pending reads on segments that used to be in the abandoned list
+// called for example from `arena.c` before decommitting
void _mi_abandoned_await_readers(void) {
- uintptr_t n;
+ size_t n;
do {
- n = mi_atomic_read(&abandoned_readers);
+ n = mi_atomic_load_acquire(&abandoned_readers);
if (n != 0) mi_atomic_yield();
} while (n != 0);
}
static mi_segment_t* mi_abandoned_pop(void) {
mi_segment_t* segment;
// Check efficiently if it is empty (or if the visited list needs to be moved)
- mi_tagged_segment_t ts = mi_atomic_read_relaxed(&abandoned);
+ mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned);
segment = mi_tagged_segment_ptr(ts);
if (mi_likely(segment == NULL)) {
if (mi_likely(!mi_abandoned_visited_revisit())) { // try to swap in the visited list on NULL
// Do a pop. We use a reader count to prevent
// a segment to be decommitted while a read is still pending,
// and a tagged pointer to prevent A-B-A link corruption.
- // (this is called from `memory.c:_mi_mem_free` for example)
- mi_atomic_increment(&abandoned_readers); // ensure no segment gets decommitted
+ // (this is called from `region.c:_mi_mem_free` for example)
+ mi_atomic_increment_relaxed(&abandoned_readers); // ensure no segment gets decommitted
mi_tagged_segment_t next = 0;
+ ts = mi_atomic_load_acquire(&abandoned);
do {
- ts = mi_atomic_read(&abandoned);
segment = mi_tagged_segment_ptr(ts);
if (segment != NULL) {
- next = mi_tagged_segment(segment->abandoned_next, ts); // note: reads the segment's `abandoned_next` field so should not be decommitted
+ mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next);
+ next = mi_tagged_segment(anext, ts); // note: reads the segment's `abandoned_next` field so should not be decommitted
}
- } while (segment != NULL && !mi_atomic_cas_weak(&abandoned, next, ts));
- mi_atomic_decrement(&abandoned_readers); // release reader lock
+ } while (segment != NULL && !mi_atomic_cas_weak_acq_rel(&abandoned, &ts, next));
+ mi_atomic_decrement_relaxed(&abandoned_readers); // release reader lock
if (segment != NULL) {
- segment->abandoned_next = NULL;
+ mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL);
+ mi_atomic_decrement_relaxed(&abandoned_count);
}
return segment;
}
static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) {
mi_assert_internal(segment->used == segment->abandoned);
mi_assert_internal(segment->used > 0);
- mi_assert_internal(segment->abandoned_next == NULL);
- mi_assert_expensive(mi_segment_is_valid(segment, tld));
-
- // remove the segment from the free page queue if needed
- mi_reset_delayed(tld);
- mi_pages_reset_remove_all_in_segment(segment, mi_option_is_enabled(mi_option_abandoned_page_reset), tld);
- mi_segment_remove_from_free_queue(segment, tld);
- mi_assert_internal(segment->next == NULL && segment->prev == NULL);
+ mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL);
+ mi_assert_internal(segment->abandoned_visits == 0);
+ mi_assert_expensive(mi_segment_is_valid(segment,tld));
+
+ // remove the free pages from the free page queues
+ mi_slice_t* slice = &segment->slices[0];
+ const mi_slice_t* end = mi_segment_slices_end(segment);
+ while (slice < end) {
+ mi_assert_internal(slice->slice_count > 0);
+ mi_assert_internal(slice->slice_offset == 0);
+ if (slice->xblock_size == 0) { // a free page
+ mi_segment_span_remove_from_queue(slice,tld);
+ slice->xblock_size = 0; // but keep it free
+ }
+ slice = slice + slice->slice_count;
+ }
+ // perform delayed decommits
+ mi_segment_delayed_decommit(segment, mi_option_is_enabled(mi_option_abandoned_page_decommit) /* force? */, tld->stats);
+
// all pages in the segment are abandoned; add it to the abandoned list
_mi_stat_increase(&tld->stats->segments_abandoned, 1);
- mi_segments_track_size(-((long)segment->segment_size), tld);
+ mi_segments_track_size(-((long)mi_segment_size(segment)), tld);
segment->thread_id = 0;
- segment->abandoned_next = NULL;
- segment->abandoned_visits = 0;
+ mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL);
+ segment->abandoned_visits = 1; // from 0 to 1 to signify it is abandoned
mi_abandoned_push(segment);
}
mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE);
mi_assert_internal(mi_page_heap(page) == NULL);
mi_segment_t* segment = _mi_page_segment(page);
- mi_assert_expensive(!mi_pages_reset_contains(page, tld));
- mi_assert_expensive(mi_segment_is_valid(segment, tld));
- segment->abandoned++;
+
+ mi_assert_expensive(mi_segment_is_valid(segment,tld));
+ segment->abandoned++;
+
_mi_stat_increase(&tld->stats->pages_abandoned, 1);
mi_assert_internal(segment->abandoned <= segment->used);
if (segment->used == segment->abandoned) {
Reclaim abandoned pages
----------------------------------------------------------- */
-// Possibly clear pages and check if free space is available
-static bool mi_segment_check_free(mi_segment_t* segment, size_t block_size, bool* all_pages_free)
+static mi_slice_t* mi_slices_start_iterate(mi_segment_t* segment, const mi_slice_t** end) {
+ mi_slice_t* slice = &segment->slices[0];
+ *end = mi_segment_slices_end(segment);
+ mi_assert_internal(slice->slice_count>0 && slice->xblock_size>0); // segment allocated page
+ slice = slice + slice->slice_count; // skip the first segment allocated page
+ return slice;
+}
+
+// Possibly free pages and check if free space is available
+static bool mi_segment_check_free(mi_segment_t* segment, size_t slices_needed, size_t block_size, mi_segments_tld_t* tld)
{
mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE);
+ mi_assert_internal(mi_segment_is_abandoned(segment));
bool has_page = false;
- size_t pages_used = 0;
- size_t pages_used_empty = 0;
- for (size_t i = 0; i < segment->capacity; i++) {
- mi_page_t* page = &segment->pages[i];
- if (page->segment_in_use) {
- pages_used++;
+
+ // for all slices
+ const mi_slice_t* end;
+ mi_slice_t* slice = mi_slices_start_iterate(segment, &end);
+ while (slice < end) {
+ mi_assert_internal(slice->slice_count > 0);
+ mi_assert_internal(slice->slice_offset == 0);
+ if (mi_slice_is_used(slice)) { // used page
// ensure used count is up to date and collect potential concurrent frees
+ mi_page_t* const page = mi_slice_to_page(slice);
_mi_page_free_collect(page, false);
if (mi_page_all_free(page)) {
- // if everything free already, page can be reused for some block size
- // note: don't clear the page yet as we can only OS reset it once it is reclaimed
- pages_used_empty++;
- has_page = true;
- }
- else if (page->xblock_size == block_size && mi_page_has_any_available(page)) {
- // a page has available free blocks of the right size
- has_page = true;
+ // if this page is all free now, free it without adding to any queues (yet)
+ mi_assert_internal(page->next == NULL && page->prev==NULL);
+ _mi_stat_decrease(&tld->stats->pages_abandoned, 1);
+ segment->abandoned--;
+ slice = mi_segment_page_clear(page, tld); // re-assign slice due to coalesce!
+ mi_assert_internal(!mi_slice_is_used(slice));
+ if (slice->slice_count >= slices_needed) {
+ has_page = true;
+ }
}
+ else {
+ if (page->xblock_size == block_size && mi_page_has_any_available(page)) {
+ // a page has available free blocks of the right size
+ has_page = true;
+ }
+ }
}
else {
- // whole empty page
- has_page = true;
+ // empty span
+ if (slice->slice_count >= slices_needed) {
+ has_page = true;
+ }
}
- }
- mi_assert_internal(pages_used == segment->used && pages_used >= pages_used_empty);
- if (all_pages_free != NULL) {
- *all_pages_free = ((pages_used - pages_used_empty) == 0);
+ slice = slice + slice->slice_count;
}
return has_page;
}
-
-// Reclaim a segment; returns NULL if the segment was freed
+// Reclaim an abandoned segment; returns NULL if the segment was freed
// set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full.
static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) {
- mi_assert_internal(segment->abandoned_next == NULL);
+ mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL);
+ mi_assert_expensive(mi_segment_is_valid(segment, tld));
if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; }
segment->thread_id = _mi_thread_id();
segment->abandoned_visits = 0;
- mi_segments_track_size((long)segment->segment_size, tld);
- mi_assert_internal(segment->next == NULL && segment->prev == NULL);
- mi_assert_expensive(mi_segment_is_valid(segment, tld));
+ mi_segments_track_size((long)mi_segment_size(segment), tld);
+ mi_assert_internal(segment->next == NULL);
_mi_stat_decrease(&tld->stats->segments_abandoned, 1);
-
- for (size_t i = 0; i < segment->capacity; i++) {
- mi_page_t* page = &segment->pages[i];
- if (page->segment_in_use) {
+
+ // for all slices
+ const mi_slice_t* end;
+ mi_slice_t* slice = mi_slices_start_iterate(segment, &end);
+ while (slice < end) {
+ mi_assert_internal(slice->slice_count > 0);
+ mi_assert_internal(slice->slice_offset == 0);
+ if (mi_slice_is_used(slice)) {
+ // in use: reclaim the page in our heap
+ mi_page_t* page = mi_slice_to_page(slice);
mi_assert_internal(!page->is_reset);
mi_assert_internal(page->is_committed);
- mi_assert_internal(mi_page_not_in_queue(page, tld));
mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE);
mi_assert_internal(mi_page_heap(page) == NULL);
- segment->abandoned--;
- mi_assert(page->next == NULL);
+ mi_assert_internal(page->next == NULL && page->prev==NULL);
_mi_stat_decrease(&tld->stats->pages_abandoned, 1);
- // set the heap again and allow heap thread delayed free again.
+ segment->abandoned--;
+ // set the heap again and allow delayed free again
mi_page_set_heap(page, heap);
_mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set)
- // TODO: should we not collect again given that we just collected in `check_free`?
_mi_page_free_collect(page, false); // ensure used count is up to date
if (mi_page_all_free(page)) {
- // if everything free already, clear the page directly
- mi_segment_page_clear(segment, page, true, tld); // reset is ok now
+ // if everything free by now, free the page
+ slice = mi_segment_page_clear(page, tld); // set slice again due to coalesceing
}
else {
// otherwise reclaim it into the heap
}
}
}
- else if (page->is_committed && !page->is_reset) { // not in-use, and not reset yet
- // note: do not reset as this includes pages that were not touched before
- // mi_pages_reset_add(segment, page, tld);
+ else {
+ // the span is free, add it to our page queues
+ slice = mi_segment_span_free_coalesce(slice, tld); // set slice again due to coalesceing
}
+ mi_assert_internal(slice->slice_count>0 && slice->slice_offset==0);
+ slice = slice + slice->slice_count;
}
- mi_assert_internal(segment->abandoned == 0);
- if (segment->used == 0) {
+
+ mi_assert(segment->abandoned == 0);
+ if (segment->used == 0) { // due to page_clear
mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed));
mi_segment_free(segment, false, tld);
return NULL;
}
else {
- if (segment->page_kind <= MI_PAGE_MEDIUM && mi_segment_has_free(segment)) {
- mi_segment_insert_in_free_queue(segment, tld);
- }
return segment;
}
}
}
}
-static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t block_size, mi_page_kind_t page_kind, bool* reclaimed, mi_segments_tld_t* tld)
+static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slices, size_t block_size, bool* reclaimed, mi_segments_tld_t* tld)
{
*reclaimed = false;
mi_segment_t* segment;
- int max_tries = 8; // limit the work to bound allocation times
+ long max_tries = mi_option_get_clamp(mi_option_max_segment_reclaim, 8, 1024); // limit the work to bound allocation times
while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) {
segment->abandoned_visits++;
- bool all_pages_free;
- bool has_page = mi_segment_check_free(segment,block_size,&all_pages_free); // try to free up pages (due to concurrent frees)
- if (all_pages_free) {
+ bool has_page = mi_segment_check_free(segment,needed_slices,block_size,tld); // try to free up pages (due to concurrent frees)
+ if (segment->used == 0) {
// free the segment (by forced reclaim) to make it available to other threads.
// note1: we prefer to free a segment as that might lead to reclaiming another
// segment that is still partially used.
// freeing but that would violate some invariants temporarily)
mi_segment_reclaim(segment, heap, 0, NULL, tld);
}
- else if (has_page && segment->page_kind == page_kind) {
- // found a free page of the right kind, or page of the right block_size with free space
+ else if (has_page) {
+ // found a large enough free span, or a page of the right block_size with free space
// we return the result of reclaim (which is usually `segment`) as it might free
// the segment due to concurrent frees (in which case `NULL` is returned).
return mi_segment_reclaim(segment, heap, block_size, reclaimed, tld);
}
- else if (segment->abandoned_visits >= 3) {
- // always reclaim on 3rd visit to limit the list length.
+ else if (segment->abandoned_visits > 3) {
+ // always reclaim on 3rd visit to limit the abandoned queue length.
mi_segment_reclaim(segment, heap, 0, NULL, tld);
}
else {
// otherwise, push on the visited list so it gets not looked at too quickly again
+ mi_segment_delayed_decommit(segment, true /* force? */, tld->stats); // forced decommit if needed as we may not visit soon again
mi_abandoned_visited_push(segment);
}
}
}
+void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld)
+{
+ mi_segment_t* segment;
+ int max_tries = (force ? 16*1024 : 1024); // limit latency
+ if (force) {
+ mi_abandoned_visited_revisit();
+ }
+ while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) {
+ mi_segment_check_free(segment,0,0,tld); // try to free up pages (due to concurrent frees)
+ if (segment->used == 0) {
+ // free the segment (by forced reclaim) to make it available to other threads.
+ // note: we could in principle optimize this by skipping reclaim and directly
+ // freeing but that would violate some invariants temporarily)
+ mi_segment_reclaim(segment, heap, 0, NULL, tld);
+ }
+ else {
+ // otherwise, decommit if needed and push on the visited list
+ // note: forced decommit can be expensive if many threads are destroyed/created as in mstress.
+ mi_segment_delayed_decommit(segment, force, tld->stats);
+ mi_abandoned_visited_push(segment);
+ }
+ }
+}
+
/* -----------------------------------------------------------
Reclaim or allocate
----------------------------------------------------------- */
-static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t block_size, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
+static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_slices, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
{
- mi_assert_internal(page_kind <= MI_PAGE_LARGE);
mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE);
- // 1. try to get a segment from our cache
- mi_segment_t* segment = mi_segment_cache_pop(MI_SEGMENT_SIZE, tld);
- if (segment != NULL) {
- mi_segment_init(segment, 0, page_kind, page_shift, tld, os_tld);
- return segment;
- }
- // 2. try to reclaim an abandoned segment
+ mi_assert_internal(block_size <= MI_LARGE_OBJ_SIZE_MAX);
+
+ // 1. try to reclaim an abandoned segment
bool reclaimed;
- segment = mi_segment_try_reclaim(heap, block_size, page_kind, &reclaimed, tld);
+ mi_segment_t* segment = mi_segment_try_reclaim(heap, needed_slices, block_size, &reclaimed, tld);
if (reclaimed) {
// reclaimed the right page right into the heap
- mi_assert_internal(segment != NULL && segment->page_kind == page_kind && page_kind <= MI_PAGE_LARGE);
+ mi_assert_internal(segment != NULL);
return NULL; // pretend out-of-memory as the page will be in the page queue of the heap with available blocks
}
else if (segment != NULL) {
- // reclaimed a segment with empty pages (of `page_kind`) in it
+ // reclaimed a segment with a large enough empty span in it
return segment;
}
- // 3. otherwise allocate a fresh segment
- return mi_segment_alloc(0, page_kind, page_shift, tld, os_tld);
+ // 2. otherwise allocate a fresh segment
+ return mi_segment_alloc(0, tld, os_tld, NULL);
}
/* -----------------------------------------------------------
- Small page allocation
+ Page allocation
----------------------------------------------------------- */
-static mi_page_t* mi_segment_find_free(mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_assert_internal(mi_segment_has_free(segment));
- mi_assert_expensive(mi_segment_is_valid(segment, tld));
- for (size_t i = 0; i < segment->capacity; i++) { // TODO: use a bitmap instead of search?
- mi_page_t* page = &segment->pages[i];
- if (!page->segment_in_use) {
- bool ok = mi_segment_page_claim(segment, page, tld);
- if (ok) return page;
+static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_kind, size_t required, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
+{
+ mi_assert_internal(required <= MI_LARGE_OBJ_SIZE_MAX && page_kind <= MI_PAGE_LARGE);
+
+ // find a free page
+ size_t page_size = _mi_align_up(required, (required > MI_MEDIUM_PAGE_SIZE ? MI_MEDIUM_PAGE_SIZE : MI_SEGMENT_SLICE_SIZE));
+ size_t slices_needed = page_size / MI_SEGMENT_SLICE_SIZE;
+ mi_assert_internal(slices_needed * MI_SEGMENT_SLICE_SIZE == page_size);
+ mi_page_t* page = mi_segments_page_find_and_allocate(slices_needed, tld); //(required <= MI_SMALL_SIZE_MAX ? 0 : slices_needed), tld);
+ if (page==NULL) {
+ // no free page, allocate a new segment and try again
+ if (mi_segment_reclaim_or_alloc(heap, slices_needed, block_size, tld, os_tld) == NULL) {
+ // OOM or reclaimed a good page in the heap
+ return NULL;
+ }
+ else {
+ // otherwise try again
+ return mi_segments_page_alloc(heap, page_kind, required, block_size, tld, os_tld);
}
}
- mi_assert(false);
- return NULL;
-}
-
-// Allocate a page inside a segment. Requires that the page has free pages
-static mi_page_t* mi_segment_page_alloc_in(mi_segment_t* segment, mi_segments_tld_t* tld) {
- mi_assert_internal(mi_segment_has_free(segment));
- return mi_segment_find_free(segment, tld);
-}
-
-static mi_page_t* mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, mi_page_kind_t kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
- // find an available segment the segment free queue
- mi_segment_queue_t* const free_queue = mi_segment_free_queue_of_kind(kind, tld);
- if (mi_segment_queue_is_empty(free_queue)) {
- // possibly allocate or reclaim a fresh segment
- mi_segment_t* const segment = mi_segment_reclaim_or_alloc(heap, block_size, kind, page_shift, tld, os_tld);
- if (segment == NULL) return NULL; // return NULL if out-of-memory (or reclaimed)
- mi_assert_internal(free_queue->first == segment);
- mi_assert_internal(segment->page_kind==kind);
- mi_assert_internal(segment->used < segment->capacity);
- }
- mi_assert_internal(free_queue->first != NULL);
- mi_page_t* const page = mi_segment_page_alloc_in(free_queue->first, tld);
- mi_assert_internal(page != NULL);
-#if MI_DEBUG>=2
- // verify it is committed
- _mi_segment_page_start(_mi_page_segment(page), page, sizeof(void*), NULL, NULL)[0] = 0;
-#endif
+ mi_assert_internal(page != NULL && page->slice_count*MI_SEGMENT_SLICE_SIZE == page_size);
+ mi_assert_internal(_mi_ptr_segment(page)->thread_id == _mi_thread_id());
+ mi_segment_delayed_decommit(_mi_ptr_segment(page), false, tld->stats);
return page;
}
-static mi_page_t* mi_segment_small_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
- return mi_segment_page_alloc(heap, block_size, MI_PAGE_SMALL,MI_SMALL_PAGE_SHIFT,tld,os_tld);
-}
-static mi_page_t* mi_segment_medium_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
- return mi_segment_page_alloc(heap, block_size, MI_PAGE_MEDIUM, MI_MEDIUM_PAGE_SHIFT, tld, os_tld);
-}
/* -----------------------------------------------------------
- large page allocation
+ Huge page allocation
----------------------------------------------------------- */
-static mi_page_t* mi_segment_large_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
- mi_segment_t* segment = mi_segment_reclaim_or_alloc(heap,block_size,MI_PAGE_LARGE,MI_LARGE_PAGE_SHIFT,tld,os_tld);
- if (segment == NULL) return NULL;
- mi_page_t* page = mi_segment_find_free(segment, tld);
- mi_assert_internal(page != NULL);
-#if MI_DEBUG>=2
- _mi_segment_page_start(segment, page, sizeof(void*), NULL, NULL)[0] = 0;
-#endif
- return page;
-}
-
static mi_page_t* mi_segment_huge_page_alloc(size_t size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
{
- mi_segment_t* segment = mi_segment_alloc(size, MI_PAGE_HUGE, MI_SEGMENT_SHIFT,tld,os_tld);
- if (segment == NULL) return NULL;
- mi_assert_internal(mi_segment_page_size(segment) - segment->segment_info_size - (2*(MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= size);
- segment->thread_id = 0; // huge pages are immediately abandoned
- mi_segments_track_size(-(long)segment->segment_size, tld);
- mi_page_t* page = mi_segment_find_free(segment, tld);
- mi_assert_internal(page != NULL);
+ mi_page_t* page = NULL;
+ mi_segment_t* segment = mi_segment_alloc(size,tld,os_tld,&page);
+ if (segment == NULL || page==NULL) return NULL;
+ mi_assert_internal(segment->used==1);
+ mi_assert_internal(mi_page_block_size(page) >= size);
+ segment->thread_id = 0; // huge segments are immediately abandoned
return page;
}
// free huge block from another thread
void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) {
// huge page segments are always abandoned and can be freed immediately by any thread
- mi_assert_internal(segment->page_kind==MI_PAGE_HUGE);
+ mi_assert_internal(segment->kind==MI_SEGMENT_HUGE);
mi_assert_internal(segment == _mi_page_segment(page));
- mi_assert_internal(mi_atomic_read_relaxed(&segment->thread_id)==0);
+ mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id)==0);
// claim it and free
mi_heap_t* heap = mi_heap_get_default(); // issue #221; don't use the internal get_default_heap as we need to ensure the thread is initialized.
// paranoia: if this it the last reference, the cas should always succeed
- if (mi_atomic_cas_strong(&segment->thread_id, heap->thread_id, 0)) {
+ size_t expected_tid = 0;
+ if (mi_atomic_cas_strong_acq_rel(&segment->thread_id, &expected_tid, heap->thread_id)) {
mi_block_set_next(page, block, page->free);
page->free = block;
page->used--;
page->is_zero = false;
mi_assert(page->used == 0);
mi_tld_t* tld = heap->tld;
- const size_t bsize = mi_page_usable_block_size(page);
- if (bsize > MI_HUGE_OBJ_SIZE_MAX) {
- _mi_stat_decrease(&tld->stats.giant, bsize);
- }
- else {
- _mi_stat_decrease(&tld->stats.huge, bsize);
- }
- mi_segments_track_size((long)segment->segment_size, &tld->segments);
_mi_segment_page_free(page, true, &tld->segments);
}
+#if (MI_DEBUG!=0)
+ else {
+ mi_assert_internal(false);
+ }
+#endif
}
/* -----------------------------------------------------------
- Page allocation
+ Page allocation and free
----------------------------------------------------------- */
-
mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
mi_page_t* page;
if (block_size <= MI_SMALL_OBJ_SIZE_MAX) {
- page = mi_segment_small_page_alloc(heap, block_size, tld, os_tld);
+ page = mi_segments_page_alloc(heap,MI_PAGE_SMALL,block_size,block_size,tld,os_tld);
}
else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) {
- page = mi_segment_medium_page_alloc(heap, block_size, tld, os_tld);
+ page = mi_segments_page_alloc(heap,MI_PAGE_MEDIUM,MI_MEDIUM_PAGE_SIZE,block_size,tld, os_tld);
}
else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) {
- page = mi_segment_large_page_alloc(heap, block_size, tld, os_tld);
+ page = mi_segments_page_alloc(heap,MI_PAGE_LARGE,block_size,block_size,tld, os_tld);
}
else {
page = mi_segment_huge_page_alloc(block_size,tld,os_tld);
}
mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld));
- mi_assert_internal(page == NULL || (mi_segment_page_size(_mi_page_segment(page)) - (MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= block_size);
- mi_reset_delayed(tld);
- mi_assert_internal(page == NULL || mi_page_not_in_queue(page, tld));
return page;
}
+
+
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include "stats.c"
#include "random.c"
#include "os.c"
+#include "bitmap.c"
#include "arena.c"
-#include "region.c"
+#include "segment-cache.c"
#include "segment.c"
#include "page.c"
#include "heap.c"
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2021, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
#include <stdio.h> // fputs, stderr
#include <string.h> // memset
+#if defined(_MSC_VER) && (_MSC_VER < 1920)
+#pragma warning(disable:4204) // non-constant aggregate initializer
+#endif
/* -----------------------------------------------------------
Statistics operations
if (mi_is_in_main(stat))
{
// add atomically (for abandoned pages)
- mi_atomic_addi64(&stat->current,amount);
- mi_atomic_maxi64(&stat->peak, mi_atomic_readi64(&stat->current));
+ int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount);
+ mi_atomic_maxi64_relaxed(&stat->peak, current + amount);
if (amount > 0) {
- mi_atomic_addi64(&stat->allocated,amount);
+ mi_atomic_addi64_relaxed(&stat->allocated,amount);
}
else {
- mi_atomic_addi64(&stat->freed, -amount);
+ mi_atomic_addi64_relaxed(&stat->freed, -amount);
}
}
else {
void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) {
if (mi_is_in_main(stat)) {
- mi_atomic_addi64( &stat->count, 1 );
- mi_atomic_addi64( &stat->total, (int64_t)amount );
+ mi_atomic_addi64_relaxed( &stat->count, 1 );
+ mi_atomic_addi64_relaxed( &stat->total, (int64_t)amount );
}
else {
stat->count++;
static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src, int64_t unit) {
if (stat==src) return;
if (src->allocated==0 && src->freed==0) return;
- mi_atomic_addi64( &stat->allocated, src->allocated * unit);
- mi_atomic_addi64( &stat->current, src->current * unit);
- mi_atomic_addi64( &stat->freed, src->freed * unit);
- // peak scores do not work across threads..
- mi_atomic_addi64( &stat->peak, src->peak * unit);
+ mi_atomic_addi64_relaxed( &stat->allocated, src->allocated * unit);
+ mi_atomic_addi64_relaxed( &stat->current, src->current * unit);
+ mi_atomic_addi64_relaxed( &stat->freed, src->freed * unit);
+ // peak scores do not work across threads..
+ mi_atomic_addi64_relaxed( &stat->peak, src->peak * unit);
}
static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src, int64_t unit) {
if (stat==src) return;
- mi_atomic_addi64( &stat->total, src->total * unit);
- mi_atomic_addi64( &stat->count, src->count * unit);
+ mi_atomic_addi64_relaxed( &stat->total, src->total * unit);
+ mi_atomic_addi64_relaxed( &stat->count, src->count * unit);
}
// must be thread safe as it is called from stats_merge
mi_stat_add(&stats->malloc, &src->malloc, 1);
mi_stat_add(&stats->segments_cache, &src->segments_cache, 1);
+ mi_stat_add(&stats->normal, &src->normal, 1);
mi_stat_add(&stats->huge, &src->huge, 1);
- mi_stat_add(&stats->giant, &src->giant, 1);
+ mi_stat_add(&stats->large, &src->large, 1);
mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1);
mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls, 1);
mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1);
mi_stat_counter_add(&stats->searches, &src->searches, 1);
+ mi_stat_counter_add(&stats->normal_count, &src->normal_count, 1);
mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1);
- mi_stat_counter_add(&stats->giant_count, &src->giant_count, 1);
+ mi_stat_counter_add(&stats->large_count, &src->large_count, 1);
#if MI_STAT>1
for (size_t i = 0; i <= MI_BIN_HUGE; i++) {
- if (src->normal[i].allocated > 0 || src->normal[i].freed > 0) {
- mi_stat_add(&stats->normal[i], &src->normal[i], 1);
+ if (src->normal_bins[i].allocated > 0 || src->normal_bins[i].freed > 0) {
+ mi_stat_add(&stats->normal_bins[i], &src->normal_bins[i], 1);
}
}
#endif
// unit == 0: count as decimal
// unit < 0 : count in binary
static void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) {
- char buf[32];
+ char buf[32]; buf[0] = 0;
int len = 32;
- const char* suffix = (unit <= 0 ? " " : "b");
+ const char* suffix = (unit <= 0 ? " " : "B");
const int64_t base = (unit == 0 ? 1000 : 1024);
if (unit>0) n *= unit;
const int64_t pos = (n < 0 ? -n : n);
if (pos < base) {
- snprintf(buf, len, "%d %s ", (int)n, suffix);
+ if (n!=1 || suffix[0] != 'B') { // skip printing 1 B for the unit column
+ snprintf(buf, len, "%d %-3s", (int)n, (n==0 ? "" : suffix));
+ }
}
else {
- int64_t divider = base;
- const char* magnitude = "k";
- if (pos >= divider*base) { divider *= base; magnitude = "m"; }
- if (pos >= divider*base) { divider *= base; magnitude = "g"; }
+ int64_t divider = base;
+ const char* magnitude = "K";
+ if (pos >= divider*base) { divider *= base; magnitude = "M"; }
+ if (pos >= divider*base) { divider *= base; magnitude = "G"; }
const int64_t tens = (n / (divider/10));
const long whole = (long)(tens/10);
const long frac1 = (long)(tens%10);
- snprintf(buf, len, "%ld.%ld %s%s", whole, frac1, magnitude, suffix);
+ char unitdesc[8];
+ snprintf(unitdesc, 8, "%s%s%s", magnitude, (base==1024 ? "i" : ""), suffix);
+ snprintf(buf, len, "%ld.%ld %-3s", whole, (frac1 < 0 ? -frac1 : frac1), unitdesc);
}
_mi_fprintf(out, arg, (fmt==NULL ? "%11s" : fmt), buf);
}
mi_print_amount(stat->peak, unit, out, arg);
mi_print_amount(stat->allocated, unit, out, arg);
mi_print_amount(stat->freed, unit, out, arg);
+ mi_print_amount(stat->current, unit, out, arg);
mi_print_amount(unit, 1, out, arg);
mi_print_count(stat->allocated, unit, out, arg);
if (stat->allocated > stat->freed)
mi_print_amount(stat->peak, -1, out, arg);
mi_print_amount(stat->allocated, -1, out, arg);
mi_print_amount(stat->freed, -1, out, arg);
+ mi_print_amount(stat->current, -1, out, arg);
if (unit==-1) {
_mi_fprintf(out, arg, "%22s", "");
}
else {
mi_print_amount(stat->peak, 1, out, arg);
mi_print_amount(stat->allocated, 1, out, arg);
+ _mi_fprintf(out, arg, "%11s", " "); // no freed
+ mi_print_amount(stat->current, 1, out, arg);
_mi_fprintf(out, arg, "\n");
}
}
static void mi_print_header(mi_output_fun* out, void* arg ) {
- _mi_fprintf(out, arg, "%10s: %10s %10s %10s %10s %10s\n", "heap stats", "peak ", "total ", "freed ", "unit ", "count ");
+ _mi_fprintf(out, arg, "%10s: %10s %10s %10s %10s %10s %10s\n", "heap stats", "peak ", "total ", "freed ", "current ", "unit ", "count ");
}
#if MI_STAT>1
-static void mi_stats_print_bins(mi_stat_count_t* all, const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) {
+static void mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) {
bool found = false;
char buf[64];
for (size_t i = 0; i <= max; i++) {
if (bins[i].allocated > 0) {
found = true;
int64_t unit = _mi_bin_size((uint8_t)i);
- snprintf(buf, 64, "%s %3zu", fmt, i);
- mi_stat_add(all, &bins[i], unit);
+ snprintf(buf, 64, "%s %3lu", fmt, (long)i);
mi_stat_print(&bins[i], buf, unit, out, arg);
}
}
- //snprintf(buf, 64, "%s all", fmt);
- //mi_stat_print(all, buf, 1);
if (found) {
_mi_fprintf(out, arg, "\n");
mi_print_header(out, arg);
// Print statistics
//------------------------------------------------------------
-static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit);
+static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults);
-static void _mi_stats_print(mi_stats_t* stats, mi_msecs_t elapsed, mi_output_fun* out0, void* arg0) mi_attr_noexcept {
+static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept {
// wrap the output function to be line buffered
char buf[256];
- buffered_t buffer = { out0, arg0, buf, 0, 255 };
+ buffered_t buffer = { out0, arg0, NULL, 0, 255 };
+ buffer.buf = buf;
mi_output_fun* out = &mi_buffered_out;
void* arg = &buffer;
// and print using that
mi_print_header(out,arg);
#if MI_STAT>1
- mi_stat_count_t normal = { 0,0,0,0 };
- mi_stats_print_bins(&normal, stats->normal, MI_BIN_HUGE, "normal",out,arg);
- mi_stat_print(&normal, "normal", 1, out, arg);
+ mi_stats_print_bins(stats->normal_bins, MI_BIN_HUGE, "normal",out,arg);
+ #endif
+ #if MI_STAT
+ mi_stat_print(&stats->normal, "normal", (stats->normal_count.count == 0 ? 1 : -(stats->normal.allocated / stats->normal_count.count)), out, arg);
+ mi_stat_print(&stats->large, "large", (stats->large_count.count == 0 ? 1 : -(stats->large.allocated / stats->large_count.count)), out, arg);
mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out, arg);
- mi_stat_print(&stats->giant, "giant", (stats->giant_count.count == 0 ? 1 : -(stats->giant.allocated / stats->giant_count.count)), out, arg);
mi_stat_count_t total = { 0,0,0,0 };
- mi_stat_add(&total, &normal, 1);
+ mi_stat_add(&total, &stats->normal, 1);
+ mi_stat_add(&total, &stats->large, 1);
mi_stat_add(&total, &stats->huge, 1);
- mi_stat_add(&total, &stats->giant, 1);
mi_stat_print(&total, "total", 1, out, arg);
- _mi_fprintf(out, arg, "malloc requested: ");
- mi_print_amount(stats->malloc.allocated, 1, out, arg);
- _mi_fprintf(out, arg, "\n\n");
+ #endif
+ #if MI_STAT>1
+ mi_stat_print(&stats->malloc, "malloc req", 1, out, arg);
+ _mi_fprintf(out, arg, "\n");
#endif
mi_stat_print(&stats->reserved, "reserved", 1, out, arg);
mi_stat_print(&stats->committed, "committed", 1, out, arg);
mi_stat_counter_print(&stats->commit_calls, "commits", out, arg);
mi_stat_print(&stats->threads, "threads", -1, out, arg);
mi_stat_counter_print_avg(&stats->searches, "searches", out, arg);
- _mi_fprintf(out, arg, "%10s: %7i\n", "numa nodes", _mi_os_numa_node_count());
- if (elapsed > 0) _mi_fprintf(out, arg, "%10s: %7ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000);
-
+ _mi_fprintf(out, arg, "%10s: %7zu\n", "numa nodes", _mi_os_numa_node_count());
+
+ mi_msecs_t elapsed;
mi_msecs_t user_time;
mi_msecs_t sys_time;
+ size_t current_rss;
size_t peak_rss;
- size_t page_faults;
- size_t page_reclaim;
+ size_t current_commit;
size_t peak_commit;
- mi_process_info(&user_time, &sys_time, &peak_rss, &page_faults, &page_reclaim, &peak_commit);
- _mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, reclaims: %lu, rss: ", "process", user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults, (unsigned long)page_reclaim );
+ size_t page_faults;
+ mi_stat_process_info(&elapsed, &user_time, &sys_time, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults);
+ _mi_fprintf(out, arg, "%10s: %7ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000);
+ _mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, rss: ", "process",
+ user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults );
mi_printf_amount((int64_t)peak_rss, 1, out, arg, "%s");
if (peak_commit > 0) {
- _mi_fprintf(out, arg, ", commit charge: ");
+ _mi_fprintf(out, arg, ", commit: ");
mi_printf_amount((int64_t)peak_commit, 1, out, arg, "%s");
}
_mi_fprintf(out, arg, "\n");
}
-static mi_msecs_t mi_time_start; // = 0
+static mi_msecs_t mi_process_start; // = 0
static mi_stats_t* mi_stats_get_default(void) {
mi_heap_t* heap = mi_heap_get_default();
mi_stats_t* stats = mi_stats_get_default();
if (stats != &_mi_stats_main) { memset(stats, 0, sizeof(mi_stats_t)); }
memset(&_mi_stats_main, 0, sizeof(mi_stats_t));
- mi_time_start = _mi_clock_start();
+ if (mi_process_start == 0) { mi_process_start = _mi_clock_start(); };
}
void mi_stats_merge(void) mi_attr_noexcept {
}
void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {
- mi_msecs_t elapsed = _mi_clock_end(mi_time_start);
mi_stats_merge_from(mi_stats_get_default());
- _mi_stats_print(&_mi_stats_main, elapsed, out, arg);
+ _mi_stats_print(&_mi_stats_main, out, arg);
}
void mi_stats_print(void* out) mi_attr_noexcept {
}
void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {
- mi_msecs_t elapsed = _mi_clock_end(mi_time_start);
- _mi_stats_print(mi_stats_get_default(), elapsed, out, arg);
+ _mi_stats_print(mi_stats_get_default(), out, arg);
}
}
#else
#include <time.h>
-#ifdef CLOCK_REALTIME
+#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)
mi_msecs_t _mi_clock_now(void) {
struct timespec t;
+ #ifdef CLOCK_MONOTONIC
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ #else
clock_gettime(CLOCK_REALTIME, &t);
+ #endif
return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);
}
#else
mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds
return msecs;
}
-static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) {
+
+static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults)
+{
+ *elapsed = _mi_clock_end(mi_process_start);
FILETIME ct;
FILETIME ut;
FILETIME st;
GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
*utime = filetime_msecs(&ut);
*stime = filetime_msecs(&st);
-
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
- *peak_rss = (size_t)info.PeakWorkingSetSize;
- *page_faults = (size_t)info.PageFaultCount;
- *peak_commit = (size_t)info.PeakPagefileUsage;
- *page_reclaim = 0;
+ *current_rss = (size_t)info.WorkingSetSize;
+ *peak_rss = (size_t)info.PeakWorkingSetSize;
+ *current_commit = (size_t)info.PagefileUsage;
+ *peak_commit = (size_t)info.PeakPagefileUsage;
+ *page_faults = (size_t)info.PageFaultCount;
}
-#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)
+#elif !defined(__wasi__) && (defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__))
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
-#if defined(__APPLE__) && defined(__MACH__)
+#if defined(__APPLE__)
#include <mach/mach.h>
#endif
return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L);
}
-static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) {
+static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults)
+{
+ *elapsed = _mi_clock_end(mi_process_start);
struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage);
+ *utime = timeval_secs(&rusage.ru_utime);
+ *stime = timeval_secs(&rusage.ru_stime);
#if !defined(__HAIKU__)
-#if defined(__APPLE__) && defined(__MACH__)
- *peak_rss = rusage.ru_maxrss;
-#else
- *peak_rss = rusage.ru_maxrss * 1024;
-#endif
*page_faults = rusage.ru_majflt;
- *page_reclaim = rusage.ru_minflt;
- *peak_commit = 0;
-#else
-// Haiku does not have (yet?) a way to
-// get these stats per process
+#endif
+ // estimate commit using our stats
+ *peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak));
+ *current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current));
+ *current_rss = *current_commit; // estimate
+#if defined(__HAIKU__)
+ // Haiku does not have (yet?) a way to
+ // get these stats per process
thread_info tid;
area_info mem;
ssize_t c;
- *peak_rss = 0;
- *page_faults = 0;
- *page_reclaim = 0;
- *peak_commit = 0;
get_thread_info(find_thread(0), &tid);
-
while (get_next_area_info(tid.team, &c, &mem) == B_OK) {
- *peak_rss += mem.ram_size;
+ *peak_rss += mem.ram_size;
}
-#endif
- *utime = timeval_secs(&rusage.ru_utime);
- *stime = timeval_secs(&rusage.ru_stime);
+ *page_faults = 0;
+#elif defined(__APPLE__)
+ *peak_rss = rusage.ru_maxrss; // BSD reports in bytes
+ struct mach_task_basic_info info;
+ mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
+ if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) {
+ *current_rss = (size_t)info.resident_size;
+ }
+#else
+ *peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB
+#endif
}
#else
#pragma message("define a way to get process info")
#endif
-static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) {
- *peak_rss = 0;
+static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults)
+{
+ *elapsed = _mi_clock_end(mi_process_start);
+ *peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak));
+ *current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current));
+ *peak_rss = *peak_commit;
+ *current_rss = *current_commit;
*page_faults = 0;
- *page_reclaim = 0;
- *peak_commit = 0;
*utime = 0;
*stime = 0;
}
#endif
+
+
+mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept
+{
+ mi_msecs_t elapsed = 0;
+ mi_msecs_t utime = 0;
+ mi_msecs_t stime = 0;
+ size_t current_rss0 = 0;
+ size_t peak_rss0 = 0;
+ size_t current_commit0 = 0;
+ size_t peak_commit0 = 0;
+ size_t page_faults0 = 0;
+ mi_stat_process_info(&elapsed,&utime, &stime, ¤t_rss0, &peak_rss0, ¤t_commit0, &peak_commit0, &page_faults0);
+ if (elapsed_msecs!=NULL) *elapsed_msecs = (elapsed < 0 ? 0 : (elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)elapsed : PTRDIFF_MAX));
+ if (user_msecs!=NULL) *user_msecs = (utime < 0 ? 0 : (utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)utime : PTRDIFF_MAX));
+ if (system_msecs!=NULL) *system_msecs = (stime < 0 ? 0 : (stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)stime : PTRDIFF_MAX));
+ if (current_rss!=NULL) *current_rss = current_rss0;
+ if (peak_rss!=NULL) *peak_rss = peak_rss0;
+ if (current_commit!=NULL) *current_commit = current_commit0;
+ if (peak_commit!=NULL) *peak_commit = peak_commit0;
+ if (page_faults!=NULL) *page_faults = page_faults0;
+}
+
cmake_minimum_required(VERSION 3.0)
project(mimalloc-test C CXX)
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
+
# Set default build type
if (NOT CMAKE_BUILD_TYPE)
if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$")
endif()
# Import mimalloc (if installed)
-find_package(mimalloc 1.6 REQUIRED NO_SYSTEM_ENVIRONMENT_PATH)
-message(STATUS "Found mimalloc installed at: ${MIMALLOC_TARGET_DIR}")
+find_package(mimalloc 2.0 REQUIRED NO_SYSTEM_ENVIRONMENT_PATH)
+message(STATUS "Found mimalloc installed at: ${MIMALLOC_LIBRARY_DIR} (${MIMALLOC_VERSION_DIR})")
# overriding with a dynamic library
add_executable(dynamic-override main-override.c)
# overriding with a static object file works reliable as the symbols in the
# object file have priority over those in library files
-add_executable(static-override-obj main-override.c ${MIMALLOC_TARGET_DIR}/mimalloc.o)
-target_include_directories(static-override-obj PUBLIC ${MIMALLOC_TARGET_DIR}/include)
+add_executable(static-override-obj main-override.c ${MIMALLOC_OBJECT_DIR}/mimalloc.o)
+target_include_directories(static-override-obj PUBLIC ${MIMALLOC_INCLUDE_DIR})
target_link_libraries(static-override-obj PUBLIC pthread)
#include <mimalloc.h>
#include <mimalloc-override.h> // redefines malloc etc.
+
static void double_free1();
static void double_free2();
static void corrupt_free();
static void block_overflow1();
static void invalid_free();
+static void test_aslr(void);
+static void test_process_info(void);
+static void test_reserved(void);
+static void negative_stat(void);
+static void alloc_huge(void);
+static void test_heap_walk(void);
int main() {
mi_version();
-
+ mi_stats_reset();
// detect double frees and heap corruption
// double_free1();
// double_free2();
// corrupt_free();
// block_overflow1();
- invalid_free();
-
+ // test_aslr();
+ // invalid_free();
+ // test_reserved();
+ // negative_stat();
+ // alloc_huge();
+ test_heap_walk();
+
void* p1 = malloc(78);
void* p2 = malloc(24);
free(p1);
p1 = mi_malloc(8);
- //char* s = strdup("hello\n");
+ char* s = strdup("hello\n");
free(p2);
+
p2 = malloc(16);
p1 = realloc(p1, 32);
free(p1);
free(p2);
- //free(s);
- //mi_collect(true);
-
+ free(s);
+
/* now test if override worked by allocating/freeing across the api's*/
//p1 = mi_malloc(32);
//free(p1);
//p2 = malloc(32);
//mi_free(p2);
- mi_stats_print(NULL);
+
+ //mi_collect(true);
+ //mi_stats_print(NULL);
+
+ // test_process_info();
return 0;
}
malloc(SZ);
}
}
+
+static void test_aslr(void) {
+ void* p[256];
+ p[0] = malloc(378200);
+ p[1] = malloc(1134626);
+ printf("p1: %p, p2: %p\n", p[0], p[1]);
+}
+
+static void test_process_info(void) {
+ size_t elapsed = 0;
+ size_t user_msecs = 0;
+ size_t system_msecs = 0;
+ size_t current_rss = 0;
+ size_t peak_rss = 0;
+ size_t current_commit = 0;
+ size_t peak_commit = 0;
+ size_t page_faults = 0;
+ for (int i = 0; i < 100000; i++) {
+ void* p = calloc(100,10);
+ free(p);
+ }
+ mi_process_info(&elapsed, &user_msecs, &system_msecs, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults);
+ printf("\n\n*** process info: elapsed %3zd.%03zd s, user: %3zd.%03zd s, rss: %zd b, commit: %zd b\n\n", elapsed/1000, elapsed%1000, user_msecs/1000, user_msecs%1000, peak_rss, peak_commit);
+}
+
+static void test_reserved(void) {
+#define KiB 1024ULL
+#define MiB (KiB*KiB)
+#define GiB (MiB*KiB)
+ mi_reserve_os_memory(4*GiB, false, true);
+ void* p1 = malloc(100);
+ void* p2 = malloc(100000);
+ void* p3 = malloc(2*GiB);
+ void* p4 = malloc(1*GiB + 100000);
+ free(p1);
+ free(p2);
+ free(p3);
+ p3 = malloc(1*GiB);
+ free(p4);
+}
+
+
+
+static void negative_stat(void) {
+ int* p = mi_malloc(60000);
+ mi_stats_print_out(NULL, NULL);
+ *p = 100;
+ mi_free(p);
+ mi_stats_print_out(NULL, NULL);
+}
+
+static void alloc_huge(void) {
+ void* p = mi_malloc(67108872);
+ mi_free(p);
+}
+
+static bool test_visit(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) {
+ if (block == NULL) {
+ printf("visiting an area with blocks of size %zu (including padding)\n", area->full_block_size);
+ }
+ else {
+ printf(" block of size %zu (allocated size is %zu)\n", block_size, mi_usable_size(block));
+ }
+ return true;
+}
+
+static void test_heap_walk(void) {
+ mi_heap_t* heap = mi_heap_new();
+ //mi_heap_malloc(heap, 2097152);
+ mi_heap_malloc(heap, 2067152);
+ mi_heap_malloc(heap, 2097160);
+ mi_heap_malloc(heap, 24576);
+ mi_heap_visit_blocks(heap, true, &test_visit, NULL);
+}
+
+// ----------------------------
+// bin size experiments
+// ------------------------------
+
+#if 0
+#include <stdint.h>
+#include <stdbool.h>
+
+#define MI_INTPTR_SIZE 8
+#define MI_LARGE_WSIZE_MAX (4*1024*1024 / MI_INTPTR_SIZE)
+
+#define MI_BIN_HUGE 100
+//#define MI_ALIGN2W
+
+// Bit scan reverse: return the index of the highest bit.
+static inline uint8_t mi_bsr32(uint32_t x);
+
+#if defined(_MSC_VER)
+#include <windows.h>
+#include <intrin.h>
+static inline uint8_t mi_bsr32(uint32_t x) {
+ uint32_t idx;
+ _BitScanReverse((DWORD*)&idx, x);
+ return idx;
+}
+#elif defined(__GNUC__) || defined(__clang__)
+static inline uint8_t mi_bsr32(uint32_t x) {
+ return (31 - __builtin_clz(x));
+}
+#else
+static inline uint8_t mi_bsr32(uint32_t x) {
+ // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
+ static const uint8_t debruijn[32] = {
+ 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12,
+ 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13,
+ };
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x++;
+ return debruijn[(x*0x076be629) >> 27];
+}
+#endif
+
+/*
+// Bit scan reverse: return the index of the highest bit.
+uint8_t _mi_bsr(uintptr_t x) {
+ if (x == 0) return 0;
+ #if MI_INTPTR_SIZE==8
+ uint32_t hi = (x >> 32);
+ return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi));
+ #elif MI_INTPTR_SIZE==4
+ return mi_bsr32(x);
+ #else
+ # error "define bsr for non-32 or 64-bit platforms"
+ #endif
+}
+*/
+
+
+static inline size_t _mi_wsize_from_size(size_t size) {
+ return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
+}
+
+// Return the bin for a given field size.
+// Returns MI_BIN_HUGE if the size is too large.
+// We use `wsize` for the size in "machine word sizes",
+// i.e. byte size == `wsize*sizeof(void*)`.
+extern inline uint8_t _mi_bin8(size_t size) {
+ size_t wsize = _mi_wsize_from_size(size);
+ uint8_t bin;
+ if (wsize <= 1) {
+ bin = 1;
+ }
+#if defined(MI_ALIGN4W)
+ else if (wsize <= 4) {
+ bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
+ }
+#elif defined(MI_ALIGN2W)
+ else if (wsize <= 8) {
+ bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
+ }
+#else
+ else if (wsize <= 8) {
+ bin = (uint8_t)wsize;
+ }
+#endif
+ else if (wsize > MI_LARGE_WSIZE_MAX) {
+ bin = MI_BIN_HUGE;
+ }
+ else {
+#if defined(MI_ALIGN4W)
+ if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes
+#endif
+ wsize--;
+ // find the highest bit
+ uint8_t b = mi_bsr32((uint32_t)wsize);
+ // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
+ // - adjust with 3 because we use do not round the first 8 sizes
+ // which each get an exact bin
+ bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3;
+ }
+ return bin;
+}
+
+static inline uint8_t _mi_bin4(size_t size) {
+ size_t wsize = _mi_wsize_from_size(size);
+ uint8_t bin;
+ if (wsize <= 1) {
+ bin = 1;
+ }
+#if defined(MI_ALIGN4W)
+ else if (wsize <= 4) {
+ bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
+ }
+#elif defined(MI_ALIGN2W)
+ else if (wsize <= 8) {
+ bin = (uint8_t)((wsize+1)&~1); // round to double word sizes
+ }
+#else
+ else if (wsize <= 8) {
+ bin = (uint8_t)wsize;
+ }
+#endif
+ else if (wsize > MI_LARGE_WSIZE_MAX) {
+ bin = MI_BIN_HUGE;
+ }
+ else {
+ uint8_t b = mi_bsr32((uint32_t)wsize);
+ bin = ((b << 1) + (uint8_t)((wsize >> (b - 1)) & 0x01)) + 3;
+ }
+ return bin;
+}
+
+static size_t _mi_binx4(size_t bsize) {
+ if (bsize==0) return 0;
+ uint8_t b = mi_bsr32((uint32_t)bsize);
+ if (b <= 1) return bsize;
+ size_t bin = ((b << 1) | (bsize >> (b - 1))&0x01);
+ return bin;
+}
+
+static size_t _mi_binx8(size_t bsize) {
+ if (bsize<=1) return bsize;
+ uint8_t b = mi_bsr32((uint32_t)bsize);
+ if (b <= 2) return bsize;
+ size_t bin = ((b << 2) | (bsize >> (b - 2))&0x03) - 5;
+ return bin;
+}
+
+static void mi_bins(void) {
+ //printf(" QNULL(1), /* 0 */ \\\n ");
+ size_t last_bin = 0;
+ size_t min_bsize = 0;
+ size_t last_bsize = 0;
+ for (size_t bsize = 1; bsize < 2*1024; bsize++) {
+ size_t size = bsize * 64 * 1024;
+ size_t bin = _mi_binx8(bsize);
+ if (bin != last_bin) {
+ printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_bsize, last_bsize, last_bin);
+ //printf("QNULL(%6zd), ", wsize);
+ //if (last_bin%8 == 0) printf("/* %i */ \\\n ", last_bin);
+ last_bin = bin;
+ min_bsize = bsize;
+ }
+ last_bsize = bsize;
+ }
+}
+#endif
#include <assert.h>
#include <string.h>
-#include <mimalloc.h>
+#include <mimalloc-override.h>
int main() {
mi_version(); // ensure mimalloc library is linked
//free(p1);
//p2 = malloc(32);
//mi_free(p2);
+ p1 = malloc(24);
+ p2 = reallocarray(p1, 16, 16);
+ free(p2);
+ p1 = malloc(24);
+ assert(reallocarr(&p1, 16, 16) == 0);
+ free(p1);
mi_stats_print(NULL);
return 0;
}
#endif
#ifdef _WIN32
-#include <windows.h>
+#include <Windows.h>
static void msleep(unsigned long msecs) { Sleep(msecs); }
#else
#include <unistd.h>
static void msleep(unsigned long msecs) { usleep(msecs * 1000UL); }
#endif
-void heap_thread_free_large(); // issue #221
-void heap_no_delete(); // issue #202
-void heap_late_free(); // issue #204
-void padding_shrink(); // issue #209
-void various_tests();
-void test_mt_shutdown();
+static void heap_thread_free_large(); // issue #221
+static void heap_no_delete(); // issue #202
+static void heap_late_free(); // issue #204
+static void padding_shrink(); // issue #209
+static void various_tests();
+static void test_mt_shutdown();
+static void large_alloc(void); // issue #363
+static void fail_aslr(); // issue #372
+static void tsan_numa_test(); // issue #414
+static void strdup_test(); // issue #445
+static void bench_alloc_large(void); // issue #xxx
int main() {
mi_stats_reset(); // ignore earlier allocations
- heap_thread_free_large();
- heap_no_delete();
- heap_late_free();
- padding_shrink();
- various_tests();
- //test_mt_shutdown();
+
+ heap_thread_free_large();
+ heap_no_delete();
+ heap_late_free();
+ padding_shrink();
+ various_tests();
+ large_alloc();
+ tsan_numa_test();
+ strdup_test();
+
+ test_mt_shutdown();
+ //fail_aslr();
+ bench_alloc_large();
mi_stats_print(NULL);
return 0;
}
};
-void various_tests() {
+static void various_tests() {
atexit(free_p);
void* p1 = malloc(78);
- void* p2 = mi_malloc_aligned(16, 24);
+ void* p2 = mi_malloc_aligned(24, 16);
free(p1);
p1 = malloc(8);
char* s = mi_strdup("hello\n");
- //char* s = _strdup("hello\n");
- //char* buf = NULL;
- //size_t len;
- //_dupenv_s(&buf,&len,"MIMALLOC_VERBOSE");
- //mi_free(buf);
-
mi_free(p2);
p2 = malloc(16);
p1 = realloc(p1, 32);
free(p1);
free(p2);
mi_free(s);
+
Test* t = new Test(42);
delete t;
t = new (std::nothrow) Test(42);
static Static s = Static();
-bool test_stl_allocator1() {
+static bool test_stl_allocator1() {
std::vector<int, mi_stl_allocator<int> > vec;
vec.push_back(1);
vec.pop_back();
struct some_struct { int i; int j; double z; };
-bool test_stl_allocator2() {
+static bool test_stl_allocator2() {
std::vector<some_struct, mi_stl_allocator<some_struct> > vec;
vec.push_back(some_struct());
vec.pop_back();
return vec.size() == 0;
}
-
+// issue 445
+static void strdup_test() {
+#ifdef _MSC_VER
+ char* s = _strdup("hello\n");
+ char* buf = NULL;
+ size_t len;
+ _dupenv_s(&buf, &len, "MIMALLOC_VERBOSE");
+ mi_free(buf);
+ mi_free(s);
+#endif
+}
// Issue #202
-void heap_no_delete_worker() {
+static void heap_no_delete_worker() {
mi_heap_t* heap = mi_heap_new();
void* q = mi_heap_malloc(heap, 1024);
// mi_heap_delete(heap); // uncomment to prevent assertion
}
-void heap_no_delete() {
+static void heap_no_delete() {
auto t1 = std::thread(heap_no_delete_worker);
t1.join();
}
// Issue #204
-volatile void* global_p;
+static volatile void* global_p;
-void t1main() {
+static void t1main() {
mi_heap_t* heap = mi_heap_new();
global_p = mi_heap_malloc(heap, 1024);
mi_heap_delete(heap);
}
-void heap_late_free() {
+static void heap_late_free() {
auto t1 = std::thread(t1main);
msleep(2000);
shared_p = mi_malloc(8);
}
-void padding_shrink(void)
+static void padding_shrink(void)
{
auto t1 = std::thread(alloc0);
t1.join();
// Issue #221
-void heap_thread_free_large_worker() {
+static void heap_thread_free_large_worker() {
mi_free(shared_p);
}
-void heap_thread_free_large() {
+static void heap_thread_free_large() {
for (int i = 0; i < 100; i++) {
- shared_p = mi_malloc_aligned(2*1024*1024 + 1, 8);
+ shared_p = mi_malloc_aligned(2 * 1024 * 1024 + 1, 8);
auto t1 = std::thread(heap_thread_free_large_worker);
t1.join();
}
-void test_mt_shutdown()
+static void test_mt_shutdown()
{
const int threads = 5;
std::vector< std::future< std::vector< char* > > > ts;
std::cout << "done" << std::endl;
}
+
+// issue #363
+using namespace std;
+
+void large_alloc(void)
+{
+ char* a = new char[1ull << 25];
+ thread th([&] {
+ delete[] a;
+ });
+ th.join();
+}
+
+// issue #372
+static void fail_aslr() {
+ size_t sz = (4ULL << 40); // 4TiB
+ void* p = malloc(sz);
+ printf("pointer p: %p: area up to %p\n", p, (uint8_t*)p + sz);
+ *(int*)0x5FFFFFFF000 = 0; // should segfault
+}
+
+// issues #414
+static void dummy_worker() {
+ void* p = mi_malloc(0);
+ mi_free(p);
+}
+
+static void tsan_numa_test() {
+ auto t1 = std::thread(dummy_worker);
+ dummy_worker();
+ t1.join();
+}
+
+// issue #?
+#include <chrono>
+#include <random>
+#include <iostream>
+
+static void bench_alloc_large(void) {
+ static constexpr int kNumBuffers = 20;
+ static constexpr size_t kMinBufferSize = 5 * 1024 * 1024;
+ static constexpr size_t kMaxBufferSize = 25 * 1024 * 1024;
+ std::unique_ptr<char[]> buffers[kNumBuffers];
+
+ std::random_device rd;
+ std::mt19937 gen(42); //rd());
+ std::uniform_int_distribution<> size_distribution(kMinBufferSize, kMaxBufferSize);
+ std::uniform_int_distribution<> buf_number_distribution(0, kNumBuffers - 1);
+
+ static constexpr int kNumIterations = 2000;
+ const auto start = std::chrono::steady_clock::now();
+ for (int i = 0; i < kNumIterations; ++i) {
+ int buffer_idx = buf_number_distribution(gen);
+ size_t new_size = size_distribution(gen);
+ buffers[buffer_idx] = std::make_unique<char[]>(new_size);
+ }
+ const auto end = std::chrono::steady_clock::now();
+ const auto num_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ const auto us_per_allocation = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / kNumIterations;
+ std::cout << kNumIterations << " allocations Done in " << num_ms << "ms." << std::endl;
+ std::cout << "Avg " << us_per_allocation << " us per allocation" << std::endl;
+}
+
--- /dev/null
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#include "mimalloc.h"
+#include "mimalloc-types.h"
+
+#include "testhelper.h"
+
+// ---------------------------------------------------------------------------
+// Helper functions
+// ---------------------------------------------------------------------------
+bool check_zero_init(uint8_t* p, size_t size);
+#if MI_DEBUG >= 2
+bool check_debug_fill_uninit(uint8_t* p, size_t size);
+bool check_debug_fill_freed(uint8_t* p, size_t size);
+#endif
+
+// ---------------------------------------------------------------------------
+// Main testing
+// ---------------------------------------------------------------------------
+int main(void) {
+ mi_option_disable(mi_option_verbose);
+
+ // ---------------------------------------------------
+ // Zeroing allocation
+ // ---------------------------------------------------
+ CHECK_BODY("zeroinit-zalloc-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-zalloc-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-zalloc_small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_small(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-calloc-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-calloc-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-rezalloc-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc(p, zalloc_size);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-rezalloc-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc(p, zalloc_size);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-recalloc-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-recalloc-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+ // ---------------------------------------------------
+ // Zeroing in aligned API
+ // ---------------------------------------------------
+ CHECK_BODY("zeroinit-zalloc_aligned-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-zalloc_aligned-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-calloc_aligned-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-calloc_aligned-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-rezalloc_aligned-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-rezalloc_aligned-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-recalloc_aligned-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-recalloc_aligned-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+#if MI_DEBUG >= 2
+ // ---------------------------------------------------
+ // Debug filling
+ // ---------------------------------------------------
+ CHECK_BODY("uninit-malloc-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-malloc-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-malloc_small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc_small(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-realloc-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc(p, malloc_size);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-realloc-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc(p, malloc_size);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-mallocn-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-mallocn-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-reallocn-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_reallocn(p, malloc_size, 1);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-reallocn-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_reallocn(p, malloc_size, 1);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-malloc_aligned-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-malloc_aligned-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-realloc_aligned-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-realloc_aligned-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+
+ CHECK_BODY("fill-freed-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ mi_free(p);
+ // First sizeof(void*) bytes will contain housekeeping data, skip these
+ result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*));
+ });
+ CHECK_BODY("fill-freed-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ mi_free(p);
+ // First sizeof(void*) bytes will contain housekeeping data, skip these
+ result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*));
+ });
+#endif
+
+ // ---------------------------------------------------
+ // Done
+ // ---------------------------------------------------[]
+ return print_test_summary();
+}
+
+// ---------------------------------------------------------------------------
+// Helper functions
+// ---------------------------------------------------------------------------
+bool check_zero_init(uint8_t* p, size_t size) {
+ if(!p)
+ return false;
+ bool result = true;
+ for (size_t i = 0; i < size; ++i) {
+ result &= p[i] == 0;
+ }
+ return result;
+}
+
+#if MI_DEBUG >= 2
+bool check_debug_fill_uninit(uint8_t* p, size_t size) {
+ if(!p)
+ return false;
+
+ bool result = true;
+ for (size_t i = 0; i < size; ++i) {
+ result &= p[i] == MI_DEBUG_UNINIT;
+ }
+ return result;
+}
+
+bool check_debug_fill_freed(uint8_t* p, size_t size) {
+ if(!p)
+ return false;
+
+ bool result = true;
+ for (size_t i = 0; i < size; ++i) {
+ result &= p[i] == MI_DEBUG_FREED;
+ }
+ return result;
+}
+#endif
/* ----------------------------------------------------------------------------
-Copyright (c) 2018, Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
+#endif
/*
Testing allocators is difficult as bugs may only surface after particular
[1] https://github.com/daanx/mimalloc-bench
*/
-#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "mimalloc.h"
// #include "mimalloc-internal.h"
+#include "mimalloc-types.h" // for MI_DEBUG
-// ---------------------------------------------------------------------------
-// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
-// ---------------------------------------------------------------------------
-static int ok = 0;
-static int failed = 0;
-
-#define CHECK_BODY(name,body) \
- do { \
- fprintf(stderr,"test: %s... ", name ); \
- bool result = true; \
- do { body } while(false); \
- if (!(result)) { \
- failed++; \
- fprintf(stderr, \
- "\n FAILED: %s:%d:\n %s\n", \
- __FILE__, \
- __LINE__, \
- #body); \
- /* exit(1); */ \
- } \
- else { \
- ok++; \
- fprintf(stderr,"ok.\n"); \
- } \
- } while (false)
-
-#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
+#include "testhelper.h"
// ---------------------------------------------------------------------------
// Test functions
// ---------------------------------------------------------------------------
-bool test_heap1();
-bool test_heap2();
-bool test_stl_allocator1();
-bool test_stl_allocator2();
+bool test_heap1(void);
+bool test_heap2(void);
+bool test_stl_allocator1(void);
+bool test_stl_allocator2(void);
// ---------------------------------------------------------------------------
// Main testing
// ---------------------------------------------------------------------------
-int main() {
+int main(void) {
mi_option_disable(mi_option_verbose);
// ---------------------------------------------------
void* p = mi_malloc(0); mi_free(p);
});
CHECK_BODY("malloc-nomem1",{
- result = (mi_malloc(SIZE_MAX/2) == NULL);
+ result = (mi_malloc((size_t)PTRDIFF_MAX + (size_t)1) == NULL);
});
CHECK_BODY("malloc-null",{
mi_free(NULL);
CHECK_BODY("calloc0",{
result = (mi_usable_size(mi_calloc(0,1000)) <= 16);
});
+ CHECK_BODY("malloc-large",{ // see PR #544.
+ void* p = mi_malloc(67108872);
+ mi_free(p);
+ });
// ---------------------------------------------------
// Extended
CHECK_BODY("malloc-aligned5", {
void* p = mi_malloc_aligned(4097,4096); size_t usable = mi_usable_size(p); result = usable >= 4097 && usable < 10000; mi_free(p);
});
+ CHECK_BODY("malloc-aligned6", {
+ bool ok = true;
+ for (size_t align = 1; align <= MI_ALIGNMENT_MAX && ok; align *= 2) {
+ void* ps[8];
+ for (int i = 0; i < 8 && ok; i++) {
+ ps[i] = mi_malloc_aligned(align*13 /*size*/, align);
+ if (ps[i] == NULL || (uintptr_t)(ps[i]) % align != 0) {
+ ok = false;
+ }
+ }
+ for (int i = 0; i < 8 && ok; i++) {
+ mi_free(ps[i]);
+ }
+ }
+ result = ok;
+ });
+ CHECK_BODY("malloc-aligned7", {
+ void* p = mi_malloc_aligned(1024,MI_ALIGNMENT_MAX); mi_free(p);
+ });
+ CHECK_BODY("malloc-aligned8", {
+ void* p = mi_malloc_aligned(1024,2*MI_ALIGNMENT_MAX); mi_free(p);
+ });
CHECK_BODY("malloc-aligned-at1", {
void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p);
});
ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p);
}
result = ok;
- });
-
+ });
+
// ---------------------------------------------------
// Heaps
// ---------------------------------------------------
// ---------------------------------------------------
// Done
// ---------------------------------------------------[]
- fprintf(stderr,"\n\n---------------------------------------------\n"
- "succeeded: %i\n"
- "failed : %i\n\n", ok, failed);
- return failed;
+ return print_test_summary();
}
// ---------------------------------------------------
/* ----------------------------------------------------------------------------
-Copyright (c) 2018,2019 Microsoft Research, Daan Leijen
+Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license.
-----------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
-#include <mimalloc.h>
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
//
// argument defaults
static int THREADS = 32; // more repeatable if THREADS <= #processors
-static int SCALE = 10; // scaling factor
+static int SCALE = 25; // scaling factor
static int ITER = 50; // N full iterations destructing and re-creating all threads
// static int THREADS = 8; // more repeatable if THREADS <= #processors
static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`?
+// #define USE_STD_MALLOC
#ifdef USE_STD_MALLOC
-#define custom_calloc(n,s) calloc(n,s)
+#define custom_calloc(n,s) malloc(n*s)
#define custom_realloc(p,s) realloc(p,s)
#define custom_free(p) free(p)
#else
-#define custom_calloc(n,s) mi_calloc(n,s)
+#include <mimalloc.h>
+#define custom_calloc(n,s) mi_malloc(n*s)
#define custom_realloc(p,s) mi_realloc(p,s)
#define custom_free(p) mi_free(p)
#endif
static void stress(intptr_t tid) {
//bench_start_thread();
- uintptr_t r = (tid * 43); // rand();
+ uintptr_t r = ((tid + 1) * 43); // rand();
const size_t max_item_shift = 5; // 128
const size_t max_item_retained_shift = max_item_shift + 2;
size_t allocs = 100 * ((size_t)SCALE) * (tid % 8 + 1); // some threads do more
static void test_stress(void) {
uintptr_t r = rand();
for (int n = 0; n < ITER; n++) {
- run_os_threads(THREADS, &stress);
+ run_os_threads(THREADS, &stress);
for (int i = 0; i < TRANSFERS; i++) {
if (chance(50, &r) || n + 1 == ITER) { // free all on last run, otherwise free half of the transfers
void* p = atomic_exchange_ptr(&transfer[i], NULL);
free_items(p);
}
}
- // mi_collect(false);
-#ifndef NDEBUG
+ #ifndef NDEBUG
+ //mi_collect(false);
+ //mi_debug_show_arenas();
+ #endif
+ #if !defined(NDEBUG) || defined(MI_TSAN)
if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); }
-#endif
+ #endif
}
}
}
#endif
-int main(int argc, char** argv) {
+int main(int argc, char** argv) {
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
if (argc >= 2) {
char* end;
if (n > 0) ITER = n;
}
printf("Using %d threads with a %d%% load-per-thread and %d iterations\n", THREADS, SCALE, ITER);
+ //mi_reserve_os_memory(1024*1024*1024ULL, false, true);
//int res = mi_reserve_huge_os_pages(4,1);
//printf("(reserve huge: %i\n)", res);
// Run ITER full iterations where half the objects in the transfer buffer survive to the next round.
srand(0x7feb352d);
- // mi_stats_reset();
+
+ //mi_reserve_os_memory(512ULL << 20, true, true);
+
+#if !defined(NDEBUG) && !defined(USE_STD_MALLOC)
+ mi_stats_reset();
+#endif
+
#ifdef STRESS
- test_stress();
+ test_stress();
#else
- test_leak();
+ test_leak();
#endif
- // mi_collect(true);
+#ifndef USE_STD_MALLOC
+ #ifndef NDEBUG
+ mi_collect(true);
+ //mi_debug_show_arenas();
+ #endif
mi_stats_print(NULL);
+#endif
//bench_end_program();
return 0;
}
#ifdef _WIN32
-#include <windows.h>
+#include <Windows.h>
static DWORD WINAPI thread_entry(LPVOID param) {
thread_entry_fun((intptr_t)param);
DWORD* tids = (DWORD*)custom_calloc(nthreads,sizeof(DWORD));
HANDLE* thandles = (HANDLE*)custom_calloc(nthreads,sizeof(HANDLE));
for (uintptr_t i = 0; i < nthreads; i++) {
- thandles[i] = CreateThread(0, 4096, &thread_entry, (void*)(i), 0, &tids[i]);
+ thandles[i] = CreateThread(0, 8*1024, &thread_entry, (void*)(i), 0, &tids[i]);
}
for (size_t i = 0; i < nthreads; i++) {
WaitForSingleObject(thandles[i], INFINITE);
pthread_t* threads = (pthread_t*)custom_calloc(nthreads,sizeof(pthread_t));
memset(threads, 0, sizeof(pthread_t) * nthreads);
//pthread_setconcurrency(nthreads);
- for (uintptr_t i = 0; i < nthreads; i++) {
+ for (size_t i = 0; i < nthreads; i++) {
pthread_create(&threads[i], NULL, &thread_entry, (void*)i);
}
for (size_t i = 0; i < nthreads; i++) {
--- /dev/null
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#ifndef TESTHELPER_H_
+#define TESTHELPER_H_
+
+#include <stdio.h>
+
+// ---------------------------------------------------------------------------
+// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
+// ---------------------------------------------------------------------------
+static int ok = 0;
+static int failed = 0;
+
+#define CHECK_BODY(name,body) \
+ do { \
+ fprintf(stderr,"test: %s... ", name ); \
+ bool result = true; \
+ do { body } while(false); \
+ if (!(result)) { \
+ failed++; \
+ fprintf(stderr, \
+ "\n FAILED: %s:%d:\n %s\n", \
+ __FILE__, \
+ __LINE__, \
+ #body); \
+ /* exit(1); */ \
+ } \
+ else { \
+ ok++; \
+ fprintf(stderr,"ok.\n"); \
+ } \
+ } while (false)
+
+#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
+
+// Print summary of test. Return value can be directly use as a return value for main().
+static inline int print_test_summary(void)
+{
+ fprintf(stderr,"\n\n---------------------------------------------\n"
+ "succeeded: %i\n"
+ "failed : %i\n\n", ok, failed);
+ return failed;
+}
+
+#endif // TESTHELPER_H_
#define SLVS_C_WHERE_DRAGGED 100031
#define SLVS_C_CURVE_CURVE_TANGENT 100032
#define SLVS_C_LENGTH_DIFFERENCE 100033
+#define SLVS_C_ARC_ARC_LEN_RATIO 100034
+#define SLVS_C_ARC_LINE_LEN_RATIO 100035
+#define SLVS_C_ARC_ARC_DIFFERENCE 100036
+#define SLVS_C_ARC_LINE_DIFFERENCE 100037
typedef struct {
Slvs_hConstraint h;
+++ /dev/null
-/.flatpak-builder
-/build-dir
-/repo
-*.flatpak
{
"app-id": "com.solvespace.SolveSpace",
- "runtime": "org.gnome.Platform",
- "runtime-version": "3.30",
- "sdk": "org.gnome.Sdk",
+ "runtime": "org.freedesktop.Platform",
+ "runtime-version": "20.08",
+ "sdk": "org.freedesktop.Sdk",
"finish-args": [
/* Access to display server and OpenGL */
- "--share=ipc", "--socket=fallback-x11", "--socket=wayland", "--device=dri",
+ "--share=ipc",
+ "--socket=fallback-x11",
+ "--socket=wayland",
+ "--device=dri",
/* Access to save files */
"--filesystem=home"
],
"cleanup": [
- "/include", "/lib/*/include",
- "*.a", "*.la", "*.m4", "/lib/libslvs*.so*", "/lib/libglibmm_generate_extra_defs*.so*",
- "/share/pkgconfig", "*.pc",
- "/share/man", "/share/doc",
+ "/include",
+ "/lib/*/include",
+ "*.a",
+ "*.la",
+ "*.m4",
+ "/lib/libslvs*.so*",
+ "/lib/libglibmm_generate_extra_defs*.so*",
+ "/share/pkgconfig",
+ "*.pc",
+ "/share/man",
+ "/share/doc",
"/share/aclocal",
/* mm-common junk */
"/bin/mm-common-prepare",
"sources": [
{
"type": "archive",
- "url": "http://ftp.gnome.org/pub/GNOME/sources/mm-common/0.9/mm-common-0.9.12.tar.xz",
- "sha256": "ceffdcce1e5b52742884c233ec604bf6fded12eea9da077ce7a62c02c87e7c0b"
+ "url": "https://download.gnome.org/sources/mm-common/1.0/mm-common-1.0.2.tar.xz",
+ "sha256": "a2a99f3fa943cf662f189163ed39a2cfc19a428d906dd4f92b387d3659d1641d"
}
]
},
"sources": [
{
"type": "archive",
- "url": "http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.10/libsigc++-2.10.1.tar.xz",
- "sha256": "c9a25f26178c6cbb147f9904d8c533b5a5c5111a41ac2eb781eb734eea446003"
+ "url": "https://download.gnome.org/sources/libsigc++/2.10/libsigc%2B%2B-2.10.6.tar.xz",
+ "sha256": "dda176dc4681bda9d5a2ac1bc55273bdd381662b7a6d49e918267d13e8774e1b"
}
]
},
{
"name": "glibmm",
- "config-opts": [
- "--disable-documentation"
- ],
+ "config-opts": [],
+ "buildsystem": "meson",
"sources": [
{
"type": "archive",
- "url": "http://ftp.gnome.org/pub/GNOME/sources/glibmm/2.58/glibmm-2.58.1.tar.xz",
- "sha256": "6e5fe03bdf1e220eeffd543e017fd2fb15bcec9235f0ffd50674aff9362a85f0"
+ "url": "https://download.gnome.org/sources/glibmm/2.64/glibmm-2.64.5.tar.xz",
+ "sha256": "508fc86e2c9141198aa16c225b16fd6b911917c0d3817602652844d0973ea386"
}
]
},
},
{
"name": "gtkmm",
- "config-opts": [
- "--disable-documentation"
- ],
+ "config-opts": [],
+ "buildsystem": "meson",
"sources": [
{
"type": "archive",
- "url": "http://ftp.gnome.org/pub/GNOME/sources/gtkmm/3.24/gtkmm-3.24.1.tar.xz",
- "sha256": "ddfe42ed2458a20a34de252854bcf4b52d3f0c671c045f56b42aa27c7542d2fd"
+ "url": "https://download.gnome.org/sources/gtkmm/3.24/gtkmm-3.24.4.tar.xz",
+ "sha256": "9beb71c3e90cfcfb790396b51e3f5e7169966751efd4f3ef9697114be3be6743"
}
]
},
"name": "libjson-c",
"sources": [
{
+ /* 0.15-nodoc doesn't build */
"type": "archive",
"url": "https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.1-nodoc.tar.gz",
"sha256": "94a26340c0785fcff4f46ff38609cf84ebcd670df0c8efd75d039cc951d80132"
"name": "SolveSpace",
"sources": [
{
- "type": "git",
- "path": "/home/whitequark/Projects/solvespace"
+ "type": "dir",
+ "path": "../.."
}
],
"buildsystem": "cmake",
+++ /dev/null
-*.snap
-solvespace-snap-src
-squashfs-root
name: solvespace
-base: core18
+base: core20
summary: Parametric 2d/3d CAD
adopt-info: solvespace
description: |
confinement: strict
license: GPL-3.0
+compression: lzo
layout:
/usr/share/solvespace:
solvespace:
command: usr/bin/solvespace
desktop: solvespace.desktop
- extensions: [gnome-3-34]
+ extensions: [gnome-3-38]
plugs: [opengl, unity7, home, removable-media, gsettings, network]
- environment:
- __EGL_VENDOR_LIBRARY_DIRS: $SNAP/gnome-platform/usr/share/glvnd/egl_vendor.d:$SNAP/usr/share/glvnd/egl_vendor.d
cli:
command: usr/bin/solvespace-cli
- extensions: [gnome-3-34]
+ extensions: [gnome-3-38]
plugs: [home, removable-media, network]
parts:
source-type: local
override-pull: |
snapcraftctl pull
- version_major=$(grep "solvespace_VERSION_MAJOR" CMakeLists.txt | tr -d "()" | cut -d" " -f2)
- version_minor=$(grep "solvespace_VERSION_MINOR" CMakeLists.txt | tr -d "()" | cut -d" " -f2)
- version="$version_major.$version_minor~$(git rev-parse --short=8 HEAD)"
+ git submodule update --init extlib/libdxfrw extlib/mimalloc extlib/eigen
+ override-build: |
+ snapcraftctl build
+ project_version=$(grep CMAKE_PROJECT_VERSION:STATIC CMakeCache.txt | cut -d "=" -f2)
+ cd $SNAPCRAFT_PART_SRC
+ version="$project_version~$(git rev-parse --short=8 HEAD)"
snapcraftctl set-version "$version"
git describe --exact-match HEAD && grade="stable" || grade="devel"
snapcraftctl set-grade "$grade"
- git submodule update --init extlib/libdxfrw extlib/mimalloc
- configflags:
+ cmake-parameters:
- -DCMAKE_INSTALL_PREFIX=/usr
- -DCMAKE_BUILD_TYPE=Release
- -DENABLE_TESTS=OFF
- -DSNAP=ON
- -DENABLE_OPENMP=ON
- -DENABLE_LTO=ON
+ build-snaps:
+ - gnome-3-38-2004-sdk
build-packages:
- zlib1g-dev
- libpng-dev
+ - libcairo2-dev
- libfreetype6-dev
- libjson-c-dev
- libgl-dev
cleanup:
after: [solvespace]
plugin: nil
- build-snaps: [core18, gnome-3-34-1804]
+ build-snaps: [gnome-3-38-2004]
override-prime: |
- # Remove all files from snap that are already included in the base snap or in
- # any connected content snaps
set -eux
- for snap in "core18" "gnome-3-34-1804"; do # List all content-snaps and base snaps you're using here
- cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \;
+ for snap in "gnome-3-38-2004"; do # List all content-snaps you're using here
+ cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" "$SNAPCRAFT_PRIME/usr/{}" \;
done
+ for cruft in bug lintian man; do
+ rm -rf $SNAPCRAFT_PRIME/usr/share/$cruft
+ done
+ find $SNAPCRAFT_PRIME/usr/share/doc/ -type f -not -name 'copyright' -delete
+ find $SNAPCRAFT_PRIME/usr/share -type d -empty -delete
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${source}")
endfunction()
elseif(APPLE)
- set(app_resource_dir ${CMAKE_BINARY_DIR}/bin/SolveSpace.app/Contents/Resources)
+ set(app_resource_dir ${CMAKE_BINARY_DIR}/Resources)
set(cli_resource_dir ${CMAKE_BINARY_DIR}/res)
function(add_resource name)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
RENAME com.solvespace.SolveSpace.desktop)
+ set(DESKTOP_FILE_NAME com.solvespace.SolveSpace.desktop)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/freedesktop/com.solvespace.SolveSpace.metainfo.xml.in
+ ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/com.solvespace.SolveSpace.metainfo.xml)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/com.solvespace.SolveSpace.metainfo.xml
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo)
+
install(FILES freedesktop/solvespace-flatpak-mime.xml
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages
RENAME com.solvespace.SolveSpace-slvs.xml)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace.desktop
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
+ set(DESKTOP_FILE_NAME solvespace.desktop)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/freedesktop/com.solvespace.SolveSpace.metainfo.xml.in
+ ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/com.solvespace.SolveSpace.metainfo.xml)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/com.solvespace.SolveSpace.metainfo.xml
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo)
+
install(FILES freedesktop/solvespace-mime.xml
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages
RENAME solvespace-slvs.xml)
RENAME solvespace.svg)
install(FILES freedesktop/solvespace-scalable.svg
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/mimetypes
- RENAME application.x-solvespace.svg)
+ RENAME application-x-solvespace.svg)
foreach(SIZE 16x16 24x24 32x32 48x48)
install(FILES freedesktop/solvespace-${SIZE}.png
RENAME solvespace.png)
install(FILES freedesktop/solvespace-${SIZE}.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/mimetypes
- RENAME application.x-solvespace.png)
- endforeach()
-
- foreach(SIZE 16x16 24x24 32x32 48x48)
- install(FILES freedesktop/solvespace-${SIZE}.xpm
- DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps)
+ RENAME application-x-solvespace.png)
endforeach()
endif()
endif()
locales/en_US.po
locales/fr_FR.po
locales/uk_UA.po
+ locales/es_AR.po
+ locales/tr_TR.po
locales/ru_RU.po
locales/zh_CN.po
fonts/unifont.hex.gz
shaders/edge.frag
shaders/edge.vert
shaders/outline.vert
- threejs/three-r76.js.gz
+ threejs/three-r111.min.js.gz
threejs/hammer-2.0.8.js.gz
threejs/SolveSpaceControls.js)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="desktop-application">
+ <id>com.solvespace.SolveSpace</id>
+
+ <name>SolveSpace</name>
+ <summary>A free (GPLv3) parametric 3d CAD tool</summary>
+
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-3.0-or-later</project_license>
+ <update_contact>ryan_AT_ryanpavlik.com</update_contact>
+
+ <categories>
+ <category>Graphics</category>
+ <category>3DGraphics</category>
+ <category>Engineering</category>
+ </categories>
+ <description>
+ <p>
+ SolveSpace is a free (GPLv3) parametric 3d CAD tool. Applications include:
+ </p>
+ <ul>
+ <li>Modeling 3d parts — draw with extrudes, revolves, and Boolean operations</li>
+ <li>Modeling 2d parts — draw the part as a single section, and export; use 3d assembly to verify fit</li>
+ <li>Modeling 3d-printed parts — export the STL or other triangle mesh expected by most slicers</li>
+ <li>Preparing 2D CAM data — export 2d vector art for a waterjet machine or laser cutter</li>
+ <li>Mechanism design — use the constraint solver to simulate planar or spatial linkages</li>
+ <li>Plane and solid geometry — replace hand-solved trigonometry with a live dimensioned drawing</li>
+ </ul>
+ </description>
+ <url type="homepage">https://solvespace.com</url>
+ <url type="bugtracker">https://github.com/solvespace/solvespace/issues</url>
+
+ <launchable type="desktop-id">@DESKTOP_FILE_NAME@</launchable>
+ <provides>
+ <mediatype>application/x-solvespace</mediatype>
+ </provides>
+
+ <content_rating type="oars-1.0" />
+
+ <releases>
+ <release version="3.0" date="2021-04-18" type="stable">
+ <description>
+ <p>Major new stable release. Includes new intersection boolean operation,
+ new types of groups, solid model suppression, usability improvements
+ (especially regarding redundant constraints and automatic constraints),
+ and more. Also includes performance and scalability improvements.</p>
+ </description>
+ <url>https://github.com/solvespace/solvespace/releases/tag/v3.0</url>
+ </release>
+
+ <release version="3.0~rc2" date="2021-01-17" type="development">
+ <description>
+ <p>Second release candidate for the 3.0 stable release.</p>
+ </description>
+ <url>https://github.com/solvespace/solvespace/releases/tag/v3.0.rc2</url>
+ </release>
+
+ <release version="3.0~rc1" date="2020-11-18" type="development">
+ <description>
+ <p>First release candidate for the 3.0 stable release.</p>
+ </description>
+ <url>https://github.com/solvespace/solvespace/releases/tag/v3.0.rc1</url>
+ </release>
+
+ <release version="2.3" date="2016-12-23" type="stable">
+ <description>
+ <p>Bug-fix release in the 2.x series, fixing some crashes.</p>
+ </description>
+ <url>https://github.com/solvespace/solvespace/releases/tag/v2.3</url>
+ </release>
+
+ <release version="2.2" date="2016-10-16" type="stable">
+ <description>
+ <p>Bug-fix release, including performance improvements.</p>
+ </description>
+ <url>https://github.com/solvespace/solvespace/releases/tag/v2.2</url>
+ </release>
+
+ <release version="2.1" date="2016-06-11" type="stable">
+ <description>
+ <p>Introduced *nix compatibility, internationalization, technical drawing mode, improved import and export, and other features and fixes.</p>
+ </description>
+ <url>https://github.com/solvespace/solvespace/releases/tag/v2.1</url>
+ </release>
+ </releases>
+
+</component>
+++ /dev/null
-/* XPM */
-static char *solvespace_16x16[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 5 1 ",
-" c black",
-". c #1ED500",
-"X c #DE00D6",
-"o c #CBCBCB",
-"O c None",
-/* pixels */
-"OOO OOOOOOOOOOOO",
-"OOO OOOOOOOOOOOO",
-"OOO OOOOOOOOOOOO",
-"OOO OOOOOXOOOOOO",
-"OOO OOOOOXoOOOOO",
-"OOO OOOOOXoOOOOO",
-"OOO OOOOOXoOOOOO",
-"OOO OOOOOXoOOOOO",
-"OOO OOOOOXoOOOOO",
-"OOO OOXXXXXXXOOO",
-"OOO OOOoooooooOO",
-"OO...OOOOOOOOOOO",
-" ... ",
-"OO...OOOOOOOOOOO",
-"OOO OOOOOOOOOOOO",
-"OOO OOOOOOOOOOOO"
-};
+++ /dev/null
-/* XPM */
-static char *solvespace_24x24[] = {
-/* columns rows colors chars-per-pixel */
-"24 24 5 1 ",
-" c black",
-". c #1ED500",
-"X c #DE00D6",
-"o c #CBCBCB",
-"O c None",
-/* pixels */
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOO OOOOOOOOOOOOOOOO",
-"OOOOOOO OOOOOOOOOOOOOOOO",
-"OOOOOOO OOOOOOOOOOOOOOOO",
-"OOOOOOO OOOOOXOOOOOOOOOO",
-"OOOOOOO OOOOOXoOOOOOOOOO",
-"OOOOOOO OOOOOXoOOOOOOOOO",
-"OOOOOOO OOOOOXoOOOOOOOOO",
-"OOOOOOO OOOOOXoOOOOOOOOO",
-"OOOOOOO OOOOOXoOOOOOOOOO",
-"OOOOOOO OOXXXXXXXOOOOOOO",
-"OOOOOOO OOOoooooooOOOOOO",
-"OOOOOO...OOOOOOOOOOOOOOO",
-"OOOO ... OOOO",
-"OOOOOO...OOOOOOOOOOOOOOO",
-"OOOOOOO OOOOOOOOOOOOOOOO",
-"OOOOOOO OOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOO"
-};
+++ /dev/null
-/* XPM */
-static char *solvespace_32x32[] = {
-/* columns rows colors chars-per-pixel */
-"32 32 5 1 ",
-" c black",
-". c #1ED500",
-"X c #DE00D6",
-"o c #CBCBCB",
-"O c None",
-/* pixels */
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOXXoOOOOOOOOOOOO",
-"OOOOOO OOOOXXXXXXXXXXXXOOOOOOOO",
-"OOOOOO OOOOXXXXXXXXXXXXOOOOOOOO",
-"OOOOOO OOOOOooooooooooooOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOO......OOOOOOOOOOOOOOOOOOOOOO",
-"OOOO......OOOOOOOOOOOOOOOOOOOOOO",
-" ...... ",
-" ...... ",
-"OOOO......OOOOOOOOOOOOOOOOOOOOOO",
-"OOOO......OOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOO OOOOOOOOOOOOOOOOOOOOOOOO"
-};
+++ /dev/null
-/* XPM */
-static char *solvespace_48x48[] = {
-/* columns rows colors chars-per-pixel */
-"48 48 5 1 ",
-" c black",
-". c #1ED500",
-"X c #DE00D6",
-"o c #CBCBCB",
-"O c None",
-/* pixels */
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOXXXXXXXXXXXXOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOXXXXXXXXXXXXOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOooooooooooooOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOO ...... OOOOOOOO",
-"OOOOOOOO ...... OOOOOOOO",
-"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
-"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"
-};
MimeType=application/x-solvespace
Icon=com.solvespace.SolveSpace
Type=Application
-Categories=Graphics
+Categories=Graphics;3DGraphics;Engineering;
Keywords=parametric;cad;2d;3d;
MimeType=application/x-solvespace
Icon=${SNAP}/meta/icons/hicolor/scalable/apps/snap.solvespace.svg
Type=Application
-Categories=Graphics
+Categories=Graphics;3DGraphics;Engineering;
Keywords=parametric;cad;2d;3d;
MimeType=application/x-solvespace
Icon=solvespace
Type=Application
-Categories=Graphics
+Categories=Graphics;3DGraphics;Engineering;
Keywords=parametric;cad;2d;3d;
de-DE,0407,Deutsch
en-US,0409,English (US)
fr-FR,040C,Français
+es-AR,2C0A,español (AR)
ru-RU,0419,Русский
+tr-TR,041F,Türkçe
uk-UA,0422,Українська
zh-CN,0804,简体中文
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
-"PO-Revision-Date: 2018-07-19 06:55+0000\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
+"PO-Revision-Date: 2022-04-30 16:44+0200\n"
"Last-Translator: Reini Urban <rurban@cpan.org>\n"
"Language-Team: none\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Zanata 4.5.0\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Poedit 2.4.2\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"Ausschneiden, Einfügen und Kopieren sind nur in einer Arbeitsebene "
"zulässig.\n"
"\n"
-"Aktivieren Sie eine mit Skizze -> In Arbeitsebene"
+"Aktivieren Sie eine mit \"Skizze -> In Arbeitsebene\"."
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
msgstr "Zwischenablage ist leer; es gibt nichts einzufügen."
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
msgstr "Die Anzahl der einzufügenden Kopien muss mind. 1 sein."
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
msgstr "Maßstab kann nicht Null sein."
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
msgstr "Wählen Sie einen Punkt, um den Drehmittelpunkt zu definieren."
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
msgstr "Wählen Sie zwei Punkte, um den Verschiebungsvektor zu definieren."
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid ""
"Transformation is identity. So all copies will be exactly on top of each "
"other."
"Die Transformation ist die Identität. Alle Kopien werden deckungsgleich "
"übereinanderliegen."
-#: clipboard.cpp:458
+#: clipboard.cpp:457
msgid "Too many items to paste; split this into smaller pastes."
msgstr ""
"Zuviele Objekte zum Einfügen; teilen Sie diese in kleinere "
"Einfügeoperationen auf."
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
msgstr "Es ist keine Arbeitsebene aktiv."
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
msgstr "Ungültiges Format: geben Sie Koordinaten als x, y, z an"
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
msgstr "Ungültiges Format: geben Sie Farben als r, g, b an"
-#: confscreen.cpp:454
+#: confscreen.cpp:417
msgid ""
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
"Der Perspektivfaktor wird sich nicht auswirken, bis Sie Ansicht -> "
"Perspektive Projektion aktivieren."
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
msgstr "Geben Sie 0 bis %d Ziffern nach dem Dezimalzeichen an."
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
msgstr "Der Exportmaßstab darf nicht Null sein!"
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
msgstr "Der Werkzeugradialabstand darf nicht negativ sein!"
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
msgstr ""
"Ungültiger Wert: Interval für automatisches Speichern muss positiv sein"
-#: confscreen.cpp:558
+#: confscreen.cpp:531
msgid "Bad format: specify interval in integral minutes"
msgstr "Ungültiges Format: geben Sie das Interval in ganzen Minuten an"
#: constraint.cpp:25
msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr "Bogen-Bogen-Längenverhältnis"
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr "Bogen-Linien-Längenverhältnis"
+
+#: constraint.cpp:27
+msgctxt "constr-name"
msgid "length-difference"
msgstr "Längendifferenz"
-#: constraint.cpp:26
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr "Bogen-Bogen-Längendifferenz"
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr "Bogen-Linien-Längendifferenz"
+
+#: constraint.cpp:30
msgctxt "constr-name"
msgid "symmetric"
msgstr "Symmetrisch"
-#: constraint.cpp:27
+#: constraint.cpp:31
msgctxt "constr-name"
msgid "symmetric-h"
msgstr "Symmetrisch-H"
-#: constraint.cpp:28
+#: constraint.cpp:32
msgctxt "constr-name"
msgid "symmetric-v"
msgstr "Symmetrisch-V"
-#: constraint.cpp:29
+#: constraint.cpp:33
msgctxt "constr-name"
msgid "symmetric-line"
msgstr "Symmetrisch-Linie"
-#: constraint.cpp:30
+#: constraint.cpp:34
msgctxt "constr-name"
msgid "at-midpoint"
msgstr "auf-Mittelpunkt"
-#: constraint.cpp:31
+#: constraint.cpp:35
msgctxt "constr-name"
msgid "horizontal"
msgstr "Horizontal"
-#: constraint.cpp:32
+#: constraint.cpp:36
msgctxt "constr-name"
msgid "vertical"
msgstr "Vertikal"
-#: constraint.cpp:33
+#: constraint.cpp:37
msgctxt "constr-name"
msgid "diameter"
msgstr "Durchmesser"
-#: constraint.cpp:34
+#: constraint.cpp:38
msgctxt "constr-name"
msgid "pt-on-circle"
msgstr "Pkt-auf-Kreis"
-#: constraint.cpp:35
+#: constraint.cpp:39
msgctxt "constr-name"
msgid "same-orientation"
msgstr "gl-Orientierung"
-#: constraint.cpp:36
+#: constraint.cpp:40
msgctxt "constr-name"
msgid "angle"
msgstr "Winkel"
-#: constraint.cpp:37
+#: constraint.cpp:41
msgctxt "constr-name"
msgid "parallel"
msgstr "Parallel"
-#: constraint.cpp:38
+#: constraint.cpp:42
msgctxt "constr-name"
msgid "arc-line-tangent"
msgstr "Bogen-Linie-Tangente"
-#: constraint.cpp:39
+#: constraint.cpp:43
msgctxt "constr-name"
msgid "cubic-line-tangent"
msgstr "Kub-Linie-Tangente"
-#: constraint.cpp:40
+#: constraint.cpp:44
msgctxt "constr-name"
msgid "curve-curve-tangent"
msgstr "Kurve-Kurve-Tangente"
-#: constraint.cpp:41
+#: constraint.cpp:45
msgctxt "constr-name"
msgid "perpendicular"
msgstr "Rechtwinklig"
-#: constraint.cpp:42
+#: constraint.cpp:46
msgctxt "constr-name"
msgid "eq-radius"
msgstr "gl-Radius"
-#: constraint.cpp:43
+#: constraint.cpp:47
msgctxt "constr-name"
msgid "eq-angle"
msgstr "gl-Winkel"
-#: constraint.cpp:44
+#: constraint.cpp:48
msgctxt "constr-name"
msgid "eq-line-len-arc-len"
msgstr "gl-Linie-Länge-Bogen-Länge"
-#: constraint.cpp:45
+#: constraint.cpp:49
msgctxt "constr-name"
msgid "lock-where-dragged"
msgstr "Fix-an-Position"
-#: constraint.cpp:46
+#: constraint.cpp:50
msgctxt "constr-name"
msgid "comment"
msgstr "Kommentar"
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
msgstr ""
"Die Bogentangente und das Liniensegment müssen einen gemeinsamen Endpunkt "
"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die "
-"Tangente einschränken. -> Sc"
+"Tangente einschränken."
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
msgstr ""
"Die Kurventangente und das Liniensegment müssen einen gemeinsamen Endpunkt "
"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die "
-"Tangente einschränken. -> Sc"
+"Tangente einschränken."
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
msgstr ""
"Die Kurven müssen einen gemeinsamen Endpunkt haben. Schränken Sie mit "
-"\"Einschränkung / Auf Punkt\" ein, bevor Sie die Tangente einschränken. -> Sc"
+"\"Einschränkung / Auf Punkt\" ein, bevor Sie die Tangente einschränken."
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply "
"to:\n"
" * eine Seitenfläche und ein Punkt [minimaler Abstand]\n"
" * ein Kreis oder ein Bogen [Durchmesser]\n"
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can "
"apply to:\n"
" * einen Punkt und einen Kreis oder Bogen [Punkt auf Kurve]\n"
" * einen Punkt und eine Seitenfläche [Punkt auf Fläche]\n"
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can "
"apply to:\n"
" * ein Liniensegment und ein Bogen [Länge des Liniensegments gleich "
"Bogenlänge]\n"
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
"Ungültige Auswahl für Einschränkung \"Längenverhältnis\". Diese "
"Einschränkung ist anwendbar auf:\n"
"\n"
" * zwei Liniensegmente\n"
+" * zwei Bögen\n"
+" * einen Bogen und ein Liniensegment\n"
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
"Ungültige Auswahl für Einschränkung \"Längendifferenz\". Diese Einschränkung "
"ist anwendbar auf:\n"
"\n"
" * zwei Liniensegmente\n"
+" * zwei Bögen\n"
+" * einen Bogen und ein Liniensegment\n"
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
" * ein Liniensegment und eine Arbeitsebene [Mittelpunkt der Linie auf "
"Ebene]\n"
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
" * eine Arbeitsebene und zwei Punkte oder ein Liniensegment [symmetrisch "
"zu Arbeitsebene]\n"
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid ""
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
"Eine Arbeitsebene muss aktiv sein, um die Symmetrie ohne explizite "
"Symmetrieebene einzuschränken."
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
"Aktivieren Sie eine Arbeitsebene (mit Skizze -> In Arbeitsebene), bevor Sie "
"horizontal oder vertikal einschränken."
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can "
"apply to:\n"
" * zwei Punkte\n"
" * ein Liniensegment\n"
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply "
"to:\n"
"\n"
" * zwei Normale\n"
-#: constraint.cpp:614
+#: constraint.cpp:663
msgid "Must select an angle constraint."
msgstr "Sie müssen einen eingeschränkten Winkel auswählen."
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
msgstr "Sie müssen eine Einschränkung mit zugeordneter Kennzeichnung angeben."
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * ein Liniensegment und eine Normale\n"
" * zwei Normale\n"
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr ""
"Die Kurven-Kurven-Tangente muss in der Arbeitsebene eingeschränkt werden."
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply "
"to:\n"
" * zwei Liniensegmente, Bögen oder Beziers mit gemeinsamem Endpunkt "
"[Tangente]\n"
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * ein Liniensegment und eine Normale\n"
" * zwei Normale\n"
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can "
"apply to:\n"
"\n"
" * einen Punkt\n"
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN"
+
+#: constraint.cpp:818
msgid "click center of comment text"
msgstr "Klicken Sie auf die Mitte des Kommentartextes"
"2d View to export bare lines and curves."
msgstr ""
"Kein Festkörper vorhanden; zeichnen Sie eines mit Extrusionen und Drehungen, "
-"oder exportieren Sie bloße Linien und Kurven mit \"2D-Ansicht exportieren\""
+"oder exportieren Sie bloße Linien und Kurven mit \"2D-Ansicht exportieren\"."
#: export.cpp:61
msgid ""
" * einen Punkt und zwei Liniensegmente [Schnittebene durch Punkt und "
"parallel zu Linien]\n"
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
msgstr "Das Netz der aktiven Gruppe ist leer; es gibt nichts zu exportieren."
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr "Freihandlinien wurden mit durchgehenden Linien ersetzt"
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr "Zickzacklinien wurden mit durchgehenden Linien ersetzt"
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr ""
"Teile der Zeichnung haben keine Entsprechung in DXF und wurden nicht "
"exportiert:\n"
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid ""
"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr ""
msgid "#references"
msgstr "#Referenzen"
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr "Die Datei ist leer. Es kann beschädigt sein."
+
+#: file.cpp:555
msgid ""
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
"Nicht erkannte Daten in der Datei. Diese Datei könnte beschädigt sein oder "
"von einer neueren Version des Programms stammen."
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Fehlende Datei"
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr "Die verlinkte Datei “%s” fehlt."
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"Falls Sie ablehnen, wird jegliche mit der fehlenden Datei verknüpfte "
"Geometrie verworfen."
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr "&Ja"
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "&Nein"
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
msgstr "&Abbrechen"
#: graphicswin.cpp:43
msgid "&Open..."
-msgstr "&Öffnen"
+msgstr "&Öffnen..."
#: graphicswin.cpp:44
msgid "Open &Recent"
#: graphicswin.cpp:51
msgid "Export 3d &Wireframe..."
-msgstr "Exportiere 3D-Drahtgittermodell"
+msgstr "Exportiere 3D-Drahtgittermodell..."
#: graphicswin.cpp:52
msgid "Export Triangle &Mesh..."
msgstr "Perspektivische Projektion"
#: graphicswin.cpp:97
+msgid "Show E&xploded View"
+msgstr "Zeige e&xplodierte Ansicht"
+
+#: graphicswin.cpp:98
msgid "Dimension &Units"
msgstr "Maßeinheit"
-#: graphicswin.cpp:98
+#: graphicswin.cpp:99
msgid "Dimensions in &Millimeters"
msgstr "Maße in Millimeter"
-#: graphicswin.cpp:99
+#: graphicswin.cpp:100
msgid "Dimensions in M&eters"
msgstr "Masse in M&etern"
-#: graphicswin.cpp:100
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
msgstr "Maße in Zoll"
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr "Maße in &Fuß und Inch"
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr "Werkzeugleiste anzeigen"
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr "Attributbrowser anzeigen"
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr "Vollbildschirm"
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr "Neue Gruppe"
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
msgstr "In 3D skizzieren"
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
msgstr "In neuer Arbeitsebene skizzieren"
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr "Kopieren und verschieben"
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr "Kopieren und drehen"
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr "E&xtrudieren"
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
msgstr "&Helix"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr "R&otieren"
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
msgstr "D&rehen"
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
-msgstr "Verknüpfen / Zusammensetzen"
+msgstr "Verknüpfen / Zusammensetzen..."
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
msgstr "Letzte verknüpfen"
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr "&Skizze"
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
msgstr "In Arbeitsebene"
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
msgstr "Im 3D-Raum"
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr "Bezugspunkt"
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr "Arbeits&ebene"
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr "&Linie"
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr "K&onstruktionslinie"
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr "&Rechteck"
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr "&Kreis"
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr "Kreisbogen"
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr "Kubischer &Bezier-Spline"
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
msgstr "&Text in Truetype-Font"
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
msgstr "B&ild"
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr "Konstruktionselement an/aus"
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr "Bogentangente an Punkt"
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr "Kurven im Schnittpunkt trennen"
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr "&Einschränkung"
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr "Abstand / Durchmesser"
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr "Referenzangabe"
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr "Winkel"
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr "Referenzwinkel"
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr "Komplementärwinkel"
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr "Referenzangabe ein/aus"
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr "Horizontal"
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr "&Vertikal"
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr "Auf Punkt / Kurve / Ebene"
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr "Gleicher Abstand / Radius / Winkel"
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
-msgstr "Längenverhältnis"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr "Länge / Bogen Verhäl&tnis"
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
-msgstr "Längendifferenz"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr "Länge / Bogen Diff&erenz"
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr "Auf &Mittelpunkt"
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr "Symmetrisch"
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr "Paral&llel / Tangente"
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr "Rechtwinklig"
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr "Gleiche Orientierung"
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr "Punkt an Position fixieren"
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr "Kommentar"
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr "&Analyse"
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr "&Volumen bestimmen"
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr "Fläche bestimmen"
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr "Umfang bestimmen"
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr "Überlagernde Teile anzeigen"
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr "Freiliegende Kanten anzeigen"
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
msgstr "Massenmittelpunkt anzeigen"
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
msgstr "&Unterbeschränkte Punkte anzeigen"
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr "Punkt nachzeichnen"
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
-msgstr "Nachzeichnen beenden"
+msgstr "Nachzeichnen beenden..."
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr "Schrittgröße…"
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr "&Hilfe"
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr "Sprache"
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr "&Website / Anleitung"
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr "&Gehe zu GitHub commit"
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr "Über"
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
msgstr "(keine vorhergehenden Dateien)"
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
msgstr "Datei '%s' existiert nicht."
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
msgstr ""
"Das Raster wird nicht angezeigt, weil keine Arbeitsebene ausgewählt ist."
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel "
"projection.\n"
"Ändern Sie den Faktor für die Perspektivprojektion in der "
"Konfigurationsmaske. Ein typischer Wert ist ca. 0,3."
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid ""
"Select a point; this point will become the center of the view on screen."
msgstr ""
"Wählen Sie einen Punkt aus; dieser Punkt wird im Mittelpunkt der "
"Bildschirmansicht sein."
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr ""
"Die ausgewählten Objekte teilen keine gemeinsamen Endpunkte mit anderen "
"Objekten."
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
"Für diesen Befehl wählen Sie einen Punkt oder ein anderes Objekt von einem "
"verknüpften Teil aus, oder aktivieren Sie eine verknüpfte Gruppe."
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
"(mit Skizze -> In Arbeitsebene), um die Ebene für das Gitterraster zu "
"definieren."
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
"für Punkte, Textkommentare, oder Einschränkungen mit einer Bezeichnung. Um "
"eine Linie auf das Raster auszurichten, wählen Sie deren Endpunkte aus."
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr ""
"Es wurde keine Arbeitsebene ausgewählt. Die Standard-Arbeitsebene für diese "
"Gruppe wird aktiviert."
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default "
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"standardmäßige Arbeitsebene. Wählen Sie eine Arbeitsebene aus, oder "
"erstellen Sie eine Gruppe in einer neuen Arbeitsebene."
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
"Ungültige Auswahl für Bogentangente an Punkt. Wählen Sie einen einzelnen "
"Punkt. Um die Bogenparameter anzugeben, wählen Sie nichts aus."
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr ""
"Erstellen Sie einen Punkt auf dem Bogen (zeichnet im Gegenuhrzeigersinn)"
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
msgstr "Klicken Sie, um einen Bezugspunkt zu platzieren"
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
msgstr "Klicken Sie auf den ersten Punkt des Liniensegments"
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
msgstr "Klicken Sie auf den ersten Punkt der Konstruktionslinie"
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
msgstr "Klicken Sie auf den ersten Punkt der kubischen Linie"
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
msgstr "Klicken Sie auf den Kreismittelpunkt"
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
msgstr "Klicken Sie auf den Ursprungspunkt der Arbeitsebene"
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
msgstr "Klicken Sie auf eine Ecke des Rechtecks"
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
msgstr "Klicken Sie auf die obere linke Ecke des Texts"
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
msgstr "Klicken Sie auf die obere linke Ecke des Bilds"
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid ""
"No entities are selected. Select entities before trying to toggle their "
"construction state."
msgid "sketch-in-3d"
msgstr "Skizze-in-3D"
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
-"Ungültige Auswahl für Skizze in neuer Arbeitsebene. Diese Gruppe kann "
+"Ungültige Auswahl für neue Skizze in der Arbeitsebene. Diese Gruppe kann "
"erstellt werden mit:\n"
"\n"
-" * einem Punkt (durch den Punkt, orthogonal zu den Koordinatenachsen)\n"
-" * einem Punkt und zwei Liniensegmenten (durch den Punkt, parallel zu den "
-"Linien)\n"
-" * einer Arbeitsebene (Kopie der Arbeitsebene)\n"
+" * einem Punkt (durch den Punkt, orthogonal zur Koordinatenachse)\n"
+" * einem Punkt und zwei Linienabschnitten (durch den Punkt, parallel zu "
+"den Linien)\n"
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
msgstr ""
"Aktivieren Sie vor der Extrusion eine Arbeitsebene (mit Skizze -> In "
-"Arbeitsebene). Die Skizze wird senkrecht zur Arbeitsebene extrudiert"
+"Arbeitsebene). Die Skizze wird senkrecht zur Arbeitsebene extrudiert."
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
msgstr "Extrusion"
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr "Rotieren kann nur mit planaren Skizzen ausgeführt werden."
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
"eine Achse parallel zur Linie/Normalen, durch den Punkt)\n"
" * einem Liniensegment (Drehung um das Liniensegment)\n"
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
msgstr "Drehung"
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr "Revolve kann nur mit planaren Skizzen ausgeführt werden."
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
"Achse parallel zu Linie / Normale, durch Punkt)\n"
" * einem Liniensegment (gedreht um Liniensegment)\n"
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
msgstr "Revolve"
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
msgstr "Helix kann nur mit planaren Skizzen ausgeführt werden."
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
"Achse parallel zu Linie / Normale, durch Punkt)\n"
" * einem Liniensegment (gedreht um Liniensegment)\n"
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
msgstr "Helix"
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
" * einem Punkt und einer Linie oder einer Normale (gedreht um eine Achse "
"durch den Punkt, parallel zur Linie / Normale)\n"
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
msgstr "Drehen"
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
msgstr "Versetzen"
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
msgstr "unbenannt"
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
msgstr "Kontur nicht geschlossen, oder kein einheitlicher Linientyp!"
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr "Punkte sind nicht alle koplanar!"
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
msgstr "Kontur überschneidet sich selbst!"
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
msgstr "Kante mit Länge Null!"
-#: modify.cpp:254
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr "Text-formatierte STL Dateien werden aktuell nicht unterstützt"
+
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr "Eine Bogentangente kann nur in einer Arbeitsebene erstellt werden."
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
msgstr ""
"Um eine Bogentangente zu erstellen, wählen Sie einen Punkt, in dem sich zwei "
"nicht-Konstruktionslinien oder -kreise in dieser Gruppe und Arbeitsebene "
-"treffen. "
+"treffen."
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
"Radius, oder erstellen Sie die gewünschte Geometrie von Hand mit \"Tangente"
"\"-Einschränkungen."
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr ""
"Dieses Objekt konnte nicht geteilt werden. Dies geht nur für Linien, Kreise "
"oder kubische Splines."
-#: modify.cpp:624
+#: modify.cpp:622
msgid "Must be sketching in workplane to split."
msgstr "Trennen ist nur in einer Arbeitsebene möglich."
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
"Wählen Sie zwei Objekte aus, die sich schneiden (z.B. zwei Linien/Kreise/"
"Bögen, oder eine Linie/Kreis/Bogen und ein Punkt)."
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
msgstr "Trennen nicht möglich; keine Überschneidung gefunden."
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr "Linientyp zuordnen"
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr "Kein Linientyp"
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr "Neu erstellter benutzerdefinierter Linientyp…"
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr "Info zu Gruppe"
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr "Info zu Linientyp"
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr "Kantenverlauf auswählen"
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr "Von/zu Referenzangabe wechseln"
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr "Anderer Komplementärwinkel"
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr "Auf Raster ausrichten"
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr "Spline-Punkt löschen"
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr "Spline-Punkt hinzufügen"
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr ""
"Spline-Punkt kann nicht hinzugefügt werden: maximale Anzahl der Punkte "
"erreicht."
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr "Konstruktionselement an/aus"
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr "Einschränkung \"Punkte deckungsgleich\" löschen"
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr "Ausschneiden"
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr "Kopieren"
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr "Alle auswählen"
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr "Einfügen"
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr "Einfügen und transformieren…"
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr "Löschen"
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr "Alle deselektieren"
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr "Aktive deselektieren"
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr "Zoom an Bildschirm anpassen"
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
msgstr "Klicken Sie auf den nächsten Punkt der Linie, oder drücken Sie Esc"
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Ein Rechteck kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
msgstr "Klicken Sie auf die gegenüberliegende Ecke des Rechtecks"
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
msgstr "Klicken Sie, um den Radius festzulegen"
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Ein Kreisbogen kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
msgstr "Klicken Sie, um einen Punkt zu platzieren"
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
msgstr ""
"Klicken Sie auf den nächsten Punkt der kubischen Linie, oder drücken Sie Esc"
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
"Eine Arbeitsebene ist bereits aktiv. Skizzieren Sie in 3D, bevor Sie eine "
"neue Arbeitsebene erstellen."
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Text kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
msgstr "Klicken Sie auf die untere rechte Ecke des Texts"
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Das Bild kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN"
-
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
msgctxt "file-type"
msgid "SolveSpace models"
msgstr "SolveSpace-Modelle"
-#: platform/gui.cpp:90
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr "ALLE"
+
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
msgstr "IDF Leiterplatte"
-#: platform/gui.cpp:94
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr "STL-Dreiecks-Netz"
+
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
msgstr "PNG-Datei"
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
msgstr "STL-Netz"
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
msgstr "Wavefront OBJ-Netz"
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
msgstr "Three.js-kompatibles Netz, mit Ansicht"
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
msgstr "Three.js-kompatibles Netz, nur Netz"
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
msgstr "VRML Textdatei"
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP-Datei"
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF-Datei"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "Eingebettetes Postscript"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "Skalierbare Vektorgrafik"
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF-Datei (AutoCAD 2007)"
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL-Datei"
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
msgstr "G-Code"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF- und DWG-Dateien"
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
msgstr "Werte durch Komma getrennt (CSV)"
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
msgstr "unbenannt"
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
msgstr "Datei speichern"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
msgstr "Datei öffnen"
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
msgstr "_Abbrechen"
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
msgstr "_Speichern"
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
msgstr "_Öffnen"
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
msgstr "Automatische Sicherungsdatei verfügbar"
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
msgstr "Eine automatische Sicherung ist für diese Skizze verfügbar."
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
msgstr "Wollen Sie die automatische Sicherungsdatei stattdessen laden?"
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
msgstr "AutoDatei &öffnen"
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
msgstr "&Nicht laden"
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
msgstr "Geänderte Datei"
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
msgstr "Wollen Sie die Änderungen an der Skizze “%s” sichern?"
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
msgstr "Wollen Sie die Änderungen an der Skizze sichern?"
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
msgstr "Ihre Änderungen werden verworfen, wenn sie nicht abgespeichert werden."
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
msgstr "&Sichern"
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
msgstr "&Verwerfen"
# solvespace.cpp:557
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
msgstr "(Neue Skizze)"
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
msgstr "Attribut-Browser"
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This "
"is probably not what you want; hide them by clicking the link at the top of "
"wahrscheinlich nicht. Verstecken Sie sie in dem auf den Link oben im "
"Textfenster klicken."
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid ""
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"Kann den Dateityp der Datei '%s' nicht auf Grund der Dateierweiterung "
"erkennen. Versuchen Sie .dxf oder .dwg."
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
msgstr ""
"Die Einschränkung muss einen Namen haben, und darf keine "
"Referenzdimensionierung sein."
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
msgstr ""
"Falsche Auswahl für die Schrittdimensionierung. Wählen Sie eine "
"Einschränkung."
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
msgstr "Der Zusammenbau funktioniert, gut."
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
"\n"
" %s"
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
"\n"
" %s"
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"Gekrümmte Flächen wurden als Dreiecksnetz angenähert.\n"
"Das verursacht Fehler, typischerweise um 1%."
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"Kurven wurden als gerade Linienstücke angenähert.\n"
"Das verursacht Fehler, typischerweise um 1%%."
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
"Diese Gruppe beinhaltet keine korrekt geschlossene 2D Fläche. Sie ist offen, "
"nicht koplanar, oder überschneidet sich selbst."
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"Kurven wurden als gerade Linienstücke angenähert.\n"
"Das verursacht Fehler, typischerweise um 1%%."
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"Kurven wurden als gerade Linienstücke angenähert.\n"
"Das verursacht Fehler, typischerweise um 1%%."
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
msgstr "Falsche Auswahl für Umfang. Wähle Liniensegmente, Bögen und Kurven."
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
msgstr "Falsche Auswahl für Punkt nachzeichnen. Wähle einen einzelnen Punkt."
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
msgstr "Konnte '%s' nicht schreiben"
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
msgstr "Das Netz schneidet sich selbst: Falsch, ungültig."
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
msgstr "Das Netz schneidet sich nicht: Gut, gültig."
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
msgstr "Das Netz hat lose Kanten: Falsch, ungültig."
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
msgstr "Das Netz hat keine lose Kanten: Gut, gültig."
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"\n"
"Das Modell hat %d Dreiecke, von %d Flächen."
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"\n"
"Keine problematischen Kanten, gut.%s"
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"\n"
"%d problematische Kanten, schlecht.%s"
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"\n"
"© 2008-%d Jonathan Westhues und andere.\n"
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
"Objekt abgeleitet wurde. Versuchen Sie, dem übergeordneten Objekt einen Typ "
"zuzuordnen."
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
-msgstr "Name des Linientyps kann nicht leer sein."
+msgstr "Name des Linientyps kann nicht leer sein"
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
msgstr "Nicht weniger als 1 Wiederholung möglich."
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
msgstr "Nicht mehr als 999 Wiederholungen möglich."
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
-msgstr "Der Name der Gruppe darf nicht leer sein."
+msgstr "Der Name der Gruppe darf nicht leer sein"
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
msgstr "Durchsichtigkeit muss zwischen Null und Eins sein."
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
msgstr "Radius darf nicht null oder negativ sein."
msgid "&OK"
msgstr "&OK"
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
msgstr "Der Maßstab kann nicht Null oder negativ sein."
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
msgstr "Ungültiges Format: geben Sie x, y, z ein"
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Ungültige Auswahl für Einschränkung \"Längenverhältnis\". Diese "
+#~ "Einschränkung ist anwendbar auf:\n"
+#~ "\n"
+#~ " * zwei Liniensegmente\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Ungültige Auswahl für Einschränkung \"Längendifferenz\". Diese "
+#~ "Einschränkung ist anwendbar auf:\n"
+#~ "\n"
+#~ " * zwei Liniensegmente\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "Längenverhältnis"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "Längendifferenz"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "Ungültige Auswahl für Skizze in neuer Arbeitsebene. Diese Gruppe kann "
+#~ "erstellt werden mit:\n"
+#~ "\n"
+#~ " * einem Punkt (durch den Punkt, orthogonal zu den Koordinatenachsen)\n"
+#~ " * einem Punkt und zwei Liniensegmenten (durch den Punkt, parallel zu "
+#~ "den Linien)\n"
+#~ " * einer Arbeitsebene (Kopie der Arbeitsebene)\n"
+
#~ msgctxt "file-type"
#~ msgid "Q3D Object file"
#~ msgstr "Q3D Objektdatei"
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
"PO-Revision-Date: 2017-01-05 10:30+0000\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"\n"
"Activate one with Sketch -> In Workplane."
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
msgstr "Clipboard is empty; nothing to paste."
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
msgstr "Number of copies to paste must be at least one."
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
msgstr "Scale cannot be zero."
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
msgstr "Select one point to define origin of rotation."
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
msgstr "Select two points to define translation vector."
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid ""
"Transformation is identity. So all copies will be exactly on top of each "
"other."
"Transformation is identity. So all copies will be exactly on top of each "
"other."
-#: clipboard.cpp:458
+#: clipboard.cpp:457
msgid "Too many items to paste; split this into smaller pastes."
msgstr "Too many items to paste; split this into smaller pastes."
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
msgstr "No workplane active."
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
msgstr "Bad format: specify coordinates as x, y, z"
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
msgstr "Bad format: specify color as r, g, b"
-#: confscreen.cpp:454
+#: confscreen.cpp:417
msgid ""
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
msgstr "Specify between 0 and %d digits after the decimal."
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
msgstr "Export scale must not be zero!"
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
msgstr "Cutter radius offset must not be negative!"
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
msgstr "Bad value: autosave interval should be positive"
-#: confscreen.cpp:558
+#: confscreen.cpp:531
msgid "Bad format: specify interval in integral minutes"
msgstr "Bad format: specify interval in integral minutes"
#: constraint.cpp:25
msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr "arc-arc-length-ratio"
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr "arc-line-length-ratio"
+
+#: constraint.cpp:27
+msgctxt "constr-name"
msgid "length-difference"
msgstr "length-difference"
-#: constraint.cpp:26
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr "arc-arc-len-difference"
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr "arc-line-len-difference"
+
+#: constraint.cpp:30
msgctxt "constr-name"
msgid "symmetric"
msgstr "symmetric"
-#: constraint.cpp:27
+#: constraint.cpp:31
msgctxt "constr-name"
msgid "symmetric-h"
msgstr "symmetric-h"
-#: constraint.cpp:28
+#: constraint.cpp:32
msgctxt "constr-name"
msgid "symmetric-v"
msgstr "symmetric-v"
-#: constraint.cpp:29
+#: constraint.cpp:33
msgctxt "constr-name"
msgid "symmetric-line"
msgstr "symmetric-line"
-#: constraint.cpp:30
+#: constraint.cpp:34
msgctxt "constr-name"
msgid "at-midpoint"
msgstr "at-midpoint"
-#: constraint.cpp:31
+#: constraint.cpp:35
msgctxt "constr-name"
msgid "horizontal"
msgstr "horizontal"
-#: constraint.cpp:32
+#: constraint.cpp:36
msgctxt "constr-name"
msgid "vertical"
msgstr "vertical"
-#: constraint.cpp:33
+#: constraint.cpp:37
msgctxt "constr-name"
msgid "diameter"
msgstr "diameter"
-#: constraint.cpp:34
+#: constraint.cpp:38
msgctxt "constr-name"
msgid "pt-on-circle"
msgstr "pt-on-circle"
-#: constraint.cpp:35
+#: constraint.cpp:39
msgctxt "constr-name"
msgid "same-orientation"
msgstr "same-orientation"
-#: constraint.cpp:36
+#: constraint.cpp:40
msgctxt "constr-name"
msgid "angle"
msgstr "angle"
-#: constraint.cpp:37
+#: constraint.cpp:41
msgctxt "constr-name"
msgid "parallel"
msgstr "parallel"
-#: constraint.cpp:38
+#: constraint.cpp:42
msgctxt "constr-name"
msgid "arc-line-tangent"
msgstr "arc-line-tangent"
-#: constraint.cpp:39
+#: constraint.cpp:43
msgctxt "constr-name"
msgid "cubic-line-tangent"
msgstr "cubic-line-tangent"
-#: constraint.cpp:40
+#: constraint.cpp:44
msgctxt "constr-name"
msgid "curve-curve-tangent"
msgstr "curve-curve-tangent"
-#: constraint.cpp:41
+#: constraint.cpp:45
msgctxt "constr-name"
msgid "perpendicular"
msgstr "perpendicular"
-#: constraint.cpp:42
+#: constraint.cpp:46
msgctxt "constr-name"
msgid "eq-radius"
msgstr "eq-radius"
-#: constraint.cpp:43
+#: constraint.cpp:47
msgctxt "constr-name"
msgid "eq-angle"
msgstr "eq-angle"
-#: constraint.cpp:44
+#: constraint.cpp:48
msgctxt "constr-name"
msgid "eq-line-len-arc-len"
msgstr "eq-line-len-arc-len"
-#: constraint.cpp:45
+#: constraint.cpp:49
msgctxt "constr-name"
msgid "lock-where-dragged"
msgstr "lock-where-dragged"
-#: constraint.cpp:46
+#: constraint.cpp:50
msgctxt "constr-name"
msgid "comment"
msgstr "comment"
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply "
"to:\n"
" * a plane face and a point (minimum distance)\n"
" * a circle or an arc (diameter)\n"
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can "
"apply to:\n"
" * a point and a circle or arc (point on curve)\n"
" * a point and a plane face (point on face)\n"
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can "
"apply to:\n"
" * two circles or arcs (equal radius)\n"
" * a line segment and an arc (line segment length equals arc length)\n"
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
" * a line segment and a point (point at midpoint)\n"
" * a line segment and a workplane (line's midpoint on plane)\n"
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
" * workplane, and two points or a line segment (symmetric about "
"workplane)\n"
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid ""
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can "
"apply to:\n"
" * two points\n"
" * a line segment\n"
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply "
"to:\n"
"\n"
" * two normals\n"
-#: constraint.cpp:614
+#: constraint.cpp:663
msgid "Must select an angle constraint."
msgstr "Must select an angle constraint."
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
msgstr "Must select a constraint with associated label."
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * a line segment and a normal\n"
" * two normals\n"
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr "Curve-curve tangency must apply in workplane."
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply "
"to:\n"
" * two normals (parallel)\n"
" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n"
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * a line segment and a normal\n"
" * two normals\n"
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can "
"apply to:\n"
"\n"
" * a point\n"
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+
+#: constraint.cpp:818
msgid "click center of comment text"
msgstr "click center of comment text"
" * a point and two line segments (plane through point and parallel to "
"lines)\n"
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
msgstr "Active group mesh is empty; nothing to export."
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr "freehand lines were replaced with continuous lines"
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr "zigzag lines were replaced with continuous lines"
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid ""
"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr ""
msgid "#references"
msgstr "#references"
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr "The file is empty. It may be corrupt."
+
+#: file.cpp:555
msgid ""
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Missing File"
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr "The linked file “%s” is not present."
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"If you decline, any geometry that depends on the missing file will be "
"permanently removed."
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr "&Yes"
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "&No"
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
msgstr "&Cancel"
msgstr "Use &Perspective Projection"
#: graphicswin.cpp:97
+msgid "Show E&xploded View"
+msgstr "Show E&xploded View"
+
+#: graphicswin.cpp:98
msgid "Dimension &Units"
msgstr "Dimension &Units"
-#: graphicswin.cpp:98
+#: graphicswin.cpp:99
msgid "Dimensions in &Millimeters"
msgstr "Dimensions in &Millimeters"
-#: graphicswin.cpp:99
+#: graphicswin.cpp:100
msgid "Dimensions in M&eters"
msgstr "Dimensions in M&eters"
-#: graphicswin.cpp:100
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
msgstr "Dimensions in &Inches"
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr "Dimensions in &Feet and Inches"
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr "Show &Toolbar"
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr "Show Property Bro&wser"
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr "&Full Screen"
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr "&New Group"
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
msgstr "Sketch In &3d"
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
msgstr "Sketch In New &Workplane"
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr "Step &Translating"
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr "Step &Rotating"
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr "E&xtrude"
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
msgstr "&Helix"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr "&Lathe"
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
msgstr "Re&volve"
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
msgstr "Link / Assemble..."
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
msgstr "Link Recent"
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr "&Sketch"
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
msgstr "In &Workplane"
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
msgstr "Anywhere In &3d"
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr "Datum &Point"
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr "&Workplane"
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr "Line &Segment"
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr "C&onstruction Line Segment"
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr "&Rectangle"
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr "&Circle"
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr "&Arc of a Circle"
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr "&Bezier Cubic Spline"
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
msgstr "&Text in TrueType Font"
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
msgstr "&Image"
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr "To&ggle Construction"
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr "Tangent &Arc at Point"
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr "Split Curves at &Intersection"
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr "&Constrain"
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr "&Distance / Diameter"
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr "Re&ference Dimension"
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr "A&ngle"
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr "Reference An&gle"
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr "Other S&upplementary Angle"
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr "Toggle R&eference Dim"
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr "&Horizontal"
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr "&Vertical"
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr "&On Point / Curve / Plane"
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr "E&qual Length / Radius / Angle"
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
-msgstr "Length Ra&tio"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr "Length / Arc Ra&tio"
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
-msgstr "Length Diff&erence"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr "Length / Arc Diff&erence"
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr "At &Midpoint"
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr "S&ymmetric"
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr "Para&llel / Tangent"
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr "&Perpendicular"
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr "Same Orient&ation"
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr "Lock Point Where &Dragged"
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr "Comment"
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr "&Analyze"
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr "Measure &Volume"
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr "Measure A&rea"
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr "Measure &Perimeter"
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr "Show &Interfering Parts"
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr "Show &Naked Edges"
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
msgstr "Show &Center of Mass"
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
msgstr "Show &Underconstrained Points"
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr "&Trace Point"
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
msgstr "&Stop Tracing..."
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr "Step &Dimension..."
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr "&Help"
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr "&Language"
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr "&Website / Manual"
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr "&Go to GitHub commit"
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr "&About"
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
msgstr "(no recent files)"
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
msgstr "File '%s' does not exist."
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
msgstr "No workplane is active, so the grid will not appear."
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel "
"projection.\n"
"For a perspective projection, modify the perspective factor in the "
"configuration screen. A value around 0.3 is typical."
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid ""
"Select a point; this point will become the center of the view on screen."
msgstr ""
"Select a point; this point will become the center of the view on screen."
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr "No additional entities share endpoints with the selected entities."
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr "No workplane selected. Activating default workplane for this group."
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default "
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"workplane group."
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr "click point on arc (draws anti-clockwise)"
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
msgstr "click to place datum point"
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
msgstr "click first point of line segment"
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
msgstr "click first point of construction line segment"
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
msgstr "click first point of cubic segment"
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
msgstr "click center of circle"
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
msgstr "click origin of workplane"
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
msgstr "click one corner of rectangle"
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
msgstr "click top left of text"
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
msgstr "click top left of image"
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid ""
"No entities are selected. Select entities before trying to toggle their "
"construction state."
msgid "sketch-in-3d"
msgstr "sketch-in-3d"
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
msgstr "extrude"
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr "Lathe operation can only be applied to planar sketches."
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
"to line / normal, through point)\n"
" * a line segment (revolved about line segment)\n"
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
msgstr "lathe"
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr "Revolve operation can only be applied to planar sketches."
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
"to line / normal, through point)\n"
" * a line segment (revolved about line segment)\n"
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
msgstr "revolve"
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
msgstr "Helix operation can only be applied to planar sketches."
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
"to line / normal, through point)\n"
" * a line segment (revolved about line segment)\n"
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
msgstr "helix"
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
" * a point and a line or a normal (rotate about an axis through the "
"point, and parallel to line / normal)\n"
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
msgstr "rotate"
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
msgstr "translate"
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
msgstr "(unnamed)"
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
msgstr "not closed contour, or not all same style!"
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr "points not all coplanar!"
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
msgstr "contour is self-intersecting!"
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
msgstr "zero-length edge!"
-#: modify.cpp:254
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr "Text-formated STL files are not currently supported"
+
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr "Must be sketching in workplane to create tangent arc."
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr "Couldn't split this entity; lines, circles, or cubics only."
-#: modify.cpp:624
+#: modify.cpp:622
msgid "Must be sketching in workplane to split."
msgstr "Must be sketching in workplane to split."
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
msgstr "Can't split; no intersection found."
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr "Assign to Style"
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr "No Style"
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr "Newly Created Custom Style..."
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr "Group Info"
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr "Style Info"
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr "Select Edge Chain"
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr "Toggle Reference Dimension"
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr "Other Supplementary Angle"
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr "Snap to Grid"
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr "Remove Spline Point"
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr "Add Spline Point"
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr "Cannot add spline point: maximum number of points reached."
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr "Toggle Construction"
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr "Delete Point-Coincident Constraint"
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr "Cut"
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr "Copy"
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr "Select All"
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr "Paste"
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr "Paste Transformed..."
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr "Delete"
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr "Unselect All"
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr "Unselect Hovered"
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr "Zoom to Fit"
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
msgstr "click next point of line, or press Esc"
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
msgstr "click to place other corner of rectangle"
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
msgstr "click to set radius"
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
msgstr "click to place point"
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
msgstr "click next point of cubic, or press Esc"
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
msgstr "click to place bottom right of text"
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
msgctxt "file-type"
msgid "SolveSpace models"
msgstr "SolveSpace models"
-#: platform/gui.cpp:90
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr "ALL"
+
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
msgstr "IDF circuit board"
-#: platform/gui.cpp:94
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr "STL triangle mesh"
+
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
msgstr "PNG image"
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
msgstr "STL mesh"
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
msgstr "Wavefront OBJ mesh"
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
msgstr "Three.js-compatible mesh, with viewer"
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
msgstr "Three.js-compatible mesh, mesh only"
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
msgstr "VRML text file"
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP file"
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF file"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "Encapsulated PostScript"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "Scalable Vector Graphics"
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF file (AutoCAD 2007)"
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL file"
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
msgstr "G Code"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF and DWG files"
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
msgstr "Comma-separated values"
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
msgstr "untitled"
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
msgstr "Save File"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
msgstr "Open File"
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
msgstr "_Cancel"
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
msgstr "_Save"
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
msgstr "_Open"
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
msgstr "Autosave Available"
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
msgstr "An autosave file is available for this sketch."
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
msgstr "Do you want to load the autosave file instead?"
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
msgstr "&Load autosave"
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
msgstr "Do&n't Load"
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
msgstr "Modified File"
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
msgstr "Do you want to save the changes you made to the sketch “%s”?"
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
msgstr "Do you want to save the changes you made to the new sketch?"
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
msgstr "Your changes will be lost if you don't save them."
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
msgstr "&Save"
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
msgstr "Do&n't Save"
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
msgstr "(new sketch)"
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
msgstr "Property Browser"
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This "
"is probably not what you want; hide them by clicking the link at the top of "
"is probably not what you want; hide them by clicking the link at the top of "
"the text window."
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid ""
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"dwg."
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
msgstr "Constraint must have a label, and must not be a reference dimension."
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
msgstr "Bad selection for step dimension; select a constraint."
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
msgstr "The assembly does not interfere, good."
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
"\n"
" %s"
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
"\n"
" %s"
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"Curved surfaces have been approximated as triangles.\n"
"This introduces error, typically of around 1%."
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
msgstr "Bad selection for perimeter; select line segments, arcs, and curves."
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
msgstr "Bad selection for trace; select a single point."
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
msgstr "Couldn't write to '%s'"
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
msgstr "The mesh is self-intersecting (NOT okay, invalid)."
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
msgstr "The mesh is not self-intersecting (okay, valid)."
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
msgstr "The mesh has naked edges (NOT okay, invalid)."
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
msgstr "The mesh is watertight (okay, valid)."
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"\n"
"The model contains %d triangles, from %d surfaces."
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"\n"
"Zero problematic edges, good.%s"
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"\n"
"%d problematic edges, bad.%s"
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"\n"
"© 2008-%d Jonathan Westhues and other authors.\n"
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
msgstr "Style name cannot be empty"
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
msgstr "Can't repeat fewer than 1 time."
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
msgstr "Can't repeat more than 999 times."
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
msgstr "Group name cannot be empty"
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
msgstr "Opacity must be between zero and one."
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
msgstr "Radius cannot be zero or negative."
msgid "&OK"
msgstr "&OK"
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
msgstr "Scale cannot be zero or negative."
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
msgstr "Bad format: specify x, y, z"
+#~ msgid "&Mirror"
+#~ msgstr "&Mirror"
+
+#~ msgctxt "group-name"
+#~ msgid "mirror"
+#~ msgstr "mirror"
+
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "Length Ra&tio"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "Length Diff&erence"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+
#~ msgctxt "file-type"
#~ msgid "Q3D Object file"
#~ msgstr "Q3D Object file"
--- /dev/null
+# Spanish/Argentina translations for SolveSpace package.
+# Copyright (C) 2017 the SolveSpace authors
+# This file is distributed under the same license as the SolveSpace package.
+# Maxi <andesfreedesign@gmail.com>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SolveSpace 3.0\n"
+"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
+"PO-Revision-Date: 2021-09-17 \n"
+"Last-Translator: andesfreedesign@gmail.com\n"
+"Language-Team: AndesFreeDesign\n"
+"Language: es_AR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: clipboard.cpp:309
+msgid ""
+"Cut, paste, and copy work only in a workplane.\n"
+"\n"
+"Activate one with Sketch -> In Workplane."
+msgstr ""
+"Cortar, pegar y copiar trabajo\n"
+"solo en un plano de trabajo.\n"
+"Activar uno con Croquis-> En Plano de trabajo"
+
+#: clipboard.cpp:326
+msgid "Clipboard is empty; nothing to paste."
+msgstr "El portapapeles está vacío; nada que pegar."
+
+#: clipboard.cpp:373
+msgid "Number of copies to paste must be at least one."
+msgstr "El número de copias para pegar debe ser al menos una."
+
+#: clipboard.cpp:389 textscreens.cpp:833
+msgid "Scale cannot be zero."
+msgstr "La escala no puede ser cero."
+
+#: clipboard.cpp:431
+msgid "Select one point to define origin of rotation."
+msgstr "Seleccione un punto para definir el origen de la rotación."
+
+#: clipboard.cpp:443
+msgid "Select two points to define translation vector."
+msgstr "Seleccione dos puntos para definir el vector de traslación."
+
+#: clipboard.cpp:453
+msgid ""
+"Transformation is identity. So all copies will be exactly on top of each "
+"other."
+msgstr ""
+"No se especificó ninguna transformación. Todas las copias estarán ubicadas "
+"en el mismo lugar."
+
+#: clipboard.cpp:457
+msgid "Too many items to paste; split this into smaller pastes."
+msgstr "Demasiados elementos para pegar; divida esto en partes más pequeñas."
+
+#: clipboard.cpp:462
+msgid "No workplane active."
+msgstr "Ningún plano de trabajo activo."
+
+#: confscreen.cpp:381
+msgid "Bad format: specify coordinates as x, y, z"
+msgstr "Formato incorrecto: especifique las coordenadas como x, y, z"
+
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
+msgid "Bad format: specify color as r, g, b"
+msgstr "Formato incorrecto: especifique color como r, g, b"
+
+#: confscreen.cpp:417
+msgid ""
+"The perspective factor will have no effect until you enable View -> Use "
+"Perspective Projection."
+msgstr ""
+"El factor de perspectiva no tendrá ningún efecto hasta que habilite Ver -> "
+"UsarProyección Perspectiva."
+
+#: confscreen.cpp:435 confscreen.cpp:445
+#, c-format
+msgid "Specify between 0 and %d digits after the decimal."
+msgstr "Especifique entre 0 y %d dígitos después del decimal."
+
+#: confscreen.cpp:457
+msgid "Export scale must not be zero!"
+msgstr "¡La escala de exportación no debe ser cero!"
+
+#: confscreen.cpp:469
+msgid "Cutter radius offset must not be negative!"
+msgstr "¡El desfase del radio de corte no debe ser negativo!"
+
+#: confscreen.cpp:528
+msgid "Bad value: autosave interval should be positive"
+msgstr "Valor incorrecto: el intervalo de autoguardado debe ser positivo"
+
+#: confscreen.cpp:531
+msgid "Bad format: specify interval in integral minutes"
+msgstr "Formato incorrecto: especifique el intervalo en minutos integrales"
+
+#: constraint.cpp:12
+msgctxt "constr-name"
+msgid "pts-coincident"
+msgstr "ps-coincidente"
+
+#: constraint.cpp:13
+msgctxt "constr-name"
+msgid "pt-pt-distance"
+msgstr "p-p-distancia"
+
+#: constraint.cpp:14
+msgctxt "constr-name"
+msgid "pt-line-distance"
+msgstr "p-línea-distancia"
+
+#: constraint.cpp:15
+msgctxt "constr-name"
+msgid "pt-plane-distance"
+msgstr "p-plano-distancia"
+
+#: constraint.cpp:16
+msgctxt "constr-name"
+msgid "pt-face-distance"
+msgstr "p-cara-distancia"
+
+#: constraint.cpp:17
+msgctxt "constr-name"
+msgid "proj-pt-pt-distance"
+msgstr "proy-p-p-distancia"
+
+#: constraint.cpp:18
+msgctxt "constr-name"
+msgid "pt-in-plane"
+msgstr "p-en-plano"
+
+#: constraint.cpp:19
+msgctxt "constr-name"
+msgid "pt-on-line"
+msgstr "p-sobre-línea"
+
+#: constraint.cpp:20
+msgctxt "constr-name"
+msgid "pt-on-face"
+msgstr "p-sobre-cara"
+
+#: constraint.cpp:21
+msgctxt "constr-name"
+msgid "eq-length"
+msgstr "igual-longitud"
+
+#: constraint.cpp:22
+msgctxt "constr-name"
+msgid "eq-length-and-pt-ln-dist"
+msgstr "igual-longitud-y-p-línea-dist"
+
+#: constraint.cpp:23
+msgctxt "constr-name"
+msgid "eq-pt-line-distances"
+msgstr "igual-p-línea-distancias"
+
+#: constraint.cpp:24
+msgctxt "constr-name"
+msgid "length-ratio"
+msgstr "longitud-radio"
+
+#: constraint.cpp:25
+msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr ""
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr ""
+
+#: constraint.cpp:27
+msgctxt "constr-name"
+msgid "length-difference"
+msgstr "longitud-diferencia"
+
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr ""
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr ""
+
+#: constraint.cpp:30
+msgctxt "constr-name"
+msgid "symmetric"
+msgstr "simetría"
+
+#: constraint.cpp:31
+msgctxt "constr-name"
+msgid "symmetric-h"
+msgstr "simetría-h"
+
+#: constraint.cpp:32
+msgctxt "constr-name"
+msgid "symmetric-v"
+msgstr "simetría-v"
+
+#: constraint.cpp:33
+msgctxt "constr-name"
+msgid "symmetric-line"
+msgstr "simetría-línea"
+
+#: constraint.cpp:34
+msgctxt "constr-name"
+msgid "at-midpoint"
+msgstr "en-puntoMedio"
+
+#: constraint.cpp:35
+msgctxt "constr-name"
+msgid "horizontal"
+msgstr "horizontal"
+
+#: constraint.cpp:36
+msgctxt "constr-name"
+msgid "vertical"
+msgstr "vertical"
+
+#: constraint.cpp:37
+msgctxt "constr-name"
+msgid "diameter"
+msgstr "diámetro"
+
+#: constraint.cpp:38
+msgctxt "constr-name"
+msgid "pt-on-circle"
+msgstr "p-sobre-círculo"
+
+#: constraint.cpp:39
+msgctxt "constr-name"
+msgid "same-orientation"
+msgstr "misma-orientación"
+
+#: constraint.cpp:40
+msgctxt "constr-name"
+msgid "angle"
+msgstr "ángulo"
+
+#: constraint.cpp:41
+msgctxt "constr-name"
+msgid "parallel"
+msgstr "paralela"
+
+#: constraint.cpp:42
+msgctxt "constr-name"
+msgid "arc-line-tangent"
+msgstr "arco-línea-tangente"
+
+#: constraint.cpp:43
+msgctxt "constr-name"
+msgid "cubic-line-tangent"
+msgstr "cúbica-línea-tangente"
+
+#: constraint.cpp:44
+msgctxt "constr-name"
+msgid "curve-curve-tangent"
+msgstr "curva-curva-tangente"
+
+#: constraint.cpp:45
+msgctxt "constr-name"
+msgid "perpendicular"
+msgstr "perpendicular"
+
+#: constraint.cpp:46
+msgctxt "constr-name"
+msgid "eq-radius"
+msgstr "igual-radio"
+
+#: constraint.cpp:47
+msgctxt "constr-name"
+msgid "eq-angle"
+msgstr "igual-ángulo"
+
+#: constraint.cpp:48
+msgctxt "constr-name"
+msgid "eq-line-len-arc-len"
+msgstr "igual-línea-long-arco-long"
+
+#: constraint.cpp:49
+msgctxt "constr-name"
+msgid "lock-where-dragged"
+msgstr "fijación"
+
+#: constraint.cpp:50
+msgctxt "constr-name"
+msgid "comment"
+msgstr "comentario"
+
+#: constraint.cpp:144
+msgid ""
+"The tangent arc and line segment must share an endpoint. Constrain them with "
+"Constrain -> On Point before constraining tangent."
+msgstr ""
+"El arco tangente y la línea deben compartir un punto final. Restringirlos "
+"con Restringir -> En el punto antes de restringir la tangente."
+
+#: constraint.cpp:163
+msgid ""
+"The tangent cubic and line segment must share an endpoint. Constrain them "
+"with Constrain -> On Point before constraining tangent."
+msgstr ""
+"La tangente cúbica y la línea deben compartir un punto final. Restringirlos "
+"con Restringir -> En el punto antes de restringir la tangente."
+
+#: constraint.cpp:189
+msgid ""
+"The curves must share an endpoint. Constrain them with Constrain -> On Point "
+"before constraining tangent."
+msgstr ""
+"Las curvas deben compartir un punto final. Restringirlos con Restringir -> "
+"En el punto antes de restringir la tangente."
+
+#: constraint.cpp:238
+msgid ""
+"Bad selection for distance / diameter constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two points (distance between points)\n"
+" * a line segment (length)\n"
+" * two points and a line segment or normal (projected distance)\n"
+" * a workplane and a point (minimum distance)\n"
+" * a line segment and a point (minimum distance)\n"
+" * a plane face and a point (minimum distance)\n"
+" * a circle or an arc (diameter)\n"
+msgstr ""
+"Mala selección para la restricción de distancia / diámetro. Esta restricción "
+"puede aplicarse a:\n"
+"\n"
+" * dos puntos (distancia entre puntos) \n"
+" * un segmento de línea (longitud) \n"
+" * dos puntos y un segmento de línea o normal (distancia proyectada) \n"
+" * un plano de trabajo y un punto (distancia mínima) \n"
+" * un segmento de línea y un punto (distancia mínima) \n"
+" * una cara plana y un punto (distancia mínima) \n"
+" * un círculo o un arco (diámetro) \n"
+
+#: constraint.cpp:291
+msgid ""
+"Bad selection for on point / curve / plane constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * two points (points coincident)\n"
+" * a point and a workplane (point in plane)\n"
+" * a point and a line segment (point on line)\n"
+" * a point and a circle or arc (point on curve)\n"
+" * a point and a plane face (point on face)\n"
+msgstr ""
+"Mala selección para una restricción de punto / curva / plano. Esta "
+"restricción puedeaplicar a: \n"
+"\n"
+" * dos puntos (puntos coincidentes) \n"
+" * un punto y un plano de trabajo (punto en el plano) \n"
+" * un punto y un segmento de línea (punto en la línea) \n"
+" * un punto y un círculo o arco (punto en la curva) \n"
+" * un punto y una cara plana (punto en la cara) \n"
+
+#: constraint.cpp:353
+msgid ""
+"Bad selection for equal length / radius constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * two line segments (equal length)\n"
+" * two line segments and two points (equal point-line distances)\n"
+" * a line segment and two points (equal point-line distances)\n"
+" * a line segment, and a point and line segment (point-line distance "
+"equals length)\n"
+" * four line segments or normals (equal angle between A,B and C,D)\n"
+" * three line segments or normals (equal angle between A,B and B,C)\n"
+" * two circles or arcs (equal radius)\n"
+" * a line segment and an arc (line segment length equals arc length)\n"
+msgstr ""
+"Mala selección para restricción de igualdad longitud / radio. Esta "
+"restricción puede aplicar a:\n"
+"\n"
+" * dos segmentos de línea (igual longitud)\n"
+" * dos segmentos de línea y dos puntos (distancias de línea-punto "
+"iguales)\n"
+" * un segmento de línea y dos puntos (distancias punto-línea iguales)\n"
+" * un segmento de línea, y un punto y un segmento de línea (distancia "
+"punto-línea igual a la longitud)\n"
+" * cuatro segmentos de línea o normales (ángulo igual entre A,B y C,D)\n"
+" * tres segmentos de línea o normales (ángulo igual entre A,B y B,C)\n"
+" * 2 círculos o arcos (igual radio)\n"
+" * un segmento de línea y un arco (la longitud del segmento de línea es "
+"igual a la longitud del arco)\n"
+
+#: constraint.cpp:407
+msgid ""
+"Bad selection for length ratio constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
+msgstr ""
+
+#: constraint.cpp:441
+msgid ""
+"Bad selection for length difference constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
+msgstr ""
+
+#: constraint.cpp:472
+msgid ""
+"Bad selection for at midpoint constraint. This constraint can apply to:\n"
+"\n"
+" * a line segment and a point (point at midpoint)\n"
+" * a line segment and a workplane (line's midpoint on plane)\n"
+msgstr ""
+"Mala selección para una restricción de punto medio. Esta restricción se "
+"puede aplicar a:\n"
+"\n"
+" * un segmento de línea y un punto (punto en el punto medio)\n"
+" * un segmento de línea y un plano de trabajo (punto medio de la línea en "
+"el plano)\n"
+
+#: constraint.cpp:530
+msgid ""
+"Bad selection for symmetric constraint. This constraint can apply to:\n"
+"\n"
+" * two points or a line segment (symmetric about workplane's coordinate "
+"axis)\n"
+" * line segment, and two points or a line segment (symmetric about line "
+"segment)\n"
+" * workplane, and two points or a line segment (symmetric about "
+"workplane)\n"
+msgstr ""
+"Mala selección por restricción simétrica. Esta restricción se puede aplicar "
+"a:\n"
+"\n"
+" * dos puntos o un segmento de línea (simétrico con respecto al eje de "
+"coordenadas del plano de trabajo)\n"
+" * segmento de línea, y dos puntos o un segmento de línea (simétrico con "
+"respecto al segmento de línea)\n"
+" * plano de trabajo, y dos puntos o un segmento de recta (simétrico sobre "
+"plano de trabajo)\n"
+
+#: constraint.cpp:545
+msgid ""
+"A workplane must be active when constraining symmetric without an explicit "
+"symmetry plane."
+msgstr ""
+"Un plano de trabajo debe estar activo al restringir simétrico sin un plano "
+"de simetría explícito."
+
+#: constraint.cpp:579
+msgid ""
+"Activate a workplane (with Sketch -> In Workplane) before applying a "
+"horizontal or vertical constraint."
+msgstr ""
+"Active un plano de trabajo (con Croquis -> En plano de trabajo) antes de "
+"aplicar una restricción horizontal o vertical."
+
+#: constraint.cpp:592
+msgid ""
+"Bad selection for horizontal / vertical constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * two points\n"
+" * a line segment\n"
+msgstr ""
+"Mala selección por restricción horizontal / vertical. Esta restricción puede "
+"aplicar a:\n"
+"\n"
+" * dos puntos\n"
+" * un segmento de línea\n"
+
+#: constraint.cpp:613
+msgid ""
+"Bad selection for same orientation constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two normals\n"
+msgstr ""
+"Mala selección para la misma restricción de orientación. Esta restricción "
+"puede aplicarse a:\n"
+"\n"
+" * dos normales\n"
+
+#: constraint.cpp:663
+msgid "Must select an angle constraint."
+msgstr "Debe seleccionar una restricción de ángulo."
+
+#: constraint.cpp:676
+msgid "Must select a constraint with associated label."
+msgstr "Debe seleccionar una restricción con etiqueta asociada."
+
+#: constraint.cpp:687
+msgid ""
+"Bad selection for angle constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+" * a line segment and a normal\n"
+" * two normals\n"
+msgstr ""
+"Mala selección por restricción de ángulo. Esta restricción se puede aplicar "
+"a:\n"
+"\n"
+" * dos segmentos de línea\n"
+" * un segmento de linea y una normal\n"
+" * dos normales\n"
+
+#: constraint.cpp:754
+msgid "Curve-curve tangency must apply in workplane."
+msgstr "La tangencia curva-curva debe aplicarse en el plano de trabajo."
+
+#: constraint.cpp:766
+msgid ""
+"Bad selection for parallel / tangent constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two line segments (parallel)\n"
+" * a line segment and a normal (parallel)\n"
+" * two normals (parallel)\n"
+" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n"
+msgstr ""
+"Mala selección para restricción de paralelo / tangente. Esta restricción "
+"puede aplicarse a:\n"
+"\n"
+" * dos segmentos de línea (paralelos)\n"
+" * un segmento de línea y una normal (paralelas)\n"
+" * dos normales (paralelas)\n"
+" * dos segmentos de línea, arcos, o beziers, que comparten un punto final "
+"(tangente)\n"
+
+#: constraint.cpp:784
+msgid ""
+"Bad selection for perpendicular constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+" * a line segment and a normal\n"
+" * two normals\n"
+msgstr ""
+"Mala selección por restricción perpendicular. Esta restricción se puede "
+"aplicar a:\n"
+"\n"
+" * dos segmentos de línea\n"
+" * un segmento de línea y una normal\n"
+" * dos normales\n"
+
+#: constraint.cpp:799
+msgid ""
+"Bad selection for lock point where dragged constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * a point\n"
+msgstr ""
+"Mala selección para el punto de bloqueo donde se arrastró la restricción. "
+"Esta restricción puede aplicar a:\n"
+"\n"
+" * un punto\n"
+
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "NUEVO COMENTARIO -- DOBLE-CLIC PARA EDITAR"
+
+#: constraint.cpp:818
+msgid "click center of comment text"
+msgstr "clic en el centro del texto del comentario"
+
+#: export.cpp:19
+msgid ""
+"No solid model present; draw one with extrudes and revolves, or use Export "
+"2d View to export bare lines and curves."
+msgstr ""
+"No hay un modelo sólido presente; dibuje uno con extrusiones y revoluciones, "
+"o use Exportar Vista 2d para exportar líneas y curvas desnudas."
+
+#: export.cpp:61
+msgid ""
+"Bad selection for export section. Please select:\n"
+"\n"
+" * nothing, with an active workplane (workplane is section plane)\n"
+" * a face (section plane through face)\n"
+" * a point and two line segments (plane through point and parallel to "
+"lines)\n"
+msgstr ""
+"Mala selección para la sección de exportación. Por favor seleccione:\n"
+"\n"
+" * nada, con un plano de trabajo activo (el plano de trabajo es un plano "
+"de sección)\n"
+" * una cara (plano de sección a través de la cara)\n"
+" * un punto y dos segmentos de línea (plano que pasa por el punto y "
+"paralelo a las líneas)\n"
+
+#: export.cpp:818
+msgid "Active group mesh is empty; nothing to export."
+msgstr "La malla del grupo activo está vacía; nada para exportar."
+
+#: exportvector.cpp:336
+msgid "freehand lines were replaced with continuous lines"
+msgstr "Las líneas a mano alzada fueron reemplazadas por líneas continuas."
+
+#: exportvector.cpp:338
+msgid "zigzag lines were replaced with continuous lines"
+msgstr "Las líneas en zigzag fueron reemplazadas por líneas continuas."
+
+#: exportvector.cpp:592
+msgid ""
+"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
+msgstr ""
+"Algunos aspectos del dibujo no tienen equivalente DXF y no se exportaron:\n"
+
+#: exportvector.cpp:838
+msgid ""
+"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
+msgstr ""
+"El tamaño de la página PDF supera las 5080mm x 5080mm; muchos usuarios "
+"pueden rechazar este archivo."
+
+#: file.cpp:44 group.cpp:91
+msgctxt "group-name"
+msgid "sketch-in-plane"
+msgstr "croquis-en-plano"
+
+#: file.cpp:62
+msgctxt "group-name"
+msgid "#references"
+msgstr "#referencias"
+
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr "El archivo esta vacío. Puede estar corrupto."
+
+#: file.cpp:555
+msgid ""
+"Unrecognized data in file. This file may be corrupt, or from a newer version "
+"of the program."
+msgstr ""
+"Datos no reconocidos en el archivo. Este archivo puede estar dañado o ser de "
+"una versión más reciente del programa."
+
+#: file.cpp:867
+msgctxt "title"
+msgid "Missing File"
+msgstr "Archivo perdido"
+
+#: file.cpp:868
+#, c-format
+msgctxt "dialog"
+msgid "The linked file “%s” is not present."
+msgstr "El archivo vinculado “%s” no esta presente."
+
+#: file.cpp:870
+msgctxt "dialog"
+msgid ""
+"Do you want to locate it manually?\n"
+"\n"
+"If you decline, any geometry that depends on the missing file will be "
+"permanently removed."
+msgstr ""
+"¿Quieres localizarlo manualmente?\n"
+"\n"
+"Si lo rechaza, cualquier geometría que dependa del archivo faltante se "
+"eliminará permanentemente."
+
+#: file.cpp:873
+msgctxt "button"
+msgid "&Yes"
+msgstr "&Si"
+
+#: file.cpp:875
+msgctxt "button"
+msgid "&No"
+msgstr "&No"
+
+#: file.cpp:877 solvespace.cpp:611
+msgctxt "button"
+msgid "&Cancel"
+msgstr "&Cancelar"
+
+#: graphicswin.cpp:41
+msgid "&File"
+msgstr "&Archivo"
+
+#: graphicswin.cpp:42
+msgid "&New"
+msgstr "&Nuevo"
+
+#: graphicswin.cpp:43
+msgid "&Open..."
+msgstr "&Abrir..."
+
+#: graphicswin.cpp:44
+msgid "Open &Recent"
+msgstr "Abrir &Reciente"
+
+#: graphicswin.cpp:45
+msgid "&Save"
+msgstr "&Guardar"
+
+#: graphicswin.cpp:46
+msgid "Save &As..."
+msgstr "Guardar &Como..."
+
+#: graphicswin.cpp:48
+msgid "Export &Image..."
+msgstr "Exportar &Imagen..."
+
+#: graphicswin.cpp:49
+msgid "Export 2d &View..."
+msgstr "Exportar 2d &Vista..."
+
+#: graphicswin.cpp:50
+msgid "Export 2d &Section..."
+msgstr "Exportar 2d &Corte..."
+
+#: graphicswin.cpp:51
+msgid "Export 3d &Wireframe..."
+msgstr "Exportar 3d &Estructura alámbrica..."
+
+#: graphicswin.cpp:52
+msgid "Export Triangle &Mesh..."
+msgstr "Exportar Triángulo &Malla..."
+
+#: graphicswin.cpp:53
+msgid "Export &Surfaces..."
+msgstr "Exportar &Superficies..."
+
+#: graphicswin.cpp:54
+msgid "Im&port..."
+msgstr "Im&portar..."
+
+#: graphicswin.cpp:57
+msgid "E&xit"
+msgstr "S&alir"
+
+#: graphicswin.cpp:60
+msgid "&Edit"
+msgstr "&Editar"
+
+#: graphicswin.cpp:61
+msgid "&Undo"
+msgstr "&Deshacer"
+
+#: graphicswin.cpp:62
+msgid "&Redo"
+msgstr "&Rehacer"
+
+#: graphicswin.cpp:63
+msgid "Re&generate All"
+msgstr "Re&generar Todo"
+
+#: graphicswin.cpp:65
+msgid "Snap Selection to &Grid"
+msgstr "Selección Enganche a &Cuadrícula"
+
+#: graphicswin.cpp:66
+msgid "Rotate Imported &90°"
+msgstr "Rotar importado a &90°"
+
+#: graphicswin.cpp:68
+msgid "Cu&t"
+msgstr "Cor&tar"
+
+#: graphicswin.cpp:69
+msgid "&Copy"
+msgstr "&Copiar"
+
+#: graphicswin.cpp:70
+msgid "&Paste"
+msgstr "&Pegar"
+
+#: graphicswin.cpp:71
+msgid "Paste &Transformed..."
+msgstr "Pegar &Тransformar..."
+
+#: graphicswin.cpp:72
+msgid "&Delete"
+msgstr "&Borrar"
+
+#: graphicswin.cpp:74
+msgid "Select &Edge Chain"
+msgstr "Seleccionar Cadena de &Aristas"
+
+#: graphicswin.cpp:75
+msgid "Select &All"
+msgstr "Seleccionar &Todo"
+
+#: graphicswin.cpp:76
+msgid "&Unselect All"
+msgstr "&Deseleccionar Todo"
+
+#: graphicswin.cpp:78
+msgid "&Line Styles..."
+msgstr "Estilos de Línea..."
+
+#: graphicswin.cpp:79
+msgid "&View Projection..."
+msgstr "&Ver Proyección..."
+
+#: graphicswin.cpp:81
+msgid "Con&figuration..."
+msgstr "Con&figuración..."
+
+#: graphicswin.cpp:84
+msgid "&View"
+msgstr "&Vista"
+
+#: graphicswin.cpp:85
+msgid "Zoom &In"
+msgstr "Acer&car"
+
+#: graphicswin.cpp:86
+msgid "Zoom &Out"
+msgstr "Ale&jar"
+
+#: graphicswin.cpp:87
+msgid "Zoom To &Fit"
+msgstr " Enfoque para ajustar"
+
+#: graphicswin.cpp:89
+msgid "Align View to &Workplane"
+msgstr "Alinear Vista a &Plano de trabajo"
+
+#: graphicswin.cpp:90
+msgid "Nearest &Ortho View"
+msgstr "Vista &Ortogonal mas cercana"
+
+#: graphicswin.cpp:91
+msgid "Nearest &Isometric View"
+msgstr "Vista &Isometrica mas cercana"
+
+#: graphicswin.cpp:92
+msgid "&Center View At Point"
+msgstr "&Vista Central en Punto"
+
+#: graphicswin.cpp:94
+msgid "Show Snap &Grid"
+msgstr "Mostrar Enganches &Cuadrícula"
+
+#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+msgstr "Oscurecer Sólidos Inactivos"
+
+#: graphicswin.cpp:96
+msgid "Use &Perspective Projection"
+msgstr "Usar Proyección &Perspectiva"
+
+#: graphicswin.cpp:97
+msgid "Show E&xploded View"
+msgstr ""
+
+#: graphicswin.cpp:98
+msgid "Dimension &Units"
+msgstr "&Unidades de Cota"
+
+#: graphicswin.cpp:99
+msgid "Dimensions in &Millimeters"
+msgstr "Cotas en &Milímetros"
+
+#: graphicswin.cpp:100
+msgid "Dimensions in M&eters"
+msgstr "Cotas en M&etros"
+
+#: graphicswin.cpp:101
+msgid "Dimensions in &Inches"
+msgstr "Cotas en &Pulgadas"
+
+#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr ""
+
+#: graphicswin.cpp:104
+msgid "Show &Toolbar"
+msgstr "Mostrar &Barra de herramientas"
+
+#: graphicswin.cpp:105
+msgid "Show Property Bro&wser"
+msgstr "Mostrar Nave&gador de Propiedades"
+
+#: graphicswin.cpp:107
+msgid "&Full Screen"
+msgstr "&Pantalla Completa"
+
+#: graphicswin.cpp:109
+msgid "&New Group"
+msgstr "&Nuevo Grupo"
+
+#: graphicswin.cpp:110
+msgid "Sketch In &3d"
+msgstr "Сroquis En &3d"
+
+#: graphicswin.cpp:111
+msgid "Sketch In New &Workplane"
+msgstr "Сroquis En Nuevo &Plano de trabajo"
+
+#: graphicswin.cpp:113
+msgid "Step &Translating"
+msgstr "Paso &Traslación"
+
+#: graphicswin.cpp:114
+msgid "Step &Rotating"
+msgstr "Paso &Giratorio"
+
+#: graphicswin.cpp:116
+msgid "E&xtrude"
+msgstr "E&xtrusión"
+
+#: graphicswin.cpp:117
+msgid "&Helix"
+msgstr "&Hélice"
+
+#: graphicswin.cpp:118
+msgid "&Lathe"
+msgstr "&Torno"
+
+#: graphicswin.cpp:119
+msgid "Re&volve"
+msgstr "Re&volución"
+
+#: graphicswin.cpp:121
+msgid "Link / Assemble..."
+msgstr "Enlace / Ensamblar..."
+
+#: graphicswin.cpp:122
+msgid "Link Recent"
+msgstr "Enlace Reciente"
+
+#: graphicswin.cpp:124
+msgid "&Sketch"
+msgstr "&Croquis"
+
+#: graphicswin.cpp:125
+msgid "In &Workplane"
+msgstr "En &Plano de trabajo"
+
+#: graphicswin.cpp:126
+msgid "Anywhere In &3d"
+msgstr "En cualquier lugar en &3d"
+
+#: graphicswin.cpp:128
+msgid "Datum &Point"
+msgstr "Referencia &Punto"
+
+#: graphicswin.cpp:129
+msgid "&Workplane"
+msgstr "&Plano de trabajo"
+
+#: graphicswin.cpp:131
+msgid "Line &Segment"
+msgstr "Línea &Segmento"
+
+#: graphicswin.cpp:132
+msgid "C&onstruction Line Segment"
+msgstr "S&egmento de Línea de Construcción"
+
+#: graphicswin.cpp:133
+msgid "&Rectangle"
+msgstr "&Rectángulo"
+
+#: graphicswin.cpp:134
+msgid "&Circle"
+msgstr "&Círculo"
+
+#: graphicswin.cpp:135
+msgid "&Arc of a Circle"
+msgstr "&Arco de un Círculo"
+
+#: graphicswin.cpp:136
+msgid "&Bezier Cubic Spline"
+msgstr "&Spline Cúbico de Bezier"
+
+#: graphicswin.cpp:138
+msgid "&Text in TrueType Font"
+msgstr "&Texto en Fuente TrueType"
+
+#: graphicswin.cpp:139
+msgid "&Image"
+msgstr "&Imagen"
+
+#: graphicswin.cpp:141
+msgid "To&ggle Construction"
+msgstr "Al&ternar Construcción"
+
+#: graphicswin.cpp:142
+msgid "Tangent &Arc at Point"
+msgstr "Tangente &Arco en el Punto"
+
+#: graphicswin.cpp:143
+msgid "Split Curves at &Intersection"
+msgstr "Dividir Curvas en &Intersección"
+
+#: graphicswin.cpp:145
+msgid "&Constrain"
+msgstr "&Restricción"
+
+#: graphicswin.cpp:146
+msgid "&Distance / Diameter"
+msgstr "&Distancia / Diámetro"
+
+#: graphicswin.cpp:147
+msgid "Re&ference Dimension"
+msgstr "Co&ta de Referencia"
+
+#: graphicswin.cpp:148
+msgid "A&ngle"
+msgstr "Á&ngulo"
+
+#: graphicswin.cpp:149
+msgid "Reference An&gle"
+msgstr "Ángulo de Re&ferencia"
+
+#: graphicswin.cpp:150
+msgid "Other S&upplementary Angle"
+msgstr "Otro Á&ngulo Suplementario"
+
+#: graphicswin.cpp:151
+msgid "Toggle R&eference Dim"
+msgstr "Alternar C&ota Referencia"
+
+#: graphicswin.cpp:153
+msgid "&Horizontal"
+msgstr "&Horizontal"
+
+#: graphicswin.cpp:154
+msgid "&Vertical"
+msgstr "&Vertical"
+
+#: graphicswin.cpp:156
+msgid "&On Point / Curve / Plane"
+msgstr "&Sobre Punto / Curva / Plano"
+
+#: graphicswin.cpp:157
+msgid "E&qual Length / Radius / Angle"
+msgstr "I&gual Longitud / Radio / Ángulo"
+
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr ""
+
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr ""
+
+#: graphicswin.cpp:160
+msgid "At &Midpoint"
+msgstr "En &PuntoMedio"
+
+#: graphicswin.cpp:161
+msgid "S&ymmetric"
+msgstr "S&imetría"
+
+#: graphicswin.cpp:162
+msgid "Para&llel / Tangent"
+msgstr "Para&lela / Tangente"
+
+#: graphicswin.cpp:163
+msgid "&Perpendicular"
+msgstr "&Perpendicular"
+
+#: graphicswin.cpp:164
+msgid "Same Orient&ation"
+msgstr "Misma Orient&ación"
+
+#: graphicswin.cpp:165
+msgid "Lock Point Where &Dragged"
+msgstr "Punto de Bloqueo Donde &Arrastrado"
+
+#: graphicswin.cpp:167
+msgid "Comment"
+msgstr "Comentario"
+
+#: graphicswin.cpp:169
+msgid "&Analyze"
+msgstr "&Analizar"
+
+#: graphicswin.cpp:170
+msgid "Measure &Volume"
+msgstr "Medición &Volumen"
+
+#: graphicswin.cpp:171
+msgid "Measure A&rea"
+msgstr "Medición Á&rea"
+
+#: graphicswin.cpp:172
+msgid "Measure &Perimeter"
+msgstr "Medición &Perímetro"
+
+#: graphicswin.cpp:173
+msgid "Show &Interfering Parts"
+msgstr "Mostrar &Piezas que Interfieren"
+
+#: graphicswin.cpp:174
+msgid "Show &Naked Edges"
+msgstr "Mostrar &Aristas Desnudas"
+
+#: graphicswin.cpp:175
+msgid "Show &Center of Mass"
+msgstr "Mostrar &Centro de Masa"
+
+#: graphicswin.cpp:177
+msgid "Show &Underconstrained Points"
+msgstr "Mostrar &Puntos Subrestringidos"
+
+#: graphicswin.cpp:179
+msgid "&Trace Point"
+msgstr "&Punto de Rastro"
+
+#: graphicswin.cpp:180
+msgid "&Stop Tracing..."
+msgstr "&Dejar de rastrear..."
+
+#: graphicswin.cpp:181
+msgid "Step &Dimension..."
+msgstr "Cota &Paso..."
+
+#: graphicswin.cpp:183
+msgid "&Help"
+msgstr "&Ayuda"
+
+#: graphicswin.cpp:184
+msgid "&Language"
+msgstr "&Lenguaje"
+
+#: graphicswin.cpp:185
+msgid "&Website / Manual"
+msgstr "&Sitio Web / Manual"
+
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr ""
+
+#: graphicswin.cpp:188
+msgid "&About"
+msgstr "&Acerca"
+
+#: graphicswin.cpp:362
+msgid "(no recent files)"
+msgstr "(no hay archivos recientes)"
+
+#: graphicswin.cpp:370
+#, c-format
+msgid "File '%s' does not exist."
+msgstr "El archivo '%s' no existe."
+
+#: graphicswin.cpp:737
+msgid "No workplane is active, so the grid will not appear."
+msgstr ""
+"No hay ningún plano de trabajo activo, por lo que la cuadrícula no aparecerá."
+
+#: graphicswin.cpp:752
+msgid ""
+"The perspective factor is set to zero, so the view will always be a parallel "
+"projection.\n"
+"\n"
+"For a perspective projection, modify the perspective factor in the "
+"configuration screen. A value around 0.3 is typical."
+msgstr ""
+"El factor de perspectiva se establece en cero, por lo que la vista siempre "
+"será una proyección paralela.\n"
+"\n"
+"Para una proyección en perspectiva, modifique el factor de perspectiva en la "
+"pantalla de configuración. Un valor de alrededor de 0,3 es típico."
+
+#: graphicswin.cpp:837
+msgid ""
+"Select a point; this point will become the center of the view on screen."
+msgstr ""
+"Seleccione un punto; este punto se convertirá en el centro de la vista en "
+"pantalla."
+
+#: graphicswin.cpp:1137
+msgid "No additional entities share endpoints with the selected entities."
+msgstr ""
+"Ninguna entidad adicional comparte puntos finales con las entidades "
+"seleccionadas."
+
+#: graphicswin.cpp:1155
+msgid ""
+"To use this command, select a point or other entity from an linked part, or "
+"make a link group the active group."
+msgstr ""
+"Para usar este comando, seleccione un punto u otra entidad de una parte "
+"vinculada, o convertir un grupo de enlaces en el grupo activo."
+
+#: graphicswin.cpp:1178
+msgid ""
+"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
+"to define the plane for the snap grid."
+msgstr ""
+"No hay ningún plano de trabajo activo. Activar un plano de trabajo (con "
+"Croquis -> En plano de trabajo) para definir el plano para el enganche a la "
+"cuadrícula."
+
+#: graphicswin.cpp:1185
+msgid ""
+"Can't snap these items to grid; select points, text comments, or constraints "
+"with a label. To snap a line, select its endpoints."
+msgstr ""
+"No se pueden enganchar estos elementos a la cuadrícula; seleccionar puntos, "
+"comentarios de texto o restricciones con una etiqueta. Para enganchar una "
+"línea, seleccione sus puntos finales."
+
+#: graphicswin.cpp:1270
+msgid "No workplane selected. Activating default workplane for this group."
+msgstr ""
+"No se seleccionó ningún plano de trabajo. Activando el plano de trabajo "
+"predeterminado para este grupo."
+
+#: graphicswin.cpp:1273
+msgid ""
+"No workplane is selected, and the active group does not have a default "
+"workplane. Try selecting a workplane, or activating a sketch-in-new-"
+"workplane group."
+msgstr ""
+"No se selecciona ningún plano de trabajo y el grupo activo no tiene un plano "
+"de trabajo. Intente seleccionar un plano de trabajo o activar un croquis-en-"
+"nuevo-grupo de plano de trabajo."
+
+#: graphicswin.cpp:1294
+msgid ""
+"Bad selection for tangent arc at point. Select a single point, or select "
+"nothing to set up arc parameters."
+msgstr ""
+"Mala selección de arco tangente en el punto. Seleccione un solo punto o no "
+"seleccione nada para configurar los parámetros del arco."
+
+#: graphicswin.cpp:1305
+msgid "click point on arc (draws anti-clockwise)"
+msgstr "clic en el punto en el arco (dibuja en sentido antihorario)"
+
+#: graphicswin.cpp:1306
+msgid "click to place datum point"
+msgstr "clic para colocar el punto de referencia"
+
+#: graphicswin.cpp:1307
+msgid "click first point of line segment"
+msgstr "clic en el primer punto del segmento de línea"
+
+#: graphicswin.cpp:1309
+msgid "click first point of construction line segment"
+msgstr "clic en el primer punto del segmento de línea de construcción"
+
+#: graphicswin.cpp:1310
+msgid "click first point of cubic segment"
+msgstr "clic en el primer punto del segmento cúbico"
+
+#: graphicswin.cpp:1311
+msgid "click center of circle"
+msgstr "clic en el centro del círculo"
+
+#: graphicswin.cpp:1312
+msgid "click origin of workplane"
+msgstr "clic en origen del plano de trabajo"
+
+#: graphicswin.cpp:1313
+msgid "click one corner of rectangle"
+msgstr "clic en una esquina del rectángulo"
+
+#: graphicswin.cpp:1314
+msgid "click top left of text"
+msgstr "clic en la parte superior izquierda del texto"
+
+#: graphicswin.cpp:1320
+msgid "click top left of image"
+msgstr "clic en la parte superior izquierda de la imagen"
+
+#: graphicswin.cpp:1346
+msgid ""
+"No entities are selected. Select entities before trying to toggle their "
+"construction state."
+msgstr ""
+"No se seleccionaron entidades. Seleccione entidades antes de intentar "
+"alternar su estado de construcción."
+
+#: group.cpp:86
+msgctxt "group-name"
+msgid "sketch-in-3d"
+msgstr "croquis-en-3d"
+
+#: group.cpp:150
+msgid ""
+"Bad selection for new sketch in workplane. This group can be created with:\n"
+"\n"
+" * a point (through the point, orthogonal to coordinate axes)\n"
+" * a point and two line segments (through the point, parallel to the "
+"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
+" * a workplane (copy of the workplane)\n"
+msgstr ""
+
+#: group.cpp:166
+msgid ""
+"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
+"will be extruded normal to the workplane."
+msgstr ""
+"Active un plano de trabajo (Croquis -> En plano de trabajo) antes de "
+"extruir. El croquis se extruirá normal al plano de trabajo."
+
+#: group.cpp:175
+msgctxt "group-name"
+msgid "extrude"
+msgstr "extruir"
+
+#: group.cpp:180
+msgid "Lathe operation can only be applied to planar sketches."
+msgstr "La operación de torno solo se puede aplicar a croquis planos."
+
+#: group.cpp:191
+msgid ""
+"Bad selection for new lathe group. This group can be created with:\n"
+"\n"
+" * a point and a line segment or normal (revolved about an axis parallel "
+"to line / normal, through point)\n"
+" * a line segment (revolved about line segment)\n"
+msgstr ""
+"Mala selección para el nuevo grupo de torno. Este grupo se puede crear con:\n"
+"\n"
+" * un punto y un segmento de línea o normal (revolucionado alrededor de "
+"un eje paralelo a la línea / normal, a través del punto)\n"
+" * un segmento de línea (revolucionado sobre un segmento de línea)\n"
+
+#: group.cpp:201
+msgctxt "group-name"
+msgid "lathe"
+msgstr "torno"
+
+#: group.cpp:206
+msgid "Revolve operation can only be applied to planar sketches."
+msgstr "La operación de revolución solo se puede aplicar a croquis planos."
+
+#: group.cpp:217
+msgid ""
+"Bad selection for new revolve group. This group can be created with:\n"
+"\n"
+" * a point and a line segment or normal (revolved about an axis parallel "
+"to line / normal, through point)\n"
+" * a line segment (revolved about line segment)\n"
+msgstr ""
+"Mala selección para el nuevo grupo de revolución. Este grupo se puede crear "
+"con:\n"
+"\n"
+" * un punto y un segmento de línea o normal (revolucionado alrededor de "
+"un eje paralelo a la línea / normal, a través del punto)\n"
+" * un segmento de línea (revolucionado sobre un segmento de línea)\n"
+
+#: group.cpp:229
+msgctxt "group-name"
+msgid "revolve"
+msgstr "revolución"
+
+#: group.cpp:234
+msgid "Helix operation can only be applied to planar sketches."
+msgstr "La operación de hélice solo se puede aplicar a croquis planos."
+
+#: group.cpp:245
+msgid ""
+"Bad selection for new helix group. This group can be created with:\n"
+"\n"
+" * a point and a line segment or normal (revolved about an axis parallel "
+"to line / normal, through point)\n"
+" * a line segment (revolved about line segment)\n"
+msgstr ""
+"Mala selección para el nuevo grupo de hélice. Este grupo se puede crear "
+"con:\n"
+"\n"
+" * un punto y un segmento de recta o normal (girado alrededor de un eje "
+"paralelo a la línea / normal, a través del punto)\n"
+" * un segmento de línea (girado sobre un segmento de línea)\n"
+
+#: group.cpp:257
+msgctxt "group-name"
+msgid "helix"
+msgstr "hélice"
+
+#: group.cpp:270
+msgid ""
+"Bad selection for new rotation. This group can be created with:\n"
+"\n"
+" * a point, while locked in workplane (rotate in plane, about that "
+"point)\n"
+" * a point and a line or a normal (rotate about an axis through the "
+"point, and parallel to line / normal)\n"
+msgstr ""
+"Mala selección para nueva rotación. Este grupo se puede crear con:\n"
+"\n"
+" * un punto, mientras está bloqueado en el plano de trabajo (girar en el "
+"plano, sobre ese punto)\n"
+" * un punto y una línea o una normal (rotar alrededor de un eje a través "
+"de un punto y paralela a la línea / normal)\n"
+
+#: group.cpp:283
+msgctxt "group-name"
+msgid "rotate"
+msgstr "rotar"
+
+#: group.cpp:294
+msgctxt "group-name"
+msgid "translate"
+msgstr "trasladar"
+
+#: group.cpp:416
+msgid "(unnamed)"
+msgstr "(sin nombre)"
+
+#: groupmesh.cpp:707
+msgid "not closed contour, or not all same style!"
+msgstr "¡Contorno no cerrado, o no todos del mismo estilo!"
+
+#: groupmesh.cpp:720
+msgid "points not all coplanar!"
+msgstr "¡No todos los puntos son coplanares!"
+
+#: groupmesh.cpp:722
+msgid "contour is self-intersecting!"
+msgstr "¡El contorno se intersecta a sí mismo!"
+
+#: groupmesh.cpp:724
+msgid "zero-length edge!"
+msgstr "¡arista de longitud cero!"
+
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr ""
+
+#: modify.cpp:252
+msgid "Must be sketching in workplane to create tangent arc."
+msgstr ""
+"Debe estar dibujando en el plano de trabajo para crear un arco tangente."
+
+#: modify.cpp:299
+msgid ""
+"To create a tangent arc, select a point where two non-construction lines or "
+"circles in this group and workplane join."
+msgstr ""
+"Para crear un arco tangente, seleccione un punto donde dos líneas que no "
+"sean de construcción o los círculos de este grupo y el plano de trabajo se "
+"unen."
+
+#: modify.cpp:386
+msgid ""
+"Couldn't round this corner. Try a smaller radius, or try creating the "
+"desired geometry by hand with tangency constraints."
+msgstr ""
+"No pude redondear esta esquina. Pruebe con un radio más pequeño o intente "
+"crear la geometría deseada a mano con restricciones de tangencia."
+
+#: modify.cpp:595
+msgid "Couldn't split this entity; lines, circles, or cubics only."
+msgstr "No se pudo dividir esta entidad; solo líneas, círculos o cúbicos."
+
+#: modify.cpp:622
+msgid "Must be sketching in workplane to split."
+msgstr "Debe estar dibujando en el plano de trabajo para dividir."
+
+#: modify.cpp:629
+msgid ""
+"Select two entities that intersect each other (e.g. two lines/circles/arcs "
+"or a line/circle/arc and a point)."
+msgstr ""
+"Seleccione dos entidades que se crucen entre sí (por ejemplo, dos líneas / "
+"círculos / arcos o una línea / círculo / arco y un punto)."
+
+#: modify.cpp:734
+msgid "Can't split; no intersection found."
+msgstr "No se puede dividir; no se encontró ninguna intersección."
+
+#: mouse.cpp:557
+msgid "Assign to Style"
+msgstr "Asignar a Estilo"
+
+#: mouse.cpp:573
+msgid "No Style"
+msgstr "Sin Estilo"
+
+#: mouse.cpp:576
+msgid "Newly Created Custom Style..."
+msgstr "Estilo Personalizado Recién Creado..."
+
+#: mouse.cpp:583
+msgid "Group Info"
+msgstr "Información de Grupo"
+
+#: mouse.cpp:603
+msgid "Style Info"
+msgstr "Información de Estilo"
+
+#: mouse.cpp:623
+msgid "Select Edge Chain"
+msgstr "Seleccionar Cadena de Arista"
+
+#: mouse.cpp:629
+msgid "Toggle Reference Dimension"
+msgstr "Alternar Cota de Referencia"
+
+#: mouse.cpp:635
+msgid "Other Supplementary Angle"
+msgstr "Otro Ángulo Suplementario"
+
+#: mouse.cpp:640
+msgid "Snap to Grid"
+msgstr "Enganchar a la cuadrícula"
+
+#: mouse.cpp:649
+msgid "Remove Spline Point"
+msgstr "Remover Punto de Spline"
+
+#: mouse.cpp:684
+msgid "Add Spline Point"
+msgstr "Agregar Punto de Spline"
+
+#: mouse.cpp:688
+msgid "Cannot add spline point: maximum number of points reached."
+msgstr ""
+"No se puede agregar un punto de spline: se alcanzó el número máximo de "
+"puntos."
+
+#: mouse.cpp:713
+msgid "Toggle Construction"
+msgstr "Alternar Construcción"
+
+#: mouse.cpp:729
+msgid "Delete Point-Coincident Constraint"
+msgstr "Eliminar restricción de punto-coincidente"
+
+#: mouse.cpp:747
+msgid "Cut"
+msgstr "Cortar"
+
+#: mouse.cpp:749
+msgid "Copy"
+msgstr "Copiar"
+
+#: mouse.cpp:753
+msgid "Select All"
+msgstr "Seleccionar Todo "
+
+#: mouse.cpp:758
+msgid "Paste"
+msgstr "Pegar"
+
+#: mouse.cpp:760
+msgid "Paste Transformed..."
+msgstr "Pegar Transformado ..."
+
+#: mouse.cpp:765
+msgid "Delete"
+msgstr "Eliminar"
+
+#: mouse.cpp:768
+msgid "Unselect All"
+msgstr "Deseleccionar Todo"
+
+#: mouse.cpp:775
+msgid "Unselect Hovered"
+msgstr "Deselección Flotante"
+
+#: mouse.cpp:784
+msgid "Zoom to Fit"
+msgstr "Zoom para ajustar"
+
+#: mouse.cpp:986 mouse.cpp:1274
+msgid "click next point of line, or press Esc"
+msgstr "clic en el siguiente punto de la línea o presione Esc"
+
+#: mouse.cpp:992
+msgid ""
+"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"No se puede dibujar un rectángulo en 3d; primero, active un plano de trabajo "
+"con Croquis -> En Plano de trabajo."
+
+#: mouse.cpp:1026
+msgid "click to place other corner of rectangle"
+msgstr "clic para colocar la otra esquina del rectángulo"
+
+#: mouse.cpp:1047
+msgid "click to set radius"
+msgstr "clic para establecer el radio"
+
+#: mouse.cpp:1052
+msgid ""
+"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"No se puede dibujar un arco en 3d; primero, active un plano de trabajo con "
+"Croquis -> En Plano de trabajo."
+
+#: mouse.cpp:1071
+msgid "click to place point"
+msgstr "clic para colocar el punto"
+
+#: mouse.cpp:1087
+msgid "click next point of cubic, or press Esc"
+msgstr "clic en el siguiente punto del cúbico, o presione Esc"
+
+#: mouse.cpp:1092
+msgid ""
+"Sketching in a workplane already; sketch in 3d before creating new workplane."
+msgstr ""
+"Dibujando en un plano de trabajo ya; croquis en 3d antes de crear un nuevo "
+"plano de trabajo."
+
+#: mouse.cpp:1108
+msgid ""
+"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"No se puede dibujar texto en 3D; primero, active un plano de trabajo con "
+"Croquis -> En Plano de trabajo."
+
+#: mouse.cpp:1125
+msgid "click to place bottom right of text"
+msgstr "clic para colocar la parte inferior derecha del texto"
+
+#: mouse.cpp:1131
+msgid ""
+"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"No se puede dibujar una imagen en 3D; primero, active un plano de trabajo "
+"con Croquis -> En Plano de Trabajo."
+
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
+msgctxt "file-type"
+msgid "SolveSpace models"
+msgstr "SolveSpace modelos"
+
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr ""
+
+#: platform/gui.cpp:91
+msgctxt "file-type"
+msgid "IDF circuit board"
+msgstr "placa circuito IDF"
+
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr ""
+
+#: platform/gui.cpp:96
+msgctxt "file-type"
+msgid "PNG image"
+msgstr "imagen PNG"
+
+#: platform/gui.cpp:100
+msgctxt "file-type"
+msgid "STL mesh"
+msgstr "STL malla"
+
+#: platform/gui.cpp:101
+msgctxt "file-type"
+msgid "Wavefront OBJ mesh"
+msgstr "Wavefront OBJ malla"
+
+#: platform/gui.cpp:102
+msgctxt "file-type"
+msgid "Three.js-compatible mesh, with viewer"
+msgstr "Three.js-malla compatible, con visor"
+
+#: platform/gui.cpp:103
+msgctxt "file-type"
+msgid "Three.js-compatible mesh, mesh only"
+msgstr "Three.js-malla compatible, solo malla"
+
+#: platform/gui.cpp:104
+msgctxt "file-type"
+msgid "VRML text file"
+msgstr "Archivo texto VRML"
+
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
+msgctxt "file-type"
+msgid "STEP file"
+msgstr "Archivo STEP"
+
+#: platform/gui.cpp:112
+msgctxt "file-type"
+msgid "PDF file"
+msgstr "Archivo PDF"
+
+#: platform/gui.cpp:113
+msgctxt "file-type"
+msgid "Encapsulated PostScript"
+msgstr "Encapsulado PostScript"
+
+#: platform/gui.cpp:114
+msgctxt "file-type"
+msgid "Scalable Vector Graphics"
+msgstr "Gráficos Vectoriales Escalables"
+
+#: platform/gui.cpp:116 platform/gui.cpp:123
+msgctxt "file-type"
+msgid "DXF file (AutoCAD 2007)"
+msgstr "Archivo DXF (AutoCAD 2007)"
+
+#: platform/gui.cpp:117
+msgctxt "file-type"
+msgid "HPGL file"
+msgstr "Archivo HPGL"
+
+#: platform/gui.cpp:118
+msgctxt "file-type"
+msgid "G Code"
+msgstr "G Code"
+
+#: platform/gui.cpp:127
+msgctxt "file-type"
+msgid "AutoCAD DXF and DWG files"
+msgstr "Archivos AutoCAD DXF y DWG"
+
+#: platform/gui.cpp:131
+msgctxt "file-type"
+msgid "Comma-separated values"
+msgstr "Valores separados por comas"
+
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
+msgid "untitled"
+msgstr "sin título"
+
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
+msgctxt "title"
+msgid "Save File"
+msgstr "Guardar Archivo"
+
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
+msgctxt "title"
+msgid "Open File"
+msgstr "Abrir Archivo"
+
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
+msgctxt "button"
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
+msgctxt "button"
+msgid "_Save"
+msgstr "_Guardar"
+
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
+msgctxt "button"
+msgid "_Open"
+msgstr "_Abrir"
+
+#: solvespace.cpp:171
+msgctxt "title"
+msgid "Autosave Available"
+msgstr "Autoguardado Disponible"
+
+#: solvespace.cpp:172
+msgctxt "dialog"
+msgid "An autosave file is available for this sketch."
+msgstr "Un archivo de autoguardado está disponible para este croquis."
+
+#: solvespace.cpp:173
+msgctxt "dialog"
+msgid "Do you want to load the autosave file instead?"
+msgstr "¿Desea cargar el archivo de autoguardado en su lugar?"
+
+#: solvespace.cpp:174
+msgctxt "button"
+msgid "&Load autosave"
+msgstr "&Cargar autoguardado"
+
+#: solvespace.cpp:176
+msgctxt "button"
+msgid "Do&n't Load"
+msgstr "No Cargar"
+
+#: solvespace.cpp:599
+msgctxt "title"
+msgid "Modified File"
+msgstr "Archivo Modificado"
+
+#: solvespace.cpp:601
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr "¿Desea guardar los cambios que realizó en el croquis “%s”?"
+
+#: solvespace.cpp:604
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr "¿Desea guardar los cambios que realizó en el nuevo croquis?"
+
+#: solvespace.cpp:607
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr "Sus cambios se perderán si no los guarda."
+
+#: solvespace.cpp:608
+msgctxt "button"
+msgid "&Save"
+msgstr "&Guardar"
+
+#: solvespace.cpp:610
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr "No& Guardar"
+
+#: solvespace.cpp:631
+msgctxt "title"
+msgid "(new sketch)"
+msgstr "(nuevo croquis)"
+
+#: solvespace.cpp:638
+msgctxt "title"
+msgid "Property Browser"
+msgstr "Explorador de Propiedades"
+
+#: solvespace.cpp:700
+msgid ""
+"Constraints are currently shown, and will be exported in the toolpath. This "
+"is probably not what you want; hide them by clicking the link at the top of "
+"the text window."
+msgstr ""
+"Las restricciones se muestran actualmente y se exportarán en la trayectoria."
+"Probablemente esto no sea lo que quieres; ocultarlos haciendo clic en el "
+"enlace en la parte superior de la ventana de texto."
+
+#: solvespace.cpp:772
+#, c-format
+msgid ""
+"Can't identify file type from file extension of filename '%s'; try .dxf or ."
+"dwg."
+msgstr ""
+"No se puede identificar el tipo de archivo a partir de la extensión del "
+"nombre del archivo '%s'; intente .dxf o .dwg."
+
+#: solvespace.cpp:824
+msgid "Constraint must have a label, and must not be a reference dimension."
+msgstr ""
+"La restricción debe tener una etiqueta y no debe ser una cota de referencia."
+
+#: solvespace.cpp:828
+msgid "Bad selection for step dimension; select a constraint."
+msgstr "Mala selección para la cota del paso; seleccione una restricción."
+
+#: solvespace.cpp:852
+msgid "The assembly does not interfere, good."
+msgstr "El ensamble no interfiere, bien."
+
+#: solvespace.cpp:868
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+"El volumen del modelo sólido es:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:877
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+"\n"
+"El volumen de la malla del grupo actual es:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:882
+msgid ""
+"\n"
+"\n"
+"Curved surfaces have been approximated as triangles.\n"
+"This introduces error, typically of around 1%."
+msgstr ""
+"\n"
+"\n"
+"Las superficies curvas se han aproximado como triángulos.\n"
+"Esto introduce un error, normalmente alrededor del 1%."
+
+#: solvespace.cpp:897
+#, c-format
+msgid ""
+"The surface area of the selected faces is:\n"
+"\n"
+" %s\n"
+"\n"
+"Curves have been approximated as piecewise linear.\n"
+"This introduces error, typically of around 1%%."
+msgstr ""
+"El área de la superficie de las caras seleccionadas es:\n"
+"\n"
+" %s\n"
+"\n"
+"Las curvas se han aproximado como lineales por partes.\n"
+"Esto introduce un error, normalmente alrededor del 1%%."
+
+#: solvespace.cpp:906
+msgid ""
+"This group does not contain a correctly-formed 2d closed area. It is open, "
+"not coplanar, or self-intersecting."
+msgstr ""
+"Este grupo no contiene un área cerrada 2d correctamente formada. Está "
+"abierta, no coplanares, ni auto-intersectantes."
+
+#: solvespace.cpp:918
+#, c-format
+msgid ""
+"The area of the region sketched in this group is:\n"
+"\n"
+" %s\n"
+"\n"
+"Curves have been approximated as piecewise linear.\n"
+"This introduces error, typically of around 1%%."
+msgstr ""
+"El área de la región croquizada en este grupo es:\n"
+"\n"
+" %s\n"
+"\n"
+"Las curvas se han aproximado como lineales por partes.\n"
+"Esto introduce un error, normalmente alrededor del 1%%."
+
+#: solvespace.cpp:938
+#, c-format
+msgid ""
+"The total length of the selected entities is:\n"
+"\n"
+" %s\n"
+"\n"
+"Curves have been approximated as piecewise linear.\n"
+"This introduces error, typically of around 1%%."
+msgstr ""
+"La longitud total de las entidades seleccionadas es:\n"
+"\n"
+" %s\n"
+"\n"
+"Las curvas se han aproximado como lineales por partes.\n"
+"Esto introduce un error, normalmente alrededor del 1%%."
+
+#: solvespace.cpp:944
+msgid "Bad selection for perimeter; select line segments, arcs, and curves."
+msgstr ""
+"Mala selección de perímetro; seleccione segmentos de línea, arcos y curvas."
+
+#: solvespace.cpp:960
+msgid "Bad selection for trace; select a single point."
+msgstr "Mala selección de rastreo; seleccione un solo punto."
+
+#: solvespace.cpp:987
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr "No pude escribir a '%s'"
+
+#: solvespace.cpp:1017
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr "La malla se intersecta a si misma (NO está bien, no es válida)."
+
+#: solvespace.cpp:1018
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr "La malla no se intersecta (está bien, es válida)."
+
+#: solvespace.cpp:1020
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr "La malla tiene bordes desnudos (NO está bien, no es válida)."
+
+#: solvespace.cpp:1021
+msgid "The mesh is watertight (okay, valid)."
+msgstr "La malla es estanca (está bien, es válida)."
+
+#: solvespace.cpp:1024
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+"\n"
+"\n"
+"El modelo contiene %d triángulos, desde %d superficies."
+
+#: solvespace.cpp:1028
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Cero aristas problemáticas, bien.%s"
+
+#: solvespace.cpp:1031
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d problematic edges, bad.%s"
+msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d aristas problemáticas, mal.%s"
+
+#: solvespace.cpp:1044
+#, c-format
+msgid ""
+"This is SolveSpace version %s.\n"
+"\n"
+"For more information, see http://solvespace.com/\n"
+"\n"
+"SolveSpace is free software: you are free to modify\n"
+"and/or redistribute it under the terms of the GNU\n"
+"General Public License (GPL) version 3 or later.\n"
+"\n"
+"There is NO WARRANTY, to the extent permitted by\n"
+"law. For details, visit http://gnu.org/licenses/\n"
+"\n"
+"© 2008-%d Jonathan Westhues and other authors.\n"
+msgstr ""
+"Esta es la versión de SolveSpace %s.\n"
+"\n"
+"Para más información, ver http://solvespace.com/\n"
+"\n"
+"SolveSpace es software libre: eres libre de modificarlo\n"
+"y/o redistribuirlo bajo los términos de la GNU\n"
+"Licencia Pública General (GPL) version 3 o posterior.\n"
+"\n"
+"NO HAY GARANTÍA, en la medida permitida por\n"
+"ley. Para detalles, visita http://gnu.org/licenses/\n"
+"\n"
+"© 2008-%d Jonathan Westhues y otros autores.\n"
+
+#: style.cpp:185
+msgid ""
+"Can't assign style to an entity that's derived from another entity; try "
+"assigning a style to this entity's parent."
+msgstr ""
+"No se puede asignar estilo a una entidad derivada de otra entidad;; intente "
+"asignar un estilo al padre de esta entidad."
+
+#: style.cpp:735
+msgid "Style name cannot be empty"
+msgstr "El nombre del estilo no puede estar vacío"
+
+#: textscreens.cpp:791
+msgid "Can't repeat fewer than 1 time."
+msgstr "No se puede repetir menos de 1 vez."
+
+#: textscreens.cpp:795
+msgid "Can't repeat more than 999 times."
+msgstr "No se puede repetir más de 999 veces."
+
+#: textscreens.cpp:820
+msgid "Group name cannot be empty"
+msgstr "El nombre del grupo no puede estar vacío"
+
+#: textscreens.cpp:872
+msgid "Opacity must be between zero and one."
+msgstr "La opacidad debe estar entre cero y uno."
+
+#: textscreens.cpp:907
+msgid "Radius cannot be zero or negative."
+msgstr "El radio no puede ser cero o negativo."
+
+#: toolbar.cpp:18
+msgid "Sketch line segment"
+msgstr "Croquizar segmento de línea"
+
+#: toolbar.cpp:20
+msgid "Sketch rectangle"
+msgstr "Croquizar rectángulo"
+
+#: toolbar.cpp:22
+msgid "Sketch circle"
+msgstr "Croquizar círculo"
+
+#: toolbar.cpp:24
+msgid "Sketch arc of a circle"
+msgstr "Croquizar arco de un círculo"
+
+#: toolbar.cpp:26
+msgid "Sketch curves from text in a TrueType font"
+msgstr "Croquizar curvas desde texto en fuente TrueType"
+
+#: toolbar.cpp:28
+msgid "Sketch image from a file"
+msgstr "Croquizar imagen desde un archivo"
+
+#: toolbar.cpp:30
+msgid "Create tangent arc at selected point"
+msgstr "Crear arco tangente en el punto seleccionado"
+
+#: toolbar.cpp:32
+msgid "Sketch cubic Bezier spline"
+msgstr "Croquizar spline de Bezier cúbico"
+
+#: toolbar.cpp:34
+msgid "Sketch datum point"
+msgstr "Croquizar punto de referencia"
+
+#: toolbar.cpp:36
+msgid "Toggle construction"
+msgstr "Alternar construcción"
+
+#: toolbar.cpp:38
+msgid "Split lines / curves where they intersect"
+msgstr "Dividir líneas / curvas donde se intersectan"
+
+#: toolbar.cpp:42
+msgid "Constrain distance / diameter / length"
+msgstr "Restringir distancia / diámetro / longitud"
+
+#: toolbar.cpp:44
+msgid "Constrain angle"
+msgstr "Restringir ángulo"
+
+#: toolbar.cpp:46
+msgid "Constrain to be horizontal"
+msgstr "Restringir para ser horizontal"
+
+#: toolbar.cpp:48
+msgid "Constrain to be vertical"
+msgstr "Restringir para ser vertical"
+
+#: toolbar.cpp:50
+msgid "Constrain to be parallel or tangent"
+msgstr "Restringir para ser paralela o tangente"
+
+#: toolbar.cpp:52
+msgid "Constrain to be perpendicular"
+msgstr "Restringir para ser perpendicular"
+
+#: toolbar.cpp:54
+msgid "Constrain point on line / curve / plane / point"
+msgstr "Restringir punto en línea / curva / plano / punto"
+
+#: toolbar.cpp:56
+msgid "Constrain symmetric"
+msgstr "Restringir simétrico"
+
+#: toolbar.cpp:58
+msgid "Constrain equal length / radius / angle"
+msgstr "Restringir igualdad longitud / radio / ángulo"
+
+#: toolbar.cpp:60
+msgid "Constrain normals in same orientation"
+msgstr "Restringir normales en la misma orientación"
+
+#: toolbar.cpp:62
+msgid "Other supplementary angle"
+msgstr "Otro ángulo suplementario"
+
+#: toolbar.cpp:64
+msgid "Toggle reference dimension"
+msgstr "Alternar cota de referencia"
+
+#: toolbar.cpp:68
+msgid "New group extruding active sketch"
+msgstr "Nuevo grupo de extrusión de croquis activo"
+
+#: toolbar.cpp:70
+msgid "New group rotating active sketch"
+msgstr "Nuevo croquis activo giratorio de grupo"
+
+#: toolbar.cpp:72
+msgid "New group helix from active sketch"
+msgstr "Nueva hélice de grupo a partir del croquis activo"
+
+#: toolbar.cpp:74
+msgid "New group revolve active sketch"
+msgstr "Nuevo croquis activo de revolución de grupo"
+
+#: toolbar.cpp:76
+msgid "New group step and repeat rotating"
+msgstr "Nuevo paso de grupo y rotación repetida"
+
+#: toolbar.cpp:78
+msgid "New group step and repeat translating"
+msgstr "Nuevo paso de grupo y traslación repetida"
+
+#: toolbar.cpp:80
+msgid "New group in new workplane (thru given entities)"
+msgstr "Nuevo grupo en nuevo plano de trabajo (a través de entidades dadas)"
+
+#: toolbar.cpp:82
+msgid "New group in 3d"
+msgstr "Nuevo grupo en 3d"
+
+#: toolbar.cpp:84
+msgid "New group linking / assembling file"
+msgstr "Nuevo enlace de grupo / archivo de ensamble"
+
+#: toolbar.cpp:88
+msgid "Nearest isometric view"
+msgstr "Vista isométrica más cercana"
+
+#: toolbar.cpp:90
+msgid "Align view to active workplane"
+msgstr "Alinear vista al plano de trabajo activo"
+
+#: util.cpp:165
+msgctxt "title"
+msgid "Error"
+msgstr "Error"
+
+#: util.cpp:165
+msgctxt "title"
+msgid "Message"
+msgstr "Mensaje"
+
+#: util.cpp:170
+msgctxt "button"
+msgid "&OK"
+msgstr "&Aceptar"
+
+#: view.cpp:127
+msgid "Scale cannot be zero or negative."
+msgstr "La escala no debe ser cero o negativa."
+
+#: view.cpp:139 view.cpp:148
+msgid "Bad format: specify x, y, z"
+msgstr "Formato incorrecto: especifica x, y, z"
+
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Mala selección por restricción de la relación de longitud. Esta "
+#~ "restricción se puede aplicar a:\n"
+#~ "\n"
+#~ " * dos segmentos de línea\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Mala selección por restricción de diferencia de longitud. Esta "
+#~ "restricción puede aplicar a:\n"
+#~ "\n"
+#~ " * dos segmentos de línea\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "Relación Lo&ngitud"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "Diferencia Long&itud"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "Mala selección para un nuevo croquis en el plano de trabajo. Este grupo "
+#~ "se puede crear con:\n"
+#~ "\n"
+#~ " * un punto (a través del punto, ortogonal a los ejes de coordenadas)\n"
+#~ " * un punto y dos segmentos de línea (a través del punto, paralelo a "
+#~ "líneas)\n"
+#~ " * un plano de trabajo (copia de un plano de trabajo)\n"
+
+#~ msgctxt "file-type"
+#~ msgid "Q3D Object file"
+#~ msgstr "Archivo Objeto Q3D"
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
"PO-Revision-Date: 2018-07-14 06:12+0000\n"
"Last-Translator: whitequark <whitequark@whitequark.org>\n"
"Language-Team: none\n"
"X-Generator: Zanata 4.4.5\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"\n"
"Activez un plan avec \"Dessin -> Dans plan de travail\"."
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
msgstr "Presse papier vide; rien à coller."
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
msgstr "Le nombre de copies à coller doit être d'au moins un."
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
msgstr "L'échelle ne peut pas être zéro."
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
msgstr "Sélectionnez un point pour définir l'origine de la rotation."
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
msgstr "Sélectionnez deux points pour définir le vecteur de translation."
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid ""
"Transformation is identity. So all copies will be exactly on top of each "
"other."
"Transformation identique. Donc, toutes les copies seront exactement les unes "
"au-dessus des autres."
-#: clipboard.cpp:458
+#: clipboard.cpp:457
msgid "Too many items to paste; split this into smaller pastes."
msgstr "Trop d'éléments à coller; Divisez-les en plus petits groupes."
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
msgstr "Pas d'espace de travail actif."
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
msgstr "Mauvais format: spécifiez les coordonnées comme x, y, z"
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
msgstr "Mauvais format; spécifiez la couleur comme r, v, b"
-#: confscreen.cpp:454
+#: confscreen.cpp:417
msgid ""
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
"Le facteur de perspective n'aura aucun effet tant que vous n'aurez pas "
"activé \"Affichage -> Utiliser la projection de perspective\"."
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
msgstr ""
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
msgstr "L'échelle d'export ne doit pas être zéro!"
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
msgstr "Le décalage du rayon de coupe ne doit pas être négatif!"
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
msgstr ""
"Mauvaise valeur: l'intervalle d'enregistrement automatique devrait être "
"positif"
-#: confscreen.cpp:558
+#: confscreen.cpp:531
msgid "Bad format: specify interval in integral minutes"
msgstr "Mauvais format: spécifiez un nombre entier de minutes"
#: constraint.cpp:25
msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr ""
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr ""
+
+#: constraint.cpp:27
+msgctxt "constr-name"
msgid "length-difference"
msgstr "longueur-difference"
-#: constraint.cpp:26
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr ""
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr ""
+
+#: constraint.cpp:30
msgctxt "constr-name"
msgid "symmetric"
msgstr "symétrique"
-#: constraint.cpp:27
+#: constraint.cpp:31
msgctxt "constr-name"
msgid "symmetric-h"
msgstr "symétrique-h"
-#: constraint.cpp:28
+#: constraint.cpp:32
msgctxt "constr-name"
msgid "symmetric-v"
msgstr "symétrique-v"
-#: constraint.cpp:29
+#: constraint.cpp:33
msgctxt "constr-name"
msgid "symmetric-line"
msgstr "symétrique-ligne"
-#: constraint.cpp:30
+#: constraint.cpp:34
msgctxt "constr-name"
msgid "at-midpoint"
msgstr "au-point-milieu"
-#: constraint.cpp:31
+#: constraint.cpp:35
msgctxt "constr-name"
msgid "horizontal"
msgstr "horizontal"
-#: constraint.cpp:32
+#: constraint.cpp:36
msgctxt "constr-name"
msgid "vertical"
msgstr "vertical"
-#: constraint.cpp:33
+#: constraint.cpp:37
msgctxt "constr-name"
msgid "diameter"
msgstr "diamètre"
-#: constraint.cpp:34
+#: constraint.cpp:38
msgctxt "constr-name"
msgid "pt-on-circle"
msgstr "pt-sur-cercle"
-#: constraint.cpp:35
+#: constraint.cpp:39
msgctxt "constr-name"
msgid "same-orientation"
msgstr "même-orientation"
-#: constraint.cpp:36
+#: constraint.cpp:40
msgctxt "constr-name"
msgid "angle"
msgstr "angle"
-#: constraint.cpp:37
+#: constraint.cpp:41
msgctxt "constr-name"
msgid "parallel"
msgstr "parallèle"
-#: constraint.cpp:38
+#: constraint.cpp:42
msgctxt "constr-name"
msgid "arc-line-tangent"
msgstr "arc-ligne-tangente"
-#: constraint.cpp:39
+#: constraint.cpp:43
msgctxt "constr-name"
msgid "cubic-line-tangent"
msgstr "cubique-ligne-tangente"
-#: constraint.cpp:40
+#: constraint.cpp:44
msgctxt "constr-name"
msgid "curve-curve-tangent"
msgstr "courbe-courbe-tangente"
-#: constraint.cpp:41
+#: constraint.cpp:45
msgctxt "constr-name"
msgid "perpendicular"
msgstr "perpendiculaire"
-#: constraint.cpp:42
+#: constraint.cpp:46
msgctxt "constr-name"
msgid "eq-radius"
msgstr "eg-rayon"
-#: constraint.cpp:43
+#: constraint.cpp:47
msgctxt "constr-name"
msgid "eq-angle"
msgstr "eg-angle"
-#: constraint.cpp:44
+#: constraint.cpp:48
msgctxt "constr-name"
msgid "eq-line-len-arc-len"
msgstr "eg-ligne-long-arc-long"
-#: constraint.cpp:45
+#: constraint.cpp:49
msgctxt "constr-name"
msgid "lock-where-dragged"
msgstr "verrouillé-où-déplacé"
-#: constraint.cpp:46
+#: constraint.cpp:50
msgctxt "constr-name"
msgid "comment"
msgstr "commentaire"
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la "
"tangente\"."
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la "
"tangente\"."
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
"Les courbes doivent partager un point final. Contraignez-les avec "
"\"Contrainte -> Sur point avant de contraindre la tangente\"."
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply "
"to:\n"
" * Une face plane et un point (distance minimale)\n"
" * Un cercle ou un arc (diamètre)\n"
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can "
"apply to:\n"
" * Un point et un cercle ou un arc (point sur courbe)\n"
" * Un point et une face plane (point sur une face)\n"
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can "
"apply to:\n"
" * Un segment de ligne et un arc (la longueur de segment de ligne est "
"égale à la longueur d'arc)\n"
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-"Mauvaise sélection pour la contrainte du rapport de longueur. Cette "
-"contrainte peut s'appliquer à:\n"
-"\n"
-" * Deux segments de ligne\n"
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-"Mauvaise sélection pour la contrainte de différence de longueur. Cette "
-"contrainte peut s'appliquer à:\n"
-"\n"
-" * Deux segments de ligne\n"
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
" * Un segment de ligne et un point (point au milieu)\n"
" * Un segment de ligne et un plan de travail (point médian dans le plan)\n"
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
" * Plan de travail, et deux points ou un segment de ligne (symétrique au "
"plan de travail)\n"
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid ""
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
"Un plan de travail doit être actif lors d'une contrainte de symétrie sans "
"plan de symétrie explicite."
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
"Activez un plan de travail (avec Dessin -> Dans plan de travail) avant "
"d'appliquer une contrainte horizontale ou verticale."
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can "
"apply to:\n"
" * deux points\n"
" * Un segment de ligne\n"
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply "
"to:\n"
"\n"
" * Deux normales\n"
-#: constraint.cpp:614
+#: constraint.cpp:663
msgid "Must select an angle constraint."
msgstr "Vous devez sélectionner une contrainte d'angle."
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
msgstr "Vous devez sélectionner une contrainte avec une étiquette associée."
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * Un segment de ligne et une normale\n"
" * Deux normales\n"
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr "Courbe-Courbe tangence doit s'appliquer dans le plan de travail."
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply "
"to:\n"
" * Deux segments de ligne, des arcs ou des Béziers, qui partagent un "
"point final (tangent)\n"
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * Un segment de ligne et une normale\n"
" * Deux normales\n"
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can "
"apply to:\n"
"\n"
" * un point\n"
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER"
+
+#: constraint.cpp:818
msgid "click center of comment text"
msgstr "cliquez le centre du texte de commentaire"
" * Un point et deux segments de ligne (plan au-travers d'un point et "
"parallèle aux lignes)\n"
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
msgstr "Le maillage du groupe actif est vide; Rien à exporter."
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr "les lignes à main levée ont été remplacées par des lignes continues"
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr "les lignes en zigzag ont été remplacées par des lignes continues"
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr ""
"Certains aspects du dessin n'ont pas d'équivalent DXF et n'ont pas été "
"exportés:\n"
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid ""
"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr ""
msgid "#references"
msgstr "#références"
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr ""
+
+#: file.cpp:555
msgid ""
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
"Données non reconnues dans le fichier. Ce fichier peut être corrompu ou "
"depuis une version plus récente du programme."
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Fichier manquant"
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr ""
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"permanently removed."
msgstr ""
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr ""
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr ""
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
msgstr ""
msgstr "Utiliser la vue en &Perspective"
#: graphicswin.cpp:97
+msgid "Show E&xploded View"
+msgstr ""
+
+#: graphicswin.cpp:98
msgid "Dimension &Units"
msgstr "&Unités de dimensions"
-#: graphicswin.cpp:98
+#: graphicswin.cpp:99
msgid "Dimensions in &Millimeters"
msgstr "Dimensions en &Millimètres"
-#: graphicswin.cpp:99
+#: graphicswin.cpp:100
msgid "Dimensions in M&eters"
msgstr "Dimensions en &Mètres"
-#: graphicswin.cpp:100
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
msgstr "Dimensions en &Pouces"
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr ""
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr "Affichage &Barre d'outils"
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr "Affichage du &Navigateur de Propriété"
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr "&Plein Ecran"
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr "&Nouveau Groupe"
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
msgstr "Dessin en &3d"
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
msgstr "Dessin dans un nouveau &Plan de travail"
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr "Espacement &Linéaire"
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr "Espacement &Circulaire"
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr "E&xtruder"
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
msgstr "&Helix"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr "&Lathe"
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
msgstr "Ré&volution"
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
msgstr "Lié / Assembler..."
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
msgstr "Lié Récent"
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr "&Dessin"
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
msgstr "Dans le &Plan de travail"
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
msgstr "N'importe où dans la &3d"
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr "&Point"
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr "&Plan de travail"
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr "Ligne - &Polyligne"
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr "Ligne de C&onstruction"
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr "&Rectangle"
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr "&Cercle"
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr "&Arc de Cercle"
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr "Spline Cubique de &Beziers"
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
msgstr "&Texte en Police TrueType"
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
msgstr "&Image"
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr "&Basculer en mode \"Construction\""
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr "&Arc Tangent au Point"
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr "Diviser les Courbes à l'&Intersection"
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr "&Constraintes"
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr "&Distance / Diamètre"
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr "Dimension Maîtresse / Indicative"
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr "A&ngle"
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr "An&gle Maître / Indicatif"
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr "Autre angle S&upplémentaire"
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr "Basculer cote Maîtresse / cote Indicative"
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr "&Horizontal"
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr "&Vertical"
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr "&Sur Point / Courbe / Plan"
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr "&Egale Longueur / Rayon / Angle"
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
-msgstr "R&apport de Longueur"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr ""
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
-msgstr "D&ifférence de Longueur"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr ""
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr "Au &Milieu"
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr "&Symétrique"
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr "Para&llèle / Tangent"
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr "&Perpendiculaire"
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr "Même Orient&ation"
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr "Accrocher le point à l'&Emplacement"
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr "Commentaire"
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr "&Analyse"
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr "Mesure &Volume"
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr "Mesure &Aire"
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr "Mesure &Périmètre"
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr "Montrer les Pièces &Interférentes"
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr "Montrer les Arêtes &Nues"
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
msgstr "Montrer le &Centre de Gravité"
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
msgstr "Montrer les &sous-contraintes Points"
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr "&Tracer Point"
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
msgstr "&Arrêt Tracé..."
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr "Espacement &Dimension..."
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr "&Aide"
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr "&Langue"
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr "&Site web / Manuel"
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr ""
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr "&A propos"
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
msgstr "(pas de fichier récent)"
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
msgstr ""
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
msgstr "Pas de plan de travail actif, donc la grille ne va pas apparaître."
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel "
"projection.\n"
"Pour une projection en perspective, modifiez le facteur de perspective dans "
"l'écran de configuration. Une valeur d'environ 0,3 est typique."
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid ""
"Select a point; this point will become the center of the view on screen."
msgstr ""
"Sélectionnez un point. Ce point deviendra le centre de la vue à l'écran."
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr ""
"Aucune entité supplémentaire ne partage des points d'extrémité avec les "
"entités sélectionnées."
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
"Pour utiliser cette commande, sélectionnez un point ou une autre entité à "
"partir d'une pièce liée ou créez un groupe de liens dans le groupe actif."
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
"Aucun plan de travail n'est actif. Activez un plan de travail (avec Dessin -"
"> Dans plan de travail) pour définir le plan pour la grille d'accrochage."
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
"des textes de commentaires ou des contraintes avec une étiquette. Pour "
"accrocher une ligne, sélectionnez ses points d'extrémité."
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr ""
"Aucun plan de travail sélectionné. Activation du plan de travail par défaut "
"pour ce groupe."
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default "
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"de travail par défaut. Essayez de sélectionner un plan de travail ou "
"d'activer un groupe de \"Dessin dans nouveau plan travail\"."
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
"Mauvaise sélection pour l'arc tangent au point. Sélectionnez un seul point, "
"ou ne sélectionnez rien pour configurer les paramètres de l'arc."
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr ""
"cliquez un point sur l'arc (dessine dans le sens inverse des aiguilles d'une "
"montre)"
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
msgstr "cliquez pour placer un point"
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
msgstr "cliquez le premier point du segment de ligne"
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
msgstr "cliquez le premier point de la ligne de construction"
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
msgstr "cliquez le premier point du segment cubique"
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
msgstr "cliquez pour placer le centre du cercle"
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
msgstr "cliquez pour placer l'origine du plan de travail"
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
msgstr "cliquez un coin du rectangle"
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
msgstr "cliquez le haut à gauche du texte"
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
msgstr "cliquez le haut à gauche de l'image"
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid ""
"No entities are selected. Select entities before trying to toggle their "
"construction state."
msgid "sketch-in-3d"
msgstr "dessin-en-3d"
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
-"Mauvaise sélection pour un nouveau dessin dans le plan de travail. Ce groupe "
-"peut être créé avec:\n"
-"\n"
-" * Un point (par le point, orthogonal aux axes de coordonnées)\n"
-" * Un point et deux segments de ligne (par le point, parallèle aux "
-"lignes)\n"
-" * Un plan de travail (copie du plan de travail)\n"
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
"Activez un plan de travail (Dessin -> Dans plan de travail) avant "
"l'extrusion. Le croquis sera extrudé normalement au plan de travail."
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
msgstr "extruder"
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
"parallèle à la ligne / point normal, par le point)\n"
" * Un segment de ligne (révolution sur le segment de ligne)\n"
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
msgstr "révolution"
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
msgstr ""
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
msgstr ""
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
" * Un point et une ligne ou une normale (tourner autour d'un axe par le "
"point et parallèle à la ligne / normale)\n"
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
msgstr "rotation"
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
msgstr "translation"
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
msgstr "(sans nom)"
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
msgstr "contour non fermé ou tout n'est pas du même style!"
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr "les points ne sont pas tous coplanaires!"
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
msgstr "le contour s'entrecroise!"
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
msgstr "arête de longueur nulle!"
-#: modify.cpp:254
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr ""
+
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr "Vous devez dessiner dans un plan pour créer un arc tangent."
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
"Pour créer un arc tangent, sélectionnez un point où deux lignes (pas de "
"construction) ou cercles de ce groupe et de ce plan se joignent."
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
"Impossible d'arrondir ce coin. Essayez un rayon plus petit, ou essayez de "
"créer la géométrie souhaitée à la main avec des contraintes tangentielles."
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr ""
"Impossible de diviser cette entité; Lignes, cercles ou cubiques uniquement."
-#: modify.cpp:624
+#: modify.cpp:622
msgid "Must be sketching in workplane to split."
msgstr "Vous devez dessiner dans un plan de travail pour diviser."
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
msgstr ""
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
msgstr "Impossible de diviser; pas d'intersection trouvée."
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr "Appliquer au style"
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr "Pas de style"
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr "Style personnalisé nouvellement créé ..."
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr "Info Groupe"
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr "Info Style"
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr "Sélection Chaîne d'arêtes"
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr "Basculer cote maîtresse / cote indicative"
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr "Autre angle supplémentaire"
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr "Accrocher à la grille"
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr "Effacer le point de la Spline"
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr "Ajouter un point à la Spline"
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr ""
"Impossible d'ajouter le point spline: nombre maximum de points atteints."
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr "Basculer en mode \"construction\"."
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr "Effacer la contraint Point-Coïncident"
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr "Couper"
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr "Copier"
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr "Sélectionner tout"
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr "Coller"
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr "Coller transformé..."
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr "Effacer"
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr "Désélectionner tout"
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr "Désélectionner survolé"
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr "Zoom pour ajuster"
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
msgstr "cliquez pou le prochain point de ligne or appuyez sur Esc"
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Impossible de dessiner un rectangle en 3d; D'abord, activez un plan de "
"travail avec \"Dessin -> Dans plan de travail\"."
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
msgstr "cliquez pour placer un autre coin de rectangle"
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
msgstr "cliquez pour ajuster le rayon"
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Ne peut pas dessiner l'arc en 3d; D'abord, activez un plan de travail avec "
"\"Dessin -> Dans plan de travail\"."
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
msgstr "cliquez pour placer un point"
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
msgstr "cliquez le prochain point cubique ou appuyez sur Esc"
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
"Vous dessinez déjà dans un plan de travail; Sélectionner \"Dessiner en 3d\" "
"avant de créer un nouveau plan de travail."
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Impossible de dessiner du texte en 3d; D'abord, activer un plan de travail "
"avec \"Dessin -> Dans plan de travail\"."
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
msgstr ""
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
"Impossible de dessiner l'image en 3d; D'abord, activez un plan de travail "
"avec \"Dessin -> Dans plan de travail\"."
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER"
-
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
msgctxt "file-type"
msgid "SolveSpace models"
msgstr ""
-#: platform/gui.cpp:90
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr ""
+
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
msgstr ""
-#: platform/gui.cpp:94
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr ""
+
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
msgstr ""
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
msgstr ""
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
msgstr ""
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
msgstr ""
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
msgstr ""
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
msgstr ""
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
msgstr ""
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
msgstr ""
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr ""
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr ""
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr ""
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
msgstr ""
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
msgstr ""
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr ""
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
msgstr ""
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
msgstr "sans nom"
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
msgstr "Sauver fichier"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
msgstr "Ouvrir Fichier"
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
msgstr "_Annuler"
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
msgstr "_Sauver"
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
msgstr ""
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
msgstr "Sauvegarde automatique existante"
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
msgstr ""
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
msgstr ""
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
msgstr ""
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
msgstr ""
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
msgstr "Fichier modifié"
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
msgstr ""
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
msgstr ""
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
msgstr ""
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
msgstr ""
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
msgstr ""
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
msgstr "(nouveau dessin)"
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
msgstr "Navigateur de propriété"
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This "
"is probably not what you want; hide them by clicking the link at the top of "
"the text window."
msgstr ""
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid ""
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"dwg."
msgstr ""
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
msgstr ""
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
msgstr ""
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
msgstr ""
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
" %s"
msgstr ""
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
" %s"
msgstr ""
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"This introduces error, typically of around 1%."
msgstr ""
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
msgstr ""
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
msgstr ""
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
msgstr ""
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
msgstr ""
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
msgstr ""
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
msgstr ""
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
msgstr ""
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
msgstr ""
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"The model contains %d triangles, from %d surfaces."
msgstr ""
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"Zero problematic edges, good.%s"
msgstr ""
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"%d problematic edges, bad.%s"
msgstr ""
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"© 2008-%d Jonathan Westhues and other authors.\n"
msgstr ""
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
"Impossible d'attribuer le style à une entité dérivée d'une autre entité; "
"Essayez d'attribuer un style au parent de cette entité."
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
msgstr "Le nom d'un style ne peut pas être vide"
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
msgstr "Je ne peux pas répéter moins de 1 fois."
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
msgstr "Je ne peux pas répéter plus de 999 fois."
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
msgstr "Un nom de groupe ne peut pas être vide"
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
msgstr "L'opacité doit être entre 0 et 1."
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
msgstr "Le rayon ne peut pas être zéro ou négatif."
msgid "&OK"
msgstr ""
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
msgstr "L'échelle ne peut pas être zéro ou négative."
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
msgstr "Mauvais format: Spécifiez x, y, z"
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Mauvaise sélection pour la contrainte du rapport de longueur. Cette "
+#~ "contrainte peut s'appliquer à:\n"
+#~ "\n"
+#~ " * Deux segments de ligne\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Mauvaise sélection pour la contrainte de différence de longueur. Cette "
+#~ "contrainte peut s'appliquer à:\n"
+#~ "\n"
+#~ " * Deux segments de ligne\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "R&apport de Longueur"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "D&ifférence de Longueur"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "Mauvaise sélection pour un nouveau dessin dans le plan de travail. Ce "
+#~ "groupe peut être créé avec:\n"
+#~ "\n"
+#~ " * Un point (par le point, orthogonal aux axes de coordonnées)\n"
+#~ " * Un point et deux segments de ligne (par le point, parallèle aux "
+#~ "lignes)\n"
+#~ " * Un plan de travail (copie du plan de travail)\n"
+
#~ msgid "Specify between 0 and 8 digits after the decimal."
#~ msgstr "Spécifiez entre 0 et 8 chiffres après la virgule."
# Copyright (C) 2017 the SolveSpace authors
# This file is distributed under the same license as the SolveSpace package.
# EvilSpirit <evilspirit@evilspirit.org>, 2017.
+# Olesya Gerasimenko <translation-team@basealt.ru>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
-"PO-Revision-Date: 2017-04-21 10:29+0700\n"
-"Last-Translator: evilspirit@evilspirit.org\n"
-"Language-Team: EvilSpirit\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
+"PO-Revision-Date: 2021-10-04 15:33+0300\n"
+"Last-Translator: Olesya Gerasimenko <translation-team@basealt.ru>\n"
+"Language-Team: Basealt Translation Team\n"
"Language: ru_RU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.1\n"
+"X-Generator: Lokalize 21.08.1\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"можно только находясь в рабочей плоскости.\n"
"Активируйте рабочую плоскость через Эскиз->В Рабочей Плоскости"
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
msgstr "Буфер обмена пуст; нечего вставлять."
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
msgstr "Укажите в поле 'количество' хотя бы одну копию для вставки."
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
msgstr "Масштабный коэффициент не может быть нулевым."
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
msgstr "Выберите одну точку в качестве центра вращения."
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
msgstr "Выберите две точки, чтобы задать вектор смещения."
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid ""
"Transformation is identity. So all copies will be exactly on top of each "
"other."
msgstr ""
"Трансформация не задана. Все копии будут расположены в одном и том же месте."
-#: clipboard.cpp:458
+#: clipboard.cpp:457
msgid "Too many items to paste; split this into smaller pastes."
msgstr "Слишком много элементов для вставки; разбейте на несколько частей."
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
msgstr "Рабочая плоскость не активна"
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
msgstr "Неверный формат: введите координаты как x, y, z"
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
msgstr "Неверный формат: введите цвет как r, g, b"
-#: confscreen.cpp:454
+#: confscreen.cpp:417
msgid ""
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
"Коэффициент перспективы не будет иметь эффект, пока вы не включите Вид-"
">Перспективная Проекция."
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
msgstr "Введите число от 0 до %d."
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
msgstr "Масштабный коэффициент не может быть нулевым!"
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
msgstr "Радиус режущего инструмента не может быть отрицательным!"
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
msgstr ""
"Неверное значение: интервал автосохранения должен быть положительным числом"
-#: confscreen.cpp:558
+#: confscreen.cpp:531
msgid "Bad format: specify interval in integral minutes"
msgstr ""
"Неверный формат: введите целое число, чтобы задать интервал автосохранения"
#: constraint.cpp:25
msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr "отношение-длин-дуга-дуга"
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr "отношение-длин-дуга-отрезок"
+
+#: constraint.cpp:27
+msgctxt "constr-name"
msgid "length-difference"
msgstr "разность-длин"
-#: constraint.cpp:26
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr "разность-длин-дуга-дуга"
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr "разность-длин-дуга-отрезок"
+
+#: constraint.cpp:30
msgctxt "constr-name"
msgid "symmetric"
msgstr "симметричность"
-#: constraint.cpp:27
+#: constraint.cpp:31
msgctxt "constr-name"
msgid "symmetric-h"
msgstr "симметричность-гориз"
-#: constraint.cpp:28
+#: constraint.cpp:32
msgctxt "constr-name"
msgid "symmetric-v"
msgstr "симметричность-верт"
-#: constraint.cpp:29
+#: constraint.cpp:33
msgctxt "constr-name"
msgid "symmetric-line"
msgstr "симметричность-по-оси"
-#: constraint.cpp:30
+#: constraint.cpp:34
msgctxt "constr-name"
msgid "at-midpoint"
msgstr "на-середине"
-#: constraint.cpp:31
+#: constraint.cpp:35
msgctxt "constr-name"
msgid "horizontal"
msgstr "горизонтальность"
-#: constraint.cpp:32
+#: constraint.cpp:36
msgctxt "constr-name"
msgid "vertical"
msgstr "вертикальность"
-#: constraint.cpp:33
+#: constraint.cpp:37
msgctxt "constr-name"
msgid "diameter"
msgstr "диаметр"
-#: constraint.cpp:34
+#: constraint.cpp:38
msgctxt "constr-name"
msgid "pt-on-circle"
msgstr "тчк-на-окружности"
-#: constraint.cpp:35
+#: constraint.cpp:39
msgctxt "constr-name"
msgid "same-orientation"
msgstr "идентичная-ориентация"
-#: constraint.cpp:36
+#: constraint.cpp:40
msgctxt "constr-name"
msgid "angle"
msgstr "угол"
-#: constraint.cpp:37
+#: constraint.cpp:41
msgctxt "constr-name"
msgid "parallel"
msgstr "параллельность"
-#: constraint.cpp:38
+#: constraint.cpp:42
msgctxt "constr-name"
msgid "arc-line-tangent"
msgstr "кас-дуга-линия"
-#: constraint.cpp:39
+#: constraint.cpp:43
msgctxt "constr-name"
msgid "cubic-line-tangent"
msgstr "кас-сплайн-линия"
-#: constraint.cpp:40
+#: constraint.cpp:44
msgctxt "constr-name"
msgid "curve-curve-tangent"
msgstr "кас-кривых"
-#: constraint.cpp:41
+#: constraint.cpp:45
msgctxt "constr-name"
msgid "perpendicular"
msgstr "перпендикулярность"
-#: constraint.cpp:42
+#: constraint.cpp:46
msgctxt "constr-name"
msgid "eq-radius"
msgstr "равенство-радиусов"
-#: constraint.cpp:43
+#: constraint.cpp:47
msgctxt "constr-name"
msgid "eq-angle"
msgstr "равенство-углов"
-#: constraint.cpp:44
+#: constraint.cpp:48
msgctxt "constr-name"
msgid "eq-line-len-arc-len"
msgstr "равен-длины-линии-длины-дуги"
-#: constraint.cpp:45
+#: constraint.cpp:49
msgctxt "constr-name"
msgid "lock-where-dragged"
msgstr "фиксация"
-#: constraint.cpp:46
+#: constraint.cpp:50
msgctxt "constr-name"
msgid "comment"
msgstr "комментарий"
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение "
"касательности."
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение "
"касательности."
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение "
"касательности."
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply "
"to:\n"
" * грань и точку (расстояние от точки до плоскости грани)\n"
" * окружность или дугу (диаметр / радиус)\n"
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can "
"apply to:\n"
" * точку и окружность / дугу / сплайн (точка на кривой)\n"
" * точку и грань (точка на грани)\n"
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can "
"apply to:\n"
" * две окружности / дуги (равенство радиусов)\n"
" * отрезок и дугу (равенство длины отрезка и длины дуги)\n"
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-"Неправильное выделение для ограничения 'отношение длин'.\n"
-"Ð\9eгÑ\80аниÑ\87ение можеÑ\82 пÑ\80инимаÑ\82Ñ\8c в каÑ\87еÑ\81Ñ\82ве вÑ\8bделениÑ\8f Ñ\81ледÑ\83Ñ\8eÑ\89ие пÑ\80имиÑ\82ивÑ\8b:\n"
+"Неправильное выделение для ограничения 'отношение длин'. Ограничение может "
+"принимать в качестве выделения следующие примитивы:\n"
"\n"
" * два отрезка\n"
+" * две дуги\n"
+" * дугу и отрезок\n"
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-"Ð\9dепÑ\80авилÑ\8cное вÑ\8bделение длÑ\8f огÑ\80аниÑ\87ениÑ\8f 'Ñ\80азниÑ\86а длин'.\n"
-"Ð\9eгÑ\80аниÑ\87ение можеÑ\82 пÑ\80инимаÑ\82Ñ\8c в каÑ\87еÑ\81Ñ\82ве вÑ\8bделениÑ\8f Ñ\81ледÑ\83Ñ\8eÑ\89ие пÑ\80имиÑ\82ивÑ\8b:\n"
+"Ð\9dепÑ\80авилÑ\8cное вÑ\8bделение длÑ\8f огÑ\80аниÑ\87ениÑ\8f 'Ñ\80азноÑ\81Ñ\82Ñ\8c длин'. Ð\9eгÑ\80аниÑ\87ение можеÑ\82 "
+"принимать в качестве выделения следующие примитивы:\n"
"\n"
" * два отрезка\n"
+" * две дуги\n"
+" * дугу и отрезок\n"
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
" * точку и отрезок (точка на середине отрезка)\n"
" * отрезок и рабочую плоскость (середина отрезка на плоскости)\n"
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
" * рабочую плоскость и две точки / отрезок (симметричность относительно "
"рабочей плоскости\n"
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid ""
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
"Рабочая плоскость должна быть активна для того, чтобы создать\n"
"ограничение симметричности без явного указания плоскости симметрии."
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
"Рабочая плоскость должна быть активирована (Эскиз -> В рабочей плоскости)\n"
"перед тем, как накладывать ограничения горизонтальности / вертикальности."
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can "
"apply to:\n"
" * две точки\n"
" * отрезок\n"
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply "
"to:\n"
"\n"
" * two normals\n"
msgstr ""
-"Неправильное выделение для ограничения \"идентичная ориентация\".\n"
+"Неправильное выделение для ограничения 'идентичная ориентация'.\n"
"Ограничение может принимать в качестве выделения следующие примитивы:\n"
"\n"
" * два координатных базиса('нормали')\n"
-#: constraint.cpp:614
+#: constraint.cpp:663
msgid "Must select an angle constraint."
msgstr ""
"Переключатся между смежными углами можно только выбрав ограничение угла."
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
msgstr ""
"Переключать режим 'размера для справок' возможно только для ограничений, "
"имеющих размерное значение."
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * отрезок и координатный базис (нормаль)\n"
" * два координатных базиса (нормали)\n"
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr ""
"Ограничение касательности может быть наложено только в рабочей плоскости."
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply "
"to:\n"
" * два отрезка, две дуги или два сплайна, соединенных крайними точками "
"(касательность)\n"
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * отрезок и координатный базис (нормаль)\n"
" * два координатных базиса (нормали)\n"
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can "
"apply to:\n"
"\n"
" * a point\n"
msgstr ""
-"Неправильное выделение для ограничения 'Фиксация'.\n"
+"Неправильное выделение для ограничения 'фиксация'.\n"
"Ограничение может принимать в качестве выделения следующие примитивы:\n"
"\n"
" * точку\n"
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ"
+
+#: constraint.cpp:818
msgid "click center of comment text"
msgstr "кликните мышью там, где будет расположен текстовый комментарий"
"No solid model present; draw one with extrudes and revolves, or use Export "
"2d View to export bare lines and curves."
msgstr ""
+"Тела не найдены; создайте их или используйте экспорт двумерных объектов."
#: export.cpp:61
msgid ""
" * a point and two line segments (plane through point and parallel to "
"lines)\n"
msgstr ""
+"Неправильное выделение для экспорта сечения. Необходимо выделить:\n"
+"\n"
+" * Ничего, но с активированной рабочей плоскостью (рабочая плоскость "
+"будет плоскостью сечения)\n"
+" * грань (сечение через грань)\n"
+" * точку и два отрезка (сечение плоскостью, заданной двумя отрезками, "
+"построенной через указанную точку)\n"
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
-msgstr ""
+msgstr "Активная группа не содержит тел; нечего экспортировать."
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr "Стили линии 'от руки' были заменены сплошными линиями"
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr "Стили линии 'зиг-заг' были заменены сплошными линиями"
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr ""
"Некоторые элементы чертежа не имеют аналогов в DXF-представлении и не были "
"экспортированы:\n"
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid ""
"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr ""
msgid "#references"
msgstr "система-координат"
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr "Файл пуст. Возможно он поврежден."
+
+#: file.cpp:555
msgid ""
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
"Некоторые данные из этого файла не распознаны. Возможно, файл поврежден или "
"создан в более новой версии программы"
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Файл Отсутствует"
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
-msgstr ""
+msgstr "Связанный файл “%s” отсутствует."
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"Если вы ответите \"Нет\", то вся геометрия, которая зависит от "
"отсутствующего файла будет удалена."
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr "Да"
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "Нет"
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
msgstr "Отменить"
#: graphicswin.cpp:78
msgid "&Line Styles..."
-msgstr ""
+msgstr "Стили Линий..."
#: graphicswin.cpp:79
msgid "&View Projection..."
-msgstr "&View Прое&кция..."
+msgstr "&Проекция вида..."
#: graphicswin.cpp:81
msgid "Con&figuration..."
-msgstr ""
+msgstr "Настройки..."
#: graphicswin.cpp:84
msgid "&View"
#: graphicswin.cpp:95
msgid "Darken Inactive Solids"
-msgstr ""
+msgstr "Затемнять Неактивные Тела"
#: graphicswin.cpp:96
msgid "Use &Perspective Projection"
msgstr "Перспективная Прое&кция"
#: graphicswin.cpp:97
-msgid "Dimension &Units"
-msgstr ""
+msgid "Show E&xploded View"
+msgstr "Показать &Развернутый Вид"
#: graphicswin.cpp:98
+msgid "Dimension &Units"
+msgstr "Единицы Измерения"
+
+#: graphicswin.cpp:99
msgid "Dimensions in &Millimeters"
msgstr "Размеры в Ми&ллиметрах"
-#: graphicswin.cpp:99
+#: graphicswin.cpp:100
msgid "Dimensions in M&eters"
-msgstr ""
+msgstr "Размеры в Метрах"
-#: graphicswin.cpp:100
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
msgstr "Размеры в Дю&ймах"
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr "Размеры в &Футах и дюймах"
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr "Показывать Па&нель Инструментов"
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr "Показывать Брау&зер"
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr "Полно&экранный Режим"
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr "&Группа"
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
msgstr "Создать Эскиз в &3d"
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
msgstr "Создать Эскиз в Новой &Рабочей Плоскости"
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr "&Линейный Массив"
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr "&Круговой Массив"
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr "Тело &Выдавливания"
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
-msgstr ""
+msgstr "Тело Винтовое"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr "Тело В&ращения"
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
-msgstr ""
+msgstr "Тело В&ращения"
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
msgstr "&Импорт Детали / Сборка..."
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
msgstr "Последние &Детали"
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr "&Эскиз"
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
msgstr "В &Рабочей Плоскости"
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
msgstr "Режим &3d"
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr "Опорная &Точка"
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr "Рабочая &Плоскость"
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr "&Отрезок"
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr "&Вспомогательный Отрезок"
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr "Прямоу&гольник"
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr "О&кружность"
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr "Д&уга Окружности"
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr "Кубический &Сплайн Безье"
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
msgstr "Т&екст TrueType"
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
msgstr "И&зображение"
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr "Переключить Режим Вс&помогательных Построений"
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr "Кас&ательная в Точке"
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr "Ра&збить Кривые Пересечением"
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr "&Ограничения"
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr "&Расстояние / Диаметр"
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr "&Справочный Размер"
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr "&Угол"
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr "С&правочный Угол"
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr "Переключить Сме&жный Угол"
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr "Переключить Режим Размера Для Спра&вок"
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr "&Горизонтальность"
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr "&Вертикальность"
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr "&Точка на Примитиве"
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr "&Равенство Длин / Радиусов / Углов"
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
-msgstr "Отно&шение Длин"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr "&Отношение длин (дуга)"
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
-msgstr "Ра&зница Длин"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr "Р&азность длин (дуга)"
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr "&На Середине"
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr "С&имметричность"
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr "Пара&ллельность / Касательность"
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr "Перпендикул&ярность"
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr "Идентичная &Ориентация"
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr "За&фиксировать"
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr "Текстовый &Комментарий"
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr "&Анализ"
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr "Измерить &Объем"
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr "Измерить П&лощадь"
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr "Измерить П&ериметр"
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr "Показать Пе&ресекающиеся Детали"
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr "Показать Про&блемные Ребра"
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
-msgstr ""
+msgstr "Показать Центр Масс"
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
-msgstr ""
+msgstr "Показать Свободные Точки"
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr "Включить &Трассировку Точки"
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
msgstr "Остановить Тра&ссировку..."
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr "Плавное Из&менение Размера..."
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr "&Помощь"
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr "&Язык"
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr "Вебсайт / &Справка"
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr ""
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr "О &Программе"
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
msgstr "(пусто)"
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
-msgstr ""
+msgstr "Файл '%s' не существует."
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
msgstr "Сетку не будет видно, пока рабочая плоскость не активирована."
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel "
"projection.\n"
"перспективы на конфигурационной странице браузера.\n"
"Значение по умолчанию 0.3."
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid ""
"Select a point; this point will become the center of the view on screen."
msgstr "Выделите точку. Вид будет отцентрован по этой точке."
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr "Нет дополнительных объектов, соединенных с выбранными примитивами."
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
msgstr ""
"Чтобы использовать эту команду, выделите точку или другой примитив, "
-"принадлежащий импортированной детали или активируйте группу импортированной "
+"принадлежащий импортированной детали, или активируйте группу импортированной "
"детали."
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
"Рабочая плоскость не активна. Активируйте ее через Эскиз -> В Рабочей "
"Плоскости чтобы определить плоскость для сетки."
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
"текстовые комментарии или ограничения с размерными значениями. Чтобы "
"привязать отрезок или другой примитив, выбирайте его точки."
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr ""
"Рабочая плоскость не активна. Активирована рабочая плоскость по умолчанию "
"для данной группы."
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default "
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"по умолчанию. Попробуйте выделить рабочую плоскость или создать новую с "
"помощью Группа -> Создать Эскиз в Новой Рабочей Плоскости."
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
"точку, либо запустите команду без выделения, чтобы перейти к окну настроек "
"этой команды."
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr ""
"кликните мышью там, где хотите создать дугу окружности (дуга будет "
"нарисована против часовой стрелки)"
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
msgstr "кликните мышью там, где хотите создать опорную точку"
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
msgstr "кликните мышью там, где хотите создать первую точку отрезка"
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
msgstr ""
"кликните мышью там, где хотите создать первую точку вспомогательного отрезка"
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
msgstr ""
"кликните мышью там, где хотите создать первую точку кубического сплайна Безье"
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
msgstr "кликните мышью там, где будет находиться центр окружности"
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
msgstr ""
"кликните мышью там, где будет находиться точка, через которую будет "
"построена рабочая плоскость"
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
msgstr "кликните мышью там, где будет находиться один из углов прямоугольника"
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
msgstr "кликните мышью там, где хотите создать текст"
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
msgstr ""
+"кликните мышью там, где будет расположен левый верхний угол изображения"
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid ""
"No entities are selected. Select entities before trying to toggle their "
"construction state."
msgid "sketch-in-3d"
msgstr "эскиз-в-3d"
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
-"Неправильное выделение для создания эскиза.\n"
-"Группа может быть создана, используя в качестве выделения следующие "
-"примитивы:\n"
+"Неправильное выделение для создания эскиза в рабочей плоскости. Группа может "
+"быть создана, используя в качестве выделения следующие примитивы:\n"
"\n"
-" * точку (рабочая плоскость, ориентированная к ближайшему виду, "
-"проходящая через точку)\n"
-" * точку и два отрезка (рабочая плоскость, проходящая через точку и "
-"параллельная отрезкам)\n"
-" * рабочую плоскость (копия рабочей плоскости)\n"
+" * точку (через точку, ортогонально осям координат)\n"
+" * точку и два отрезка (через точку, параллельно отрезкам)\n"
+" * точку и нормаль (через точку, ортогонально нормали)\n"
+" * рабочую плоскость (копию рабочей плоскости)\n"
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
"Выберите рабочую плоскость (Эскиз -> В Рабочей Плоскости) перед созданием "
"группы выдавливания. Эскиз будет выдавлен по нормали к рабочей плоскости."
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
msgstr "тело-выдавливания"
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr ""
+"Операция создания тела вращения может быть применена только к плоским "
+"эскизам."
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
"Группа может быть создана, используя в качестве выделения следующие "
"примитивы:\n"
"\n"
-" * точку и отрезок / координатных базис (нормаль) (тело вращения вокруг "
+" * точку и отрезок / координатный базис (нормаль) (тело вращения вокруг "
"оси, проходящей через точку и параллельной отрезку / нормали)\n"
" * отрезок (тело вращения вокруг оси, проходящей через отрезок)\n"
"\n"
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
msgstr "тело-вращения"
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr ""
+"Операция создания тела вращения может быть применена только к плоским "
+"эскизам."
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
"to line / normal, through point)\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
+"Неправильное выделение для создания группы тела вращения. \n"
+"Группа может быть создана, используя в качестве выделения следующие "
+"примитивы:\n"
+"\n"
+" * точку и отрезок / координатный базис (нормаль) (тело вращения вокруг "
+"оси, проходящей через точку и параллельной отрезку / нормали)\n"
+" * отрезок (тело вращения вокруг оси, проходящей через отрезок)\n"
+"\n"
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
-msgstr ""
+msgstr "тело-вращения"
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
msgstr ""
+"Операция создания винтового тела может быть применена только к плоским "
+"эскизам."
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
"to line / normal, through point)\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
+"Неправильное выделение для создания винтового тела.\n"
+"Группа может быть создана, используя в качестве выделения следующие "
+"примитивы:\n"
+"\n"
+" * точку и отрезок или координатный базис (нормаль) (вращение вокруг "
+"направления, параллельного линии / нормали, построенное через выбранную "
+"точку)\n"
+" * отрезок (вращение вокруг отрезка)\n"
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
-msgstr ""
+msgstr "тело-винтовое"
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
"\n"
" * точку при активной рабочей плоскости (вращение в плоскости вокруг "
"выбранной точки)\n"
-" * точку и отрезок / координатных базис (нормаль) (вращение вокруг оси, "
+" * точку и отрезок / координатный базис (нормаль) (вращение вокруг оси, "
"проходящей через точку и параллельной отрезку / нормали)\n"
"\n"
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
msgstr "круговой-массив"
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
msgstr "линейный-массив"
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
msgstr "(без имени)"
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
msgstr "незамкнутый контур или несовпадение стилей!"
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr "не все точки лежат в одной плоскости!"
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
msgstr "контур имеет самопересечения!"
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
msgstr "вырожденный отрезок!"
-#: modify.cpp:254
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr ""
+
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr ""
"Скругления эскиза можно создавать только когда рабочая плоскость "
"активирована."
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
"Чтобы создать скругление эскиза, выберите точку, где соединяются два "
"примитива, не принадлежащих к вспомогательной геометрии."
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
"Невозможно скруглить угол. Попробуйте радиус поменьше или создайте требуемую "
"геометрию с помощью Ограничения -> Параллельность / Касательность."
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr ""
"Невозможно разделить такие примитивы. Выберите линии, окружности или "
"кубические сплайны."
-#: modify.cpp:624
+#: modify.cpp:622
msgid "Must be sketching in workplane to split."
msgstr ""
"Пересечение примитивов работает только когда рабочая плоскость активна."
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
msgstr ""
+"Выберите два пересекающихся примитива (два отрезка/окружности/дуги или "
+"отрезок/окружность/дугу и точку)"
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
msgstr "Невозможно разделить пересекаемые примитивы: пересечений нет."
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr "Применить Стиль"
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr "Стиль по Умолчанию"
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr "Создать Новый Стиль..."
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr "Настройки Группы"
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr "Настройки Стиля"
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr "Выделить Последовательность Примитивов"
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr "Переключить Режим Размера Для Справок"
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr "Переключить Смежный Угол"
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr "Привязать к Сетке"
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr "Удалить Точку Сплайна"
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr "Добавить Точку Сплайна"
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr ""
"Невозможно добавить точку сплайна: достигнуто ограничение максимального "
"количества точек для сплайна."
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr "Переключить Режим 'Дополнительные Построения'."
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr "Удалить Ограничение Совпадения Точек"
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr "Вырезать"
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr "Копировать"
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr "Выделить Все"
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr "Вставить"
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr "Вставить с Трансформацией..."
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr "Удалить"
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr "Сбросить Выделение"
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr "Снять Выделение с Выбранного"
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr "Показать Все"
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
msgstr "кликните мышью там, где хотите расположить следующую точку"
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
"Невозможно начертить прямоугольник, когда рабочая плоскость не активна."
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
msgstr "кликните мышью там, где хотите расположить другой угол прямоугольника"
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
msgstr "кликните, чтобы задать радиус"
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "Невозможно создать дугу, когда нет активной рабочей плоскости."
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
msgstr "кликните мышью там, где хотите создать точку"
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
msgstr ""
"кликните мышью там, где хотите создать следующую точку сплайна или нажмите "
"Esc для завершения операции."
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
"Рабочая плоскость уже активна. Перейдите в режим 3d перед созданием новой "
"рабочей плоскости."
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "Невозможно создать текст, когда нет активной рабочей плоскости."
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
-msgstr ""
+msgstr "кликните, чтобы расположить правый нижний угол текста"
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-msgstr ""
-
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ"
+msgstr "Невозможно создать изображение. Активируйте рабочую плоскость."
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
msgctxt "file-type"
msgid "SolveSpace models"
msgstr "проекты SolveSpace"
-#: platform/gui.cpp:90
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr "ВСЕ"
+
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
-msgstr ""
+msgstr "IDF печатная плата"
-#: platform/gui.cpp:94
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr "STL треугольная сетка"
+
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
msgstr "PNG изображение"
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
msgstr "STL полигональная сетка"
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
msgstr "Wavefront OBJ полигональная сетка"
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
-msgstr "Three.js-совместимая полигональная сетка с просмторщиком"
+msgstr "Three.js-совместимая полигональная сетка с просмотрщиком"
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
msgstr "Three.js-совместимая полигональная сетка"
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
-msgstr ""
+msgstr "VRML файл"
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP файл"
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF документ"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "Encapsulated PostScript"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "SVG изображение"
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF файл (AutoCAD 2007)"
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL файл"
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
msgstr "G Code"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF и DWG файлы"
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
msgstr "CSV файлы (значения, разделенные запятой)"
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
msgstr "без имени"
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
msgstr "Сохранить Файл"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
msgstr "Открыть Файл"
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
msgstr "Отменить"
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
msgstr "Сохранить"
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
-msgstr ""
+msgstr "_Открыть"
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
msgstr "Автосохранение Доступно"
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
-msgstr ""
+msgstr "Автоматически сохраненный файл доступен для данного проекта."
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
-msgstr ""
+msgstr "Хотите загрузить автосохраненный файл вместо исходного?"
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
-msgstr ""
+msgstr "&Загрузить Автосохранение"
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
-msgstr ""
+msgstr "&Не Загружать"
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
msgstr "Измененный Файл"
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
-msgstr ""
+msgstr "Сохранить изменения, сделанные в файле “%s”?"
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
-msgstr ""
+msgstr "Сохранить изменения, сделанные в новом проекте?"
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
-msgstr ""
+msgstr "Изменения будут утеряны, если их не сохранить."
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
-msgstr ""
+msgstr "&Сохранить"
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
-msgstr ""
+msgstr "&Не Сохранять"
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
msgstr "(новый проект)"
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
msgstr "Браузер"
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This "
"is probably not what you want; hide them by clicking the link at the top of "
"the text window."
msgstr ""
+"Ограничения отображаются, и будут экспортированы в файл. Предположительно, "
+"это не то, что требуется, если так, необходимо спрятать их, нажав ссылку "
+"вверху окна Браузера."
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid ""
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"dwg."
msgstr ""
+"Неподдерживаемый тип файла '%s'. Поддерживаются файлы с расширением .dxf и ."
+"dwg."
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
-msgstr ""
+msgstr "У ограничения должно быть значение и оно не должно быть справочным."
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
msgstr ""
+"Неправильное выделение для операции изменения значения с заданным шагом; "
+"необходимо выбрать ограничение со значением."
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
-msgstr ""
+msgstr "Сборка не содержит пересечения деталей - это хорошо."
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
"\n"
" %s"
msgstr ""
+"Объем тел:\n"
+"\n"
+" %s"
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
"\n"
" %s"
msgstr ""
+"\n"
+"Объем тел текущей группы:\n"
+"\n"
+" %s"
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"Curved surfaces have been approximated as triangles.\n"
"This introduces error, typically of around 1%."
msgstr ""
+"\n"
+"\n"
+"Кривые аппроксимированы кусочно-линейными функциями.\n"
+"Это приводит к ошибке в расчетах, обычно в пределах 1%."
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
msgstr ""
+"Площадь поверхности выбранных граней:\n"
+"\n"
+" %s\n"
+"\n"
+"Кривые аппроксимированы кусочно-линейными функциями.\n"
+"Это приводит к ошибке в расчетах, обычно в пределах 1%%."
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
msgstr ""
+"Эта группа не содержит замкнутых областей. В ней нет замкнутых контуров, "
+"примитивы не лежат в одной плоскости или самопересекаются."
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
msgstr ""
+"Площадь замкнутой области текущей группы:\n"
+"\n"
+" %s\n"
+"\n"
+"Кривые аппроксимированы кусочно-линейными функциями.\n"
+"Это приводит к ошибке в расчетах, обычно в пределах 1%%."
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
msgstr ""
+"Длина выбранных примитивов:\n"
+"\n"
+" %s\n"
+"\n"
+"Кривые аппроксимированы кусочно-линейными функциями.\n"
+"Это приводит к ошибке в расчетах, обычно в пределах 1%%."
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
msgstr ""
+"Неправильное выделение для расчета периметра; необходимо выбирать только "
+"отрезки, дуги и кривые в качестве исходных данных"
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
-msgstr ""
+msgstr "Неправильное выделение для трассировки; необходимо выбрать одну точку."
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
-msgstr ""
+msgstr "Невозможно записать в '%s'"
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
-msgstr ""
+msgstr "Полигональная сетка содержит самопересечения (это плохо)"
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
-msgstr ""
+msgstr "Полигональная сетка не содержит самопересечений (это хорошо)"
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
-msgstr ""
+msgstr "Полигональная сетка содержит \"оголенные\" ребра (это плохо)"
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
-msgstr ""
+msgstr "Полигональная сетка герметична (это хорошо)"
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"\n"
"The model contains %d triangles, from %d surfaces."
msgstr ""
+"\n"
+"\n"
+"Модель содержит %d треугольников, содержащихся в %d поверхностях."
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"\n"
"Zero problematic edges, good.%s"
msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Нет проблемных ребер - это хорошо.%s"
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"\n"
"%d problematic edges, bad.%s"
msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d найдены проблемные ребра - это плохо.%s"
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"\n"
"© 2008-%d Jonathan Westhues and other authors.\n"
msgstr ""
+"Это SolveSpace версии %s.\n"
+"\n"
+"Для дополнительной информации посетите сайт: http://solvespace.com/\n"
+"\n"
+"SolveSpace - это свободное программное обеспечение: поощряется изменение, "
+"улучшение\n"
+"распространение программы по условиям лицензии GNU\n"
+"General Public License (GPL) версии 3 или новее.\n"
+"\n"
+"НИКАКИХ ГАРАНТИЙ за пределами прав, \n"
+"предусмотренных законом. Дополнительная информация на сайте: http://gnu.org/"
+"licenses/\n"
+"\n"
+"© 2008-%d Джонатан Вэстью и другие авторы.\n"
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
"Невозможно применить стиль к примитиву, который произошел от другого "
"примитива. Попробуйте применить стиль к исходному примитиву."
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
msgstr "Имя стиля не может быть пустым."
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
msgstr "Невозможно сделать повторение меньше, чем 1 раз."
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
msgstr "Невозможно сделать повтор больше, чем 999 раз."
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
msgstr "Имя группы не может быть пустым."
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
msgstr "Прозрачность должна быть числом от нуля до единицы."
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
msgstr "Радиус не может быть нулевым или отрицательным."
#: toolbar.cpp:28
msgid "Sketch image from a file"
-msgstr ""
+msgstr "Импортировать изображение из файла"
#: toolbar.cpp:30
msgid "Create tangent arc at selected point"
#: toolbar.cpp:72
msgid "New group helix from active sketch"
-msgstr ""
+msgstr "Создать группу тела выдавливания по винтовой линии из текущего эскиза"
#: toolbar.cpp:74
msgid "New group revolve active sketch"
-msgstr ""
+msgstr "Создать группу тела вращения из текущего эскиза"
#: toolbar.cpp:76
msgid "New group step and repeat rotating"
msgid "&OK"
msgstr "ХОРОШО"
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
msgstr "Масштабный коэффициент не может быть нулевым или отрицательным."
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
msgstr "Неверный формат: введите данные как x, y, z"
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Неправильное выделение для ограничения 'отношение длин'.\n"
+#~ "Ограничение может принимать в качестве выделения следующие примитивы:\n"
+#~ "\n"
+#~ " * два отрезка\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Неправильное выделение для ограничения 'разница длин'.\n"
+#~ "Ограничение может принимать в качестве выделения следующие примитивы:\n"
+#~ "\n"
+#~ " * два отрезка\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "Отно&шение Длин"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "Ра&зница Длин"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "Неправильное выделение для создания эскиза.\n"
+#~ "Группа может быть создана, используя в качестве выделения следующие "
+#~ "примитивы:\n"
+#~ "\n"
+#~ " * точку (рабочая плоскость, ориентированная к ближайшему виду, "
+#~ "проходящая через точку)\n"
+#~ " * точку и два отрезка (рабочая плоскость, проходящая через точку и "
+#~ "параллельная отрезкам)\n"
+#~ " * рабочую плоскость (копия рабочей плоскости)\n"
+
#~ msgid "Specify between 0 and 8 digits after the decimal."
#~ msgstr "Введите число от 0 до 8."
--- /dev/null
+# Turkish translations for SolveSpace package.
+# Copyright (C) 2017 the SolveSpace authors
+# This file is distributed under the same license as the SolveSpace package.
+# Automatically generated, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SolveSpace 3.0\n"
+"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
+"PO-Revision-Date: 2022-02-01 23:02+0300\n"
+"Last-Translator: Mustafa Halil GÖRENTAŞ <halil.mustafa@gmail.com>\n"
+"Language-Team: app4soft\n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 3.0\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+#: clipboard.cpp:309
+msgid ""
+"Cut, paste, and copy work only in a workplane.\n"
+"\n"
+"Activate one with Sketch -> In Workplane."
+msgstr ""
+"Çalışmayı yalnızca bir çalışma düzleminde kesin, yapıştırın ve kopyalayın.\n"
+"\n"
+"Çizim -> Çalışma Düzleminde menüsü ile bir düzlemi etkinleştirin."
+
+#: clipboard.cpp:326
+msgid "Clipboard is empty; nothing to paste."
+msgstr "Pano boş; yapıştırılacak bir şey yok."
+
+#: clipboard.cpp:373
+msgid "Number of copies to paste must be at least one."
+msgstr "Yapıştırılacak kopya sayısı en az bir olmalıdır."
+
+#: clipboard.cpp:389 textscreens.cpp:833
+msgid "Scale cannot be zero."
+msgstr "Ölçek sıfır olamaz."
+
+#: clipboard.cpp:431
+msgid "Select one point to define origin of rotation."
+msgstr "Çevirme merkezini tanımlamak için bir nokta seçin."
+
+#: clipboard.cpp:443
+msgid "Select two points to define translation vector."
+msgstr "Doğrusal kopyalama vektörünü tanımlamak için iki nokta seçin."
+
+#: clipboard.cpp:453
+msgid ""
+"Transformation is identity. So all copies will be exactly on top of each "
+"other."
+msgstr "Dönüşüm özdeştir. Yani tüm kopyalar tam olarak üst üste gelecek."
+
+#: clipboard.cpp:457
+msgid "Too many items to paste; split this into smaller pastes."
+msgstr ""
+"Yapıştırılamayacak kadar çok öğe; bunu daha küçük yapıştıma şeklinde bölün."
+
+#: clipboard.cpp:462
+msgid "No workplane active."
+msgstr "Etkin çalışma düzlemi yok."
+
+#: confscreen.cpp:381
+msgid "Bad format: specify coordinates as x, y, z"
+msgstr "Hatalı biçim: koordinatları x, y, z olarak belirtin"
+
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
+msgid "Bad format: specify color as r, g, b"
+msgstr "Hatalı biçim: rengi r, g, b olarak belirtin"
+
+#: confscreen.cpp:417
+msgid ""
+"The perspective factor will have no effect until you enable View -> Use "
+"Perspective Projection."
+msgstr ""
+"Görünüm -> Perspektif Projeksiyonu Kullan'ı etkinleştirene kadar perspektif "
+"katsayısının hiçbir etkisi olmayacaktır."
+
+#: confscreen.cpp:435 confscreen.cpp:445
+#, c-format
+msgid "Specify between 0 and %d digits after the decimal."
+msgstr "Ondalık basamak sonrası 0 ile %d arasında rakam belirtin."
+
+#: confscreen.cpp:457
+msgid "Export scale must not be zero!"
+msgstr "Dışa aktarma ölçeği sıfır olmamalıdır!"
+
+#: confscreen.cpp:469
+msgid "Cutter radius offset must not be negative!"
+msgstr "Kesici yarıçap ofseti negatif olmamalıdır!"
+
+#: confscreen.cpp:528
+msgid "Bad value: autosave interval should be positive"
+msgstr "Hatalı değer: otomatik kaydetme süresi pozitif olmalıdır"
+
+#: confscreen.cpp:531
+msgid "Bad format: specify interval in integral minutes"
+msgstr "Hatalı biçim: süre aralığını dakika cinsinden belirtin"
+
+#: constraint.cpp:12
+msgctxt "constr-name"
+msgid "pts-coincident"
+msgstr "çakışık-nktlar"
+
+#: constraint.cpp:13
+msgctxt "constr-name"
+msgid "pt-pt-distance"
+msgstr "nkt-nkt-mesafe"
+
+#: constraint.cpp:14
+msgctxt "constr-name"
+msgid "pt-line-distance"
+msgstr "nkt-çizgi-mesafesi"
+
+#: constraint.cpp:15
+msgctxt "constr-name"
+msgid "pt-plane-distance"
+msgstr "nkt-düzlem-mesafesi"
+
+#: constraint.cpp:16
+msgctxt "constr-name"
+msgid "pt-face-distance"
+msgstr "nkt-yüzey-mesafesi"
+
+#: constraint.cpp:17
+msgctxt "constr-name"
+msgid "proj-pt-pt-distance"
+msgstr "proj-nkt-nkt-mesafesi"
+
+#: constraint.cpp:18
+msgctxt "constr-name"
+msgid "pt-in-plane"
+msgstr "düzlemde-nkt"
+
+#: constraint.cpp:19
+msgctxt "constr-name"
+msgid "pt-on-line"
+msgstr "çizgide-nkt"
+
+#: constraint.cpp:20
+msgctxt "constr-name"
+msgid "pt-on-face"
+msgstr "yüzeyde-nkt"
+
+#: constraint.cpp:21
+msgctxt "constr-name"
+msgid "eq-length"
+msgstr "eşit-uzunluk"
+
+#: constraint.cpp:22
+msgctxt "constr-name"
+msgid "eq-length-and-pt-ln-dist"
+msgstr "eşit-uzunluk-ve-çzg-nkt-mesafesi"
+
+#: constraint.cpp:23
+msgctxt "constr-name"
+msgid "eq-pt-line-distances"
+msgstr "eşit-nkt-çizgi-mesafesi"
+
+#: constraint.cpp:24
+msgctxt "constr-name"
+msgid "length-ratio"
+msgstr "uzunluk-oranı"
+
+#: constraint.cpp:25
+msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr "yay-yay-uzunluk-oranı"
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr "yay-çizgi-uzunluk-oranı"
+
+#: constraint.cpp:27
+msgctxt "constr-name"
+msgid "length-difference"
+msgstr "uzunluk-farkı"
+
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr "yay-yay-uzunluk-farkı"
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr "yay-çizgi-uzunluk-farkı"
+
+#: constraint.cpp:30
+msgctxt "constr-name"
+msgid "symmetric"
+msgstr "simetrik"
+
+#: constraint.cpp:31
+msgctxt "constr-name"
+msgid "symmetric-h"
+msgstr "simetrik-y"
+
+#: constraint.cpp:32
+msgctxt "constr-name"
+msgid "symmetric-v"
+msgstr "simetrik-d"
+
+#: constraint.cpp:33
+msgctxt "constr-name"
+msgid "symmetric-line"
+msgstr "simetrik-çizgi"
+
+#: constraint.cpp:34
+msgctxt "constr-name"
+msgid "at-midpoint"
+msgstr "orta noktada"
+
+#: constraint.cpp:35
+msgctxt "constr-name"
+msgid "horizontal"
+msgstr "yatay"
+
+#: constraint.cpp:36
+msgctxt "constr-name"
+msgid "vertical"
+msgstr "dikey"
+
+#: constraint.cpp:37
+msgctxt "constr-name"
+msgid "diameter"
+msgstr "çap"
+
+#: constraint.cpp:38
+msgctxt "constr-name"
+msgid "pt-on-circle"
+msgstr "çemberde-nkt"
+
+#: constraint.cpp:39
+msgctxt "constr-name"
+msgid "same-orientation"
+msgstr "aynı-yön"
+
+#: constraint.cpp:40
+msgctxt "constr-name"
+msgid "angle"
+msgstr "açı"
+
+#: constraint.cpp:41
+msgctxt "constr-name"
+msgid "parallel"
+msgstr "paralel"
+
+#: constraint.cpp:42
+msgctxt "constr-name"
+msgid "arc-line-tangent"
+msgstr "yay-çizgi-teğet"
+
+#: constraint.cpp:43
+msgctxt "constr-name"
+msgid "cubic-line-tangent"
+msgstr "k.eğri-çizgi-teğet"
+
+#: constraint.cpp:44
+msgctxt "constr-name"
+msgid "curve-curve-tangent"
+msgstr "eğri-eğri-teğet"
+
+#: constraint.cpp:45
+msgctxt "constr-name"
+msgid "perpendicular"
+msgstr "dik"
+
+#: constraint.cpp:46
+msgctxt "constr-name"
+msgid "eq-radius"
+msgstr "eşit-yarıçap"
+
+#: constraint.cpp:47
+msgctxt "constr-name"
+msgid "eq-angle"
+msgstr "eşit-açı"
+
+#: constraint.cpp:48
+msgctxt "constr-name"
+msgid "eq-line-len-arc-len"
+msgstr "eşit-çizgi-uzn-yay-uzn"
+
+#: constraint.cpp:49
+msgctxt "constr-name"
+msgid "lock-where-dragged"
+msgstr "sürüklendiği-yerde-kilitli"
+
+#: constraint.cpp:50
+msgctxt "constr-name"
+msgid "comment"
+msgstr "yorum"
+
+#: constraint.cpp:144
+msgid ""
+"The tangent arc and line segment must share an endpoint. Constrain them with "
+"Constrain -> On Point before constraining tangent."
+msgstr ""
+"Teğet için yay ve çizgi parçası bir uç noktayı paylaşmalıdır. Teğet "
+"kısıtlamasından önce bunları Kısıtla -> Noktada ile kısıtlayın."
+
+#: constraint.cpp:163
+msgid ""
+"The tangent cubic and line segment must share an endpoint. Constrain them "
+"with Constrain -> On Point before constraining tangent."
+msgstr ""
+"Teğet için eğri ve çizgi parçası bir uç noktayı paylaşmalıdır. Teğet "
+"kısıtlamasından önce onları Kısıtla -> Noktada ile kısıtlayın."
+
+#: constraint.cpp:189
+msgid ""
+"The curves must share an endpoint. Constrain them with Constrain -> On Point "
+"before constraining tangent."
+msgstr ""
+"Eğriler bir uç noktayı paylaşmalıdır. Teğet kısıtlamasından önce onları "
+"Kısıtla -> Noktada ile kısıtlayın."
+
+#: constraint.cpp:238
+msgid ""
+"Bad selection for distance / diameter constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two points (distance between points)\n"
+" * a line segment (length)\n"
+" * two points and a line segment or normal (projected distance)\n"
+" * a workplane and a point (minimum distance)\n"
+" * a line segment and a point (minimum distance)\n"
+" * a plane face and a point (minimum distance)\n"
+" * a circle or an arc (diameter)\n"
+msgstr ""
+"Mesafe / çap kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * iki nokta (noktalar arası mesafe)\n"
+" * bir çizgi parçası (uzunluk)\n"
+" * iki nokta ve bir çizgi parçası veya normal (izdüşüm mesafesi)\n"
+" * bir çalışma düzlemi ve bir nokta (minimum mesafe)\n"
+" * bir çizgi parçası ve bir nokta (minimum mesafe)\n"
+" * bir düzlem yüzeyi ve bir nokta (minimum mesafe)\n"
+" * bir daire veya yay (çap)\n"
+
+#: constraint.cpp:291
+msgid ""
+"Bad selection for on point / curve / plane constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * two points (points coincident)\n"
+" * a point and a workplane (point in plane)\n"
+" * a point and a line segment (point on line)\n"
+" * a point and a circle or arc (point on curve)\n"
+" * a point and a plane face (point on face)\n"
+msgstr ""
+"Noktada / Eğride / Düzlemde kısıtlaması oluşturmak için hatalı seçim. Bu "
+"kısıtlama şunlara uygulanabilir:\n"
+"\n"
+" * iki nokta (çakışan noktalar)\n"
+" * bir nokta ve bir çalışma düzlemi (nokta ile düzlem çakışır)\n"
+" * bir nokta ve bir çizgi parçası (nokta ile çizgi çakışır)\n"
+" * bir nokta ve bir daire veya yay (nokta ile eğri çakışır)\n"
+" * bir nokta ve bir düzlem yüzeyi (nokta ile yüzey çakışır)\n"
+
+#: constraint.cpp:353
+msgid ""
+"Bad selection for equal length / radius constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * two line segments (equal length)\n"
+" * two line segments and two points (equal point-line distances)\n"
+" * a line segment and two points (equal point-line distances)\n"
+" * a line segment, and a point and line segment (point-line distance "
+"equals length)\n"
+" * four line segments or normals (equal angle between A,B and C,D)\n"
+" * three line segments or normals (equal angle between A,B and B,C)\n"
+" * two circles or arcs (equal radius)\n"
+" * a line segment and an arc (line segment length equals arc length)\n"
+msgstr ""
+"Eşit uzunluk / yarıçap kısıtlaması oluşturmak için hatalı seçim. Bu "
+"kısıtlama şunlara uygulanabilir:\n"
+"\n"
+" * iki çizgi parçası (eşit uzunluk)\n"
+" * iki çizgi parçası ve iki nokta (eşit nokta-çizgi arası mesafeler)\n"
+" * bir çizgi parçası ve iki nokta (eşit nokta-çizgi arası mesafeler)\n"
+" * bir çizgi parçası ve bir nokta ve çizgi parçası (nokta-çizgi arası "
+"mesafe, çizgi uzunluğa eşittir)\n"
+" * dört çizgi parçası veya normal (A, B ve C, D arasında eşit açı)\n"
+" * üç çizgi parçası veya normal (A, B ve B, C arasında eşit açı)\n"
+" * iki daire veya yay (eşit yarıçap)\n"
+" * bir çizgi parçası ve bir yay (çizgi parçasının uzunluğu, yayın "
+"uzunluğuna eşittir)\n"
+
+#: constraint.cpp:407
+msgid ""
+"Bad selection for length ratio constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
+msgstr ""
+"Uzunluk oranı kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama "
+"aşağıdakiler için geçerli olabilir:\n"
+"\n"
+" * iki çizgi parçası\n"
+" * iki yay\n"
+" * bir yay ve bir çizgi parçası\n"
+
+#: constraint.cpp:441
+msgid ""
+"Bad selection for length difference constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
+msgstr ""
+"Uzunluk farkı kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama "
+"aşağıdakiler için geçerli olabilir:\n"
+"\n"
+" * iki çizgi parçası\n"
+" * iki yay\n"
+" * bir yay ve bir çizgi parçası\n"
+
+#: constraint.cpp:472
+msgid ""
+"Bad selection for at midpoint constraint. This constraint can apply to:\n"
+"\n"
+" * a line segment and a point (point at midpoint)\n"
+" * a line segment and a workplane (line's midpoint on plane)\n"
+msgstr ""
+"Orta nokta kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * bir çizgi parçası ve bir nokta (nokta çizgi ortasında)\n"
+" * bir çizgi parçası ve bir çalışma düzlemi (çizgi düzlemin ortasına "
+"taşınır )\n"
+
+#: constraint.cpp:530
+msgid ""
+"Bad selection for symmetric constraint. This constraint can apply to:\n"
+"\n"
+" * two points or a line segment (symmetric about workplane's coordinate "
+"axis)\n"
+" * line segment, and two points or a line segment (symmetric about line "
+"segment)\n"
+" * workplane, and two points or a line segment (symmetric about "
+"workplane)\n"
+msgstr ""
+"Simetri kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * iki nokta veya bir çizgi parçası (çalışma düzleminin koordinat "
+"eksenine göre simetrik)\n"
+" * çizgi parçası ve iki nokta veya bir çizgi parçası (çizgi parçası "
+"etrafında simetrik)\n"
+" * çalışma düzlemi ve iki nokta veya bir çizgi parçası (çalışma düzlemine "
+"göre simetrik)\n"
+
+#: constraint.cpp:545
+msgid ""
+"A workplane must be active when constraining symmetric without an explicit "
+"symmetry plane."
+msgstr ""
+"Simetri kısıtlamasında simetri düzlemini olarak kullanılacak bir çalışma "
+"düzlemi etkin olmalıdır."
+
+#: constraint.cpp:579
+msgid ""
+"Activate a workplane (with Sketch -> In Workplane) before applying a "
+"horizontal or vertical constraint."
+msgstr ""
+"Yatay veya dikey bir kısıtlama uygulamadan önce bir çalışma düzlemini (Çizim "
+"-> Çalışma Düzleminde menüsü ile) etkinleştirin."
+
+#: constraint.cpp:592
+msgid ""
+"Bad selection for horizontal / vertical constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * two points\n"
+" * a line segment\n"
+msgstr ""
+"Yatay / Dikey kısıtlama oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * iki nokta\n"
+" * bir çizgi parçası\n"
+
+#: constraint.cpp:613
+msgid ""
+"Bad selection for same orientation constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two normals\n"
+msgstr ""
+"Aynı yön kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * iki normal\n"
+
+#: constraint.cpp:663
+msgid "Must select an angle constraint."
+msgstr "Bir açı kısıtlaması seçilmelidir."
+
+#: constraint.cpp:676
+msgid "Must select a constraint with associated label."
+msgstr "İlgili etikete sahip bir kısıtlama seçilmelidir."
+
+#: constraint.cpp:687
+msgid ""
+"Bad selection for angle constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+" * a line segment and a normal\n"
+" * two normals\n"
+msgstr ""
+"Açı kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * iki çizgi parçası\n"
+" * bir çizgi parçası ve normal\n"
+" * iki normal\n"
+
+#: constraint.cpp:754
+msgid "Curve-curve tangency must apply in workplane."
+msgstr "Eğri-eğri teğetliği çalışma düzlemine uygulanmalıdır."
+
+#: constraint.cpp:766
+msgid ""
+"Bad selection for parallel / tangent constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two line segments (parallel)\n"
+" * a line segment and a normal (parallel)\n"
+" * two normals (parallel)\n"
+" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n"
+msgstr ""
+"Paralel / Teğet kısıtlaması oluşturmak için hatalı seçim. Bu kısıtlama "
+"şunlara uygulanabilir:\n"
+"\n"
+" * iki çizgi parçası (paralel)\n"
+" * bir çizgi parçası ve normal (paralel)\n"
+" * iki normal (paralel)\n"
+" * bir uç noktayı paylaşan(teğet) iki çizgi parçası, yay veya bezier'ler\n"
+
+#: constraint.cpp:784
+msgid ""
+"Bad selection for perpendicular constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+" * a line segment and a normal\n"
+" * two normals\n"
+msgstr ""
+"Dikey kısıtlama oluşturmak için hatalı seçim. Bu kısıtlama şunlara "
+"uygulanabilir:\n"
+"\n"
+" * iki çizgi parçası\n"
+" * bir çizgi parçası ve normal\n"
+" * iki normal\n"
+
+#: constraint.cpp:799
+msgid ""
+"Bad selection for lock point where dragged constraint. This constraint can "
+"apply to:\n"
+"\n"
+" * a point\n"
+msgstr ""
+"Sürüklendiği yerde noktayı kısıtlamak için hatalı seçim. Bu kısıtlama "
+"şunlara uygulanabilir:\n"
+"\n"
+"* bir nokta\n"
+
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "YENI YORUM -- DÜZENLEMEK ICIN CIFT-TIKLAYIN"
+
+#: constraint.cpp:818
+msgid "click center of comment text"
+msgstr "yorum metninin ortasını tıklatın"
+
+#: export.cpp:19
+msgid ""
+"No solid model present; draw one with extrudes and revolves, or use Export "
+"2d View to export bare lines and curves."
+msgstr ""
+"Katı model yok; katılama ve döndürme komutları ile bir model çizin veya açık "
+"çizgileri ve eğrileri dışa vermek için Görüntüyü 2d olarak Dışa Aktar'ı "
+"kullanın."
+
+#: export.cpp:61
+msgid ""
+"Bad selection for export section. Please select:\n"
+"\n"
+" * nothing, with an active workplane (workplane is section plane)\n"
+" * a face (section plane through face)\n"
+" * a point and two line segments (plane through point and parallel to "
+"lines)\n"
+msgstr ""
+"Kesiti Dışa Aktarmak için hatalı seçim. Lütfen şunlardan birini seçin:\n"
+"\n"
+" * aktif bir çalışma düzleminde iken hiçbir şey seçmeyin (çalışma "
+"düzlemi, kesit düzlemidir)\n"
+" * bir yüzey (yüzeyden kesit düzlemi)\n"
+" * bir nokta ve iki çizgi parçası (nokta ve paralel çizgiler boyunca "
+"düzlem)\n"
+
+#: export.cpp:818
+msgid "Active group mesh is empty; nothing to export."
+msgstr "Etkin grup ağı boş; dışa aktarılacak bir şey yok."
+
+#: exportvector.cpp:336
+msgid "freehand lines were replaced with continuous lines"
+msgstr "serbest çizgiler, sürekli çizgilerle değiştirildi"
+
+#: exportvector.cpp:338
+msgid "zigzag lines were replaced with continuous lines"
+msgstr "zikzak çizgiler sürekli çizgilerle değiştirildi"
+
+#: exportvector.cpp:592
+msgid ""
+"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
+msgstr "Çizimin bazı yönlerinin DXF eşdeğeri yoktur ve dışa aktarılmamıştır:\n"
+
+#: exportvector.cpp:838
+msgid ""
+"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
+msgstr ""
+"PDF sayfa boyutu 200 x 200 inç'i aşıyor; birçok görüntüleyici bu dosyayı "
+"reddedebilir."
+
+#: file.cpp:44 group.cpp:91
+msgctxt "group-name"
+msgid "sketch-in-plane"
+msgstr "düzlemde çizim"
+
+#: file.cpp:62
+msgctxt "group-name"
+msgid "#references"
+msgstr "#referanslar"
+
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr "Dosya boş. Bozuk olabilir."
+
+#: file.cpp:555
+msgid ""
+"Unrecognized data in file. This file may be corrupt, or from a newer version "
+"of the program."
+msgstr ""
+"Dosyada veriler tanınmadı. Bu dosya bozuk veya programın daha yeni bir "
+"sürümü ile oluşturulmuş olabilir."
+
+#: file.cpp:867
+msgctxt "title"
+msgid "Missing File"
+msgstr "Kayıp Dosya"
+
+#: file.cpp:868
+#, c-format
+msgctxt "dialog"
+msgid "The linked file “%s” is not present."
+msgstr "\"%s\" bağlantılı dosya yok."
+
+#: file.cpp:870
+msgctxt "dialog"
+msgid ""
+"Do you want to locate it manually?\n"
+"\n"
+"If you decline, any geometry that depends on the missing file will be "
+"permanently removed."
+msgstr ""
+"Konumu El ile bulmak istiyor musunuz?\n"
+"\n"
+"Reddederseniz, eksik dosyaya bağlı olan geometri kalıcı olarak "
+"kaldırılacaktır."
+
+#: file.cpp:873
+msgctxt "button"
+msgid "&Yes"
+msgstr "&Evet"
+
+#: file.cpp:875
+msgctxt "button"
+msgid "&No"
+msgstr "&Hayır"
+
+#: file.cpp:877 solvespace.cpp:611
+msgctxt "button"
+msgid "&Cancel"
+msgstr "&İptal"
+
+#: graphicswin.cpp:41
+msgid "&File"
+msgstr "&Dosya"
+
+#: graphicswin.cpp:42
+msgid "&New"
+msgstr "&Yeni"
+
+#: graphicswin.cpp:43
+msgid "&Open..."
+msgstr "&Aç..."
+
+#: graphicswin.cpp:44
+msgid "Open &Recent"
+msgstr "&Son Erişilenden Aç"
+
+#: graphicswin.cpp:45
+msgid "&Save"
+msgstr "&Kaydet"
+
+#: graphicswin.cpp:46
+msgid "Save &As..."
+msgstr "&Farklı kaydet..."
+
+#: graphicswin.cpp:48
+msgid "Export &Image..."
+msgstr "&Resim olarak dışa aktar..."
+
+#: graphicswin.cpp:49
+msgid "Export 2d &View..."
+msgstr "&Görüntüyü 2d olarak dışa aktar..."
+
+#: graphicswin.cpp:50
+msgid "Export 2d &Section..."
+msgstr "&Kesiti 2d olarak dışa aktar..."
+
+#: graphicswin.cpp:51
+msgid "Export 3d &Wireframe..."
+msgstr "3d &TelKafes olarak dışa aktar..."
+
+#: graphicswin.cpp:52
+msgid "Export Triangle &Mesh..."
+msgstr "&Üçgensel Ağ olarak dışa aktar..."
+
+#: graphicswin.cpp:53
+msgid "Export &Surfaces..."
+msgstr "Y&üzeyleri dışa aktar..."
+
+#: graphicswin.cpp:54
+msgid "Im&port..."
+msgstr "&İçe Aktar..."
+
+#: graphicswin.cpp:57
+msgid "E&xit"
+msgstr "&Çıkış"
+
+#: graphicswin.cpp:60
+msgid "&Edit"
+msgstr "D&üzen"
+
+#: graphicswin.cpp:61
+msgid "&Undo"
+msgstr "&Geri al"
+
+#: graphicswin.cpp:62
+msgid "&Redo"
+msgstr "&Yinele"
+
+#: graphicswin.cpp:63
+msgid "Re&generate All"
+msgstr "Tümünü Yeniden &Oluştur"
+
+#: graphicswin.cpp:65
+msgid "Snap Selection to &Grid"
+msgstr "Seçimi &Izgaraya Tuttur"
+
+#: graphicswin.cpp:66
+msgid "Rotate Imported &90°"
+msgstr "İçe Aktarılanları &90° Döndür"
+
+#: graphicswin.cpp:68
+msgid "Cu&t"
+msgstr "&Kes"
+
+#: graphicswin.cpp:69
+msgid "&Copy"
+msgstr "K&opyala"
+
+#: graphicswin.cpp:70
+msgid "&Paste"
+msgstr "Y&apıştır"
+
+#: graphicswin.cpp:71
+msgid "Paste &Transformed..."
+msgstr "&Dönüştürerek Yapıştır..."
+
+#: graphicswin.cpp:72
+msgid "&Delete"
+msgstr "&Sil"
+
+#: graphicswin.cpp:74
+msgid "Select &Edge Chain"
+msgstr "Kenar &Zincirini Seç"
+
+#: graphicswin.cpp:75
+msgid "Select &All"
+msgstr "&Tümünü Seç"
+
+#: graphicswin.cpp:76
+msgid "&Unselect All"
+msgstr "Tüm Seçimi &Kaldır"
+
+#: graphicswin.cpp:78
+msgid "&Line Styles..."
+msgstr "&Çizgi Biçimi..."
+
+#: graphicswin.cpp:79
+msgid "&View Projection..."
+msgstr "&Projeksiyonu Görüntüle..."
+
+#: graphicswin.cpp:81
+msgid "Con&figuration..."
+msgstr "Y&apılandır..."
+
+#: graphicswin.cpp:84
+msgid "&View"
+msgstr "&Görünüm"
+
+#: graphicswin.cpp:85
+msgid "Zoom &In"
+msgstr "&Yakınlaş"
+
+#: graphicswin.cpp:86
+msgid "Zoom &Out"
+msgstr "&Uzaklaş"
+
+#: graphicswin.cpp:87
+msgid "Zoom To &Fit"
+msgstr "&Sığacak Şekilde Yakınlaş"
+
+#: graphicswin.cpp:89
+msgid "Align View to &Workplane"
+msgstr "Görünümü &Çalışma Düzlemine Hizala"
+
+#: graphicswin.cpp:90
+msgid "Nearest &Ortho View"
+msgstr "En Yakın &Dik Görünüm"
+
+#: graphicswin.cpp:91
+msgid "Nearest &Isometric View"
+msgstr "En Yakın &İzometrik Görünüm"
+
+#: graphicswin.cpp:92
+msgid "&Center View At Point"
+msgstr "&Noktayı Merkezde Görüntüle"
+
+#: graphicswin.cpp:94
+msgid "Show Snap &Grid"
+msgstr "Yakalama &Izgarasını Göster"
+
+#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+msgstr "Aktif Olmayan Katıları &Koyulaştır"
+
+#: graphicswin.cpp:96
+msgid "Use &Perspective Projection"
+msgstr "&Perspektif Projeksiyonu Kullan"
+
+#: graphicswin.cpp:97
+msgid "Show E&xploded View"
+msgstr "Pat&latılmış Görünümü Göster"
+
+#: graphicswin.cpp:98
+msgid "Dimension &Units"
+msgstr "Ölçü &Birimleri"
+
+#: graphicswin.cpp:99
+msgid "Dimensions in &Millimeters"
+msgstr "&Milimetre cinsinden ölçü"
+
+#: graphicswin.cpp:100
+msgid "Dimensions in M&eters"
+msgstr "M&etre cinsinden ölçü"
+
+#: graphicswin.cpp:101
+msgid "Dimensions in &Inches"
+msgstr "&İnç cinsinden ölçü"
+
+#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr "&Fit ve İnç cinsinden ölçü"
+
+#: graphicswin.cpp:104
+msgid "Show &Toolbar"
+msgstr "&Araç Çubuğunu Göster"
+
+#: graphicswin.cpp:105
+msgid "Show Property Bro&wser"
+msgstr "&Özellik Penceresini Göster"
+
+#: graphicswin.cpp:107
+msgid "&Full Screen"
+msgstr "&Tam Ekran"
+
+#: graphicswin.cpp:109
+msgid "&New Group"
+msgstr "Yeni &Grup"
+
+#: graphicswin.cpp:110
+msgid "Sketch In &3d"
+msgstr "&3d'de Çizim Yap"
+
+#: graphicswin.cpp:111
+msgid "Sketch In New &Workplane"
+msgstr "&Yeni Çalışma Düzleminde Çizim Yap"
+
+#: graphicswin.cpp:113
+msgid "Step &Translating"
+msgstr "&Doğrusal Kopya"
+
+#: graphicswin.cpp:114
+msgid "Step &Rotating"
+msgstr "D&airesel Kopya"
+
+#: graphicswin.cpp:116
+msgid "E&xtrude"
+msgstr "&Uzatarak Katıla"
+
+#: graphicswin.cpp:117
+msgid "&Helix"
+msgstr "&Helis"
+
+#: graphicswin.cpp:118
+msgid "&Lathe"
+msgstr "&Tam döndürerek katıla"
+
+#: graphicswin.cpp:119
+msgid "Re&volve"
+msgstr "&Kısmen döndürerek katıla"
+
+#: graphicswin.cpp:121
+msgid "Link / Assemble..."
+msgstr "Bağla / Montajla..."
+
+#: graphicswin.cpp:122
+msgid "Link Recent"
+msgstr "Son Erişilenden Bağla"
+
+#: graphicswin.cpp:124
+msgid "&Sketch"
+msgstr "&Çizim"
+
+#: graphicswin.cpp:125
+msgid "In &Workplane"
+msgstr "Ç&alışma Düzleminde"
+
+#: graphicswin.cpp:126
+msgid "Anywhere In &3d"
+msgstr "&3d'de Herhangi Bir Yerde"
+
+#: graphicswin.cpp:128
+msgid "Datum &Point"
+msgstr "Referasn &Noktası"
+
+#: graphicswin.cpp:129
+msgid "&Workplane"
+msgstr "Ça&lışma Düzlemi"
+
+#: graphicswin.cpp:131
+msgid "Line &Segment"
+msgstr "Ç&izgi"
+
+#: graphicswin.cpp:132
+msgid "C&onstruction Line Segment"
+msgstr "&Yardımcı Çizgi"
+
+#: graphicswin.cpp:133
+msgid "&Rectangle"
+msgstr "&Dikdörtgen"
+
+#: graphicswin.cpp:134
+msgid "&Circle"
+msgstr "D&aire"
+
+#: graphicswin.cpp:135
+msgid "&Arc of a Circle"
+msgstr "Çember &Yayı"
+
+#: graphicswin.cpp:136
+msgid "&Bezier Cubic Spline"
+msgstr "Bezier Kübik &Eğri"
+
+#: graphicswin.cpp:138
+msgid "&Text in TrueType Font"
+msgstr "TrueType Yazı Tipinde &Metin"
+
+#: graphicswin.cpp:139
+msgid "&Image"
+msgstr "&Resim / Görüntü"
+
+#: graphicswin.cpp:141
+msgid "To&ggle Construction"
+msgstr "Yap&ıyı Değiştir"
+
+#: graphicswin.cpp:142
+msgid "Tangent &Arc at Point"
+msgstr "&Yuvarlat (Radyus)"
+
+#: graphicswin.cpp:143
+msgid "Split Curves at &Intersection"
+msgstr "Eğrileri Kesişim Yerinden &Böl"
+
+#: graphicswin.cpp:145
+msgid "&Constrain"
+msgstr "&Kısıtla"
+
+#: graphicswin.cpp:146
+msgid "&Distance / Diameter"
+msgstr "&Mesafe / Çap"
+
+#: graphicswin.cpp:147
+msgid "Re&ference Dimension"
+msgstr "&Referans Ölçü"
+
+#: graphicswin.cpp:148
+msgid "A&ngle"
+msgstr "&Açı"
+
+#: graphicswin.cpp:149
+msgid "Reference An&gle"
+msgstr "Referans A&çı"
+
+#: graphicswin.cpp:150
+msgid "Other S&upplementary Angle"
+msgstr "Diğer &Bütünler Açı"
+
+#: graphicswin.cpp:151
+msgid "Toggle R&eference Dim"
+msgstr "Ölçüyü Re&ferans Yap / Yapma"
+
+#: graphicswin.cpp:153
+msgid "&Horizontal"
+msgstr "&Yatay"
+
+#: graphicswin.cpp:154
+msgid "&Vertical"
+msgstr "&Dikey"
+
+#: graphicswin.cpp:156
+msgid "&On Point / Curve / Plane"
+msgstr "&Noktada / Eğride / Düzlemde"
+
+#: graphicswin.cpp:157
+msgid "E&qual Length / Radius / Angle"
+msgstr "&Eşit Uzunluk / Yarıçap / Açı"
+
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr "&Uzunluk / Yay Oranı"
+
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr "Uzunluk / Yay &Farkı"
+
+#: graphicswin.cpp:160
+msgid "At &Midpoint"
+msgstr "&Orta Noktada"
+
+#: graphicswin.cpp:161
+msgid "S&ymmetric"
+msgstr "&Simetrik"
+
+#: graphicswin.cpp:162
+msgid "Para&llel / Tangent"
+msgstr "&Paralel / Teğet"
+
+#: graphicswin.cpp:163
+msgid "&Perpendicular"
+msgstr "D&ik"
+
+#: graphicswin.cpp:164
+msgid "Same Orient&ation"
+msgstr "Aynı &Yön"
+
+#: graphicswin.cpp:165
+msgid "Lock Point Where &Dragged"
+msgstr "Sürüklendiği Yerde Noktayı &Kilitle"
+
+#: graphicswin.cpp:167
+msgid "Comment"
+msgstr "Y&orum"
+
+#: graphicswin.cpp:169
+msgid "&Analyze"
+msgstr "&Analiz"
+
+#: graphicswin.cpp:170
+msgid "Measure &Volume"
+msgstr "&Hacmi Hesapla"
+
+#: graphicswin.cpp:171
+msgid "Measure A&rea"
+msgstr "&Alanı Hesapla"
+
+#: graphicswin.cpp:172
+msgid "Measure &Perimeter"
+msgstr "&Çevre Uzunluğunu Hesapla"
+
+#: graphicswin.cpp:173
+msgid "Show &Interfering Parts"
+msgstr "&Engelleyici Parçaları Göster"
+
+#: graphicswin.cpp:174
+msgid "Show &Naked Edges"
+msgstr "A&çık Kenarları Göster"
+
+#: graphicswin.cpp:175
+msgid "Show &Center of Mass"
+msgstr "&Kütle Merkezini Göster"
+
+#: graphicswin.cpp:177
+msgid "Show &Underconstrained Points"
+msgstr "Kı&sıtlanmamış Noktaları Göster"
+
+#: graphicswin.cpp:179
+msgid "&Trace Point"
+msgstr "&İzlenecek Nokta"
+
+#: graphicswin.cpp:180
+msgid "&Stop Tracing..."
+msgstr "&İzlemeyi Durdur..."
+
+#: graphicswin.cpp:181
+msgid "Step &Dimension..."
+msgstr "Adım &Ölçüsünü Ayarla..."
+
+#: graphicswin.cpp:183
+msgid "&Help"
+msgstr "&Yardım"
+
+#: graphicswin.cpp:184
+msgid "&Language"
+msgstr "&Dil"
+
+#: graphicswin.cpp:185
+msgid "&Website / Manual"
+msgstr "&Web sitesi / Kılavuz"
+
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr "GitHub Commitlere git"
+
+#: graphicswin.cpp:188
+msgid "&About"
+msgstr "&Hakkında"
+
+#: graphicswin.cpp:362
+msgid "(no recent files)"
+msgstr "(son dosyalar yok)"
+
+#: graphicswin.cpp:370
+#, c-format
+msgid "File '%s' does not exist."
+msgstr "'%s' dosyası mevcut değil."
+
+#: graphicswin.cpp:737
+msgid "No workplane is active, so the grid will not appear."
+msgstr "Etkin çalışma düzlemi yok, bu nedenle ızgara görünmeyecektir."
+
+#: graphicswin.cpp:752
+msgid ""
+"The perspective factor is set to zero, so the view will always be a parallel "
+"projection.\n"
+"\n"
+"For a perspective projection, modify the perspective factor in the "
+"configuration screen. A value around 0.3 is typical."
+msgstr ""
+"Perspektif katsayısı sıfıra ayarlanmıştır, bu nedenle görünüm her zaman "
+"paralel bir projeksiyon olacaktır.\n"
+"\n"
+"Perspektif bir projeksiyon için, yapılandırma ekranındaki perspektif "
+"katsayısını değiştirin. 0.3 civarında bir değer normaldir."
+
+#: graphicswin.cpp:837
+msgid ""
+"Select a point; this point will become the center of the view on screen."
+msgstr "Bir nokta seçin; bu nokta ekrandaki görüntünün merkezi olacaktır."
+
+#: graphicswin.cpp:1137
+msgid "No additional entities share endpoints with the selected entities."
+msgstr "Hiçbir ek öğe, seçili öğeler ile uç noktaları paylaşmıyor."
+
+#: graphicswin.cpp:1155
+msgid ""
+"To use this command, select a point or other entity from an linked part, or "
+"make a link group the active group."
+msgstr ""
+"Bu komutu kullanmak için, bağlantılı bir parçadan bir nokta veya başka bir "
+"öğe seçin veya bir bağlantı grubunu etkin grup haline getirin."
+
+#: graphicswin.cpp:1178
+msgid ""
+"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
+"to define the plane for the snap grid."
+msgstr ""
+"Hiçbir çalışma düzlemi etkin değil. Izgaranın yakalanacağı düzlemini "
+"tanımlamak için bir çalışma düzlemini (Çizim -> Çalışma Düzleminde ile) "
+"etkinleştirin."
+
+#: graphicswin.cpp:1185
+msgid ""
+"Can't snap these items to grid; select points, text comments, or constraints "
+"with a label. To snap a line, select its endpoints."
+msgstr ""
+"Bu öğeler ızgaraya tutturulamıyor; etiketli noktaları, metin yorumlarını "
+"veya kısıtlamaları seçin. Bir çizgiyi tutturmak için uç noktalarını seçin."
+
+#: graphicswin.cpp:1270
+msgid "No workplane selected. Activating default workplane for this group."
+msgstr ""
+"Çalışma düzlemi seçilmedi. Bu grup için varsayılan çalışma düzlemi "
+"etkinleştiriliyor."
+
+#: graphicswin.cpp:1273
+msgid ""
+"No workplane is selected, and the active group does not have a default "
+"workplane. Try selecting a workplane, or activating a sketch-in-new-"
+"workplane group."
+msgstr ""
+"Hiçbir çalışma düzlemi seçilmedi ve aktif grubun varsayılan bir çalışma "
+"düzlemi yok. Bir çalışma düzlemi seçmeyi veya bir yeni çalışma düzleminde "
+"çizim grubunu etkinleştirmeyi deneyin."
+
+#: graphicswin.cpp:1294
+msgid ""
+"Bad selection for tangent arc at point. Select a single point, or select "
+"nothing to set up arc parameters."
+msgstr ""
+"Noktada teğet yay (radyus) oluşturmak için hatalı seçim. Tek bir nokta seçin "
+"veya yay parametrelerini ayarlamak için hiçbir şey seçmeyin."
+
+#: graphicswin.cpp:1305
+msgid "click point on arc (draws anti-clockwise)"
+msgstr "yayın ilk noktası için tıklayın (saat yönünün tersine çizilir)"
+
+#: graphicswin.cpp:1306
+msgid "click to place datum point"
+msgstr "referans noktayı yerleştirmek için tıklayın"
+
+#: graphicswin.cpp:1307
+msgid "click first point of line segment"
+msgstr "çizgi parçasının ilk noktası için tıklayın"
+
+#: graphicswin.cpp:1309
+msgid "click first point of construction line segment"
+msgstr "yardımcı çizginin ilk noktası için tıklayın"
+
+#: graphicswin.cpp:1310
+msgid "click first point of cubic segment"
+msgstr "kübik eğri parçanın ilk noktası için tıklayın"
+
+#: graphicswin.cpp:1311
+msgid "click center of circle"
+msgstr "dairenin merkez konumu için tıklayın"
+
+#: graphicswin.cpp:1312
+msgid "click origin of workplane"
+msgstr "çalışma düzleminin merkez konumu için tıklayın"
+
+#: graphicswin.cpp:1313
+msgid "click one corner of rectangle"
+msgstr "dikdörtgenin bir köşe noktası için tıklayın"
+
+#: graphicswin.cpp:1314
+msgid "click top left of text"
+msgstr "metnin sol üst köşe konumu için tıklayın"
+
+#: graphicswin.cpp:1320
+msgid "click top left of image"
+msgstr "görüntünün sol üst köşe konumu için tıklayın"
+
+#: graphicswin.cpp:1346
+msgid ""
+"No entities are selected. Select entities before trying to toggle their "
+"construction state."
+msgstr ""
+"Hiçbir öğe seçilmedi. Yapı durumlarını değiştirmeye çalışmadan önce öğeleri "
+"seçin."
+
+#: group.cpp:86
+msgctxt "group-name"
+msgid "sketch-in-3d"
+msgstr "3d-de-çizim"
+
+#: group.cpp:150
+msgid ""
+"Bad selection for new sketch in workplane. This group can be created with:\n"
+"\n"
+" * a point (through the point, orthogonal to coordinate axes)\n"
+" * a point and two line segments (through the point, parallel to the "
+"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
+" * a workplane (copy of the workplane)\n"
+msgstr ""
+"Çalışma düzleminde yeni çizim oluşturmak için hatalı seçim. Bu grup "
+"aşağıdakilerle oluşturulabilir:\n"
+"\n"
+" * bir nokta (noktadan geçen, koordinat eksenine dik)\n"
+" * bir nokta ve iki doğru parçası (noktadan geçen, doğrulara paralel)\n"
+" * bir nokta ve bir normal (noktadan normale dik)\n"
+" * bir çalışma düzlemi (çalışma düzleminin kopyası)\n"
+
+#: group.cpp:166
+msgid ""
+"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
+"will be extruded normal to the workplane."
+msgstr ""
+"Katılama işleminden önce bir çalışma düzlemini etkinleştirin. Çizim, "
+"çalışma düzlemine dik olarak katılanacaktır."
+
+#: group.cpp:175
+msgctxt "group-name"
+msgid "extrude"
+msgstr "doğrusal katıla"
+
+#: group.cpp:180
+msgid "Lathe operation can only be applied to planar sketches."
+msgstr ""
+"Tam tur döndürerek katılama işlemi, yalnızca düzlemsel çizimlere "
+"uygulanabilir."
+
+#: group.cpp:191
+msgid ""
+"Bad selection for new lathe group. This group can be created with:\n"
+"\n"
+" * a point and a line segment or normal (revolved about an axis parallel "
+"to line / normal, through point)\n"
+" * a line segment (revolved about line segment)\n"
+msgstr ""
+"Tamamen döndürerek yeni katılama grubu oluşturmak için hatalı seçim. Bu grup "
+"şu şekilde oluşturulabilir:\n"
+"\n"
+" * bir nokta ve bir çizgi parçası veya normal (çizgiye / normale paralel "
+"bir eksen etrafında, nokta boyunca döndürülür )\n"
+" * bir çizgi parçası (çizgi parçası etrafında döndürülür)\n"
+
+#: group.cpp:201
+msgctxt "group-name"
+msgid "lathe"
+msgstr "tamamen döndürerek katıla"
+
+#: group.cpp:206
+msgid "Revolve operation can only be applied to planar sketches."
+msgstr ""
+"Kısmen döndürerek katılama işlemi, yalnızca düzlemsel çizimlere "
+"uygulanabilir."
+
+#: group.cpp:217
+msgid ""
+"Bad selection for new revolve group. This group can be created with:\n"
+"\n"
+" * a point and a line segment or normal (revolved about an axis parallel "
+"to line / normal, through point)\n"
+" * a line segment (revolved about line segment)\n"
+msgstr ""
+"Kısmen döndürerek yeni katılama grubu oluşturmak için hatalı seçim. Bu grup "
+"şu şekilde oluşturulabilir:\n"
+"\n"
+"\n"
+" * bir nokta ve bir çizgi parçası veya normal (çizgiye / normale paralel, "
+"noktadan geçen bir eksen etrafında döndürülür)\n"
+" * bir çizgi parçası (çizgi parçası etrafında döndürülür)\n"
+
+#: group.cpp:229
+msgctxt "group-name"
+msgid "revolve"
+msgstr "kısmen döndürerek katıla"
+
+#: group.cpp:234
+msgid "Helix operation can only be applied to planar sketches."
+msgstr "Helis işlemi yalnızca düzlemsel çizimlere uygulanabilir."
+
+#: group.cpp:245
+msgid ""
+"Bad selection for new helix group. This group can be created with:\n"
+"\n"
+" * a point and a line segment or normal (revolved about an axis parallel "
+"to line / normal, through point)\n"
+" * a line segment (revolved about line segment)\n"
+msgstr ""
+"Yeni helis grubu oluşturmak için hatalı seçim. Bu grup şunlarla "
+"oluşturulabilir:\n"
+"\n"
+" * bir nokta ve bir çizgi parçası veya normal (çizgiye / normale paralel, "
+"noktadan geçen bir eksen etrafında döndürülür)\n"
+" * bir çizgi parçası (çizgi parçası etrafında döndürülür)\n"
+
+#: group.cpp:257
+msgctxt "group-name"
+msgid "helix"
+msgstr "helis"
+
+#: group.cpp:270
+msgid ""
+"Bad selection for new rotation. This group can be created with:\n"
+"\n"
+" * a point, while locked in workplane (rotate in plane, about that "
+"point)\n"
+" * a point and a line or a normal (rotate about an axis through the "
+"point, and parallel to line / normal)\n"
+msgstr ""
+"Yeni dairesel kopyalama/çoğaltma oluşturmak için hatalı seçim. Bu grup "
+"şunlarla oluşturulabilir:\n"
+"\n"
+" * bir nokta, çalışma düzleminde kilitli olduğu sürece (düzlemde o nokta "
+"etrafında çevirin)\n"
+" * bir nokta ve bir çizgi veya bir normal ( çizgiye / normale paralel ve "
+"noktadan geçen bir eksen etrafında çevirin)\n"
+
+#: group.cpp:283
+msgctxt "group-name"
+msgid "rotate"
+msgstr "dairesel kopya"
+
+#: group.cpp:294
+msgctxt "group-name"
+msgid "translate"
+msgstr "doğrusal kopya"
+
+#: group.cpp:416
+msgid "(unnamed)"
+msgstr "(isimsiz)"
+
+#: groupmesh.cpp:707
+msgid "not closed contour, or not all same style!"
+msgstr "kapali olmayan kontur veya tümü ayni bicimde degil!"
+
+#: groupmesh.cpp:720
+msgid "points not all coplanar!"
+msgstr "noktaların hepsi aynı düzlemde değil!"
+
+#: groupmesh.cpp:722
+msgid "contour is self-intersecting!"
+msgstr "kontur kendisiyle kesisiyor!"
+
+#: groupmesh.cpp:724
+msgid "zero-length edge!"
+msgstr "sıfır-uzunluklu kenar!"
+
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr "Metin-biçimli STL dosyaları şu anda desteklenmiyor"
+
+#: modify.cpp:252
+msgid "Must be sketching in workplane to create tangent arc."
+msgstr "Teğet yay oluşturmak için çalışma düzleminde çizim yapılmalıdır."
+
+#: modify.cpp:299
+msgid ""
+"To create a tangent arc, select a point where two non-construction lines or "
+"circles in this group and workplane join."
+msgstr ""
+"Bir teğet yay oluşturmak için, bu gruptaki iki (yardımcı) referans-olmayan "
+"çizginin veya dairenin ve çalışma düzleminin birleştiği bir nokta seçin."
+
+#: modify.cpp:386
+msgid ""
+"Couldn't round this corner. Try a smaller radius, or try creating the "
+"desired geometry by hand with tangency constraints."
+msgstr ""
+"Bu köşe yuvarlatılamadı. Daha küçük bir yarıçap deneyin veya teğet "
+"kısıtlamaları ile istenen geometriyi elle oluşturmayı deneyin."
+
+#: modify.cpp:595
+msgid "Couldn't split this entity; lines, circles, or cubics only."
+msgstr ""
+"Bu öğe bölünemedi; yalnızca çizgiler, daireler veya kübik eğriler "
+"bölünebilir."
+
+#: modify.cpp:622
+msgid "Must be sketching in workplane to split."
+msgstr "Bölmek için çalışma düzleminde çizim yapılıyor olmalı."
+
+#: modify.cpp:629
+msgid ""
+"Select two entities that intersect each other (e.g. two lines/circles/arcs "
+"or a line/circle/arc and a point)."
+msgstr ""
+"Birbiriyle kesişen iki öğe seçin (örneğin iki çizgi / daire / yay veya bir "
+"çizgi / daire / yay ve bir nokta)."
+
+#: modify.cpp:734
+msgid "Can't split; no intersection found."
+msgstr "Bölünemez; kesişim bulunamadı."
+
+#: mouse.cpp:557
+msgid "Assign to Style"
+msgstr "Biçim Ata"
+
+#: mouse.cpp:573
+msgid "No Style"
+msgstr "Biçim Yok"
+
+#: mouse.cpp:576
+msgid "Newly Created Custom Style..."
+msgstr "Yeni Oluşturulan Özel Biçim ..."
+
+#: mouse.cpp:583
+msgid "Group Info"
+msgstr "Grup Bilgisi"
+
+#: mouse.cpp:603
+msgid "Style Info"
+msgstr "Biçim Bİlgisi"
+
+#: mouse.cpp:623
+msgid "Select Edge Chain"
+msgstr "Kenar Zinciri Seç"
+
+#: mouse.cpp:629
+msgid "Toggle Reference Dimension"
+msgstr "Referans Ölçüyü Değiştir"
+
+#: mouse.cpp:635
+msgid "Other Supplementary Angle"
+msgstr "Diğer Bütünler Açı"
+
+#: mouse.cpp:640
+msgid "Snap to Grid"
+msgstr "Izgaraya Tuttur"
+
+#: mouse.cpp:649
+msgid "Remove Spline Point"
+msgstr "Eğri Noktasını Sil"
+
+#: mouse.cpp:684
+msgid "Add Spline Point"
+msgstr "Eğri Noktası Ekle"
+
+#: mouse.cpp:688
+msgid "Cannot add spline point: maximum number of points reached."
+msgstr "Eğri noktası eklenemiyor: en fazla nokta sayısına ulaşıldı."
+
+#: mouse.cpp:713
+msgid "Toggle Construction"
+msgstr "Yapıyı değiştir"
+
+#: mouse.cpp:729
+msgid "Delete Point-Coincident Constraint"
+msgstr "Çakışık-Nokta Kısıtlamasını Sil"
+
+#: mouse.cpp:747
+msgid "Cut"
+msgstr "Kes"
+
+#: mouse.cpp:749
+msgid "Copy"
+msgstr "Kopyala"
+
+#: mouse.cpp:753
+msgid "Select All"
+msgstr "Tümünü Seç"
+
+#: mouse.cpp:758
+msgid "Paste"
+msgstr "Yapıştır"
+
+#: mouse.cpp:760
+msgid "Paste Transformed..."
+msgstr "Dönüştürerek Yapıştır..."
+
+#: mouse.cpp:765
+msgid "Delete"
+msgstr "Sil"
+
+#: mouse.cpp:768
+msgid "Unselect All"
+msgstr "Tüm Seçimi Kaldır"
+
+#: mouse.cpp:775
+msgid "Unselect Hovered"
+msgstr "Üzerine Gelinen Seçimi Kaldır"
+
+#: mouse.cpp:784
+msgid "Zoom to Fit"
+msgstr "Sığdırmak için Yakınlaştır"
+
+#: mouse.cpp:986 mouse.cpp:1274
+msgid "click next point of line, or press Esc"
+msgstr "çizginin sonraki noktası için tıklayın veya Esc tuşuna basın"
+
+#: mouse.cpp:992
+msgid ""
+"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"3d'de dikdörtgen çizilemez; önce Çizim -> Çalışma Düzleminde menüsü ile bir "
+"çalışma düzlemini etkinleştirin."
+
+#: mouse.cpp:1026
+msgid "click to place other corner of rectangle"
+msgstr "dikdörtgenin diğer köşesini belirtmek için tıklayın"
+
+#: mouse.cpp:1047
+msgid "click to set radius"
+msgstr "yarıçapı ayarlamak için tıklayın"
+
+#: mouse.cpp:1052
+msgid ""
+"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"3d'de yay çizemez; önce Çizim -> Çalışma Düzleminde menüsü ile bir çalışma "
+"düzlemini etkinleştirin."
+
+#: mouse.cpp:1071
+msgid "click to place point"
+msgstr "noktayı yerleştirmek için tıklayın"
+
+#: mouse.cpp:1087
+msgid "click next point of cubic, or press Esc"
+msgstr "sonraki kübik eğri noktasını tıklayın veya Esc tuşuna basın"
+
+#: mouse.cpp:1092
+msgid ""
+"Sketching in a workplane already; sketch in 3d before creating new workplane."
+msgstr ""
+"Zaten bir çalışma düzleminde çizim yapılıyor; 3d'de çizim yapmadan önce yeni "
+"çalışma düzlemi oluşturun."
+
+#: mouse.cpp:1108
+msgid ""
+"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"3d'de metin yazılamaz; önce Çizim -> Çalışma Düzleminde menüsü ile bir "
+"çalışma düzlemini etkinleştirin."
+
+#: mouse.cpp:1125
+msgid "click to place bottom right of text"
+msgstr "metnin sağ alt konumunu belirtmek için tıklayın"
+
+#: mouse.cpp:1131
+msgid ""
+"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr ""
+"3d'de görüntü/resim eklenemez; önce Çizim -> Çalışma Düzleminde menüsü ile "
+"bir çalışma düzlemini etkinleştirin."
+
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
+msgctxt "file-type"
+msgid "SolveSpace models"
+msgstr "SolveSpace Modelleri"
+
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr "TÜMÜ"
+
+#: platform/gui.cpp:91
+msgctxt "file-type"
+msgid "IDF circuit board"
+msgstr "IDF devre kartı"
+
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr "STL üçgensel mesh (ağ/kafes)"
+
+#: platform/gui.cpp:96
+msgctxt "file-type"
+msgid "PNG image"
+msgstr "PNG Görüntüsü"
+
+#: platform/gui.cpp:100
+msgctxt "file-type"
+msgid "STL mesh"
+msgstr "STL mesh (ağ/kafes)"
+
+#: platform/gui.cpp:101
+msgctxt "file-type"
+msgid "Wavefront OBJ mesh"
+msgstr "Wavefront OBJ mesh (ağ/kafes)"
+
+#: platform/gui.cpp:102
+msgctxt "file-type"
+msgid "Three.js-compatible mesh, with viewer"
+msgstr "Görüntüleyicili, Three.js-uyumlu mesh (ağ/kafes)"
+
+#: platform/gui.cpp:103
+msgctxt "file-type"
+msgid "Three.js-compatible mesh, mesh only"
+msgstr "Three.js-uyumlu mesh, sadece mesh (ağ/kafes)"
+
+#: platform/gui.cpp:104
+msgctxt "file-type"
+msgid "VRML text file"
+msgstr "VRML metin dosyası"
+
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
+msgctxt "file-type"
+msgid "STEP file"
+msgstr "STEP dosyası"
+
+#: platform/gui.cpp:112
+msgctxt "file-type"
+msgid "PDF file"
+msgstr "PDF dosyası"
+
+#: platform/gui.cpp:113
+msgctxt "file-type"
+msgid "Encapsulated PostScript"
+msgstr "Encapsulated PostScript (EPS)"
+
+#: platform/gui.cpp:114
+msgctxt "file-type"
+msgid "Scalable Vector Graphics"
+msgstr "Ölçeklenebilir Vektör Grafikleri (SVG)"
+
+#: platform/gui.cpp:116 platform/gui.cpp:123
+msgctxt "file-type"
+msgid "DXF file (AutoCAD 2007)"
+msgstr "DXF dosyası (AutoCAD 2007)"
+
+#: platform/gui.cpp:117
+msgctxt "file-type"
+msgid "HPGL file"
+msgstr "HPGL dosyası"
+
+#: platform/gui.cpp:118
+msgctxt "file-type"
+msgid "G Code"
+msgstr "G Kodu"
+
+#: platform/gui.cpp:127
+msgctxt "file-type"
+msgid "AutoCAD DXF and DWG files"
+msgstr "AutoCAD DXF ve DWG dosyaları"
+
+#: platform/gui.cpp:131
+msgctxt "file-type"
+msgid "Comma-separated values"
+msgstr "Virgülle ayrılmış değerler (CSV)"
+
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
+msgid "untitled"
+msgstr "isimsiz"
+
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
+msgctxt "title"
+msgid "Save File"
+msgstr "Dosyayı Kaydet"
+
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
+msgctxt "title"
+msgid "Open File"
+msgstr "Dosyayı Aç"
+
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
+msgctxt "button"
+msgid "_Cancel"
+msgstr "_İptal"
+
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
+msgctxt "button"
+msgid "_Save"
+msgstr "_Kaydet"
+
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
+msgctxt "button"
+msgid "_Open"
+msgstr "_Aç"
+
+#: solvespace.cpp:171
+msgctxt "title"
+msgid "Autosave Available"
+msgstr "Otomatik Kaydetme Kullanılabilir"
+
+#: solvespace.cpp:172
+msgctxt "dialog"
+msgid "An autosave file is available for this sketch."
+msgstr "Bu çizim için otomatik kaydetme dosyası kullanılabilir."
+
+#: solvespace.cpp:173
+msgctxt "dialog"
+msgid "Do you want to load the autosave file instead?"
+msgstr "Bunun yerine otomatik kaydetme dosyasını yüklemek istiyor musunuz?"
+
+#: solvespace.cpp:174
+msgctxt "button"
+msgid "&Load autosave"
+msgstr "&Otomatik kaydı yükle"
+
+#: solvespace.cpp:176
+msgctxt "button"
+msgid "Do&n't Load"
+msgstr "&Yükleme"
+
+#: solvespace.cpp:599
+msgctxt "title"
+msgid "Modified File"
+msgstr "Değiştirilen Dosya"
+
+#: solvespace.cpp:601
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr "\"%s\" çiziminde yaptığınız değişiklikleri kaydetmek istiyor musunuz?"
+
+#: solvespace.cpp:604
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr "Yeni çizimde yaptığınız değişiklikleri kaydetmek istiyor musunuz?"
+
+#: solvespace.cpp:607
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr "Bunları kaydetmezseniz değişiklikleriniz kaybolur."
+
+#: solvespace.cpp:608
+msgctxt "button"
+msgid "&Save"
+msgstr "&Kaydet"
+
+#: solvespace.cpp:610
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr "K&aydetme"
+
+#: solvespace.cpp:631
+msgctxt "title"
+msgid "(new sketch)"
+msgstr "(yeni çizim)"
+
+#: solvespace.cpp:638
+msgctxt "title"
+msgid "Property Browser"
+msgstr "Özellik Penceresi"
+
+#: solvespace.cpp:700
+msgid ""
+"Constraints are currently shown, and will be exported in the toolpath. This "
+"is probably not what you want; hide them by clicking the link at the top of "
+"the text window."
+msgstr ""
+"Kısıtlamalar şu anda gösterilmektedir ve takım yolunda dışa aktarılacaktır. "
+"Muhtemelen istediğiniz bu değil; Özellik Penceresinin üst kısmındaki "
+"bağlantıya tıklayarak bunları gizleyin."
+
+#: solvespace.cpp:772
+#, c-format
+msgid ""
+"Can't identify file type from file extension of filename '%s'; try .dxf or ."
+"dwg."
+msgstr ""
+"'%s' dosya adının dosya uzantısından dosya türü belirlenemiyor; .dxf veya ."
+"dwg'yi deneyin."
+
+#: solvespace.cpp:824
+msgid "Constraint must have a label, and must not be a reference dimension."
+msgstr "Kısıtlamanın bir etiketi olmalı ve bir referans ölçüsü olmamalıdır."
+
+#: solvespace.cpp:828
+msgid "Bad selection for step dimension; select a constraint."
+msgstr "Adım ölçüsü ayarlamak için hatalı seçim; bir kısıtlama seçin."
+
+#: solvespace.cpp:852
+msgid "The assembly does not interfere, good."
+msgstr "Montajda engel oluşturan parça yok, iyi."
+
+#: solvespace.cpp:868
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+"Katı modelin hacmi:\n"
+"\n"
+" % s"
+
+#: solvespace.cpp:877
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+"\n"
+"Mevcut ağ (kafes) grubunun hacmi:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:882
+msgid ""
+"\n"
+"\n"
+"Curved surfaces have been approximated as triangles.\n"
+"This introduces error, typically of around 1%."
+msgstr ""
+"\n"
+"\n"
+"Kavisli (Eğri) yüzeyler üçgenler olarak yaklaştırılmıştır.\n"
+"Bu, genel olarak yaklaşık 1% hataya neden olur."
+
+#: solvespace.cpp:897
+#, c-format
+msgid ""
+"The surface area of the selected faces is:\n"
+"\n"
+" %s\n"
+"\n"
+"Curves have been approximated as piecewise linear.\n"
+"This introduces error, typically of around 1%%."
+msgstr ""
+"Seçili yüzlerin yüzey alanı:\n"
+"\n"
+" %s\n"
+"\n"
+"Eğriler, doğrusal parçalı olarak yaklaştırılmıştır.\n"
+"Bu, genel olarak yaklaşık 1%% hataya neden olur."
+
+#: solvespace.cpp:906
+msgid ""
+"This group does not contain a correctly-formed 2d closed area. It is open, "
+"not coplanar, or self-intersecting."
+msgstr ""
+"Bu grup, doğru biçimlendirilmiş 2d kapalı alan içermiyor. Açık, eş-düzlemli "
+"değil veya kendisiyle kesişiyor."
+
+#: solvespace.cpp:918
+#, c-format
+msgid ""
+"The area of the region sketched in this group is:\n"
+"\n"
+" %s\n"
+"\n"
+"Curves have been approximated as piecewise linear.\n"
+"This introduces error, typically of around 1%%."
+msgstr ""
+"Bu grupta çizilen bölgenin alanı:\n"
+"\n"
+" %s\n"
+"\n"
+"Eğriler, doğrusal parçalı olarak yaklaştırılmıştır.\n"
+"Bu, genel olarak yaklaşık 1%% hataya neden olur."
+
+#: solvespace.cpp:938
+#, c-format
+msgid ""
+"The total length of the selected entities is:\n"
+"\n"
+" %s\n"
+"\n"
+"Curves have been approximated as piecewise linear.\n"
+"This introduces error, typically of around 1%%."
+msgstr ""
+"Seçilen öğelerin toplam uzunluğu:\n"
+"\n"
+" %s\n"
+"\n"
+"Eğriler, parçalı doğrusal olarak yaklaştırıldı.\n"
+"Bu, genel olarak yaklaşık 1%% hataya neden olur."
+
+#: solvespace.cpp:944
+msgid "Bad selection for perimeter; select line segments, arcs, and curves."
+msgstr ""
+"Çevre uzunluğunu hesabı için hatalı seçim; çizgi parçalarını, yayları ve "
+"eğrileri seçin."
+
+#: solvespace.cpp:960
+msgid "Bad selection for trace; select a single point."
+msgstr "Nokta izleme işlemi için hatalı seçim; tek bir nokta seçin."
+
+#: solvespace.cpp:987
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr "\"%s\" öğesine yazılamadı"
+
+#: solvespace.cpp:1017
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr "Ağ (Kafes) kendisiyle kesişiyor (İyi DEĞİL, geçersiz)."
+
+#: solvespace.cpp:1018
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr "Ağ (Kafes) kendisi ile kesişmiyor (iyi, geçerli)."
+
+#: solvespace.cpp:1020
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr "Ağın (Kafesin) açık kenarları var (iyi DEĞİL, geçersiz)."
+
+#: solvespace.cpp:1021
+msgid "The mesh is watertight (okay, valid)."
+msgstr "Ağ (Kafes) çok sıkı (iyi, geçerli)"
+
+#: solvespace.cpp:1024
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+"\n"
+"\n"
+"Model, %d yüzeyden %d üçgen içeriyor."
+
+#: solvespace.cpp:1028
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Sıfır sorunlu kenar, iyi.%s"
+
+#: solvespace.cpp:1031
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d problematic edges, bad.%s"
+msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d sorunlu kenar, kötü.%s"
+
+#: solvespace.cpp:1044
+#, c-format
+msgid ""
+"This is SolveSpace version %s.\n"
+"\n"
+"For more information, see http://solvespace.com/\n"
+"\n"
+"SolveSpace is free software: you are free to modify\n"
+"and/or redistribute it under the terms of the GNU\n"
+"General Public License (GPL) version 3 or later.\n"
+"\n"
+"There is NO WARRANTY, to the extent permitted by\n"
+"law. For details, visit http://gnu.org/licenses/\n"
+"\n"
+"© 2008-%d Jonathan Westhues and other authors.\n"
+msgstr ""
+"Bu SolveSpace'in %s sürümüdür.\n"
+"\n"
+"Daha fazla bilgi için bkz., http://solvespace.com/\n"
+"\n"
+"SolveSpace ücretsiz bir yazılımdır: GNU Genel Kamu \n"
+"Lisansı (GPL) sürüm 3 veya daha sonraki hükümleri altında \n"
+"onu değiştirmekte ve / veya yeniden dağıtmakta özgürsünüz.\n"
+"\n"
+"Yasaların izin verdiği ölçüde GARANTİ YOKTUR. \n"
+"Ayrıntılar için http://gnu.org/licenses/ adresini ziyaret edin.\n"
+"\n"
+"© 2008-% d Jonathan Westhues ve diğer yazarlar.\n"
+
+#: style.cpp:185
+msgid ""
+"Can't assign style to an entity that's derived from another entity; try "
+"assigning a style to this entity's parent."
+msgstr ""
+"Başka bir öğeden türetilen bir öğeye biçim atayamazsınız; bu öğenin üst "
+"öğesine bir biçim atamayı deneyin."
+
+#: style.cpp:735
+msgid "Style name cannot be empty"
+msgstr "Biçim adı boş olamaz"
+
+#: textscreens.cpp:791
+msgid "Can't repeat fewer than 1 time."
+msgstr "1 defadan az tekrarlanamaz."
+
+#: textscreens.cpp:795
+msgid "Can't repeat more than 999 times."
+msgstr "999 defadan fazla tekrarlanamaz."
+
+#: textscreens.cpp:820
+msgid "Group name cannot be empty"
+msgstr "Grup adı boş olamaz"
+
+#: textscreens.cpp:872
+msgid "Opacity must be between zero and one."
+msgstr "Şeffaflık değeri sıfır ile bir arasında olmalıdır."
+
+#: textscreens.cpp:907
+msgid "Radius cannot be zero or negative."
+msgstr "Yarıçap sıfır veya negatif değer olamaz."
+
+#: toolbar.cpp:18
+msgid "Sketch line segment"
+msgstr "Çizgi parçası çiz"
+
+#: toolbar.cpp:20
+msgid "Sketch rectangle"
+msgstr "Dikdörtgen çiz"
+
+#: toolbar.cpp:22
+msgid "Sketch circle"
+msgstr "Daire çiz"
+
+#: toolbar.cpp:24
+msgid "Sketch arc of a circle"
+msgstr "Bir çember yayı çiz"
+
+#: toolbar.cpp:26
+msgid "Sketch curves from text in a TrueType font"
+msgstr "TrueType yazı tipindeki metinden eğriler çiz"
+
+#: toolbar.cpp:28
+msgid "Sketch image from a file"
+msgstr "Bir dosyadan görüntü (resim) ekle"
+
+#: toolbar.cpp:30
+msgid "Create tangent arc at selected point"
+msgstr "Seçilen noktada radyus (teğet yay) oluştur"
+
+#: toolbar.cpp:32
+msgid "Sketch cubic Bezier spline"
+msgstr "Kübik Bezier Eğri Çiz"
+
+#: toolbar.cpp:34
+msgid "Sketch datum point"
+msgstr "Referans Nokta Ekle"
+
+#: toolbar.cpp:36
+msgid "Toggle construction"
+msgstr "Yapıyı değiştir"
+
+#: toolbar.cpp:38
+msgid "Split lines / curves where they intersect"
+msgstr "Çizgileri / eğrileri kesiştikleri yerden böl"
+
+#: toolbar.cpp:42
+msgid "Constrain distance / diameter / length"
+msgstr "Mesafeyi / çapı / uzunluğu kısıtla"
+
+#: toolbar.cpp:44
+msgid "Constrain angle"
+msgstr "Açıyı kısıtla"
+
+#: toolbar.cpp:46
+msgid "Constrain to be horizontal"
+msgstr "Yatay olarak kısıtla"
+
+#: toolbar.cpp:48
+msgid "Constrain to be vertical"
+msgstr "Dikey olarak kısıtla"
+
+#: toolbar.cpp:50
+msgid "Constrain to be parallel or tangent"
+msgstr "Paralel veya teğet olarak kısıtla"
+
+#: toolbar.cpp:52
+msgid "Constrain to be perpendicular"
+msgstr "Dik olarak kısıtla"
+
+#: toolbar.cpp:54
+msgid "Constrain point on line / curve / plane / point"
+msgstr "Noktayı çizgi / eğri / düzlem / nokta ile çakıştırarak kısıtla"
+
+#: toolbar.cpp:56
+msgid "Constrain symmetric"
+msgstr "Simetrik olarak kısıtla"
+
+#: toolbar.cpp:58
+msgid "Constrain equal length / radius / angle"
+msgstr "Eşit uzunluk / yarıçap / açı olarak kısıtla"
+
+#: toolbar.cpp:60
+msgid "Constrain normals in same orientation"
+msgstr "Normalleri aynı yönde kısıtla"
+
+#: toolbar.cpp:62
+msgid "Other supplementary angle"
+msgstr "Diğer bütünler açı"
+
+#: toolbar.cpp:64
+msgid "Toggle reference dimension"
+msgstr "Ölçüyü Referans Yap / Yapma"
+
+#: toolbar.cpp:68
+msgid "New group extruding active sketch"
+msgstr "Etkin çizimi uzatıp katılayarak yeni grup oluştur"
+
+#: toolbar.cpp:70
+msgid "New group rotating active sketch"
+msgstr "Etkin çizimi tam döndürerek yeni grup oluştur"
+
+#: toolbar.cpp:72
+msgid "New group helix from active sketch"
+msgstr "Etkin çizimden sarmal yeni grup oluştur"
+
+#: toolbar.cpp:74
+msgid "New group revolve active sketch"
+msgstr "Etkin çizimi kısmen döndürerek yeni grup oluştur"
+
+#: toolbar.cpp:76
+msgid "New group step and repeat rotating"
+msgstr "Adım ve tekrar değeri belirterek dairesel kopya grubu oluştur"
+
+#: toolbar.cpp:78
+msgid "New group step and repeat translating"
+msgstr "Adım ve tekrar değeri belirterek yeni doğrusal kopyalama grup oluştur"
+
+#: toolbar.cpp:80
+msgid "New group in new workplane (thru given entities)"
+msgstr ""
+"Yeni çalışma düzleminde yeni grup oluştur (verilen öğeler aracılığıyla)"
+
+#: toolbar.cpp:82
+msgid "New group in 3d"
+msgstr "3d'de yeni grup oluştur"
+
+#: toolbar.cpp:84
+msgid "New group linking / assembling file"
+msgstr "Bağlantı / Montaj dosyası ile yeni grup oluştur"
+
+#: toolbar.cpp:88
+msgid "Nearest isometric view"
+msgstr "En yakın izometrik görünüm"
+
+#: toolbar.cpp:90
+msgid "Align view to active workplane"
+msgstr "Görünümü etkin çalışma düzlemine hizala"
+
+#: util.cpp:165
+msgctxt "title"
+msgid "Error"
+msgstr "Hata"
+
+#: util.cpp:165
+msgctxt "title"
+msgid "Message"
+msgstr "Mesaj"
+
+#: util.cpp:170
+msgctxt "button"
+msgid "&OK"
+msgstr "&Tamam"
+
+#: view.cpp:127
+msgid "Scale cannot be zero or negative."
+msgstr "Ölçek sıfır veya negatif olamaz."
+
+#: view.cpp:139 view.cpp:148
+msgid "Bad format: specify x, y, z"
+msgstr "Kötü biçim: x, y, z'yi belirtin"
+
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Uzunluk oranı sınırlandırması için hatalı seçim. Bu sınırlandırma şunlara "
+#~ "uygulanabilir:\n"
+#~ "\n"
+#~ " * iki çizgi parçası\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "Uzunluk farkı sınırlandırması için hatalı seçim. Bu sınırlandırma şunlara "
+#~ "uygulanabilir:\n"
+#~ "\n"
+#~ " * iki çizgi parçası\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "&Uzunluk Oranı"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "U&zunluk Farkı"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "Çalışma düzleminde yeni taslak çizmek için hatalı seçim. Bu grup şunlarla "
+#~ "oluşturulabilir:\n"
+#~ "\n"
+#~ " * bir nokta (nokta boyunca, eksenleri koordine etmek için "
+#~ "ortogonal)\n"
+#~ " * bir nokta ve iki çizgi parçası (noktadan, çizgilere paralel)\n"
+#~ " * bir çalışma düzlemi (çalışma düzleminin kopyası)\n"
+
+#~ msgctxt "file-type"
+#~ msgid "Q3D Object file"
+#~ msgstr "Q3D Object file"
# Ukrainian translations for SolveSpace package.
# Copyright (C) 2017 the SolveSpace authors
# This file is distributed under the same license as the SolveSpace package.
-# AppSoft4 <appsoft@ua.fm>, 2017.
+# app4soft <appsoft@ua.fm>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
-"PO-Revision-Date: 2017-01-05 10:30+0000\n"
-"Last-Translator: appsoft@ua.fm\n"
-"Language-Team: OpenOrienteeringUkraine\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
+"PO-Revision-Date: 2021-04-14 01:42+0300\n"
+"Last-Translator: https://github.com/Symbian9\n"
+"Language-Team: app4soft\n"
"Language: uk_UA\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.4.2\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"Activate one with Sketch -> In Workplane."
msgstr ""
+"Вирізання, вставка та копіювання працює лише у площині.\n"
+"\n"
+"Активуйте одну через Креслення -> У площині."
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
-msgstr ""
+msgstr "Буфер обміну порожній; немає чого вставляти."
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
-msgstr ""
+msgstr "Кількість копій для вставки має бути не менше одної."
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
-msgstr ""
+msgstr "Масштаб не може бути нульовим."
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
-msgstr ""
+msgstr "Оберіть одну точку для визначення центру обертання."
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
-msgstr ""
+msgstr "Оберіть дві точки для визначення вектору розміщення."
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid ""
"Transformation is identity. So all copies will be exactly on top of each "
"other."
msgstr ""
-#: clipboard.cpp:458
+#: clipboard.cpp:457
+#, fuzzy
msgid "Too many items to paste; split this into smaller pastes."
-msgstr ""
+msgstr "Забагато об'єктів для вставки; рзділіть копіювання на кілька етапів."
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
-msgstr ""
+msgstr "Немає активної площини."
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
-msgstr ""
+msgstr "Некоректний формат: визначте координати X, Y, Z"
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
-msgstr ""
+msgstr "Некоректний формат: визначте колір як R, G, B"
-#: confscreen.cpp:454
+#: confscreen.cpp:417
+#, fuzzy
msgid ""
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
msgstr ""
+"Значення перспективи не матиме ефекту допоки не ввімкнено Вигляд -> "
+"Використовувати Перспективну проєкцію."
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
-msgstr ""
+msgstr "Визначте кількість десяткових знаків від 0 до %d."
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
-msgstr ""
+msgstr "Масштаб експорту не може бути нульовим!"
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
-msgstr ""
+msgstr "Радіус відступу різання не може бути від'ємним!"
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
-msgstr ""
+msgstr "Некоректне значення: інтервал автозбереження має бути додатнім"
-#: confscreen.cpp:558
+#: confscreen.cpp:531
+#, fuzzy
msgid "Bad format: specify interval in integral minutes"
-msgstr ""
+msgstr "Некоректний формат: визначте цілим числом інтервал у хвилинах"
#: constraint.cpp:12
msgctxt "constr-name"
msgid "pts-coincident"
-msgstr ""
+msgstr "співпадіння-тчк"
#: constraint.cpp:13
msgctxt "constr-name"
msgid "pt-pt-distance"
-msgstr ""
+msgstr "відстань-тчк-тчк"
#: constraint.cpp:14
msgctxt "constr-name"
msgid "pt-line-distance"
-msgstr ""
+msgstr "відстань-тчк-лінія"
#: constraint.cpp:15
msgctxt "constr-name"
msgid "pt-plane-distance"
-msgstr ""
+msgstr "відстань-тчк-площина"
#: constraint.cpp:16
msgctxt "constr-name"
msgid "pt-face-distance"
-msgstr ""
+msgstr "відстань-тчк-грань"
#: constraint.cpp:17
msgctxt "constr-name"
msgid "proj-pt-pt-distance"
-msgstr ""
+msgstr "проєційна-відстань-тчк-тчк"
#: constraint.cpp:18
msgctxt "constr-name"
msgid "pt-in-plane"
-msgstr ""
+msgstr "тчк-у-площині"
#: constraint.cpp:19
msgctxt "constr-name"
msgid "pt-on-line"
-msgstr ""
+msgstr "тчк-на-лінії"
#: constraint.cpp:20
msgctxt "constr-name"
msgid "pt-on-face"
-msgstr ""
+msgstr "тчк-на-грані"
#: constraint.cpp:21
msgctxt "constr-name"
msgid "eq-length"
-msgstr ""
+msgstr "рівні-довжини"
#: constraint.cpp:22
msgctxt "constr-name"
msgid "eq-length-and-pt-ln-dist"
-msgstr ""
+msgstr "рівні-довжина-відстань-тчк-лінія"
#: constraint.cpp:23
msgctxt "constr-name"
msgid "eq-pt-line-distances"
-msgstr ""
+msgstr "рівна-відстань-тчк-лінія"
#: constraint.cpp:24
msgctxt "constr-name"
msgid "length-ratio"
-msgstr ""
+msgstr "пропорція-довжин"
#: constraint.cpp:25
msgctxt "constr-name"
-msgid "length-difference"
+msgid "arc-arc-length-ratio"
msgstr ""
#: constraint.cpp:26
msgctxt "constr-name"
-msgid "symmetric"
+msgid "arc-line-length-ratio"
msgstr ""
#: constraint.cpp:27
msgctxt "constr-name"
-msgid "symmetric-h"
-msgstr ""
+msgid "length-difference"
+msgstr "різниця-довжин"
#: constraint.cpp:28
msgctxt "constr-name"
-msgid "symmetric-v"
+msgid "arc-arc-len-difference"
msgstr ""
#: constraint.cpp:29
msgctxt "constr-name"
-msgid "symmetric-line"
+msgid "arc-line-len-difference"
msgstr ""
#: constraint.cpp:30
msgctxt "constr-name"
-msgid "at-midpoint"
-msgstr ""
+msgid "symmetric"
+msgstr "симетрія"
#: constraint.cpp:31
msgctxt "constr-name"
-msgid "horizontal"
-msgstr ""
+msgid "symmetric-h"
+msgstr "симетрія-вертикально"
#: constraint.cpp:32
msgctxt "constr-name"
-msgid "vertical"
-msgstr ""
+msgid "symmetric-v"
+msgstr "симетрія-горизонтально"
#: constraint.cpp:33
msgctxt "constr-name"
-msgid "diameter"
-msgstr ""
+msgid "symmetric-line"
+msgstr "симетрія-відносно-лінії"
#: constraint.cpp:34
msgctxt "constr-name"
-msgid "pt-on-circle"
-msgstr ""
+msgid "at-midpoint"
+msgstr "на-середині"
#: constraint.cpp:35
msgctxt "constr-name"
-msgid "same-orientation"
-msgstr ""
+msgid "horizontal"
+msgstr "горизонталь"
#: constraint.cpp:36
msgctxt "constr-name"
-msgid "angle"
-msgstr ""
+msgid "vertical"
+msgstr "вертикаль"
#: constraint.cpp:37
msgctxt "constr-name"
-msgid "parallel"
-msgstr ""
+msgid "diameter"
+msgstr "діаметр"
#: constraint.cpp:38
msgctxt "constr-name"
-msgid "arc-line-tangent"
-msgstr ""
+msgid "pt-on-circle"
+msgstr "тчк-на-колі"
#: constraint.cpp:39
msgctxt "constr-name"
-msgid "cubic-line-tangent"
-msgstr ""
+msgid "same-orientation"
+msgstr "співнаправленість"
#: constraint.cpp:40
msgctxt "constr-name"
-msgid "curve-curve-tangent"
-msgstr ""
+msgid "angle"
+msgstr "кут"
#: constraint.cpp:41
msgctxt "constr-name"
-msgid "perpendicular"
-msgstr ""
+msgid "parallel"
+msgstr "паралель"
#: constraint.cpp:42
msgctxt "constr-name"
-msgid "eq-radius"
-msgstr ""
+msgid "arc-line-tangent"
+msgstr "дотичні-дуга-лінія"
#: constraint.cpp:43
msgctxt "constr-name"
-msgid "eq-angle"
-msgstr ""
+msgid "cubic-line-tangent"
+msgstr "дотичні-сплайн-лінія"
#: constraint.cpp:44
msgctxt "constr-name"
-msgid "eq-line-len-arc-len"
-msgstr ""
+msgid "curve-curve-tangent"
+msgstr "дотичні-крива-крива"
#: constraint.cpp:45
msgctxt "constr-name"
-msgid "lock-where-dragged"
-msgstr ""
+msgid "perpendicular"
+msgstr "перпендикуляр"
#: constraint.cpp:46
msgctxt "constr-name"
+msgid "eq-radius"
+msgstr "рівнозначні-радіуси"
+
+#: constraint.cpp:47
+msgctxt "constr-name"
+msgid "eq-angle"
+msgstr "рівнозначні-кути"
+
+#: constraint.cpp:48
+msgctxt "constr-name"
+msgid "eq-line-len-arc-len"
+msgstr "рівнозначні-лінія-дуга"
+
+#: constraint.cpp:49
+msgctxt "constr-name"
+msgid "lock-where-dragged"
+msgstr "фіксоване-положення"
+
+#: constraint.cpp:50
+msgctxt "constr-name"
msgid "comment"
-msgstr ""
+msgstr "коментар"
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
msgstr ""
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
msgstr ""
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
msgstr ""
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply "
"to:\n"
" * a circle or an arc (diameter)\n"
msgstr ""
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can "
"apply to:\n"
" * a point and a plane face (point on face)\n"
msgstr ""
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can "
"apply to:\n"
" * a line segment and an arc (line segment length equals arc length)\n"
msgstr ""
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
" * a line segment and a workplane (line's midpoint on plane)\n"
msgstr ""
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
"workplane)\n"
msgstr ""
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid ""
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
msgstr ""
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
msgstr ""
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can "
"apply to:\n"
" * a line segment\n"
msgstr ""
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply "
"to:\n"
" * two normals\n"
msgstr ""
-#: constraint.cpp:614
+#: constraint.cpp:663
+#, fuzzy
msgid "Must select an angle constraint."
-msgstr ""
+msgstr "Необхідно обрати кут."
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
-msgstr ""
+msgstr "Необхідно обрати обмежувач з відповідною міткою."
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * two normals\n"
msgstr ""
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr ""
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply "
"to:\n"
" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n"
msgstr ""
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * two normals\n"
msgstr ""
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can "
"apply to:\n"
" * a point\n"
msgstr ""
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "КОМЕНТАР -- ДВІЧІ КЛІКНІТЬ ДЛЯ РЕДАГУВАННЯ"
+
+#: constraint.cpp:818
msgid "click center of comment text"
-msgstr ""
+msgstr "клікніть в місце де буде центр коментаря"
#: export.cpp:19
msgid ""
"No solid model present; draw one with extrudes and revolves, or use Export "
"2d View to export bare lines and curves."
msgstr ""
+"Вісутня об'ємна модель; створіть одну з допомогою екструдування та "
+"виточування або скористайтеся функцією \"Експортувати 2D Вигляд\" для "
+"еспорту лише ліній та кривих."
#: export.cpp:61
msgid ""
"lines)\n"
msgstr ""
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
-msgstr ""
+msgstr "Активна група не містить меш; немає чого експортувати."
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr ""
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr ""
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr ""
+"Деякі аспекти креслення на мають відповідників у форматі DXF і не будуть "
+"експортовані:\n"
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid ""
"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr ""
+"Розмір аркуша у PDF перевищує 200×200 дюймів; багато переглядачів можуть не "
+"підтримувати цей файл."
#: file.cpp:44 group.cpp:91
msgctxt "group-name"
msgid "sketch-in-plane"
-msgstr ""
+msgstr "креслення-в-площині"
#: file.cpp:62
msgctxt "group-name"
msgid "#references"
-msgstr ""
+msgstr "#базові-площини"
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr "Файл порожній. Він може бути пошкодженим."
+
+#: file.cpp:555
msgid ""
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
msgstr ""
+"Нерозпізнані дані у файлі. Цей файл може бути пошкодженим або збереженим "
+"новою версією програми."
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
-msgstr ""
+msgstr "Втрачений Файл"
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
-msgstr ""
+msgstr "Приєднаний файл “%s” відсутній."
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"permanently removed."
msgstr ""
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
-msgstr ""
+msgstr "&Так"
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
-msgstr ""
+msgstr "&Ні"
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
-msgstr ""
+msgstr "&Відмінити"
#: graphicswin.cpp:41
msgid "&File"
#: graphicswin.cpp:49
msgid "Export 2d &View..."
-msgstr "Експортувати 2d &Вигляд..."
+msgstr "Експортувати 2D &Вигляд..."
#: graphicswin.cpp:50
msgid "Export 2d &Section..."
-msgstr "Експортувати 2d &Секцію..."
+msgstr "Експортувати 2D &Секцію..."
#: graphicswin.cpp:51
msgid "Export 3d &Wireframe..."
-msgstr "Експортувати 3d &Скелет..."
+msgstr "Експортувати 3D &Скелет..."
#: graphicswin.cpp:52
msgid "Export Triangle &Mesh..."
#: graphicswin.cpp:72
msgid "&Delete"
-msgstr "&Delete"
+msgstr "&Видалити"
#: graphicswin.cpp:74
msgid "Select &Edge Chain"
#: graphicswin.cpp:78
msgid "&Line Styles..."
-msgstr ""
+msgstr "Стилі &Ліній..."
#: graphicswin.cpp:79
msgid "&View Projection..."
-msgstr ""
+msgstr "&Проекція Відображення..."
#: graphicswin.cpp:81
msgid "Con&figuration..."
-msgstr ""
+msgstr "&Налаштування..."
#: graphicswin.cpp:84
msgid "&View"
-msgstr "&View"
+msgstr "&Відображення"
#: graphicswin.cpp:85
msgid "Zoom &In"
#: graphicswin.cpp:92
msgid "&Center View At Point"
-msgstr "&ЦенÑ\82Ñ\80Ñ\83ваÑ\82и Ð\92иглÑ\8fд Ð\9dа Точці"
+msgstr "&ЦенÑ\82Ñ\80Ñ\83ваÑ\82и Ð\92иглÑ\8fд на Точці"
#: graphicswin.cpp:94
msgid "Show Snap &Grid"
#: graphicswin.cpp:95
msgid "Darken Inactive Solids"
-msgstr ""
+msgstr "Затінювати Неактивні Тіла"
#: graphicswin.cpp:96
msgid "Use &Perspective Projection"
msgstr "Використовувати &Перспективну Проекцію"
#: graphicswin.cpp:97
-msgid "Dimension &Units"
+msgid "Show E&xploded View"
msgstr ""
#: graphicswin.cpp:98
-msgid "Dimensions in &Millimeters"
-msgstr "РозмÑ\96Ñ\80и в &Ð\9cÑ\96лÑ\96меÑ\82Ñ\80аÑ\85"
+msgid "Dimension &Units"
+msgstr "РозмÑ\96Ñ\80нÑ\96 &Ð\9eдиниÑ\86Ñ\96"
#: graphicswin.cpp:99
-msgid "Dimensions in M&eters"
-msgstr ""
+msgid "Dimensions in &Millimeters"
+msgstr "Розміри у &Міліметрах"
#: graphicswin.cpp:100
+msgid "Dimensions in M&eters"
+msgstr "Розміри у &Метрах"
+
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
-msgstr "Розміри в &Дюймах"
+msgstr "Розміри у &Дюймах"
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr ""
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr "Показати Панель &Інструментів"
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr "Показати Вікно Власти&востей"
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr "&Повний Екран"
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr "&Нова Група"
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
-msgstr "Креслення В &3d"
+msgstr "Креслення у &3D"
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
-msgstr "Креслення В Новій Робочій &Площині"
+msgstr "Креслення у Новій &Площині"
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr "Покрокове &Переміщення"
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr "Покрокове &Обертання"
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr "Ви&давити"
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
-msgstr ""
+msgstr "&Спіраль"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr "&Виточити"
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
-msgstr ""
+msgstr "&Обертати"
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
-msgstr "Ð\9fÑ\80иÑ\94днаÑ\82и / Ð\9cонÑ\82Ñ\83вати..."
+msgstr "Ð\9fÑ\80иÑ\94днаÑ\82и / Ð\97Ñ\96бÑ\80ати..."
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
-msgstr "Приєднати Недавні"
+msgstr "Приєднати Нещодавні"
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr "&Креслення"
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
-msgstr "Ð\92 Робочій &Площині"
+msgstr "У Робочій &Площині"
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
-msgstr "Ð\91Ñ\83дÑ\8c-де Ð\92 &3d"
+msgstr "Ð\91Ñ\83дÑ\8c-де в &3D"
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr "Опорна &Точка"
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr "Робоча &Площина"
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr "&Відрізок Прямої"
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr "Контсрук&ційний Відрізок Прямої"
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr "&Прямокутник"
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr "&Коло"
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr "&Дуга Кола"
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr "Кубічний Сплайн &Без'є"
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
-msgstr "&Текст з TrueType Шрифтом"
+msgstr "&Текст із TrueType Шрифтом"
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
-msgstr ""
+msgstr "&Зображення"
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr "Пере&мкнути Конструктивність"
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr "Дотична &Дуга на Точці"
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr "Розрізати Криві на &Перетині"
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr "&Обмежити"
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr "&Відстань / Діаметр"
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr "Від&носний Розмір"
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr "К&ут"
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr "Відносний К&ут"
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr "Інший Су&міжний Кут"
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr "Перемкнути Від&носність Розмірів"
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr "&Горизонтально"
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr "&Вертикально"
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr "&На точці / Кривій / Площині"
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr "Рі&вні Довжина / Радіус / Кут"
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
-msgstr "Про&порція Довжин"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr ""
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
-msgstr "Рі&зниця Довжин"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr ""
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr "До &Середини"
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr "Си&метрично"
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr "Пара&лельно / Дотична"
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr "&Препендикулярно"
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr "Однакова Орієн&тація"
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr "Фіксувати Точку Після &Переміщення"
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr "Коментар"
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr "&Аналізувати"
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr "Обрахувати &Об'єм"
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr "Обрахувати Пл&ощу"
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr "Обрахувати &Периметр"
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr "Показати &Дотичні Частини"
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr "Показати &Приховані Ребра"
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
-msgstr ""
+msgstr "Показати &Центр Масс"
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
-msgstr ""
+msgstr "Показати &Надмірно Обмежені Точки"
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr "&Трасувати Точку"
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
msgstr "&Зупити Трасування..."
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr "Прорахувати &Розмір..."
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr "&Довідка"
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr "&Мова"
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr "&Вебсайт / Посібник"
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr ""
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr "&Про програму"
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
-msgstr ""
+msgstr "(нємає нещодавніх файлів)"
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
-msgstr ""
+msgstr "Файл '%s' відсутній."
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
-msgstr ""
+msgstr "Відсутня активна площина - сітка не відображатиметься."
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel "
"projection.\n"
"configuration screen. A value around 0.3 is typical."
msgstr ""
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid ""
"Select a point; this point will become the center of the view on screen."
msgstr ""
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr ""
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
msgstr ""
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
msgstr ""
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
msgstr ""
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr ""
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default "
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"workplane group."
msgstr ""
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
msgstr ""
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr ""
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
-msgstr ""
+msgstr "клікніть для встановлення вихідної точки"
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
-msgstr ""
+msgstr "клікніть першу точку прямої лінії"
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
-msgstr ""
+msgstr "клікніть першу точку конструктивної прямої лінії"
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
-msgstr ""
+msgstr "клікніть першу точку кривої"
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
-msgstr ""
+msgstr "клікніть в місце де буде центр коментаря"
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
-msgstr ""
+msgstr "клікніть в центр відліку площини"
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
-msgstr ""
+msgstr "клікніть для встановлення першого кута прямокутника"
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
-msgstr ""
+msgstr "клікніть для встановлення верхньої лівої межі тексту"
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
-msgstr ""
+msgstr "клікніть для встановлення верхньої лівої межі зображення"
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid ""
"No entities are selected. Select entities before trying to toggle their "
"construction state."
#: group.cpp:86
msgctxt "group-name"
msgid "sketch-in-3d"
-msgstr ""
+msgstr "ескіз-в-3D"
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
msgstr ""
+"Активуйте робочу площину ( Ескіз -> У Площині) перед екструдуванням. Ескіз "
+"буде екструдовано перпендикулярно до робочої площини."
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
-msgstr ""
+msgstr "видавлювання"
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
-msgstr ""
+msgstr "проточування"
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
-msgstr ""
+msgstr "прокручування"
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
-msgstr ""
+msgstr "Спіраль може бути створена лише на основі площинного ескізу."
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
-msgstr ""
+msgstr "спіраль"
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
"point, and parallel to line / normal)\n"
msgstr ""
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
-msgstr ""
+msgstr "крутіння"
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
-msgstr ""
+msgstr "перекладання"
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
-msgstr ""
+msgstr "(безіменне)"
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
-msgstr ""
+msgstr "не замкнений контур або не все в єдиному стилі!"
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr ""
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
-msgstr ""
+msgstr "контур самоперетинається!"
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
+msgstr "ребро нульової довжини!"
+
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
msgstr ""
-#: modify.cpp:254
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr ""
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
msgstr ""
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
msgstr ""
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr ""
-#: modify.cpp:624
+#: modify.cpp:622
+#, fuzzy
msgid "Must be sketching in workplane to split."
-msgstr ""
+msgstr "Має бути накреслений у робочій площині для розділеня."
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
msgstr ""
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
-msgstr ""
+msgstr "Неможливо розділити; відсутній перетин."
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr "Встановити Стиль"
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr "Без Стилю"
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr "Створити Користувацький Стиль..."
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr "Параметри Групи"
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr "Параметри Стилю"
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr "Виділити Ланцюг Ребер"
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr "Перемкнути Відносність Розміру"
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr "Інший Суміжний Кут"
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr "Прикріпити до Сітки"
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr "Видалити Точку Сплайну"
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr "Додати Точку Сплайну"
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr ""
+"Неможливо додати точку сплайна: перевищено максимальну кількість точок."
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr "Пермкнути Конструктивність"
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr "Роз'єднати З'єднання Точок"
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr "Вирізати"
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr "Копіювати"
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr "Виділити Усе"
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr "Вставити"
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr "Вставити Трансформованим..."
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr "Видалити"
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr "Зняти Виділення з Усього"
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr "Зняти Виділення з Наведеного"
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr "Умістити на Екрані"
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
-msgstr ""
+msgstr "клікніть наступну точку лінії або натисніть Esc"
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
-msgstr ""
+msgstr "клікніть для встановлення іншого кута прямокутника"
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
-msgstr ""
+msgstr "клікніть для визначення радіусу"
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
-msgstr ""
+msgstr "клікніть для встановлення точки"
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
-msgstr ""
+msgstr "клікніть наступну точку кривої або натисніть Esc"
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
-msgstr ""
+msgstr "клікніть для встановлення нижньої правої межі тексту"
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-msgstr ""
-
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
msgctxt "file-type"
msgid "SolveSpace models"
+msgstr "SolveSpace модель"
+
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
msgstr ""
-#: platform/gui.cpp:90
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
+msgstr "IDF друкована плата"
+
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
msgstr ""
-#: platform/gui.cpp:94
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
-msgstr ""
+msgstr "PNG зображення"
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
-msgstr ""
+msgstr "STL меш"
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
-msgstr ""
+msgstr "Wavefront OBJ меш"
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
-msgstr ""
+msgstr "Three.js-сумісний меш, з переглядачем"
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
-msgstr ""
+msgstr "Three.js-сумісний меш, лише меш"
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
-msgstr ""
+msgstr "VRML меш, текстовий формат"
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
-msgstr ""
+msgstr "STEP файл"
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
-msgstr ""
+msgstr "PDF файл"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
-msgstr ""
+msgstr "Encapsulated PostScript"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
-msgstr ""
+msgstr "Scalable Vector Graphics, векторний формат"
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
-msgstr ""
+msgstr "DXF файл (AutoCAD 2007)"
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
-msgstr ""
+msgstr "HPGL файл"
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
-msgstr ""
+msgstr "G Code"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
-msgstr ""
+msgstr "AutoCAD DXF та DWG файли"
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
-msgstr ""
+msgstr "Comma-separated values"
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
-msgstr ""
+msgstr "без імені"
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
-msgstr ""
+msgstr "Зберегти Файл"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
-msgstr ""
+msgstr "Відкрити Файл"
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
-msgstr ""
+msgstr "_Скасувати"
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
-msgstr ""
+msgstr "_Зберегти"
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
-msgstr ""
+msgstr "_Відкрити"
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
-msgstr ""
+msgstr "Наявні автозбереження"
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
-msgstr ""
+msgstr "Наявні автозбереження для цього креслення."
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
-msgstr ""
+msgstr "Завантажити файл автозбереження?"
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
-msgstr ""
+msgstr "&Завантажити автозбереження"
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
-msgstr ""
+msgstr "&Не Завантажувати"
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
-msgstr ""
+msgstr "Файл Змінено"
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
-msgstr ""
+msgstr "Чи хочете ви зберегти зміни зроблені вами у ескізі “%s”?"
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
-msgstr ""
+msgstr "Чи хочете ви зберегти зміни зроблені вами у новому ескізі?"
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
-msgstr ""
+msgstr "Ваші зміни буде втрачено якщо ви не збережете їх."
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
-msgstr ""
+msgstr "&Зберегти"
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
-msgstr ""
+msgstr "&Не Зберігати"
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
-msgstr ""
+msgstr "(нове креслення)"
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
-msgstr ""
+msgstr "Браузер Властивостей"
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This "
"is probably not what you want; hide them by clicking the link at the top of "
"the text window."
msgstr ""
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid ""
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"dwg."
msgstr ""
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
-msgstr ""
+msgstr "Обмежувач має містити мітку і бути не відносним розміром."
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
-msgstr ""
+msgstr "Поганий вибір для крокової зміни розміру; оберіть обмежувач."
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
msgstr ""
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
"\n"
" %s"
msgstr ""
+"Об'єм твердого тіла становить:\n"
+"\n"
+" %s"
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
"\n"
" %s"
msgstr ""
+"\n"
+"Об'єм поточної групи мешу становить:\n"
+"\n"
+" %s"
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"This introduces error, typically of around 1%."
msgstr ""
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
msgstr ""
+"Ця група не місить коректно сформованого замкненої 2D площини. Вона "
+"відкрита, не компланарна, або ж самоперетинається."
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
msgstr ""
+"Площа заповнення ескізу у цій групі становить:\n"
+"\n"
+" %s\n"
+"\n"
+"Криві наближено до ламаних ліній.\n"
+"Це вносить похибку, зазвичай близько 1%%."
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%."
msgstr ""
+"Загальна довжина обраних елементів становить:\n"
+"\n"
+" %s\n"
+"\n"
+"Криві наближено до ламаних ліній.\n"
+"Це вносить похибку, зазвичай близько 1%%."
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
-msgstr ""
+msgstr "Поганий вибір для периметру; оберіть відрізки, дуги та криві."
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
-msgstr ""
+msgstr "Поганий вибір для вістежування шляху; оберіть одну точку."
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
-msgstr ""
+msgstr "Неможливо записати у '%s'"
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
-msgstr ""
+msgstr "Меш самоперетинається (НЕ добре, недійсний)."
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
-msgstr ""
+msgstr "Меш самоперетинається (добре, дійсний)."
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
-msgstr ""
+msgstr "Меш містить оголені ребра (НЕ добре, недійсний)."
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
-msgstr ""
+msgstr "Меш водонепроникний (добре, дійсний)."
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"The model contains %d triangles, from %d surfaces."
msgstr ""
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"\n"
"Zero problematic edges, good.%s"
msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Відсутні проблемні ребра, добре.%s"
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"\n"
"%d problematic edges, bad.%s"
msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d проблемних ребер, погано.%s"
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"\n"
"© 2008-%d Jonathan Westhues and other authors.\n"
msgstr ""
+"Це SolveSpace версії %s.\n"
+"\n"
+"Більше інформації на сайті http://solvespace.com/\n"
+"\n"
+"SolveSpace є вільною програмою: ви можете модифікувати\n"
+"та/або розповсюджувати її відповідно до ліцензії GNU\n"
+"General Public License (GPL) версії 3 чи новішої.\n"
+"\n"
+"ВІЧСУТНІ БУДЬ-ЯКІ ГАРАНТІЇ, в межах, доволених\n"
+"законом. Деталі на сайті http://gnu.org/licenses/\n"
+"\n"
+"© 2008-%d Jonathan Westhues та інші автори.\n"
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
msgstr ""
+"Неможливо призначити стиль елементу який походить від іншого елемента; "
+"спробуйте призначити стиль батьківському елементу."
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
-msgstr ""
+msgstr "Стиль не може містити порожнє ім'я"
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
-msgstr ""
+msgstr "Не можливо повторити менше 1 разу."
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
-msgstr ""
+msgstr "Не можливо повторити понад 999 разів."
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
-msgstr ""
+msgstr "Група не може містити порожнє ім'я"
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
-msgstr ""
+msgstr "Непрозорість має бути між 0 та 1."
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
-msgstr ""
+msgstr "Радіус не може бути нульовим чи від'ємним."
#: toolbar.cpp:18
msgid "Sketch line segment"
#: toolbar.cpp:28
msgid "Sketch image from a file"
-msgstr ""
+msgstr "Вставити зображення з файлу"
#: toolbar.cpp:30
msgid "Create tangent arc at selected point"
#: toolbar.cpp:68
msgid "New group extruding active sketch"
-msgstr "Ð\9dова гÑ\80Ñ\83па екÑ\81Ñ\82Ñ\80Ñ\83дÑ\83ваннÑ\8f акÑ\82ивного кÑ\80еÑ\81леннÑ\8f"
+msgstr "Ð\9dова гÑ\80Ñ\83па екÑ\81Ñ\82Ñ\80Ñ\83дÑ\83ваннÑ\8f акÑ\82ивного еÑ\81кÑ\96зÑ\83"
#: toolbar.cpp:70
msgid "New group rotating active sketch"
-msgstr "Ð\9dова гÑ\80Ñ\83па обеÑ\80Ñ\82аннÑ\8f акÑ\82иного кÑ\80еÑ\81леннÑ\8f"
+msgstr "Ð\9dова гÑ\80Ñ\83па обеÑ\80Ñ\82аннÑ\8f акÑ\82иного еÑ\81кÑ\96зÑ\83"
#: toolbar.cpp:72
msgid "New group helix from active sketch"
-msgstr ""
+msgstr "Нова група спіралі з активного ескізу"
#: toolbar.cpp:74
msgid "New group revolve active sketch"
-msgstr ""
+msgstr "Нова група обертання активного ескізу"
#: toolbar.cpp:76
msgid "New group step and repeat rotating"
#: toolbar.cpp:82
msgid "New group in 3d"
-msgstr "Нова група в 3d"
+msgstr "Нова група в 3D"
#: toolbar.cpp:84
msgid "New group linking / assembling file"
#: util.cpp:165
msgctxt "title"
msgid "Error"
-msgstr ""
+msgstr "Помилка"
#: util.cpp:165
msgctxt "title"
msgid "Message"
-msgstr ""
+msgstr "Повідомлення"
#: util.cpp:170
msgctxt "button"
msgid "&OK"
-msgstr ""
+msgstr "&OK"
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
-msgstr ""
+msgstr "Масштаб не може бути нульовим чи від'ємним."
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
-msgstr ""
+msgstr "Некоректний формат: визначте X, Y, Z"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "Про&порція Довжин"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "Рі&зниця Довжин"
#~ msgid "Show Degrees of &Freedom"
#~ msgstr "Показати Степені &Свободи"
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
-"PO-Revision-Date: 2020-09-28 12:42+0800\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
+"PO-Revision-Date: 2021-04-03 13:10-0400\n"
"Last-Translator: lomatus@163.com\n"
"Language-Team: none\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.4.1\n"
+"X-Generator: Poedit 2.4.2\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"\n"
"使用\"工作平面中的草图 -+\"激活一个。"
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
msgstr "剪贴板为空;没有要粘贴的内容。"
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
msgstr "要粘贴的副本数必须至少为 1 个。"
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
msgstr "缩放不能为零。"
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
msgstr "选择一个点以定义旋转原点。"
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
msgstr "选择两个点来定义转换向量。"
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid ""
"Transformation is identity. So all copies will be exactly on top of each "
"other."
msgstr "转换就是标识,因此所有的复制在彼此之上。"
-#: clipboard.cpp:458
+#: clipboard.cpp:457
msgid "Too many items to paste; split this into smaller pastes."
msgstr "要粘贴的项目太多; 请把他们拆分。"
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
msgstr "没有工作平面处于活动状态。"
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
msgstr "格式错误:将坐标指定为 x、y、z"
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
msgstr "格式错误:将颜色指定为 r、g、b"
-#: confscreen.cpp:454
+#: confscreen.cpp:417
msgid ""
"The perspective factor will have no effect until you enable View -> Use "
"Perspective Projection."
msgstr "在启用\"视图 -= 使用透视投影\"之前,透视因子将不起作用。"
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
msgstr "在十进制之后指定 0 和 %d 数字之间。"
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
msgstr "输出比例不能为零!"
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
msgstr "刀具半径偏移不能为负数!"
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
msgstr "坏值:自动保存间隔应为正"
-#: confscreen.cpp:558
+#: confscreen.cpp:531
msgid "Bad format: specify interval in integral minutes"
msgstr "格式错误:以整数分钟为单位指定间隔"
#: constraint.cpp:25
msgctxt "constr-name"
+msgid "arc-arc-length-ratio"
+msgstr ""
+
+#: constraint.cpp:26
+msgctxt "constr-name"
+msgid "arc-line-length-ratio"
+msgstr ""
+
+#: constraint.cpp:27
+msgctxt "constr-name"
msgid "length-difference"
msgstr "长度不同"
-#: constraint.cpp:26
+#: constraint.cpp:28
+msgctxt "constr-name"
+msgid "arc-arc-len-difference"
+msgstr ""
+
+#: constraint.cpp:29
+msgctxt "constr-name"
+msgid "arc-line-len-difference"
+msgstr ""
+
+#: constraint.cpp:30
msgctxt "constr-name"
msgid "symmetric"
msgstr "对称的"
-#: constraint.cpp:27
+#: constraint.cpp:31
msgctxt "constr-name"
msgid "symmetric-h"
msgstr "水平对称"
-#: constraint.cpp:28
+#: constraint.cpp:32
msgctxt "constr-name"
msgid "symmetric-v"
msgstr "纵向对称"
-#: constraint.cpp:29
+#: constraint.cpp:33
msgctxt "constr-name"
msgid "symmetric-line"
msgstr "线对称"
-#: constraint.cpp:30
+#: constraint.cpp:34
msgctxt "constr-name"
msgid "at-midpoint"
msgstr "在中点"
-#: constraint.cpp:31
+#: constraint.cpp:35
msgctxt "constr-name"
msgid "horizontal"
msgstr "水平约束"
-#: constraint.cpp:32
+#: constraint.cpp:36
msgctxt "constr-name"
msgid "vertical"
msgstr "垂直约束"
-#: constraint.cpp:33
+#: constraint.cpp:37
msgctxt "constr-name"
msgid "diameter"
msgstr "直径约束"
-#: constraint.cpp:34
+#: constraint.cpp:38
msgctxt "constr-name"
msgid "pt-on-circle"
msgstr "圆点约束"
-#: constraint.cpp:35
+#: constraint.cpp:39
msgctxt "constr-name"
msgid "same-orientation"
msgstr "相同原点"
-#: constraint.cpp:36
+#: constraint.cpp:40
msgctxt "constr-name"
msgid "angle"
msgstr "角度约束"
-#: constraint.cpp:37
+#: constraint.cpp:41
msgctxt "constr-name"
msgid "parallel"
msgstr "平行约束"
-#: constraint.cpp:38
+#: constraint.cpp:42
msgctxt "constr-name"
msgid "arc-line-tangent"
msgstr "弧切线"
-#: constraint.cpp:39
+#: constraint.cpp:43
msgctxt "constr-name"
msgid "cubic-line-tangent"
msgstr "立方体切线"
-#: constraint.cpp:40
+#: constraint.cpp:44
msgctxt "constr-name"
msgid "curve-curve-tangent"
msgstr "曲线间切线"
-#: constraint.cpp:41
+#: constraint.cpp:45
msgctxt "constr-name"
msgid "perpendicular"
msgstr "垂直约束"
-#: constraint.cpp:42
+#: constraint.cpp:46
msgctxt "constr-name"
msgid "eq-radius"
msgstr "等于半径"
-#: constraint.cpp:43
+#: constraint.cpp:47
msgctxt "constr-name"
msgid "eq-angle"
msgstr "等于角度"
-#: constraint.cpp:44
+#: constraint.cpp:48
msgctxt "constr-name"
msgid "eq-line-len-arc-len"
msgstr "等于线长或弧长"
-#: constraint.cpp:45
+#: constraint.cpp:49
msgctxt "constr-name"
msgid "lock-where-dragged"
msgstr "锁定位置"
-#: constraint.cpp:46
+#: constraint.cpp:50
msgctxt "constr-name"
msgid "comment"
msgstr "备注"
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with "
"Constrain -> On Point before constraining tangent."
msgstr "切线弧和线段必须共享一个端点。在约束切线之前,使用约束 -= 点约束它们。"
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining tangent."
msgstr ""
"切线立方段和线段必须共享终结点。在约束切线之前,使用约束 -= 点约束它们。"
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point "
"before constraining tangent."
msgstr "曲线必须共享一个终结点。在约束切线之前,使用约束 -= 点约束它们。"
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply "
"to:\n"
" * 平面面和点(最小距离)\n"
" * 圆或弧(直径)\n"
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can "
"apply to:\n"
" * 一个点和一个圆或圆(曲线上的点)\n"
" * 点和平面面(点在脸上)\n"
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can "
"apply to:\n"
" * 两个圆或圆(相等半径)\n"
" * 线段和圆弧(线段长度等于弧长)\n"
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-"长度比率约束的选择错误。此约束可应用于:\n"
-"\n"
-"* 两个线段\n"
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply "
"to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-"长度差异约束的选择错误。此约束可应用于:\n"
-"\n"
-"* 两个线段\n"
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
"* 线段和点(点在中点)\n"
" * 线段和工作平面(平面上的线中点)\n"
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
" * 线段,和两个点或线段(对称的线段)\n"
" * 工作平面和两个点或线段(工作平面对称)\n"
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid ""
"A workplane must be active when constraining symmetric without an explicit "
"symmetry plane."
msgstr "在没有显式对称平面约束对称时,工作平面必须处于活动状态。"
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a "
"horizontal or vertical constraint."
msgstr "在应用水平或垂直约束之前,激活工作平面(使用草图 -= 在工作平面中)。"
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can "
"apply to:\n"
"• 两点\n"
" • 线段\n"
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply "
"to:\n"
"\n"
"• 两个法线\n"
-#: constraint.cpp:614
+#: constraint.cpp:663
msgid "Must select an angle constraint."
msgstr "必须选择角度约束。"
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
msgstr "必须选择具有关联标签的约束。"
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * 线段和法线\n"
" • 两个法线\n"
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr "曲线曲线切线必须应用于工作平面。"
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply "
"to:\n"
" * 两个法线(平行)\n"
" * 共享端点的两条线段、弧线或贝塞尔(切线)\n"
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * 线段和法线\n"
" • 两个法线\n"
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can "
"apply to:\n"
"\n"
"• 一点\n"
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "新备注 - 双击编辑"
+
+#: constraint.cpp:818
msgid "click center of comment text"
msgstr "单击注释文本的中心"
" * 脸(通过面的剖面)\n"
" * 一个点和两个线段(平面穿过点和平行线)\n"
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
msgstr "活动组网格为空;没有要导出的。"
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr "徒手线替换为连续线"
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr "锯齿线替换为连续线"
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid ""
"Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr "绘图的某些方面没有 DXF 等效项,并且未导出:\n"
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid ""
"PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr "PDF 页面大小超过 200 英寸或 200 英寸;许多查看器可能会拒绝此文件。"
msgid "#references"
msgstr "#参考"
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr ""
+
+#: file.cpp:555
msgid ""
"Unrecognized data in file. This file may be corrupt, or from a newer version "
"of the program."
msgstr "未识别文件内数据。该文件可能损坏,或使用新版本应用程序尝试打开。"
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "文件丢失"
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr "连接的文件不存在:\"%s\"。"
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"permanently removed."
msgstr "您是否想手工查找?如果是,所有基于该丢失文件的几何对象将会被全部删除."
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr "是(&Y)"
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "否(&N)"
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
msgstr "取消(&C)"
msgstr "使用远景透视(&P)"
#: graphicswin.cpp:97
+msgid "Show E&xploded View"
+msgstr ""
+
+#: graphicswin.cpp:98
msgid "Dimension &Units"
msgstr "标注单位(&U)"
-#: graphicswin.cpp:98
+#: graphicswin.cpp:99
msgid "Dimensions in &Millimeters"
msgstr "标注单位 mm (&M)"
-#: graphicswin.cpp:99
+#: graphicswin.cpp:100
msgid "Dimensions in M&eters"
msgstr "标注单位m (&E)"
-#: graphicswin.cpp:100
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
msgstr "标准单位英寸 (&I)"
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr ""
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr "显示工具条(&T)"
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr "显示属性浏览器(&W)"
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr "全屏(&F)"
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr "新组合(&N)"
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
msgstr "在三维内绘制(&3)"
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
msgstr "在新工作面绘制(&W)"
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr "移动(&T)"
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr "旋转(&R)"
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr "挤出(&E)"
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
msgstr "螺旋(&H)"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr "扫略(&L)"
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
msgstr "旋转(&V)"
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
msgstr "链接/装配..."
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
msgstr "连接最近文件"
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr "绘图(&S)"
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
msgstr "在工作平面(&W)"
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
msgstr "在3D的任何位置(&3)"
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr "基准点(&P)"
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr "工作面(&W)"
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr "线段(&S)"
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr "构造线段(&C)"
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr "矩形(&R)"
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr "圆线(&C)"
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr "圆弧(&A)"
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr "立方体线的贝塞尔曲线(&B)"
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
msgstr "TrueTyoe字体文字(&T)"
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
msgstr "图片(&I)"
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr "切换构造(&G)"
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr "弧线切线点(&A)"
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr "在交叉处拆分曲线(&I)"
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr "约束(&C)"
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr "距离/直径(&D)"
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr "参考标注(&F)"
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr "角度(&A)"
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr "参考角度(&G)"
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr "其它增补角度(&U)"
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr "切换参考标注(&E)"
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr "水平约束(&H)"
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr "垂直约束(&V)"
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr "在点线面(&O)"
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr "等于/长度/半径/角度(&Q)"
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
-msgstr "长度比例(&T)"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
+msgstr ""
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
-msgstr "长度偏差(&E)"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
+msgstr ""
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr "在中点(&M)"
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr "对称(&Y)"
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr "水平/切线(&L)"
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr "垂直的(&P)"
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr "相同方向(&A)"
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr "锁定点位置(&D)"
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr "备注"
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr "分析(&A)"
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr "测量体积(&V)"
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr "测量面积(&R)"
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr "测量周长(&P)"
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr "显示干涉零件(&I)"
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr "显示孤立边(&N)"
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
msgstr "显示中心(&C)"
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
msgstr "显示无效约束点(&U)"
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr "跟踪点(&T)"
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
msgstr "停止跟踪(&S)"
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr "逐步标注(&D)"
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr "帮助(&H)"
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr "语言(&L)"
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr "网页/手册(&W)"
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr ""
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr "关于(&A)"
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
msgstr "(无文件)"
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
msgstr "文件不存在: \"%s\"。"
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
msgstr "没有激活的工作面,因此无法显示轴网。"
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel "
"projection.\n"
"configuration screen. A value around 0.3 is typical."
msgstr ""
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid ""
"Select a point; this point will become the center of the view on screen."
msgstr ""
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr ""
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or "
"make a link group the active group."
msgstr ""
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
"to define the plane for the snap grid."
msgstr ""
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints "
"with a label. To snap a line, select its endpoints."
msgstr ""
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr ""
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default "
"workplane. Try selecting a workplane, or activating a sketch-in-new-"
"workplane group."
msgstr ""
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select "
"nothing to set up arc parameters."
msgstr ""
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr "点击弧线的点(逆时针方向绘制)"
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
msgstr "点击放置基准点"
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
msgstr "点击线条的起点"
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
msgstr "点击构造线的起点"
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
msgstr "点击立方体的起点"
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
msgstr "点击圆弧的中心"
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
msgstr "点击工作面的原点"
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
msgstr "点击一个矩形倒角"
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
msgstr "点击文字左上角"
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
msgstr "点击图片左上角"
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid ""
"No entities are selected. Select entities before trying to toggle their "
"construction state."
msgid "sketch-in-3d"
msgstr "3D草图"
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the "
"lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
-"在新工作面内绘图选择失败,该组可以使用:\n"
-"\n"
-" * 一个点(通过该点,正交至坐标轴)\n"
-" * 一个点和二个线段(通过点,绘制平行线至线段)\n"
-" * 一个工作面(复制工作面)\n"
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch "
"will be extruded normal to the workplane."
msgstr "挤出前先激活工作面(草图->在工作面),该草图将由工作面的法线方向挤出。"
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
msgstr "挤出"
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr "扫略操作仅可用于二维草图。"
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
" * 一个点和一个线段或法线(围绕坐标轴至线或法线的平行线,通过点)\n"
" * 一个线段(围绕线段)\n"
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
msgstr "扫略"
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
msgstr "旋转"
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
msgstr "螺旋"
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
"point, and parallel to line / normal)\n"
msgstr ""
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
msgstr "旋转"
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
msgstr "移动"
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
msgstr "(未命名)"
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
-msgstr "未闭合轮廓,或样式不一致!"
+msgstr "未闭合轮廓 , 或样式不一致!"
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr "点不在相同平面!"
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
msgstr "轮廓自相交!"
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
msgstr "边缘长度为零!"
-#: modify.cpp:254
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr ""
+
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr ""
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or "
"circles in this group and workplane join."
msgstr ""
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the "
"desired geometry by hand with tangency constraints."
msgstr ""
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr ""
-#: modify.cpp:624
+#: modify.cpp:622
msgid "Must be sketching in workplane to split."
msgstr ""
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs "
"or a line/circle/arc and a point)."
msgstr ""
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
msgstr "无法拆分;未发现较差点。"
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr "指定样式"
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr "无样式"
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr "新组样式。"
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr "组信息"
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr "样式信息"
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr "选择边缘链"
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr "切换参考标注"
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr "其它补充角度"
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr "捕捉至轴网"
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr "删除样条线的点"
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr "增加样条线的点"
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr "无法增加样条线点:超过最大限制。"
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr "切换构造"
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr "删除点一致约束"
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr "剪切"
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr "复制"
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr "全选"
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr "粘贴"
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr "粘贴移动的..."
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr "删除"
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr "取消全选"
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr "取消覆盖区域的全选"
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr "自动缩放"
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
msgstr "点击下一个点或取消(ESC)"
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "无法在3D内绘制矩形; 首先,激活工作面,草图->在工作面。"
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
msgstr "点击放置其它矩形倒角"
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
msgstr "点击设置半径"
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "无法在3D空间内绘制弧线,可使用 草图->在工作面 激活工作面。"
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
msgstr "点击放置点"
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
msgstr "点击下一个点或取消(ESC)"
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr "已经在工作面绘制;在新建工作面前在三维空间绘制。"
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "无法在三维空间内绘制文字,可使用 草图->在工作面 激活工作面。"
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
msgstr "点击文字的右下角放置"
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 激活工作面。"
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
-msgstr "新备注 - 双击编辑"
-
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
msgctxt "file-type"
msgid "SolveSpace models"
msgstr "SolveSpace模型"
-#: platform/gui.cpp:90
+#: platform/gui.cpp:89
+msgctxt "file-type"
+msgid "ALL"
+msgstr ""
+
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
msgstr ""
-#: platform/gui.cpp:94
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr ""
+
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
msgstr "PNG图片"
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
msgstr "STL网格"
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
msgstr "Wavefront OBJ网格"
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
msgstr "Three.js-网格及查看视图"
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
msgstr "Three.js-仅网格"
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
msgstr "VRML文本文件"
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP文件"
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF文件"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "封装好的PostScript"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "SVG矢量图"
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF文件(AutoCAD 2007)"
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL文件"
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
msgstr "G Code"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF/DWG文件"
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
msgstr "逗号分隔数据"
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
msgstr "未命名"
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
msgstr "保存文件"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
msgstr "打开文件"
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
msgstr "取消_C"
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
msgstr "保存_S"
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
msgstr "打开_O"
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
msgstr ""
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
msgstr ""
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
msgstr ""
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
msgstr ""
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
msgstr ""
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
msgstr ""
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
msgstr ""
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
msgstr ""
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
msgstr ""
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
msgstr ""
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
msgstr ""
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
msgstr ""
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
msgstr ""
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This "
"is probably not what you want; hide them by clicking the link at the top of "
"the text window."
msgstr ""
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid ""
"Can't identify file type from file extension of filename '%s'; try .dxf or ."
"dwg."
msgstr ""
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
msgstr ""
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
msgstr ""
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
msgstr ""
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
" %s"
msgstr ""
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
" %s"
msgstr ""
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"This introduces error, typically of around 1%."
msgstr ""
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, "
"not coplanar, or self-intersecting."
msgstr ""
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
msgstr ""
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
msgstr ""
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
msgstr ""
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
msgstr ""
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
msgstr ""
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
msgstr ""
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
msgstr ""
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"The model contains %d triangles, from %d surfaces."
msgstr ""
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"Zero problematic edges, good.%s"
msgstr ""
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"%d problematic edges, bad.%s"
msgstr ""
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"© 2008-%d Jonathan Westhues and other authors.\n"
msgstr ""
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try "
"assigning a style to this entity's parent."
msgstr "无法将样式分配给派生自其他实体的实体;尝试将样式分配给此实体的父级。"
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
msgstr "样式名称不能为空"
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
msgstr "不能重复少于 1 次。"
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
msgstr "重复不超过 999 次。"
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
msgstr "组名称不能为空"
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
msgstr "不透明度必须在零和 1 之间。"
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
msgstr "半径偏移不能为负数。"
msgid "&OK"
msgstr "&OK"
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
msgstr "缩放不能为零。"
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
msgstr "格式错误: 需指定 x, y, z"
+#~ msgid ""
+#~ "Bad selection for length ratio constraint. This constraint can apply to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "长度比率约束的选择错误。此约束可应用于:\n"
+#~ "\n"
+#~ "* 两个线段\n"
+
+#~ msgid ""
+#~ "Bad selection for length difference constraint. This constraint can apply "
+#~ "to:\n"
+#~ "\n"
+#~ " * two line segments\n"
+#~ msgstr ""
+#~ "长度差异约束的选择错误。此约束可应用于:\n"
+#~ "\n"
+#~ "* 两个线段\n"
+
+#~ msgid "Length Ra&tio"
+#~ msgstr "长度比例(&T)"
+
+#~ msgid "Length Diff&erence"
+#~ msgstr "长度偏差(&E)"
+
+#~ msgid ""
+#~ "Bad selection for new sketch in workplane. This group can be created "
+#~ "with:\n"
+#~ "\n"
+#~ " * a point (through the point, orthogonal to coordinate axes)\n"
+#~ " * a point and two line segments (through the point, parallel to the "
+#~ "lines)\n"
+#~ " * a workplane (copy of the workplane)\n"
+#~ msgstr ""
+#~ "在新工作面内绘图选择失败,该组可以使用:\n"
+#~ "\n"
+#~ " * 一个点(通过该点,正交至坐标轴)\n"
+#~ " * 一个点和二个线段(通过点,绘制平行线至线段)\n"
+#~ " * 一个工作面(复制工作面)\n"
+
#~ msgctxt "file-type"
#~ msgid "Q3D Object file"
#~ msgstr "Q3D对象文件"
msgstr ""
"Project-Id-Version: SolveSpace 3.0\n"
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
-"POT-Creation-Date: 2021-01-17 19:54+0200\n"
+"POT-Creation-Date: 2022-02-01 16:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: clipboard.cpp:310
+#: clipboard.cpp:309
msgid ""
"Cut, paste, and copy work only in a workplane.\n"
"\n"
"Activate one with Sketch -> In Workplane."
msgstr ""
-#: clipboard.cpp:327
+#: clipboard.cpp:326
msgid "Clipboard is empty; nothing to paste."
msgstr ""
-#: clipboard.cpp:374
+#: clipboard.cpp:373
msgid "Number of copies to paste must be at least one."
msgstr ""
-#: clipboard.cpp:390 textscreens.cpp:783
+#: clipboard.cpp:389 textscreens.cpp:833
msgid "Scale cannot be zero."
msgstr ""
-#: clipboard.cpp:432
+#: clipboard.cpp:431
msgid "Select one point to define origin of rotation."
msgstr ""
-#: clipboard.cpp:444
+#: clipboard.cpp:443
msgid "Select two points to define translation vector."
msgstr ""
-#: clipboard.cpp:454
+#: clipboard.cpp:453
msgid "Transformation is identity. So all copies will be exactly on top of each other."
msgstr ""
-#: clipboard.cpp:458
+#: clipboard.cpp:457
msgid "Too many items to paste; split this into smaller pastes."
msgstr ""
-#: clipboard.cpp:463
+#: clipboard.cpp:462
msgid "No workplane active."
msgstr ""
-#: confscreen.cpp:418
+#: confscreen.cpp:381
msgid "Bad format: specify coordinates as x, y, z"
msgstr ""
-#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+#: confscreen.cpp:391 style.cpp:729 textscreens.cpp:864
msgid "Bad format: specify color as r, g, b"
msgstr ""
-#: confscreen.cpp:454
+#: confscreen.cpp:417
msgid ""
"The perspective factor will have no effect until you enable View -> Use Perspective Projection."
msgstr ""
-#: confscreen.cpp:467 confscreen.cpp:477
+#: confscreen.cpp:435 confscreen.cpp:445
#, c-format
msgid "Specify between 0 and %d digits after the decimal."
msgstr ""
-#: confscreen.cpp:489
+#: confscreen.cpp:457
msgid "Export scale must not be zero!"
msgstr ""
-#: confscreen.cpp:501
+#: confscreen.cpp:469
msgid "Cutter radius offset must not be negative!"
msgstr ""
-#: confscreen.cpp:555
+#: confscreen.cpp:528
msgid "Bad value: autosave interval should be positive"
msgstr ""
-#: confscreen.cpp:558
+#: confscreen.cpp:531
msgid "Bad format: specify interval in integral minutes"
msgstr ""
#: constraint.cpp:25
msgctxt "constr-name"
-msgid "length-difference"
+msgid "arc-arc-length-ratio"
msgstr ""
#: constraint.cpp:26
msgctxt "constr-name"
-msgid "symmetric"
+msgid "arc-line-length-ratio"
msgstr ""
#: constraint.cpp:27
msgctxt "constr-name"
-msgid "symmetric-h"
+msgid "length-difference"
msgstr ""
#: constraint.cpp:28
msgctxt "constr-name"
-msgid "symmetric-v"
+msgid "arc-arc-len-difference"
msgstr ""
#: constraint.cpp:29
msgctxt "constr-name"
-msgid "symmetric-line"
+msgid "arc-line-len-difference"
msgstr ""
#: constraint.cpp:30
msgctxt "constr-name"
-msgid "at-midpoint"
+msgid "symmetric"
msgstr ""
#: constraint.cpp:31
msgctxt "constr-name"
-msgid "horizontal"
+msgid "symmetric-h"
msgstr ""
#: constraint.cpp:32
msgctxt "constr-name"
-msgid "vertical"
+msgid "symmetric-v"
msgstr ""
#: constraint.cpp:33
msgctxt "constr-name"
-msgid "diameter"
+msgid "symmetric-line"
msgstr ""
#: constraint.cpp:34
msgctxt "constr-name"
-msgid "pt-on-circle"
+msgid "at-midpoint"
msgstr ""
#: constraint.cpp:35
msgctxt "constr-name"
-msgid "same-orientation"
+msgid "horizontal"
msgstr ""
#: constraint.cpp:36
msgctxt "constr-name"
-msgid "angle"
+msgid "vertical"
msgstr ""
#: constraint.cpp:37
msgctxt "constr-name"
-msgid "parallel"
+msgid "diameter"
msgstr ""
#: constraint.cpp:38
msgctxt "constr-name"
-msgid "arc-line-tangent"
+msgid "pt-on-circle"
msgstr ""
#: constraint.cpp:39
msgctxt "constr-name"
-msgid "cubic-line-tangent"
+msgid "same-orientation"
msgstr ""
#: constraint.cpp:40
msgctxt "constr-name"
-msgid "curve-curve-tangent"
+msgid "angle"
msgstr ""
#: constraint.cpp:41
msgctxt "constr-name"
-msgid "perpendicular"
+msgid "parallel"
msgstr ""
#: constraint.cpp:42
msgctxt "constr-name"
-msgid "eq-radius"
+msgid "arc-line-tangent"
msgstr ""
#: constraint.cpp:43
msgctxt "constr-name"
-msgid "eq-angle"
+msgid "cubic-line-tangent"
msgstr ""
#: constraint.cpp:44
msgctxt "constr-name"
-msgid "eq-line-len-arc-len"
+msgid "curve-curve-tangent"
msgstr ""
#: constraint.cpp:45
msgctxt "constr-name"
-msgid "lock-where-dragged"
+msgid "perpendicular"
msgstr ""
#: constraint.cpp:46
msgctxt "constr-name"
+msgid "eq-radius"
+msgstr ""
+
+#: constraint.cpp:47
+msgctxt "constr-name"
+msgid "eq-angle"
+msgstr ""
+
+#: constraint.cpp:48
+msgctxt "constr-name"
+msgid "eq-line-len-arc-len"
+msgstr ""
+
+#: constraint.cpp:49
+msgctxt "constr-name"
+msgid "lock-where-dragged"
+msgstr ""
+
+#: constraint.cpp:50
+msgctxt "constr-name"
msgid "comment"
msgstr ""
-#: constraint.cpp:140
+#: constraint.cpp:144
msgid ""
"The tangent arc and line segment must share an endpoint. Constrain them with Constrain -> On "
"Point before constraining tangent."
msgstr ""
-#: constraint.cpp:158
+#: constraint.cpp:163
msgid ""
"The tangent cubic and line segment must share an endpoint. Constrain them with Constrain -> On "
"Point before constraining tangent."
msgstr ""
-#: constraint.cpp:183
+#: constraint.cpp:189
msgid ""
"The curves must share an endpoint. Constrain them with Constrain -> On Point before constraining "
"tangent."
msgstr ""
-#: constraint.cpp:231
+#: constraint.cpp:238
msgid ""
"Bad selection for distance / diameter constraint. This constraint can apply to:\n"
"\n"
" * a circle or an arc (diameter)\n"
msgstr ""
-#: constraint.cpp:284
+#: constraint.cpp:291
msgid ""
"Bad selection for on point / curve / plane constraint. This constraint can apply to:\n"
"\n"
" * a point and a plane face (point on face)\n"
msgstr ""
-#: constraint.cpp:346
+#: constraint.cpp:353
msgid ""
"Bad selection for equal length / radius constraint. This constraint can apply to:\n"
"\n"
" * a line segment and an arc (line segment length equals arc length)\n"
msgstr ""
-#: constraint.cpp:385
+#: constraint.cpp:407
msgid ""
"Bad selection for length ratio constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-#: constraint.cpp:402
+#: constraint.cpp:441
msgid ""
"Bad selection for length difference constraint. This constraint can apply to:\n"
"\n"
" * two line segments\n"
+" * two arcs\n"
+" * one arc and one line segment\n"
msgstr ""
-#: constraint.cpp:428
+#: constraint.cpp:472
msgid ""
"Bad selection for at midpoint constraint. This constraint can apply to:\n"
"\n"
" * a line segment and a workplane (line's midpoint on plane)\n"
msgstr ""
-#: constraint.cpp:486
+#: constraint.cpp:530
msgid ""
"Bad selection for symmetric constraint. This constraint can apply to:\n"
"\n"
" * workplane, and two points or a line segment (symmetric about workplane)\n"
msgstr ""
-#: constraint.cpp:500
+#: constraint.cpp:545
msgid "A workplane must be active when constraining symmetric without an explicit symmetry plane."
msgstr ""
-#: constraint.cpp:530
+#: constraint.cpp:579
msgid ""
"Activate a workplane (with Sketch -> In Workplane) before applying a horizontal or vertical "
"constraint."
msgstr ""
-#: constraint.cpp:543
+#: constraint.cpp:592
msgid ""
"Bad selection for horizontal / vertical constraint. This constraint can apply to:\n"
"\n"
" * a line segment\n"
msgstr ""
-#: constraint.cpp:564
+#: constraint.cpp:613
msgid ""
"Bad selection for same orientation constraint. This constraint can apply to:\n"
"\n"
" * two normals\n"
msgstr ""
-#: constraint.cpp:614
+#: constraint.cpp:663
msgid "Must select an angle constraint."
msgstr ""
-#: constraint.cpp:627
+#: constraint.cpp:676
msgid "Must select a constraint with associated label."
msgstr ""
-#: constraint.cpp:638
+#: constraint.cpp:687
msgid ""
"Bad selection for angle constraint. This constraint can apply to:\n"
"\n"
" * two normals\n"
msgstr ""
-#: constraint.cpp:701
+#: constraint.cpp:754
msgid "Curve-curve tangency must apply in workplane."
msgstr ""
-#: constraint.cpp:711
+#: constraint.cpp:766
msgid ""
"Bad selection for parallel / tangent constraint. This constraint can apply to:\n"
"\n"
" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n"
msgstr ""
-#: constraint.cpp:729
+#: constraint.cpp:784
msgid ""
"Bad selection for perpendicular constraint. This constraint can apply to:\n"
"\n"
" * two normals\n"
msgstr ""
-#: constraint.cpp:744
+#: constraint.cpp:799
msgid ""
"Bad selection for lock point where dragged constraint. This constraint can apply to:\n"
"\n"
" * a point\n"
msgstr ""
-#: constraint.cpp:755
+#: constraint.cpp:813 mouse.cpp:1158
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr ""
+
+#: constraint.cpp:818
msgid "click center of comment text"
msgstr ""
" * a point and two line segments (plane through point and parallel to lines)\n"
msgstr ""
-#: export.cpp:822
+#: export.cpp:818
msgid "Active group mesh is empty; nothing to export."
msgstr ""
-#: exportvector.cpp:337
+#: exportvector.cpp:336
msgid "freehand lines were replaced with continuous lines"
msgstr ""
-#: exportvector.cpp:339
+#: exportvector.cpp:338
msgid "zigzag lines were replaced with continuous lines"
msgstr ""
-#: exportvector.cpp:593
+#: exportvector.cpp:592
msgid "Some aspects of the drawing have no DXF equivalent and were not exported:\n"
msgstr ""
-#: exportvector.cpp:839
+#: exportvector.cpp:838
msgid "PDF page size exceeds 200 by 200 inches; many viewers may reject this file."
msgstr ""
msgid "#references"
msgstr ""
-#: file.cpp:549
+#: file.cpp:550
+msgid "The file is empty. It may be corrupt."
+msgstr ""
+
+#: file.cpp:555
msgid "Unrecognized data in file. This file may be corrupt, or from a newer version of the program."
msgstr ""
-#: file.cpp:859
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr ""
-#: file.cpp:860
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr ""
-#: file.cpp:862
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
"If you decline, any geometry that depends on the missing file will be permanently removed."
msgstr ""
-#: file.cpp:865
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr ""
-#: file.cpp:867
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr ""
-#: file.cpp:869 solvespace.cpp:569
+#: file.cpp:877 solvespace.cpp:611
msgctxt "button"
msgid "&Cancel"
msgstr ""
msgstr ""
#: graphicswin.cpp:97
-msgid "Dimension &Units"
+msgid "Show E&xploded View"
msgstr ""
#: graphicswin.cpp:98
-msgid "Dimensions in &Millimeters"
+msgid "Dimension &Units"
msgstr ""
#: graphicswin.cpp:99
-msgid "Dimensions in M&eters"
+msgid "Dimensions in &Millimeters"
msgstr ""
#: graphicswin.cpp:100
+msgid "Dimensions in M&eters"
+msgstr ""
+
+#: graphicswin.cpp:101
msgid "Dimensions in &Inches"
msgstr ""
#: graphicswin.cpp:102
+msgid "Dimensions in &Feet and Inches"
+msgstr ""
+
+#: graphicswin.cpp:104
msgid "Show &Toolbar"
msgstr ""
-#: graphicswin.cpp:103
+#: graphicswin.cpp:105
msgid "Show Property Bro&wser"
msgstr ""
-#: graphicswin.cpp:105
+#: graphicswin.cpp:107
msgid "&Full Screen"
msgstr ""
-#: graphicswin.cpp:107
+#: graphicswin.cpp:109
msgid "&New Group"
msgstr ""
-#: graphicswin.cpp:108
+#: graphicswin.cpp:110
msgid "Sketch In &3d"
msgstr ""
-#: graphicswin.cpp:109
+#: graphicswin.cpp:111
msgid "Sketch In New &Workplane"
msgstr ""
-#: graphicswin.cpp:111
+#: graphicswin.cpp:113
msgid "Step &Translating"
msgstr ""
-#: graphicswin.cpp:112
+#: graphicswin.cpp:114
msgid "Step &Rotating"
msgstr ""
-#: graphicswin.cpp:114
+#: graphicswin.cpp:116
msgid "E&xtrude"
msgstr ""
-#: graphicswin.cpp:115
+#: graphicswin.cpp:117
msgid "&Helix"
msgstr ""
-#: graphicswin.cpp:116
+#: graphicswin.cpp:118
msgid "&Lathe"
msgstr ""
-#: graphicswin.cpp:117
+#: graphicswin.cpp:119
msgid "Re&volve"
msgstr ""
-#: graphicswin.cpp:119
+#: graphicswin.cpp:121
msgid "Link / Assemble..."
msgstr ""
-#: graphicswin.cpp:120
+#: graphicswin.cpp:122
msgid "Link Recent"
msgstr ""
-#: graphicswin.cpp:122
+#: graphicswin.cpp:124
msgid "&Sketch"
msgstr ""
-#: graphicswin.cpp:123
+#: graphicswin.cpp:125
msgid "In &Workplane"
msgstr ""
-#: graphicswin.cpp:124
+#: graphicswin.cpp:126
msgid "Anywhere In &3d"
msgstr ""
-#: graphicswin.cpp:126
+#: graphicswin.cpp:128
msgid "Datum &Point"
msgstr ""
-#: graphicswin.cpp:127
+#: graphicswin.cpp:129
msgid "&Workplane"
msgstr ""
-#: graphicswin.cpp:129
+#: graphicswin.cpp:131
msgid "Line &Segment"
msgstr ""
-#: graphicswin.cpp:130
+#: graphicswin.cpp:132
msgid "C&onstruction Line Segment"
msgstr ""
-#: graphicswin.cpp:131
+#: graphicswin.cpp:133
msgid "&Rectangle"
msgstr ""
-#: graphicswin.cpp:132
+#: graphicswin.cpp:134
msgid "&Circle"
msgstr ""
-#: graphicswin.cpp:133
+#: graphicswin.cpp:135
msgid "&Arc of a Circle"
msgstr ""
-#: graphicswin.cpp:134
+#: graphicswin.cpp:136
msgid "&Bezier Cubic Spline"
msgstr ""
-#: graphicswin.cpp:136
+#: graphicswin.cpp:138
msgid "&Text in TrueType Font"
msgstr ""
-#: graphicswin.cpp:137
+#: graphicswin.cpp:139
msgid "&Image"
msgstr ""
-#: graphicswin.cpp:139
+#: graphicswin.cpp:141
msgid "To&ggle Construction"
msgstr ""
-#: graphicswin.cpp:140
+#: graphicswin.cpp:142
msgid "Tangent &Arc at Point"
msgstr ""
-#: graphicswin.cpp:141
+#: graphicswin.cpp:143
msgid "Split Curves at &Intersection"
msgstr ""
-#: graphicswin.cpp:143
+#: graphicswin.cpp:145
msgid "&Constrain"
msgstr ""
-#: graphicswin.cpp:144
+#: graphicswin.cpp:146
msgid "&Distance / Diameter"
msgstr ""
-#: graphicswin.cpp:145
+#: graphicswin.cpp:147
msgid "Re&ference Dimension"
msgstr ""
-#: graphicswin.cpp:146
+#: graphicswin.cpp:148
msgid "A&ngle"
msgstr ""
-#: graphicswin.cpp:147
+#: graphicswin.cpp:149
msgid "Reference An&gle"
msgstr ""
-#: graphicswin.cpp:148
+#: graphicswin.cpp:150
msgid "Other S&upplementary Angle"
msgstr ""
-#: graphicswin.cpp:149
+#: graphicswin.cpp:151
msgid "Toggle R&eference Dim"
msgstr ""
-#: graphicswin.cpp:151
+#: graphicswin.cpp:153
msgid "&Horizontal"
msgstr ""
-#: graphicswin.cpp:152
+#: graphicswin.cpp:154
msgid "&Vertical"
msgstr ""
-#: graphicswin.cpp:154
+#: graphicswin.cpp:156
msgid "&On Point / Curve / Plane"
msgstr ""
-#: graphicswin.cpp:155
+#: graphicswin.cpp:157
msgid "E&qual Length / Radius / Angle"
msgstr ""
-#: graphicswin.cpp:156
-msgid "Length Ra&tio"
+#: graphicswin.cpp:158
+msgid "Length / Arc Ra&tio"
msgstr ""
-#: graphicswin.cpp:157
-msgid "Length Diff&erence"
+#: graphicswin.cpp:159
+msgid "Length / Arc Diff&erence"
msgstr ""
-#: graphicswin.cpp:158
+#: graphicswin.cpp:160
msgid "At &Midpoint"
msgstr ""
-#: graphicswin.cpp:159
+#: graphicswin.cpp:161
msgid "S&ymmetric"
msgstr ""
-#: graphicswin.cpp:160
+#: graphicswin.cpp:162
msgid "Para&llel / Tangent"
msgstr ""
-#: graphicswin.cpp:161
+#: graphicswin.cpp:163
msgid "&Perpendicular"
msgstr ""
-#: graphicswin.cpp:162
+#: graphicswin.cpp:164
msgid "Same Orient&ation"
msgstr ""
-#: graphicswin.cpp:163
+#: graphicswin.cpp:165
msgid "Lock Point Where &Dragged"
msgstr ""
-#: graphicswin.cpp:165
+#: graphicswin.cpp:167
msgid "Comment"
msgstr ""
-#: graphicswin.cpp:167
+#: graphicswin.cpp:169
msgid "&Analyze"
msgstr ""
-#: graphicswin.cpp:168
+#: graphicswin.cpp:170
msgid "Measure &Volume"
msgstr ""
-#: graphicswin.cpp:169
+#: graphicswin.cpp:171
msgid "Measure A&rea"
msgstr ""
-#: graphicswin.cpp:170
+#: graphicswin.cpp:172
msgid "Measure &Perimeter"
msgstr ""
-#: graphicswin.cpp:171
+#: graphicswin.cpp:173
msgid "Show &Interfering Parts"
msgstr ""
-#: graphicswin.cpp:172
+#: graphicswin.cpp:174
msgid "Show &Naked Edges"
msgstr ""
-#: graphicswin.cpp:173
+#: graphicswin.cpp:175
msgid "Show &Center of Mass"
msgstr ""
-#: graphicswin.cpp:175
+#: graphicswin.cpp:177
msgid "Show &Underconstrained Points"
msgstr ""
-#: graphicswin.cpp:177
+#: graphicswin.cpp:179
msgid "&Trace Point"
msgstr ""
-#: graphicswin.cpp:178
+#: graphicswin.cpp:180
msgid "&Stop Tracing..."
msgstr ""
-#: graphicswin.cpp:179
+#: graphicswin.cpp:181
msgid "Step &Dimension..."
msgstr ""
-#: graphicswin.cpp:181
+#: graphicswin.cpp:183
msgid "&Help"
msgstr ""
-#: graphicswin.cpp:182
+#: graphicswin.cpp:184
msgid "&Language"
msgstr ""
-#: graphicswin.cpp:183
+#: graphicswin.cpp:185
msgid "&Website / Manual"
msgstr ""
-#: graphicswin.cpp:185
+#: graphicswin.cpp:186
+msgid "&Go to GitHub commit"
+msgstr ""
+
+#: graphicswin.cpp:188
msgid "&About"
msgstr ""
-#: graphicswin.cpp:355
+#: graphicswin.cpp:362
msgid "(no recent files)"
msgstr ""
-#: graphicswin.cpp:363
+#: graphicswin.cpp:370
#, c-format
msgid "File '%s' does not exist."
msgstr ""
-#: graphicswin.cpp:725
+#: graphicswin.cpp:737
msgid "No workplane is active, so the grid will not appear."
msgstr ""
-#: graphicswin.cpp:740
+#: graphicswin.cpp:752
msgid ""
"The perspective factor is set to zero, so the view will always be a parallel projection.\n"
"\n"
"around 0.3 is typical."
msgstr ""
-#: graphicswin.cpp:819
+#: graphicswin.cpp:837
msgid "Select a point; this point will become the center of the view on screen."
msgstr ""
-#: graphicswin.cpp:1114
+#: graphicswin.cpp:1137
msgid "No additional entities share endpoints with the selected entities."
msgstr ""
-#: graphicswin.cpp:1132
+#: graphicswin.cpp:1155
msgid ""
"To use this command, select a point or other entity from an linked part, or make a link group the "
"active group."
msgstr ""
-#: graphicswin.cpp:1155
+#: graphicswin.cpp:1178
msgid ""
"No workplane is active. Activate a workplane (with Sketch -> In Workplane) to define the plane "
"for the snap grid."
msgstr ""
-#: graphicswin.cpp:1162
+#: graphicswin.cpp:1185
msgid ""
"Can't snap these items to grid; select points, text comments, or constraints with a label. To "
"snap a line, select its endpoints."
msgstr ""
-#: graphicswin.cpp:1247
+#: graphicswin.cpp:1270
msgid "No workplane selected. Activating default workplane for this group."
msgstr ""
-#: graphicswin.cpp:1250
+#: graphicswin.cpp:1273
msgid ""
"No workplane is selected, and the active group does not have a default workplane. Try selecting a "
"workplane, or activating a sketch-in-new-workplane group."
msgstr ""
-#: graphicswin.cpp:1271
+#: graphicswin.cpp:1294
msgid ""
"Bad selection for tangent arc at point. Select a single point, or select nothing to set up arc "
"parameters."
msgstr ""
-#: graphicswin.cpp:1282
+#: graphicswin.cpp:1305
msgid "click point on arc (draws anti-clockwise)"
msgstr ""
-#: graphicswin.cpp:1283
+#: graphicswin.cpp:1306
msgid "click to place datum point"
msgstr ""
-#: graphicswin.cpp:1284
+#: graphicswin.cpp:1307
msgid "click first point of line segment"
msgstr ""
-#: graphicswin.cpp:1286
+#: graphicswin.cpp:1309
msgid "click first point of construction line segment"
msgstr ""
-#: graphicswin.cpp:1287
+#: graphicswin.cpp:1310
msgid "click first point of cubic segment"
msgstr ""
-#: graphicswin.cpp:1288
+#: graphicswin.cpp:1311
msgid "click center of circle"
msgstr ""
-#: graphicswin.cpp:1289
+#: graphicswin.cpp:1312
msgid "click origin of workplane"
msgstr ""
-#: graphicswin.cpp:1290
+#: graphicswin.cpp:1313
msgid "click one corner of rectangle"
msgstr ""
-#: graphicswin.cpp:1291
+#: graphicswin.cpp:1314
msgid "click top left of text"
msgstr ""
-#: graphicswin.cpp:1297
+#: graphicswin.cpp:1320
msgid "click top left of image"
msgstr ""
-#: graphicswin.cpp:1309
+#: graphicswin.cpp:1346
msgid "No entities are selected. Select entities before trying to toggle their construction state."
msgstr ""
msgid "sketch-in-3d"
msgstr ""
-#: group.cpp:142
+#: group.cpp:150
msgid ""
"Bad selection for new sketch in workplane. This group can be created with:\n"
"\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, parallel to the lines)\n"
+" * a point and a normal (through the point, orthogonal to the normal)\n"
" * a workplane (copy of the workplane)\n"
msgstr ""
-#: group.cpp:154
+#: group.cpp:166
msgid ""
"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch will be extruded "
"normal to the workplane."
msgstr ""
-#: group.cpp:163
+#: group.cpp:175
msgctxt "group-name"
msgid "extrude"
msgstr ""
-#: group.cpp:168
+#: group.cpp:180
msgid "Lathe operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:179
+#: group.cpp:191
msgid ""
"Bad selection for new lathe group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:189
+#: group.cpp:201
msgctxt "group-name"
msgid "lathe"
msgstr ""
-#: group.cpp:194
+#: group.cpp:206
msgid "Revolve operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:205
+#: group.cpp:217
msgid ""
"Bad selection for new revolve group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:217
+#: group.cpp:229
msgctxt "group-name"
msgid "revolve"
msgstr ""
-#: group.cpp:222
+#: group.cpp:234
msgid "Helix operation can only be applied to planar sketches."
msgstr ""
-#: group.cpp:233
+#: group.cpp:245
msgid ""
"Bad selection for new helix group. This group can be created with:\n"
"\n"
" * a line segment (revolved about line segment)\n"
msgstr ""
-#: group.cpp:245
+#: group.cpp:257
msgctxt "group-name"
msgid "helix"
msgstr ""
-#: group.cpp:258
+#: group.cpp:270
msgid ""
"Bad selection for new rotation. This group can be created with:\n"
"\n"
"line / normal)\n"
msgstr ""
-#: group.cpp:271
+#: group.cpp:283
msgctxt "group-name"
msgid "rotate"
msgstr ""
-#: group.cpp:282
+#: group.cpp:294
msgctxt "group-name"
msgid "translate"
msgstr ""
-#: group.cpp:400
+#: group.cpp:416
msgid "(unnamed)"
msgstr ""
-#: groupmesh.cpp:709
+#: groupmesh.cpp:707
msgid "not closed contour, or not all same style!"
msgstr ""
-#: groupmesh.cpp:722
+#: groupmesh.cpp:720
msgid "points not all coplanar!"
msgstr ""
-#: groupmesh.cpp:724
+#: groupmesh.cpp:722
msgid "contour is self-intersecting!"
msgstr ""
-#: groupmesh.cpp:726
+#: groupmesh.cpp:724
msgid "zero-length edge!"
msgstr ""
-#: modify.cpp:254
+#: importmesh.cpp:136
+msgid "Text-formated STL files are not currently supported"
+msgstr ""
+
+#: modify.cpp:252
msgid "Must be sketching in workplane to create tangent arc."
msgstr ""
-#: modify.cpp:301
+#: modify.cpp:299
msgid ""
"To create a tangent arc, select a point where two non-construction lines or circles in this group "
"and workplane join."
msgstr ""
-#: modify.cpp:388
+#: modify.cpp:386
msgid ""
"Couldn't round this corner. Try a smaller radius, or try creating the desired geometry by hand "
"with tangency constraints."
msgstr ""
-#: modify.cpp:597
+#: modify.cpp:595
msgid "Couldn't split this entity; lines, circles, or cubics only."
msgstr ""
-#: modify.cpp:624
+#: modify.cpp:622
msgid "Must be sketching in workplane to split."
msgstr ""
-#: modify.cpp:631
+#: modify.cpp:629
msgid ""
"Select two entities that intersect each other (e.g. two lines/circles/arcs or a line/circle/arc "
"and a point)."
msgstr ""
-#: modify.cpp:736
+#: modify.cpp:734
msgid "Can't split; no intersection found."
msgstr ""
-#: mouse.cpp:560
+#: mouse.cpp:557
msgid "Assign to Style"
msgstr ""
-#: mouse.cpp:576
+#: mouse.cpp:573
msgid "No Style"
msgstr ""
-#: mouse.cpp:579
+#: mouse.cpp:576
msgid "Newly Created Custom Style..."
msgstr ""
-#: mouse.cpp:586
+#: mouse.cpp:583
msgid "Group Info"
msgstr ""
-#: mouse.cpp:606
+#: mouse.cpp:603
msgid "Style Info"
msgstr ""
-#: mouse.cpp:626
+#: mouse.cpp:623
msgid "Select Edge Chain"
msgstr ""
-#: mouse.cpp:632
+#: mouse.cpp:629
msgid "Toggle Reference Dimension"
msgstr ""
-#: mouse.cpp:638
+#: mouse.cpp:635
msgid "Other Supplementary Angle"
msgstr ""
-#: mouse.cpp:643
+#: mouse.cpp:640
msgid "Snap to Grid"
msgstr ""
-#: mouse.cpp:652
+#: mouse.cpp:649
msgid "Remove Spline Point"
msgstr ""
-#: mouse.cpp:687
+#: mouse.cpp:684
msgid "Add Spline Point"
msgstr ""
-#: mouse.cpp:691
+#: mouse.cpp:688
msgid "Cannot add spline point: maximum number of points reached."
msgstr ""
-#: mouse.cpp:716
+#: mouse.cpp:713
msgid "Toggle Construction"
msgstr ""
-#: mouse.cpp:731
+#: mouse.cpp:729
msgid "Delete Point-Coincident Constraint"
msgstr ""
-#: mouse.cpp:750
+#: mouse.cpp:747
msgid "Cut"
msgstr ""
-#: mouse.cpp:752
+#: mouse.cpp:749
msgid "Copy"
msgstr ""
-#: mouse.cpp:756
+#: mouse.cpp:753
msgid "Select All"
msgstr ""
-#: mouse.cpp:761
+#: mouse.cpp:758
msgid "Paste"
msgstr ""
-#: mouse.cpp:763
+#: mouse.cpp:760
msgid "Paste Transformed..."
msgstr ""
-#: mouse.cpp:768
+#: mouse.cpp:765
msgid "Delete"
msgstr ""
-#: mouse.cpp:771
+#: mouse.cpp:768
msgid "Unselect All"
msgstr ""
-#: mouse.cpp:778
+#: mouse.cpp:775
msgid "Unselect Hovered"
msgstr ""
-#: mouse.cpp:787
+#: mouse.cpp:784
msgid "Zoom to Fit"
msgstr ""
-#: mouse.cpp:989 mouse.cpp:1276
+#: mouse.cpp:986 mouse.cpp:1274
msgid "click next point of line, or press Esc"
msgstr ""
-#: mouse.cpp:995
+#: mouse.cpp:992
msgid "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1029
+#: mouse.cpp:1026
msgid "click to place other corner of rectangle"
msgstr ""
-#: mouse.cpp:1049
+#: mouse.cpp:1047
msgid "click to set radius"
msgstr ""
-#: mouse.cpp:1054
+#: mouse.cpp:1052
msgid "Can't draw arc in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1073
+#: mouse.cpp:1071
msgid "click to place point"
msgstr ""
-#: mouse.cpp:1089
+#: mouse.cpp:1087
msgid "click next point of cubic, or press Esc"
msgstr ""
-#: mouse.cpp:1094
+#: mouse.cpp:1092
msgid "Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
-#: mouse.cpp:1110
+#: mouse.cpp:1108
msgid "Can't draw text in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1127
+#: mouse.cpp:1125
msgid "click to place bottom right of text"
msgstr ""
-#: mouse.cpp:1133
+#: mouse.cpp:1131
msgid "Can't draw image in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1160
-msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+#: platform/gui.cpp:85 platform/gui.cpp:90 solvespace.cpp:553
+msgctxt "file-type"
+msgid "SolveSpace models"
msgstr ""
-#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+#: platform/gui.cpp:89
msgctxt "file-type"
-msgid "SolveSpace models"
+msgid "ALL"
msgstr ""
-#: platform/gui.cpp:90
+#: platform/gui.cpp:91
msgctxt "file-type"
msgid "IDF circuit board"
msgstr ""
-#: platform/gui.cpp:94
+#: platform/gui.cpp:92
+msgctxt "file-type"
+msgid "STL triangle mesh"
+msgstr ""
+
+#: platform/gui.cpp:96
msgctxt "file-type"
msgid "PNG image"
msgstr ""
-#: platform/gui.cpp:98
+#: platform/gui.cpp:100
msgctxt "file-type"
msgid "STL mesh"
msgstr ""
-#: platform/gui.cpp:99
+#: platform/gui.cpp:101
msgctxt "file-type"
msgid "Wavefront OBJ mesh"
msgstr ""
-#: platform/gui.cpp:100
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "Three.js-compatible mesh, with viewer"
msgstr ""
-#: platform/gui.cpp:101
+#: platform/gui.cpp:103
msgctxt "file-type"
msgid "Three.js-compatible mesh, mesh only"
msgstr ""
-#: platform/gui.cpp:102
+#: platform/gui.cpp:104
msgctxt "file-type"
msgid "VRML text file"
msgstr ""
-#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+#: platform/gui.cpp:108 platform/gui.cpp:115 platform/gui.cpp:122
msgctxt "file-type"
msgid "STEP file"
msgstr ""
-#: platform/gui.cpp:110
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "PDF file"
msgstr ""
-#: platform/gui.cpp:111
+#: platform/gui.cpp:113
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr ""
-#: platform/gui.cpp:112
+#: platform/gui.cpp:114
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr ""
-#: platform/gui.cpp:114 platform/gui.cpp:121
+#: platform/gui.cpp:116 platform/gui.cpp:123
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr ""
-#: platform/gui.cpp:115
+#: platform/gui.cpp:117
msgctxt "file-type"
msgid "HPGL file"
msgstr ""
-#: platform/gui.cpp:116
+#: platform/gui.cpp:118
msgctxt "file-type"
msgid "G Code"
msgstr ""
-#: platform/gui.cpp:125
+#: platform/gui.cpp:127
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr ""
-#: platform/gui.cpp:129
+#: platform/gui.cpp:131
msgctxt "file-type"
msgid "Comma-separated values"
msgstr ""
-#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630
+#: platform/guigtk.cpp:1382 platform/guimac.mm:1509 platform/guiwin.cpp:1641
msgid "untitled"
msgstr ""
-#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321
-#: platform/guiwin.cpp:1573
+#: platform/guigtk.cpp:1393 platform/guigtk.cpp:1426 platform/guimac.mm:1467
+#: platform/guiwin.cpp:1639
msgctxt "title"
msgid "Save File"
msgstr ""
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304
-#: platform/guiwin.cpp:1575
+#: platform/guigtk.cpp:1394 platform/guigtk.cpp:1427 platform/guimac.mm:1450
+#: platform/guiwin.cpp:1645
msgctxt "title"
msgid "Open File"
msgstr ""
-#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372
+#: platform/guigtk.cpp:1397 platform/guigtk.cpp:1433
msgctxt "button"
msgid "_Cancel"
msgstr ""
-#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370
+#: platform/guigtk.cpp:1398 platform/guigtk.cpp:1431
msgctxt "button"
msgid "_Save"
msgstr ""
-#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371
+#: platform/guigtk.cpp:1399 platform/guigtk.cpp:1432
msgctxt "button"
msgid "_Open"
msgstr ""
-#: solvespace.cpp:169
+#: solvespace.cpp:171
msgctxt "title"
msgid "Autosave Available"
msgstr ""
-#: solvespace.cpp:170
+#: solvespace.cpp:172
msgctxt "dialog"
msgid "An autosave file is available for this sketch."
msgstr ""
-#: solvespace.cpp:171
+#: solvespace.cpp:173
msgctxt "dialog"
msgid "Do you want to load the autosave file instead?"
msgstr ""
-#: solvespace.cpp:172
+#: solvespace.cpp:174
msgctxt "button"
msgid "&Load autosave"
msgstr ""
-#: solvespace.cpp:174
+#: solvespace.cpp:176
msgctxt "button"
msgid "Do&n't Load"
msgstr ""
-#: solvespace.cpp:557
+#: solvespace.cpp:599
msgctxt "title"
msgid "Modified File"
msgstr ""
-#: solvespace.cpp:559
+#: solvespace.cpp:601
#, c-format
msgctxt "dialog"
msgid "Do you want to save the changes you made to the sketch “%s”?"
msgstr ""
-#: solvespace.cpp:562
+#: solvespace.cpp:604
msgctxt "dialog"
msgid "Do you want to save the changes you made to the new sketch?"
msgstr ""
-#: solvespace.cpp:565
+#: solvespace.cpp:607
msgctxt "dialog"
msgid "Your changes will be lost if you don't save them."
msgstr ""
-#: solvespace.cpp:566
+#: solvespace.cpp:608
msgctxt "button"
msgid "&Save"
msgstr ""
-#: solvespace.cpp:568
+#: solvespace.cpp:610
msgctxt "button"
msgid "Do&n't Save"
msgstr ""
-#: solvespace.cpp:589
+#: solvespace.cpp:631
msgctxt "title"
msgid "(new sketch)"
msgstr ""
-#: solvespace.cpp:596
+#: solvespace.cpp:638
msgctxt "title"
msgid "Property Browser"
msgstr ""
-#: solvespace.cpp:658
+#: solvespace.cpp:700
msgid ""
"Constraints are currently shown, and will be exported in the toolpath. This is probably not what "
"you want; hide them by clicking the link at the top of the text window."
msgstr ""
-#: solvespace.cpp:730
+#: solvespace.cpp:772
#, c-format
msgid "Can't identify file type from file extension of filename '%s'; try .dxf or .dwg."
msgstr ""
-#: solvespace.cpp:778
+#: solvespace.cpp:824
msgid "Constraint must have a label, and must not be a reference dimension."
msgstr ""
-#: solvespace.cpp:782
+#: solvespace.cpp:828
msgid "Bad selection for step dimension; select a constraint."
msgstr ""
-#: solvespace.cpp:806
+#: solvespace.cpp:852
msgid "The assembly does not interfere, good."
msgstr ""
-#: solvespace.cpp:822
+#: solvespace.cpp:868
#, c-format
msgid ""
"The volume of the solid model is:\n"
" %s"
msgstr ""
-#: solvespace.cpp:831
+#: solvespace.cpp:877
#, c-format
msgid ""
"\n"
" %s"
msgstr ""
-#: solvespace.cpp:836
+#: solvespace.cpp:882
msgid ""
"\n"
"\n"
"This introduces error, typically of around 1%."
msgstr ""
-#: solvespace.cpp:851
+#: solvespace.cpp:897
#, c-format
msgid ""
"The surface area of the selected faces is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:860
+#: solvespace.cpp:906
msgid ""
"This group does not contain a correctly-formed 2d closed area. It is open, not coplanar, or self-"
"intersecting."
msgstr ""
-#: solvespace.cpp:872
+#: solvespace.cpp:918
#, c-format
msgid ""
"The area of the region sketched in this group is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:892
+#: solvespace.cpp:938
#, c-format
msgid ""
"The total length of the selected entities is:\n"
"This introduces error, typically of around 1%%."
msgstr ""
-#: solvespace.cpp:898
+#: solvespace.cpp:944
msgid "Bad selection for perimeter; select line segments, arcs, and curves."
msgstr ""
-#: solvespace.cpp:914
+#: solvespace.cpp:960
msgid "Bad selection for trace; select a single point."
msgstr ""
-#: solvespace.cpp:941
+#: solvespace.cpp:987
#, c-format
msgid "Couldn't write to '%s'"
msgstr ""
-#: solvespace.cpp:971
+#: solvespace.cpp:1017
msgid "The mesh is self-intersecting (NOT okay, invalid)."
msgstr ""
-#: solvespace.cpp:972
+#: solvespace.cpp:1018
msgid "The mesh is not self-intersecting (okay, valid)."
msgstr ""
-#: solvespace.cpp:974
+#: solvespace.cpp:1020
msgid "The mesh has naked edges (NOT okay, invalid)."
msgstr ""
-#: solvespace.cpp:975
+#: solvespace.cpp:1021
msgid "The mesh is watertight (okay, valid)."
msgstr ""
-#: solvespace.cpp:978
+#: solvespace.cpp:1024
#, c-format
msgid ""
"\n"
"The model contains %d triangles, from %d surfaces."
msgstr ""
-#: solvespace.cpp:982
+#: solvespace.cpp:1028
#, c-format
msgid ""
"%s\n"
"Zero problematic edges, good.%s"
msgstr ""
-#: solvespace.cpp:985
+#: solvespace.cpp:1031
#, c-format
msgid ""
"%s\n"
"%d problematic edges, bad.%s"
msgstr ""
-#: solvespace.cpp:998
+#: solvespace.cpp:1044
#, c-format
msgid ""
"This is SolveSpace version %s.\n"
"© 2008-%d Jonathan Westhues and other authors.\n"
msgstr ""
-#: style.cpp:166
+#: style.cpp:185
msgid ""
"Can't assign style to an entity that's derived from another entity; try assigning a style to this "
"entity's parent."
msgstr ""
-#: style.cpp:665
+#: style.cpp:735
msgid "Style name cannot be empty"
msgstr ""
-#: textscreens.cpp:741
+#: textscreens.cpp:791
msgid "Can't repeat fewer than 1 time."
msgstr ""
-#: textscreens.cpp:745
+#: textscreens.cpp:795
msgid "Can't repeat more than 999 times."
msgstr ""
-#: textscreens.cpp:770
+#: textscreens.cpp:820
msgid "Group name cannot be empty"
msgstr ""
-#: textscreens.cpp:813
+#: textscreens.cpp:872
msgid "Opacity must be between zero and one."
msgstr ""
-#: textscreens.cpp:848
+#: textscreens.cpp:907
msgid "Radius cannot be zero or negative."
msgstr ""
msgid "&OK"
msgstr ""
-#: view.cpp:78
+#: view.cpp:127
msgid "Scale cannot be zero or negative."
msgstr ""
-#: view.cpp:90 view.cpp:99
+#: view.cpp:139 view.cpp:148
msgid "Bad format: specify x, y, z"
msgstr ""
changeBasis.makeBasis(camera.right, camera.up, n);
for (var i = 0; i < 2; i++) {
- var newLightPos = changeBasis.applyToVector3Array(
- [obj.lights.d[i].direction[0], obj.lights.d[i].direction[1],
- obj.lights.d[i].direction[2]]);
+ var newLightPos = new THREE.Vector3(obj.lights.d[i].direction[0],
+ obj.lights.d[i].direction[1],
+ obj.lights.d[i].direction[2]).applyMatrix4(changeBasis);
directionalLightArray[i].position.set(newLightPos[0],
newLightPos[1], newLightPos[2]);
}
}
geometry.computeBoundingSphere();
- return new THREE.Mesh(geometry, new THREE.MultiMaterial(materialList));
+ return new THREE.Mesh(geometry, materialList);
}
function createEdges(meshObj) {
1 VERSIONINFO
-FILEVERSION ${solvespace_VERSION_MAJOR},${solvespace_VERSION_MINOR},0,0
-PRODUCTVERSION ${solvespace_VERSION_MAJOR},${solvespace_VERSION_MINOR},0,0
+FILEVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},0,0
+PRODUCTVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},0,0
FILEFLAGSMASK 0
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
BEGIN
VALUE "CompanyName", "The SolveSpace authors"
VALUE "ProductName", "SolveSpace"
- VALUE "ProductVersion", "${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}"
+ VALUE "ProductVersion", "${PROJECT_VERSION}~${solvespace_GIT_HASH}"
VALUE "FileDescription", "SolveSpace, a parametric 2d/3d CAD"
- VALUE "FileVersion", "${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}"
+ VALUE "FileVersion", "${PROJECT_VERSION}~${solvespace_GIT_HASH}"
VALUE "OriginalFilename", "solvespace.exe"
VALUE "InternalName", "solvespace"
- VALUE "LegalCopyright", "(c) 2008-2021 Jonathan Westhues and other authors"
+ VALUE "LegalCopyright", "(c) 2008-2022 Jonathan Westhues and other authors"
END
END
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
+# solvespace dependencies
+add_library(slvs_deps INTERFACE)
+target_include_directories(slvs_deps INTERFACE SYSTEM
+ ${OPENGL_INCLUDE_DIR}
+ ${ZLIB_INCLUDE_DIR}
+ ${PNG_PNG_INCLUDE_DIR}
+ ${FREETYPE_INCLUDE_DIRS}
+ ${CAIRO_INCLUDE_DIRS}
+ ${MIMALLOC_INCLUDE_DIR}
+ ${EIGEN3_INCLUDE_DIRS})
+target_link_libraries(slvs_deps INTERFACE
+ dxfrw
+ ${ZLIB_LIBRARY}
+ ${PNG_LIBRARY}
+ ${FREETYPE_LIBRARY}
+ ${CAIRO_LIBRARIES}
+ mimalloc-static)
+
+if(Backtrace_FOUND)
+ target_include_directories(slvs_deps INTERFACE SYSTEM
+ ${Backtrace_INCLUDE_DIRS})
+ target_link_libraries(slvs_deps INTERFACE
+ ${Backtrace_LIBRARY})
+endif()
+
+if(SPACEWARE_FOUND)
+ target_include_directories(slvs_deps INTERFACE SYSTEM
+ ${SPACEWARE_INCLUDE_DIR})
+ target_link_libraries(slvs_deps INTERFACE
+ ${SPACEWARE_LIBRARIES})
+endif()
+
+if(ENABLE_OPENMP)
+ target_link_libraries(slvs_deps INTERFACE slvs_openmp)
+endif()
+
+target_compile_options(slvs_deps
+ INTERFACE ${COVERAGE_FLAGS})
+
# platform utilities
if(APPLE)
- set(util_LIBRARIES
+ target_link_libraries(slvs_deps INTERFACE
${APPKIT_LIBRARY})
endif()
# libslvs
-
-set(libslvs_SOURCES
+add_library(slvs SHARED
+ solvespace.h
+ platform/platform.h
util.cpp
entity.cpp
expr.cpp
constraint.cpp
constrainteq.cpp
system.cpp
- platform/platform.cpp)
-
-set(libslvs_HEADERS
- solvespace.h
- platform/platform.h)
-
-add_library(slvs SHARED
- ${libslvs_SOURCES}
- ${libslvs_HEADERS}
- ${util_SOURCES}
+ platform/platform.cpp
lib.cpp)
target_compile_definitions(slvs
target_include_directories(slvs
PUBLIC ${CMAKE_SOURCE_DIR}/include)
-target_link_libraries(slvs
- ${util_LIBRARIES}
- mimalloc-static)
-
-add_dependencies(slvs
- mimalloc-static)
+target_link_libraries(slvs PRIVATE slvs_deps)
set_target_properties(slvs PROPERTIES
PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/slvs.h
- VERSION ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
+ VERSION ${PROJECT_VERSION}
SOVERSION 1)
if(NOT WIN32)
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
-# solvespace dependencies
-
-include_directories(
- ${OPENGL_INCLUDE_DIR}
- ${ZLIB_INCLUDE_DIR}
- ${PNG_PNG_INCLUDE_DIR}
- ${FREETYPE_INCLUDE_DIRS}
- ${CAIRO_INCLUDE_DIRS}
- ${MIMALLOC_INCLUDE_DIR}
- ${OpenMP_CXX_INCLUDE_DIRS})
-
-if(Backtrace_FOUND)
- include_directories(
- ${Backtrace_INCLUDE_DIRS})
-endif()
-
-if(SPACEWARE_FOUND)
- include_directories(
- ${SPACEWARE_INCLUDE_DIR})
-endif()
-
-if(OPENGL STREQUAL 3)
- set(gl_SOURCES
- render/gl3shader.cpp
- render/rendergl3.cpp)
-elseif(OPENGL STREQUAL 1)
- set(gl_SOURCES
- render/rendergl1.cpp)
-else()
- message(FATAL_ERROR "Unsupported OpenGL version ${OPENGL}")
-endif()
-
-set(platform_SOURCES
- ${gl_SOURCES}
- platform/entrygui.cpp)
-
-if(WIN32)
- list(APPEND platform_SOURCES
- platform/guiwin.cpp)
-
- set(platform_LIBRARIES
- comctl32
- ${SPACEWARE_LIBRARIES})
-elseif(APPLE)
- add_compile_options(
- -fobjc-arc)
-
- list(APPEND platform_SOURCES
- platform/guimac.mm)
-else()
- list(APPEND platform_SOURCES
- platform/guigtk.cpp)
-
- set(platform_LIBRARIES
- ${SPACEWARE_LIBRARIES})
-
- foreach(pkg_config_lib GTKMM JSONC FONTCONFIG)
- include_directories(${${pkg_config_lib}_INCLUDE_DIRS})
- link_directories(${${pkg_config_lib}_LIBRARY_DIRS})
- list(APPEND platform_LIBRARIES ${${pkg_config_lib}_LIBRARIES})
- endforeach()
-endif()
-
set(every_platform_SOURCES
platform/guiwin.cpp
platform/guigtk.cpp
# solvespace library
-set(solvespace_core_HEADERS
+set(solvespace_core_gl_SOURCES
+ solvespace.cpp)
+
+add_library(solvespace-core STATIC
dsc.h
expr.h
polygon.h
platform/platform.h
render/render.h
render/gl3shader.h
- srf/surface.h)
-
-set(solvespace_core_SOURCES
+ srf/surface.h
bsp.cpp
clipboard.cpp
confscreen.cpp
groupmesh.cpp
importdxf.cpp
importidf.cpp
+ importmesh.cpp
mesh.cpp
modify.cpp
mouse.cpp
srf/merge.cpp
srf/ratpoly.cpp
srf/raycast.cpp
+ srf/shell.cpp
srf/surface.cpp
srf/surfinter.cpp
srf/triangulate.cpp)
-set(solvespace_core_gl_SOURCES
- solvespace.cpp)
-
-add_library(solvespace-core STATIC
- ${util_SOURCES}
- ${solvespace_core_HEADERS}
- ${solvespace_core_SOURCES})
-
-add_dependencies(solvespace-core
- mimalloc-static)
-
-target_link_libraries(solvespace-core
- ${OpenMP_CXX_LIBRARIES}
- dxfrw
- ${util_LIBRARIES}
- ${ZLIB_LIBRARY}
- ${PNG_LIBRARY}
- ${FREETYPE_LIBRARY}
- mimalloc-static)
-
-if(Backtrace_FOUND)
- target_link_libraries(solvespace-core
- ${Backtrace_LIBRARY})
-endif()
-
-target_compile_options(solvespace-core
- PRIVATE ${COVERAGE_FLAGS})
+target_link_libraries(solvespace-core PUBLIC slvs_deps)
# solvespace translations
if(HAVE_GETTEXT)
+ get_target_property(solvespace_core_SOURCES solvespace-core SOURCES)
set(inputs
${solvespace_core_SOURCES}
- ${solvespace_core_HEADERS}
${every_platform_SOURCES}
${solvespace_core_gl_SOURCES})
--keyword --keyword=_ --keyword=N_ --keyword=C_:2,1c --keyword=CN_:2,1c
--force-po --width=100 --sort-by-file
--package-name=SolveSpace
- --package-version=${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
+ --package-version=${PROJECT_VERSION}
"--copyright-holder=the PACKAGE authors"
--msgid-bugs-address=whitequark@whitequark.org
--from-code=utf-8 --output=${gen_output_pot} ${inputs}
if(ENABLE_GUI)
add_executable(solvespace WIN32 MACOSX_BUNDLE
${solvespace_core_gl_SOURCES}
- ${platform_SOURCES}
+ platform/entrygui.cpp
$<TARGET_PROPERTY:resources,EXTRA_SOURCES>)
add_dependencies(solvespace
resources)
target_link_libraries(solvespace
+ PRIVATE
solvespace-core
- ${OPENGL_LIBRARIES}
- ${platform_LIBRARIES}
- ${COVERAGE_LIBRARY})
+ ${OPENGL_LIBRARIES})
+
+ # OpenGL version
+ if(OPENGL STREQUAL 3)
+ target_sources(solvespace PRIVATE
+ render/gl3shader.cpp
+ render/rendergl3.cpp)
+ elseif(OPENGL STREQUAL 1)
+ target_sources(solvespace PRIVATE
+ render/rendergl1.cpp)
+ else()
+ message(FATAL_ERROR "Unsupported OpenGL version ${OPENGL}")
+ endif()
+
+ # Platform-specific
+ if(WIN32)
+ target_sources(solvespace PRIVATE
+ platform/guiwin.cpp)
+
+ target_link_libraries(solvespace PRIVATE comctl32)
+ elseif(APPLE)
+ target_compile_options(solvespace PRIVATE -fobjc-arc)
+ target_compile_definitions(solvespace PRIVATE GL_SILENCE_DEPRECATION)
+
+ target_sources(solvespace PRIVATE
+ platform/guimac.mm)
+ set_target_properties(solvespace PROPERTIES
+ OUTPUT_NAME SolveSpace
+ XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES"
+ XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.solvespace"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
+ else()
+ target_sources(solvespace PRIVATE
+ platform/guigtk.cpp)
+
+ target_include_directories(solvespace PRIVATE SYSTEM
+ ${GTKMM_INCLUDE_DIRS}
+ ${JSONC_INCLUDE_DIRS}
+ ${FONTCONFIG_INCLUDE_DIRS})
+ target_link_directories(solvespace PRIVATE
+ ${GTKMM_LIBRARY_DIRS}
+ ${JSONC_LIBRARY_DIRS}
+ ${FONTCONFIG_LIBRARY_DIRS})
+ target_link_libraries(solvespace PRIVATE
+ ${GTKMM_LIBRARIES}
+ ${JSONC_LIBRARIES}
+ ${FONTCONFIG_LIBRARIES})
+ endif()
if(MSVC)
set_target_properties(solvespace PROPERTIES
LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /INCREMENTAL:NO /OPT:REF")
- elseif(APPLE)
- set_target_properties(solvespace PROPERTIES
- OUTPUT_NAME SolveSpace)
endif()
endif()
# solvespace headless library
-set(headless_SOURCES
- platform/guinone.cpp
- render/rendercairo.cpp)
-
add_library(solvespace-headless STATIC EXCLUDE_FROM_ALL
${solvespace_core_gl_SOURCES}
- ${headless_SOURCES})
+ platform/guinone.cpp
+ render/rendercairo.cpp)
target_compile_definitions(solvespace-headless
- PRIVATE -DHEADLESS)
+ PRIVATE HEADLESS)
target_include_directories(solvespace-headless
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(solvespace-headless
- solvespace-core
- ${CAIRO_LIBRARIES})
-
-target_compile_options(solvespace-headless
- PRIVATE ${COVERAGE_FLAGS})
+ PRIVATE
+ solvespace-core)
# solvespace command-line executable
# solvespace macOS package
if(APPLE)
- set(bundle SolveSpace)
- set(bundle_bin ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/MacOS)
- set(bundle_resources ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/Resources/lib)
- execute_process(
- COMMAND mkdir -p ${bundle_resources}
- COMMAND cp -p /usr/local/opt/libomp/lib/libomp.dylib ${bundle_resources}/libomp.dylib
- )
- add_custom_command(TARGET solvespace POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E make_directory ${bundle_bin}
- COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:solvespace-cli> ${bundle_bin}
- COMMAND install_name_tool -change /usr/local/opt/libomp/lib/libomp.dylib "@executable_path/../Resources/lib/libomp.dylib" ${bundle_bin}/${bundle}
- COMMENT "Bundling executable solvespace-cli"
- VERBATIM)
+ set(LIBOMP_LIB_PATH ${OpenMP_CXX_INCLUDE_DIRS}/../lib/libomp.dylib)
+ set(LIBOMP_LINK_PATH "@executable_path/../Resources/libomp.dylib")
+ set(LIBOMP_LINK_PATH_UTILS "@executable_path/SolveSpace.app/Contents/Resources/libomp.dylib")
+ if(ENABLE_GUI)
+ add_custom_command(TARGET solvespace POST_BUILD
+ COMMAND cp -r ${CMAKE_BINARY_DIR}/Resources $<TARGET_BUNDLE_CONTENT_DIR:solvespace>
+ )
+ if(ENABLE_OPENMP)
+ execute_process(COMMAND install_name_tool -id ${LIBOMP_LINK_PATH} ${LIBOMP_LIB_PATH})
+ message("FROM " ${${LIBOMP_LIB_PATH}} "TO" $<TARGET_BUNDLE_CONTENT_DIR:solvespace>/Resources/libomp.dylib)
+ add_custom_command(TARGET solvespace POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBOMP_LIB_PATH} $<TARGET_BUNDLE_CONTENT_DIR:solvespace>/Resources/libomp.dylib
+ COMMAND install_name_tool -change ${LIBOMP_LINK_PATH} ${LIBOMP_LINK_PATH_UTILS} $<TARGET_FILE:solvespace-debugtool>
+ )
+ endif()
+ endif()
+ if(ENABLE_TESTS AND ENABLE_OPENMP)
+ add_custom_command(TARGET solvespace POST_BUILD
+ COMMAND install_name_tool -change ${LIBOMP_LINK_PATH} ${LIBOMP_LINK_PATH_UTILS} $<TARGET_FILE:solvespace-testsuite>)
+ endif()
+ if(ENABLE_CLI)
+ add_custom_command(TARGET solvespace POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:solvespace-cli> $<TARGET_FILE_DIR:solvespace>
+ COMMENT "Bundling executable solvespace-cli"
+ VERBATIM)
+ endif()
endif()
}
}
- Constraint *c;
- for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
- if(!SS.clipboard.ContainsEntity(c->ptA) ||
- !SS.clipboard.ContainsEntity(c->ptB) ||
- !SS.clipboard.ContainsEntity(c->entityA) ||
- !SS.clipboard.ContainsEntity(c->entityB) ||
- !SS.clipboard.ContainsEntity(c->entityC) ||
- !SS.clipboard.ContainsEntity(c->entityD) ||
- c->type == Constraint::Type::COMMENT) {
+ for(Constraint &c : SK.constraint) {
+ if(!SS.clipboard.ContainsEntity(c.ptA) ||
+ !SS.clipboard.ContainsEntity(c.ptB) ||
+ !SS.clipboard.ContainsEntity(c.entityA) ||
+ !SS.clipboard.ContainsEntity(c.entityB) ||
+ !SS.clipboard.ContainsEntity(c.entityC) ||
+ !SS.clipboard.ContainsEntity(c.entityD) ||
+ c.type == Constraint::Type::COMMENT) {
continue;
}
- SS.clipboard.c.Add(c);
+ SS.clipboard.c.Add(&c);
}
}
}
case Constraint::Type::HORIZONTAL:
case Constraint::Type::VERTICAL:
- // When rotating 90 or 270 degrees, swap the vertical / horizontal constaints
+ // When rotating 90 or 270 degrees, swap the vertical / horizontal constraints
if (EXACT(fmod(theta + (PI/2), PI) == 0)) {
if(c.type == Constraint::Type::HORIZONTAL) {
c.type = Constraint::Type::VERTICAL;
#ifndef SOLVESPACE_CONFIG_H
#define SOLVESPACE_CONFIG_H
-#define PACKAGE_VERSION "@solvespace_VERSION_MAJOR@.@solvespace_VERSION_MINOR@~@solvespace_GIT_HASH@"
+#define PACKAGE_VERSION "@PROJECT_VERSION@~@solvespace_GIT_HASH@"
+#define GIT_HASH_URL "https://github.com/solvespace/solvespace/commit/@solvespace_GIT_HASH@"
/* Non-OS X *nix only */
#define UNIX_DATADIR "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_DATAROOTDIR@/solvespace"
#include <omp.h>
#endif
-void TextWindow::ScreenChangeLightDirection(int link, uint32_t v) {
- SS.TW.ShowEditControl(8, ssprintf("%.2f, %.2f, %.2f", CO(SS.lightDir[v])));
- SS.TW.edit.meaning = Edit::LIGHT_DIRECTION;
- SS.TW.edit.i = v;
-}
-
-void TextWindow::ScreenChangeLightIntensity(int link, uint32_t v) {
- SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.lightIntensity[v]));
- SS.TW.edit.meaning = Edit::LIGHT_INTENSITY;
- SS.TW.edit.i = v;
-}
-
-void TextWindow::ScreenChangeLightAmbient(int link, uint32_t v) {
- SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.ambientIntensity));
- SS.TW.edit.meaning = Edit::LIGHT_AMBIENT;
- SS.TW.edit.i = 0;
-}
-
void TextWindow::ScreenChangeColor(int link, uint32_t v) {
SS.TW.ShowEditControlWithColorPicker(13, SS.modelColor[v]);
SS.TW.edit.i = 1;
}
-void TextWindow::ScreenChangeCameraTangent(int link, uint32_t v) {
- SS.TW.ShowEditControl(3, ssprintf("%.3f", 1000*SS.cameraTangent));
- SS.TW.edit.meaning = Edit::CAMERA_TANGENT;
-}
-
void TextWindow::ScreenChangeGridSpacing(int link, uint32_t v) {
- SS.TW.ShowEditControl(3, SS.MmToString(SS.gridSpacing));
+ SS.TW.ShowEditControl(3, SS.MmToString(SS.gridSpacing, true));
SS.TW.edit.meaning = Edit::GRID_SPACING;
}
}
void TextWindow::ScreenChangeExportOffset(int link, uint32_t v) {
- SS.TW.ShowEditControl(3, SS.MmToString(SS.exportOffset));
+ SS.TW.ShowEditControl(3, SS.MmToString(SS.exportOffset, true));
SS.TW.edit.meaning = Edit::EXPORT_OFFSET;
}
}
int col = 13;
if(v < 10) col = 11;
- SS.TW.ShowEditControl(col, SS.MmToString(d));
+ SS.TW.ShowEditControl(col, SS.MmToString(d, true));
SS.TW.edit.meaning = Edit::CANVAS_SIZE;
SS.TW.edit.i = v;
}
switch(link) {
case 'd':
SS.TW.edit.meaning = Edit::G_CODE_DEPTH;
- buf += SS.MmToString(SS.gCode.depth);
+ buf += SS.MmToString(SS.gCode.depth, true);
+ break;
+
+ case 'h':
+ SS.TW.edit.meaning = Edit::G_CODE_SAFE_HEIGHT;
+ buf += SS.MmToString(SS.gCode.safeHeight, true);
break;
case 's':
case 'F':
SS.TW.edit.meaning = Edit::G_CODE_FEED;
- buf += SS.MmToString(SS.gCode.feed);
+ buf += SS.MmToString(SS.gCode.feed, true);
break;
case 'P':
SS.TW.edit.meaning = Edit::G_CODE_PLUNGE_FEED;
- buf += SS.MmToString(SS.gCode.plungeFeed);
+ buf += SS.MmToString(SS.gCode.plungeFeed, true);
break;
}
SS.TW.ShowEditControl(14, buf);
&ScreenChangeColor, i);
}
- Printf(false, "");
- Printf(false, "%Ft light direction intensity");
- for(i = 0; i < 2; i++) {
- Printf(false, "%Bp #%d (%2,%2,%2)%Fl%D%f%Ll[c]%E "
- "%2 %Fl%D%f%Ll[c]%E",
- (i & 1) ? 'd' : 'a', i,
- CO(SS.lightDir[i]), i, &ScreenChangeLightDirection,
- SS.lightIntensity[i], i, &ScreenChangeLightIntensity);
- }
- Printf(false, "%Bp ambient lighting "
- "%2 %Fl%D%f%Ll[c]%E",
- (i & 1) ? 'd' : 'a', i,
- SS.ambientIntensity, &ScreenChangeLightAmbient);
-
Printf(false, "");
Printf(false, "%Ft chord tolerance (in percents)%E");
Printf(false, "%Ba %@ %% %Fl%Ll%f%D[change]%E; %@ mm, %d triangles",
SS.exportMaxSegments,
&ScreenChangeExportMaxSegments);
- Printf(false, "");
- Printf(false, "%Ft perspective factor (0 for parallel)%E");
- Printf(false, "%Ba %# %Fl%Ll%f%D[change]%E",
- SS.cameraTangent*1000,
- &ScreenChangeCameraTangent, 0);
Printf(false, "%Ft snap grid spacing%E");
Printf(false, "%Ba %s %Fl%Ll%f%D[change]%E",
SS.MmToString(SS.gridSpacing).c_str(),
SS.GW.Invalidate();
break;
}
+ case Edit::EXPLODE_DISTANCE: {
+ SS.explodeDistance = min(1e4, max(-1e4, SS.StringToMm(s)));
+ SS.MarkGroupDirty(SS.GW.activeGroup, true);
+ break;
+ }
case Edit::DIGITS_AFTER_DECIMAL: {
int v = atoi(s.c_str());
if(v < 0 || v > 8) {
if(e) SS.gCode.depth = (float)SS.ExprToMm(e);
break;
}
+ case Edit::G_CODE_SAFE_HEIGHT: {
+ Expr *e = Expr::From(s, /*popUpError=*/true);
+ if(e) SS.gCode.safeHeight = (float)SS.ExprToMm(e);
+ break;
+ }
case Edit::G_CODE_PASSES: {
Expr *e = Expr::From(s, /*popUpError=*/true);
if(e) SS.gCode.passes = (int)(e->Eval());
case Type::EQ_LEN_PT_LINE_D: s = C_("constr-name", "eq-length-and-pt-ln-dist"); break;
case Type::EQ_PT_LN_DISTANCES: s = C_("constr-name", "eq-pt-line-distances"); break;
case Type::LENGTH_RATIO: s = C_("constr-name", "length-ratio"); break;
+ case Type::ARC_ARC_LEN_RATIO: s = C_("constr-name", "arc-arc-length-ratio"); break;
+ case Type::ARC_LINE_LEN_RATIO: s = C_("constr-name", "arc-line-length-ratio"); break;
case Type::LENGTH_DIFFERENCE: s = C_("constr-name", "length-difference"); break;
+ case Type::ARC_ARC_DIFFERENCE: s = C_("constr-name", "arc-arc-len-difference"); break;
+ case Type::ARC_LINE_DIFFERENCE: s = C_("constr-name", "arc-line-len-difference"); break;
case Type::SYMMETRIC: s = C_("constr-name", "symmetric"); break;
case Type::SYMMETRIC_HORIZ: s = C_("constr-name", "symmetric-h"); break;
case Type::SYMMETRIC_VERT: s = C_("constr-name", "symmetric-v"); break;
Entity::NO_ENTITY, Entity::NO_ENTITY, /*other=*/false, /*other2=*/false);
}
-void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc) {
+bool Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc) {
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(),
Error(_("The tangent arc and line segment must share an "
"endpoint. Constrain them with Constrain -> "
"On Point before constraining tangent."));
- return;
+ return false;
}
+ return true;
}
-void Constraint::ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic) {
+bool Constraint::ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic) {
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector as = cubic->CubicGetStartNum(),
Error(_("The tangent cubic and line segment must share an "
"endpoint. Constrain them with Constrain -> "
"On Point before constraining tangent."));
- return;
+ return false;
}
+ return true;
}
-void Constraint::ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB) {
+bool Constraint::ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB) {
Vector as = eA->EndpointStart(),
af = eA->EndpointFinish(),
bs = eB->EndpointStart(),
Error(_("The curves must share an endpoint. Constrain them "
"with Constrain -> On Point before constraining "
"tangent."));
- return;
+ return false;
}
+ return true;
}
void Constraint::MenuConstrain(Command id) {
c.type = Type::LENGTH_RATIO;
c.entityA = gs.entity[0];
c.entityB = gs.entity[1];
+ }
+ else if(gs.arcs == 2 && gs.n == 2) {
+ c.type = Type::ARC_ARC_LEN_RATIO;
+ c.entityA = gs.entity[0];
+ c.entityB = gs.entity[1];
+ }
+ else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) {
+ c.type = Type::ARC_LINE_LEN_RATIO;
+ if(SK.GetEntity(gs.entity[0])->type == Entity::Type::ARC_OF_CIRCLE) {
+ c.entityA = gs.entity[1];
+ c.entityB = gs.entity[0];
+ } else {
+ c.entityA = gs.entity[0];
+ c.entityB = gs.entity[1];
+ }
} else {
Error(_("Bad selection for length ratio constraint. This "
"constraint can apply to:\n\n"
- " * two line segments\n"));
+ " * two line segments\n"
+ " * two arcs\n"
+ " * one arc and one line segment\n"));
return;
}
c.type = Type::LENGTH_DIFFERENCE;
c.entityA = gs.entity[0];
c.entityB = gs.entity[1];
+ }
+ else if(gs.arcs == 2 && gs.n == 2) {
+ c.type = Type::ARC_ARC_DIFFERENCE;
+ c.entityA = gs.entity[0];
+ c.entityB = gs.entity[1];
+ }
+ else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) {
+ c.type = Type::ARC_LINE_DIFFERENCE;
+ if(SK.GetEntity(gs.entity[0])->type == Entity::Type::ARC_OF_CIRCLE) {
+ c.entityA = gs.entity[1];
+ c.entityB = gs.entity[0];
+ } else {
+ c.entityA = gs.entity[0];
+ c.entityB = gs.entity[1];
+ }
} else {
Error(_("Bad selection for length difference constraint. This "
"constraint can apply to:\n\n"
- " * two line segments\n"));
+ " * two line segments\n"
+ " * two arcs\n"
+ " * one arc and one line segment\n"));
return;
}
c.ptA = gs.point[0];
// If a point is at-midpoint, then no reason to also constrain
- // it on-line; so auto-remove that.
+ // it on-line; so auto-remove that. Handle as one undo group.
+ SS.UndoRemember();
DeleteAllConstraintsFor(Type::PT_ON_LINE, c.entityA, c.ptA);
+ AddConstraint(&c, /*rememberForUndo=*/false);
+ break;
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
c.type = Type::AT_MIDPOINT;
int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
"(symmetric about workplane)\n"));
return;
}
+ // We may remove constraints so remember manually
if(c.entityA == Entity::NO_ENTITY) {
// Horizontal / vertical symmetry, implicit symmetry plane
// normal to the workplane
if(gs.lineSegments == 1) {
// If this line segment is already constrained horiz or
// vert, then auto-remove that redundant constraint.
+ // Handle as one undo group.
+ SS.UndoRemember();
DeleteAllConstraintsFor(Type::HORIZONTAL, (gs.entity[0]),
Entity::NO_ENTITY);
DeleteAllConstraintsFor(Type::VERTICAL, (gs.entity[0]),
Entity::NO_ENTITY);
+ AddConstraint(&c, /*rememberForUndo=*/false);
+ break;
}
}
AddConstraint(&c);
if(line->type == Entity::Type::ARC_OF_CIRCLE) {
swap(line, arc);
}
- ConstrainArcLineTangent(&c, line, arc);
+ if(!ConstrainArcLineTangent(&c, line, arc)) {
+ return;
+ }
c.type = Type::ARC_LINE_TANGENT;
c.entityA = arc->h;
c.entityB = line->h;
if(line->type == Entity::Type::CUBIC) {
swap(line, cubic);
}
- ConstrainCubicLineTangent(&c, line, cubic);
+ if(!ConstrainCubicLineTangent(&c, line, cubic)) {
+ return;
+ }
c.type = Type::CUBIC_LINE_TANGENT;
c.entityA = cubic->h;
c.entityB = line->h;
}
Entity *eA = SK.GetEntity(gs.entity[0]),
*eB = SK.GetEntity(gs.entity[1]);
- ConstrainCurveCurveTangent(&c, eA, eB);
+ if(!ConstrainCurveCurveTangent(&c, eA, eB)) {
+ return;
+ }
c.type = Type::CURVE_CURVE_TANGENT;
c.entityA = eA->h;
c.entityB = eB->h;
break;
case Command::COMMENT:
- SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
- SS.GW.pending.command = Command::COMMENT;
- SS.GW.pending.description = _("click center of comment text");
- SS.ScheduleShowTW();
+ if(gs.points == 1 && gs.n == 1) {
+ c.type = Type::COMMENT;
+ c.ptA = gs.point[0];
+ c.group = SS.GW.activeGroup;
+ c.workplane = SS.GW.ActiveWorkplane();
+ c.comment = _("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
+ AddConstraint(&c);
+ } else {
+ SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
+ SS.GW.pending.command = Command::COMMENT;
+ SS.GW.pending.description = _("click center of comment text");
+ SS.ScheduleShowTW();
+ }
break;
default: ssassert(false, "Unexpected menu ID");
case Type::PROJ_PT_DISTANCE:
case Type::DIAMETER:
case Type::LENGTH_RATIO:
+ case Type::ARC_ARC_LEN_RATIO:
+ case Type::ARC_LINE_LEN_RATIO:
case Type::LENGTH_DIFFERENCE:
+ case Type::ARC_ARC_DIFFERENCE:
+ case Type::ARC_LINE_DIFFERENCE:
case Type::ANGLE:
case Type::COMMENT:
return true;
case Type::EQ_PT_LN_DISTANCES:
case Type::EQUAL_ANGLE:
case Type::LENGTH_RATIO:
+ case Type::ARC_ARC_LEN_RATIO:
+ case Type::ARC_LINE_LEN_RATIO:
case Type::LENGTH_DIFFERENCE:
+ case Type::ARC_ARC_DIFFERENCE:
+ case Type::ARC_LINE_DIFFERENCE:
case Type::SYMMETRIC:
case Type::SYMMETRIC_HORIZ:
case Type::SYMMETRIC_VERT:
AddEq(l, (la->Div(lb))->Minus(exA), 0);
return;
}
+
+ case Type::ARC_ARC_LEN_RATIO: {
+ EntityBase *arc1 = SK.GetEntity(entityA),
+ *arc2 = SK.GetEntity(entityB);
+
+ // And get the arc1 radius, and the cosine of its angle
+ EntityBase *ao1 = SK.GetEntity(arc1->point[0]),
+ *as1 = SK.GetEntity(arc1->point[1]),
+ *af1 = SK.GetEntity(arc1->point[2]);
+
+ ExprVector aos1 = (as1->PointGetExprs()).Minus(ao1->PointGetExprs()),
+ aof1 = (af1->PointGetExprs()).Minus(ao1->PointGetExprs());
+ Expr *r1 = aof1.Magnitude();
+
+ ExprVector n1 = arc1->Normal()->NormalExprsN();
+ ExprVector u1 = aos1.WithMagnitude(Expr::From(1.0));
+ ExprVector v1 = n1.Cross(u1);
+ // so in our new csys, we start at (1, 0, 0)
+ Expr *costheta1 = aof1.Dot(u1)->Div(r1);
+ Expr *sintheta1 = aof1.Dot(v1)->Div(r1);
+
+ double thetas1, thetaf1, dtheta1;
+ arc1->ArcGetAngles(&thetas1, &thetaf1, &dtheta1);
+ Expr *theta1;
+ if(dtheta1 < 3*PI/4) {
+ theta1 = costheta1->ACos();
+ } else if(dtheta1 < 5*PI/4) {
+ // As the angle crosses pi, cos theta1 is not invertible;
+ // so use the sine to stop blowing up
+ theta1 = Expr::From(PI)->Minus(sintheta1->ASin());
+ } else {
+ theta1 = (Expr::From(2*PI))->Minus(costheta1->ACos());
+ }
+
+ // And get the arc2 radius, and the cosine of its angle
+ EntityBase *ao2 = SK.GetEntity(arc2->point[0]),
+ *as2 = SK.GetEntity(arc2->point[1]),
+ *af2 = SK.GetEntity(arc2->point[2]);
+
+ ExprVector aos2 = (as2->PointGetExprs()).Minus(ao2->PointGetExprs()),
+ aof2 = (af2->PointGetExprs()).Minus(ao2->PointGetExprs());
+ Expr *r2 = aof2.Magnitude();
+
+ ExprVector n2 = arc2->Normal()->NormalExprsN();
+ ExprVector u2 = aos2.WithMagnitude(Expr::From(1.0));
+ ExprVector v2 = n2.Cross(u2);
+ // so in our new csys, we start at (1, 0, 0)
+ Expr *costheta2 = aof2.Dot(u2)->Div(r2);
+ Expr *sintheta2 = aof2.Dot(v2)->Div(r2);
+
+ double thetas2, thetaf2, dtheta2;
+ arc2->ArcGetAngles(&thetas2, &thetaf2, &dtheta2);
+ Expr *theta2;
+ if(dtheta2 < 3*PI/4) {
+ theta2 = costheta2->ACos();
+ } else if(dtheta2 < 5*PI/4) {
+ // As the angle crosses pi, cos theta2 is not invertible;
+ // so use the sine to stop blowing up
+ theta2 = Expr::From(PI)->Minus(sintheta2->ASin());
+ } else {
+ theta2 = (Expr::From(2*PI))->Minus(costheta2->ACos());
+ }
+ // And write the equation; (r1*theta1) / ( r2*theta2) = some ratio
+ AddEq(l, (r1->Times(theta1))->Div(r2->Times(theta2))->Minus(exA), 0);
+ return;
+ }
+
+ case Type::ARC_LINE_LEN_RATIO: {
+ EntityBase *line = SK.GetEntity(entityA),
+ *arc1 = SK.GetEntity(entityB);
+
+ Expr *ll = Distance(workplane, line->point[0], line->point[1]);
+
+ // And get the arc1 radius, and the cosine of its angle
+ EntityBase *ao1 = SK.GetEntity(arc1->point[0]),
+ *as1 = SK.GetEntity(arc1->point[1]),
+ *af1 = SK.GetEntity(arc1->point[2]);
+
+ ExprVector aos1 = (as1->PointGetExprs()).Minus(ao1->PointGetExprs()),
+ aof1 = (af1->PointGetExprs()).Minus(ao1->PointGetExprs());
+ Expr *r1 = aof1.Magnitude();
+ ExprVector n1 = arc1->Normal()->NormalExprsN();
+ ExprVector u1 = aos1.WithMagnitude(Expr::From(1.0));
+ ExprVector v1 = n1.Cross(u1);
+ // so in our new csys, we start at (1, 0, 0)
+ Expr *costheta1 = aof1.Dot(u1)->Div(r1);
+ Expr *sintheta1 = aof1.Dot(v1)->Div(r1);
+
+ double thetas1, thetaf1, dtheta1;
+ arc1->ArcGetAngles(&thetas1, &thetaf1, &dtheta1);
+ Expr *theta1;
+ if(dtheta1 < 3*PI/4) {
+ theta1 = costheta1->ACos();
+ } else if(dtheta1 < 5*PI/4) {
+ // As the angle crosses pi, cos theta1 is not invertible;
+ // so use the sine to stop blowing up
+ theta1 = Expr::From(PI)->Minus(sintheta1->ASin());
+ } else {
+ theta1 = (Expr::From(2*PI))->Minus(costheta1->ACos());
+ }
+ // And write the equation; (r1*theta1) / ( length) = some ratio
+ AddEq(l, (r1->Times(theta1))->Div(ll)->Minus(exA), 0);
+ return;
+ }
case Type::LENGTH_DIFFERENCE: {
EntityBase *a = SK.GetEntity(entityA);
AddEq(l, (la->Minus(lb))->Minus(exA), 0);
return;
}
-
+
+ case Type::ARC_ARC_DIFFERENCE: {
+ EntityBase *arc1 = SK.GetEntity(entityA),
+ *arc2 = SK.GetEntity(entityB);
+
+ // And get the arc1 radius, and the cosine of its angle
+ EntityBase *ao1 = SK.GetEntity(arc1->point[0]),
+ *as1 = SK.GetEntity(arc1->point[1]),
+ *af1 = SK.GetEntity(arc1->point[2]);
+
+ ExprVector aos1 = (as1->PointGetExprs()).Minus(ao1->PointGetExprs()),
+ aof1 = (af1->PointGetExprs()).Minus(ao1->PointGetExprs());
+ Expr *r1 = aof1.Magnitude();
+
+ ExprVector n1 = arc1->Normal()->NormalExprsN();
+ ExprVector u1 = aos1.WithMagnitude(Expr::From(1.0));
+ ExprVector v1 = n1.Cross(u1);
+ // so in our new csys, we start at (1, 0, 0)
+ Expr *costheta1 = aof1.Dot(u1)->Div(r1);
+ Expr *sintheta1 = aof1.Dot(v1)->Div(r1);
+
+ double thetas1, thetaf1, dtheta1;
+ arc1->ArcGetAngles(&thetas1, &thetaf1, &dtheta1);
+ Expr *theta1;
+ if(dtheta1 < 3*PI/4) {
+ theta1 = costheta1->ACos();
+ } else if(dtheta1 < 5*PI/4) {
+ // As the angle crosses pi, cos theta1 is not invertible;
+ // so use the sine to stop blowing up
+ theta1 = Expr::From(PI)->Minus(sintheta1->ASin());
+ } else {
+ theta1 = (Expr::From(2*PI))->Minus(costheta1->ACos());
+ }
+
+ // And get the arc2 radius, and the cosine of its angle
+ EntityBase *ao2 = SK.GetEntity(arc2->point[0]),
+ *as2 = SK.GetEntity(arc2->point[1]),
+ *af2 = SK.GetEntity(arc2->point[2]);
+
+ ExprVector aos2 = (as2->PointGetExprs()).Minus(ao2->PointGetExprs()),
+ aof2 = (af2->PointGetExprs()).Minus(ao2->PointGetExprs());
+ Expr *r2 = aof2.Magnitude();
+
+ ExprVector n2 = arc2->Normal()->NormalExprsN();
+ ExprVector u2 = aos2.WithMagnitude(Expr::From(1.0));
+ ExprVector v2 = n2.Cross(u2);
+ // so in our new csys, we start at (1, 0, 0)
+ Expr *costheta2 = aof2.Dot(u2)->Div(r2);
+ Expr *sintheta2 = aof2.Dot(v2)->Div(r2);
+
+ double thetas2, thetaf2, dtheta2;
+ arc2->ArcGetAngles(&thetas2, &thetaf2, &dtheta2);
+ Expr *theta2;
+ if(dtheta2 < 3*PI/4) {
+ theta2 = costheta2->ACos();
+ } else if(dtheta2 < 5*PI/4) {
+ // As the angle crosses pi, cos theta2 is not invertible;
+ // so use the sine to stop blowing up
+ theta2 = Expr::From(PI)->Minus(sintheta2->ASin());
+ } else {
+ theta2 = (Expr::From(2*PI))->Minus(costheta2->ACos());
+ }
+ // And write the equation; (r1*theta1) - ( r2*theta2) = some difference
+ AddEq(l, (r1->Times(theta1))->Minus(r2->Times(theta2))->Minus(exA), 0);
+ return;
+ }
+
+ case Type::ARC_LINE_DIFFERENCE: {
+ EntityBase *line = SK.GetEntity(entityA),
+ *arc1 = SK.GetEntity(entityB);
+
+ Expr *ll = Distance(workplane, line->point[0], line->point[1]);
+
+ // And get the arc1 radius, and the cosine of its angle
+ EntityBase *ao1 = SK.GetEntity(arc1->point[0]),
+ *as1 = SK.GetEntity(arc1->point[1]),
+ *af1 = SK.GetEntity(arc1->point[2]);
+
+ ExprVector aos1 = (as1->PointGetExprs()).Minus(ao1->PointGetExprs()),
+ aof1 = (af1->PointGetExprs()).Minus(ao1->PointGetExprs());
+ Expr *r1 = aof1.Magnitude();
+ ExprVector n1 = arc1->Normal()->NormalExprsN();
+ ExprVector u1 = aos1.WithMagnitude(Expr::From(1.0));
+ ExprVector v1 = n1.Cross(u1);
+ // so in our new csys, we start at (1, 0, 0)
+ Expr *costheta1 = aof1.Dot(u1)->Div(r1);
+ Expr *sintheta1 = aof1.Dot(v1)->Div(r1);
+
+ double thetas1, thetaf1, dtheta1;
+ arc1->ArcGetAngles(&thetas1, &thetaf1, &dtheta1);
+ Expr *theta1;
+ if(dtheta1 < 3*PI/4) {
+ theta1 = costheta1->ACos();
+ } else if(dtheta1 < 5*PI/4) {
+ // As the angle crosses pi, cos theta1 is not invertible;
+ // so use the sine to stop blowing up
+ theta1 = Expr::From(PI)->Minus(sintheta1->ASin());
+ } else {
+ theta1 = (Expr::From(2*PI))->Minus(costheta1->ACos());
+ }
+ // And write the equation; (r1*theta1) - ( length) = some difference
+ AddEq(l, (r1->Times(theta1))->Minus(ll)->Minus(exA), 0);
+ return;
+ }
+
case Type::DIAMETER: {
EntityBase *circle = SK.GetEntity(entityA);
Expr *r = circle->CircleGetRadiusExpr();
}
}
return;
-
+
case Type::SYMMETRIC:
if(workplane == EntityBase::FREE_IN_3D) {
EntityBase *plane = SK.GetEntity(entityA);
SS.UndoRemember();
c->reference = !c->reference;
+ SS.MarkGroupDirty(c->group);
SS.ScheduleShowTW();
}
Entity *e = SK.GetEntity(gs.points == 1 ? gs.point[0] : gs.entity[0]);
Vector p;
-#define COSTR(p) \
+#define COSTR_NO_LINK(p) \
SS.MmToString((p).x).c_str(), \
SS.MmToString((p).y).c_str(), \
SS.MmToString((p).z).c_str()
-#define PT_AS_STR "(%Fi%s%E, %Fi%s%E, %Fi%s%E)"
-#define PT_AS_NUM "(%Fi%3%E, %Fi%3%E, %Fi%3%E)"
+#define PT_AS_STR_NO_LINK "(%Fi%s%Fd, %Fi%s%Fd, %Fi%s%Fd)"
+#define PT_AS_NUM "(%Fi%3%Fd, %Fi%3%Fd, %Fi%3%Fd)"
+#define COSTR(e, p) \
+ e->h, (&TextWindow::ScreenSelectEntity), (&TextWindow::ScreenHoverEntity), \
+ COSTR_NO_LINK(p)
+#define PT_AS_STR "%Ll%D%f%h" PT_AS_STR_NO_LINK "%E"
+#define CO_LINK(e, p) e->h, (&TextWindow::ScreenSelectEntity), (&TextWindow::ScreenHoverEntity), CO(p)
+#define PT_AS_NUM_LINK "%Ll%D%f%h" PT_AS_NUM "%E"
+
switch(e->type) {
case Entity::Type::POINT_IN_3D:
case Entity::Type::POINT_IN_2D:
case Entity::Type::POINT_N_COPY:
case Entity::Type::POINT_N_ROT_AA:
p = e->PointGetNum();
- Printf(false, "%FtPOINT%E at " PT_AS_STR, COSTR(p));
+ Printf(false, "%FtPOINT%E at " PT_AS_STR, COSTR(e, p));
break;
case Entity::Type::NORMAL_IN_3D:
case Entity::Type::WORKPLANE: {
p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(false, "%FtWORKPLANE%E");
- Printf(true, " origin = " PT_AS_STR, COSTR(p));
+ Printf(true, " origin = " PT_AS_STR, COSTR(SK.GetEntity(e->point[0]), p));
Quaternion q = e->Normal()->NormalGetNum();
p = q.RotationN();
- Printf(true, " normal = " PT_AS_NUM, CO(p));
+ Printf(true, " normal = " PT_AS_NUM_LINK, CO_LINK(e->Normal(), p));
break;
}
case Entity::Type::LINE_SEGMENT: {
Vector p0 = SK.GetEntity(e->point[0])->PointGetNum();
p = p0;
Printf(false, "%FtLINE SEGMENT%E");
- Printf(true, " thru " PT_AS_STR, COSTR(p));
+ Printf(true, " thru " PT_AS_STR, COSTR(SK.GetEntity(e->point[0]), p));
Vector p1 = SK.GetEntity(e->point[1])->PointGetNum();
p = p1;
- Printf(false, " " PT_AS_STR, COSTR(p));
+ Printf(false, " " PT_AS_STR, COSTR(SK.GetEntity(e->point[1]), p));
Printf(true, " len = %Fi%s%E",
SS.MmToString((p1.Minus(p0).Magnitude())).c_str());
break;
}
for(int i = 0; i < pts; i++) {
p = SK.GetEntity(e->point[i])->PointGetNum();
- Printf((i==0), " p%d = " PT_AS_STR, i, COSTR(p));
+ Printf((i==0), " p%d = " PT_AS_STR, i, COSTR(SK.GetEntity(e->point[i]), p));
}
break;
case Entity::Type::ARC_OF_CIRCLE: {
Printf(false, "%FtARC OF A CIRCLE%E");
p = SK.GetEntity(e->point[0])->PointGetNum();
- Printf(true, " center = " PT_AS_STR, COSTR(p));
+ Printf(true, " center = " PT_AS_STR, COSTR(SK.GetEntity(e->point[0]), p));
p = SK.GetEntity(e->point[1])->PointGetNum();
- Printf(true, " endpoints = " PT_AS_STR, COSTR(p));
+ Printf(true, " endpoints = " PT_AS_STR, COSTR(SK.GetEntity(e->point[1]), p));
p = SK.GetEntity(e->point[2])->PointGetNum();
- Printf(false, " " PT_AS_STR, COSTR(p));
+ Printf(false, " " PT_AS_STR, COSTR(SK.GetEntity(e->point[2]), p));
double r = e->CircleGetRadiusNum();
Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str());
Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str());
case Entity::Type::CIRCLE: {
Printf(false, "%FtCIRCLE%E");
p = SK.GetEntity(e->point[0])->PointGetNum();
- Printf(true, " center = " PT_AS_STR, COSTR(p));
+ Printf(true, " center = " PT_AS_STR, COSTR(SK.GetEntity(e->point[0]), p));
double r = e->CircleGetRadiusNum();
- Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str());
- Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str());
+ Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str());
+ Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str());
+ Printf(false, " circumference = %Fi%s", SS.MmToString(2*M_PI*r).c_str());
break;
}
case Entity::Type::FACE_NORMAL_PT:
p = e->FaceGetNormalNum();
Printf(true, " normal = " PT_AS_NUM, CO(p));
p = e->FaceGetPointNum();
- Printf(false, " thru = " PT_AS_STR, COSTR(p));
+ Printf(false, " thru = " PT_AS_STR, COSTR(e, p));
break;
case Entity::Type::TTF_TEXT: {
} else if(gs.n == 2 && gs.points == 2) {
Printf(false, "%FtTWO POINTS");
Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum();
- Printf(true, " at " PT_AS_STR, COSTR(p0));
+ Printf(true, " at " PT_AS_STR, COSTR(SK.GetEntity(gs.point[0]), p0));
Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum();
- Printf(false, " " PT_AS_STR, COSTR(p1));
- double d = (p1.Minus(p0)).Magnitude();
- Printf(true, " d = %Fi%s", SS.MmToString(d).c_str());
+ Printf(false, " " PT_AS_STR, COSTR(SK.GetEntity(gs.point[1]), p1));
+ Vector dv = p1.Minus(p0);
+ Printf(true, " d = %Fi%s", SS.MmToString(dv.Magnitude()).c_str());
+ Printf(false, " d(x, y, z) = " PT_AS_STR_NO_LINK, COSTR_NO_LINK(dv));
} else if(gs.n == 2 && gs.points == 1 && gs.circlesOrArcs == 1) {
Entity *ec = SK.GetEntity(gs.entity[0]);
if(ec->type == Entity::Type::CIRCLE) {
Printf(false, "%FtPOINT AND AN ARC");
} else ssassert(false, "Unexpected entity type");
Vector p = SK.GetEntity(gs.point[0])->PointGetNum();
- Printf(true, " pt at " PT_AS_STR, COSTR(p));
+ Printf(true, " pt at " PT_AS_STR, COSTR(SK.GetEntity(gs.point[0]), p));
Vector c = SK.GetEntity(ec->point[0])->PointGetNum();
- Printf(true, " center = " PT_AS_STR, COSTR(c));
+ Printf(true, " center = " PT_AS_STR, COSTR(SK.GetEntity(ec->point[0]), c));
double r = ec->CircleGetRadiusNum();
Printf(false, " diameter = %Fi%s", SS.MmToString(r*2).c_str());
Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str());
} else if(gs.n == 2 && gs.faces == 1 && gs.points == 1) {
Printf(false, "%FtA POINT AND A PLANE FACE");
Vector pt = SK.GetEntity(gs.point[0])->PointGetNum();
- Printf(true, " point = " PT_AS_STR, COSTR(pt));
+ Printf(true, " point = " PT_AS_STR, COSTR(SK.GetEntity(gs.point[0]), pt));
Vector n = SK.GetEntity(gs.face[0])->FaceGetNormalNum();
Printf(true, " plane normal = " PT_AS_NUM, CO(n));
Vector pl = SK.GetEntity(gs.face[0])->FaceGetPointNum();
- Printf(false, " plane thru = " PT_AS_STR, COSTR(pl));
+ Printf(false, " plane thru = " PT_AS_STR, COSTR(SK.GetEntity(gs.face[0]), pl));
double dd = n.Dot(pl) - n.Dot(pt);
Printf(true, " distance = %Fi%s", SS.MmToString(dd).c_str());
} else if(gs.n == 3 && gs.points == 2 && gs.vectors == 1) {
Printf(false, "%FtTWO POINTS AND A VECTOR");
Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum();
- Printf(true, " pointA = " PT_AS_STR, COSTR(p0));
+ Printf(true, " pointA = " PT_AS_STR, COSTR(SK.GetEntity(gs.point[0]), p0));
Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum();
- Printf(false, " pointB = " PT_AS_STR, COSTR(p1));
+ Printf(false, " pointB = " PT_AS_STR, COSTR(SK.GetEntity(gs.point[1]), p1));
Vector v = SK.GetEntity(gs.vector[0])->VectorGetNum();
v = v.WithMagnitude(1);
- Printf(true, " vector = " PT_AS_NUM, CO(v));
+ Printf(true, " vector = " PT_AS_NUM_LINK, CO_LINK(SK.GetEntity(gs.vector[0]), v));
double d = (p1.Minus(p0)).Dot(v);
Printf(true, " proj_d = %Fi%s", SS.MmToString(d).c_str());
} else if(gs.n == 2 && gs.lineSegments == 1 && gs.points == 1) {
Vector lp0 = SK.GetEntity(ln->point[0])->PointGetNum(),
lp1 = SK.GetEntity(ln->point[1])->PointGetNum();
Printf(false, "%FtLINE SEGMENT AND POINT%E");
- Printf(true, " ln thru " PT_AS_STR, COSTR(lp0));
- Printf(false, " " PT_AS_STR, COSTR(lp1));
+ Printf(true, " ln thru " PT_AS_STR, COSTR(SK.GetEntity(ln->point[0]), lp0));
+ Printf(false, " " PT_AS_STR, COSTR(SK.GetEntity(ln->point[1]), lp1));
Entity *p = SK.GetEntity(gs.point[0]);
Vector pp = p->PointGetNum();
- Printf(true, " point " PT_AS_STR, COSTR(pp));
+ Printf(true, " point " PT_AS_STR, COSTR(p, pp));
Printf(true, " pt-ln distance = %Fi%s%E",
SS.MmToString(pp.DistanceToLine(lp0, lp1.Minus(lp0))).c_str());
hEntity wrkpl = SS.GW.ActiveWorkplane();
v0 = v0.WithMagnitude(1);
v1 = v1.WithMagnitude(1);
- Printf(true, " vectorA = " PT_AS_NUM, CO(v0));
- Printf(false, " vectorB = " PT_AS_NUM, CO(v1));
+ Printf(true, " vectorA = " PT_AS_NUM_LINK, CO_LINK(SK.GetEntity(gs.entity[0]), v0));
+ Printf(false, " vectorB = " PT_AS_NUM_LINK, CO_LINK(SK.GetEntity(gs.entity[1]), v1));
double theta = acos(v0.Dot(v1));
Printf(true, " angle = %Fi%2%E degrees", theta*180/PI);
Vector n0 = SK.GetEntity(gs.face[0])->FaceGetNormalNum();
Printf(true, " planeA normal = " PT_AS_NUM, CO(n0));
Vector p0 = SK.GetEntity(gs.face[0])->FaceGetPointNum();
- Printf(false, " planeA thru = " PT_AS_STR, COSTR(p0));
+ Printf(false, " planeA thru = " PT_AS_STR, COSTR(SK.GetEntity(gs.face[0]), p0));
Vector n1 = SK.GetEntity(gs.face[1])->FaceGetNormalNum();
Printf(true, " planeB normal = " PT_AS_NUM, CO(n1));
Vector p1 = SK.GetEntity(gs.face[1])->FaceGetPointNum();
- Printf(false, " planeB thru = " PT_AS_STR, COSTR(p1));
+ Printf(false, " planeB thru = " PT_AS_STR, COSTR(SK.GetEntity(gs.face[1]), p1));
double theta = acos(n0.Dot(n1));
Printf(true, " angle = %Fi%2%E degrees", theta*180/PI);
BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, VERY_NEGATIVE),
Vector::From(orig.mouse.x, orig.mouse.y, VERY_POSITIVE));
- Entity *e;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != SS.GW.activeGroup) continue;
- if(e->IsFace() || e->IsDistance()) continue;
- if(!e->IsVisible()) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != SS.GW.activeGroup) continue;
+ if(e.IsFace() || e.IsDistance()) continue;
+ if(!e.IsVisible()) continue;
bool entityHasBBox;
- BBox entityBBox = e->GetOrGenerateScreenBBox(&entityHasBBox);
+ BBox entityBBox = e.GetOrGenerateScreenBBox(&entityHasBBox);
if(entityHasBBox && entityBBox.Overlaps(marqueeBBox)) {
- MakeSelected(e->h);
+ MakeSelected(e.h);
}
}
}
cached.projRight = projRight;
cached.projUp = projUp;
cached.scale = scale;
- for(Entity *e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- e->screenBBoxValid = false;
+ for(Entity &e : SK.entity) {
+ e.screenBBoxValid = false;
}
}
std::string result;
if(type == Type::ANGLE) {
result = SS.DegreeToString(valA) + "°";
- } else if(type == Type::LENGTH_RATIO) {
+ } else if(type == Type::LENGTH_RATIO || type == Type::ARC_ARC_LEN_RATIO || type == Type::ARC_LINE_LEN_RATIO) {
result = ssprintf("%.3f:1", valA);
} else if(type == Type::COMMENT) {
result = comment;
const Camera &camera = canvas->GetCamera();
Entity *circ = SK.GetEntity(he);
- Vector center = SK.GetEntity(circ->point[0])->PointGetNum();
+ Vector center = SK.GetEntity(circ->point[0])->PointGetDrawNum();
double r = circ->CircleGetRadiusNum();
Quaternion q = circ->Normal()->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV();
void Constraint::DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs,
Vector a0, Vector da, Vector b0, Vector db,
- Vector offset, Vector *ref, bool trim)
+ Vector offset, Vector *ref, bool trim,
+ Vector explodeOffset)
{
const Camera &camera = canvas->GetCamera();
double pixels = 1.0 / camera.scale;
db = db.ProjectVectorInto(workplane);
}
+ a0 = a0.Plus(explodeOffset);
+ b0 = b0.Plus(explodeOffset);
+
Vector a1 = a0.Plus(da);
Vector b1 = b0.Plus(db);
DoProjectedPoint(canvas, hcs, &bp);
}
+ if(ShouldDrawExploded()) {
+ // Offset A and B by the same offset so the constraint is drawn
+ // in the plane of one of the exploded points (rather than at an
+ // angle)
+ Vector offset = SK.GetEntity(ptA)->ExplodeOffset();
+ ap = ap.Plus(offset);
+ bp = bp.Plus(offset);
+ }
+
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
if(refs) refs->push_back(ref);
dp = (bp.Minus(ap)),
pp = SK.GetEntity(entityA)->VectorGetNum();
+ if(ShouldDrawExploded()) {
+ // explode for whichever point is in the workplane (or the first if both are)
+ Entity *pt = SK.GetEntity(ptA);
+ if(pt->group != group) {
+ pt = SK.GetEntity(ptB);
+ }
+ if(pt->group == group) {
+ Vector offset = pt->ExplodeOffset();
+ ap = ap.Plus(offset);
+ bp = bp.Plus(offset);
+ }
+ }
+
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
if(refs) refs->push_back(ref);
case Type::PT_FACE_DISTANCE:
case Type::PT_PLANE_DISTANCE: {
- Vector pt = SK.GetEntity(ptA)->PointGetNum();
+ Vector pt = SK.GetEntity(ptA)->PointGetDrawNum();
Entity *enta = SK.GetEntity(entityA);
Vector n, p;
if(type == Type::PT_PLANE_DISTANCE) {
}
case Type::PT_LINE_DISTANCE: {
- Vector pt = SK.GetEntity(ptA)->PointGetNum();
+ Entity *ptEntity = SK.GetEntity(ptA);
+ Vector pt = ptEntity->PointGetNum();
Entity *line = SK.GetEntity(entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
DoProjectedPoint(canvas, hcs, &pt);
}
+ // Only explode if the point and line are in the same group (and that group is a sketch
+ // with explode enabled) otherwise it's too visually confusing to figure out what the
+ // correct projections should be.
+ bool shouldExplode = ShouldDrawExploded()
+ && ptEntity->group == group
+ && line->group == group;
+ if(shouldExplode) {
+ Vector explodeOffset = ptEntity->ExplodeOffset();
+ pt = pt.Plus(explodeOffset);
+ lA = lA.Plus(explodeOffset);
+ lB = lB.Plus(explodeOffset);
+ }
+
// Find the closest point on the line
Vector closest = pt.ClosestPointOnLine(lA, dl);
case Type::DIAMETER: {
Entity *circle = SK.GetEntity(entityA);
- Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
+ Vector center = SK.GetEntity(circle->point[0])->PointGetDrawNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
Vector n = q.RotationN().WithMagnitude(1);
double r = circle->CircleGetRadiusNum();
Vector r = camera.projRight.ScaledBy((a+1)/camera.scale);
Vector d = camera.projUp.ScaledBy((2-a)/camera.scale);
for(int i = 0; i < 2; i++) {
- Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
+ Vector p = SK.GetEntity(i == 0 ? ptA : ptB)->PointGetDrawNum();
if(refs) refs->push_back(p);
canvas->DrawQuad(p.Plus (r).Plus (d),
p.Plus (r).Minus(d),
case Type::PT_ON_FACE:
case Type::PT_IN_PLANE: {
double s = 8/camera.scale;
- Vector p = SK.GetEntity(ptA)->PointGetNum();
+ Vector p = SK.GetEntity(ptA)->PointGetDrawNum();
if(refs) refs->push_back(p);
Vector r, d;
if(type == Type::PT_ON_FACE) {
}
case Type::WHERE_DRAGGED: {
- Vector p = SK.GetEntity(ptA)->PointGetNum();
+ Vector p = SK.GetEntity(ptA)->PointGetDrawNum();
if(refs) refs->push_back(p);
Vector u = p.Plus(gu.WithMagnitude(8/camera.scale)).Plus(
gr.WithMagnitude(8/camera.scale)),
}
DoArcForAngle(canvas, hcs, a0, da, b0, db,
- da.WithMagnitude(40/camera.scale), &ref, /*trim=*/false);
+ da.WithMagnitude(40/camera.scale), &ref, /*trim=*/false, a->ExplodeOffset());
if(refs) refs->push_back(ref);
DoArcForAngle(canvas, hcs, c0, dc, d0, dd,
- dc.WithMagnitude(40/camera.scale), &ref, /*trim=*/false);
+ dc.WithMagnitude(40/camera.scale), &ref, /*trim=*/false, c->ExplodeOffset());
if(refs) refs->push_back(ref);
return;
}
Vector ref;
- DoArcForAngle(canvas, hcs, a0, da, b0, db, disp.offset, &ref, /*trim=*/true);
+ DoArcForAngle(canvas, hcs, a0, da, b0, db, disp.offset, &ref, /*trim=*/true, a->ExplodeOffset());
DoLabel(canvas, hcs, ref, labelPos, gr, gu);
if(refs) refs->push_back(ref);
return;
if(u.Dot(ru) < 0) u = u.ScaledBy(-1);
}
- Vector p = e->VectorGetRefPoint();
+ Vector p = e->VectorGetRefPoint().Plus(e->ExplodeOffset());
Vector s = p.Plus(u).Plus(v);
DoLine(canvas, hcs, s, s.Plus(v));
Vector m = s.Plus(v.ScaledBy(0.5));
if(type == Type::ARC_LINE_TANGENT) {
Entity *arc = SK.GetEntity(entityA);
Entity *norm = SK.GetEntity(arc->normal);
- Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
+ Vector c = SK.GetEntity(arc->point[0])->PointGetDrawNum();
Vector p =
- SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
+ SK.GetEntity(arc->point[other ? 2 : 1])->PointGetDrawNum();
Vector r = p.Minus(c);
textAt = p.Plus(r.WithMagnitude(14/camera.scale));
u = norm->NormalU();
Entity *cubic = SK.GetEntity(entityA);
Vector p = other ? cubic->CubicGetFinishNum() :
cubic->CubicGetStartNum();
+ p = p.Plus(cubic->ExplodeOffset());
Vector dir = SK.GetEntity(entityB)->VectorGetNum();
Vector out = n.Cross(dir);
textAt = p.Plus(out.WithMagnitude(14/camera.scale));
u = wn->NormalU();
v = wn->NormalV();
n = wn->NormalN();
- EntityBase *eA = SK.GetEntity(entityA);
+ Entity *eA = SK.GetEntity(entityA);
// Big pain; we have to get a vector tangent to the curve
// at the shared point, which could be from either a cubic
// or an arc.
if(other) {
- textAt = eA->EndpointFinish();
+ textAt = eA->EndpointFinish().Plus(eA->ExplodeOffset());
if(eA->type == Entity::Type::CUBIC) {
dir = eA->CubicGetFinishTangentNum();
} else {
dir = n.Cross(dir);
}
} else {
- textAt = eA->EndpointStart();
+ textAt = eA->EndpointStart().Plus(eA->ExplodeOffset());
if(eA->type == Entity::Type::CUBIC) {
dir = eA->CubicGetStartTangentNum();
} else {
Vector u = (gn.Cross(n)).WithMagnitude(4/camera.scale);
Vector p = e->VectorGetRefPoint();
+ if(ShouldDrawExploded()) {
+ p = p.Plus(e->ExplodeOffset());
+ }
+
DoLine(canvas, hcs, p.Plus(u), p.Plus(u).Plus(n));
DoLine(canvas, hcs, p.Minus(u), p.Minus(u).Plus(n));
if(refs) refs->push_back(p.Plus(n.ScaledBy(0.5)));
Entity *line = SK.GetEntity(entityA);
Vector ref;
DoEqualLenTicks(canvas, hcs,
- SK.GetEntity(line->point[0])->PointGetNum(),
- SK.GetEntity(line->point[1])->PointGetNum(),
+ SK.GetEntity(line->point[0])->PointGetDrawNum(),
+ SK.GetEntity(line->point[1])->PointGetDrawNum(),
gn, &ref);
if(refs) refs->push_back(ref);
DoEqualRadiusTicks(canvas, hcs, entityB, &ref);
DoProjectedPoint(canvas, hcs, &b);
}
+ if(ShouldDrawExploded()) {
+ Vector offset = e->ExplodeOffset();
+ a = a.Plus(offset);
+ b = b.Plus(offset);
+ }
+
Vector ref;
DoEqualLenTicks(canvas, hcs, a, b, gn, &ref);
if(refs) refs->push_back(ref);
}
return;
}
+ case Type::ARC_ARC_LEN_RATIO:
+ case Type::ARC_ARC_DIFFERENCE: {
+ Entity *circle = SK.GetEntity(entityA);
+ Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
+ Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
+ Vector n = q.RotationN().WithMagnitude(1);
+ Vector ref2;
+ DoEqualRadiusTicks(canvas, hcs, entityA, &ref2);
+ DoEqualRadiusTicks(canvas, hcs, entityB, &ref2);
+
+ Vector ref = center.Plus(disp.offset);
+ // Force the label into the same plane as the circle.
+ ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));
+ if(refs) refs->push_back(ref);
+ Vector topLeft;
+ DoLabel(canvas, hcs, ref, &topLeft, gr, gu);
+ if(labelPos) *labelPos = topLeft;
+ return;
+ }
+ case Type::ARC_LINE_LEN_RATIO:
+ case Type::ARC_LINE_DIFFERENCE: {
+ Vector a, b = Vector::From(0, 0, 0);
+ Vector ref;
+ Entity *e = SK.GetEntity(entityA);
+ a = SK.GetEntity(e->point[0])->PointGetNum();
+ b = SK.GetEntity(e->point[1])->PointGetNum();
+ DoEqualLenTicks(canvas, hcs, a, b, gn, &ref);
+ if(refs) refs->push_back(ref);
+ DoEqualRadiusTicks(canvas, hcs, entityB, &ref);
+ if(refs) refs->push_back(ref);
+ ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset);
+ DoLabel(canvas, hcs, ref, labelPos, gr, gu);
+ return;
+ }
+
case Type::EQ_LEN_PT_LINE_D: {
Entity *forLen = SK.GetEntity(entityA);
Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(),
DoProjectedPoint(canvas, hcs, &a);
DoProjectedPoint(canvas, hcs, &b);
}
+ if(ShouldDrawExploded()) {
+ Vector offset = forLen->ExplodeOffset();
+ a = a.Plus(offset);
+ b = b.Plus(offset);
+ }
Vector refa;
DoEqualLenTicks(canvas, hcs, a, b, gn, &refa);
if(refs) refs->push_back(refa);
}
Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la));
+ if(ShouldDrawExploded()) {
+ Vector offset = SK.GetEntity(ptA)->ExplodeOffset();
+ pt = pt.Plus(offset);
+ closest = closest.Plus(offset);
+ }
DoLine(canvas, hcs, pt, closest);
Vector refb;
DoEqualLenTicks(canvas, hcs, pt, closest, gn, &refb);
}
Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la));
+ if(ShouldDrawExploded()) {
+ Vector offset = pte->ExplodeOffset();
+ pt = pt.Plus(offset);
+ closest = closest.Plus(offset);
+ }
DoLine(canvas, hcs, pt, closest);
Vector ref;
goto s;
}
s:
- Vector a = SK.GetEntity(ptA)->PointGetNum();
- Vector b = SK.GetEntity(ptB)->PointGetNum();
+ Vector a = SK.GetEntity(ptA)->PointGetDrawNum();
+ Vector b = SK.GetEntity(ptB)->PointGetDrawNum();
for(int i = 0; i < 2; i++) {
Vector tail = (i == 0) ? a : b;
}
// For "at midpoint", this branch is always taken.
Entity *e = SK.GetEntity(entityA);
- Vector a = SK.GetEntity(e->point[0])->PointGetNum();
- Vector b = SK.GetEntity(e->point[1])->PointGetNum();
+ Vector a = SK.GetEntity(e->point[0])->PointGetDrawNum();
+ Vector b = SK.GetEntity(e->point[1])->PointGetDrawNum();
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
Vector offset = (a.Minus(b)).Cross(n);
offset = offset.WithMagnitude(textHeight);
r.WithMagnitude(1), u.WithMagnitude(1), hcs);
if(refs) refs->push_back(o);
} else {
- Vector a = SK.GetEntity(ptA)->PointGetNum();
- Vector b = SK.GetEntity(ptB)->PointGetNum();
+ Vector a = SK.GetEntity(ptA)->PointGetDrawNum();
+ Vector b = SK.GetEntity(ptB)->PointGetDrawNum();
Entity *w = SK.GetEntity(workplane);
Vector cu = w->Normal()->NormalU();
}
hcs = canvas->GetStroke(stroke);
}
- DoLabel(canvas, hcs, disp.offset, labelPos, u, v);
- if(refs) refs->push_back(disp.offset);
+ Vector ref = disp.offset;
+ if(ptA.v) {
+ Vector a = SK.GetEntity(ptA)->PointGetNum();
+ ref = a.Plus(disp.offset);
+ }
+ DoLabel(canvas, hcs, ref, labelPos, u, v);
+ if(refs) refs->push_back(ref);
return;
}
}
case Type::PT_FACE_DISTANCE:
case Type::PROJ_PT_DISTANCE:
case Type::LENGTH_RATIO:
+ case Type::ARC_ARC_LEN_RATIO:
+ case Type::ARC_LINE_LEN_RATIO:
case Type::LENGTH_DIFFERENCE:
+ case Type::ARC_ARC_DIFFERENCE:
+ case Type::ARC_LINE_DIFFERENCE:
case Type::DIAMETER:
case Type::ANGLE:
return true;
return false;
}
}
+
+bool Constraint::ShouldDrawExploded() const {
+ return SK.GetGroup(group)->ShouldDrawExploded();
+}
List<Vector> lv = {};
sb->MakePwlInto(&lv);
for(int j = 1; j < lv.n; j++) {
- el->AddEdge(lv[j-1], lv[j], style.v, i);
+ el->AddEdge(lv[j-1], lv[j], Style::ForEntity(h).v, i);
}
lv.Clear();
}
case Type::POINT_N_ROT_AXIS_TRANS:
case Type::POINT_IN_3D:
case Type::POINT_IN_2D:
- refs->push_back(PointGetNum());
+ refs->push_back(PointGetDrawNum());
break;
case Type::NORMAL_N_COPY:
case Type::CUBIC_PERIODIC:
case Type::TTF_TEXT:
case Type::IMAGE:
- refs->push_back(SK.GetEntity(point[0])->PointGetNum());
+ refs->push_back(SK.GetEntity(point[0])->PointGetDrawNum());
break;
case Type::LINE_SEGMENT: {
- Vector a = SK.GetEntity(point[0])->PointGetNum(),
- b = SK.GetEntity(point[1])->PointGetNum();
+ Vector a = SK.GetEntity(point[0])->PointGetDrawNum(),
+ b = SK.GetEntity(point[1])->PointGetDrawNum();
refs->push_back(b.Plus(a.Minus(b).ScaledBy(0.5)));
break;
}
// Record our style for all of the Beziers that we just created.
for(; i < sbl->l.n; i++) {
- sbl->l[i].auxA = style.v;
+ sbl->l[i].auxA = Style::ForEntity(h).v;
}
}
+bool Entity::ShouldDrawExploded() const {
+ return SK.GetGroup(group)->ShouldDrawExploded();
+}
+
+Vector Entity::ExplodeOffset() const {
+ if(ShouldDrawExploded() && workplane.v != 0) {
+ int requestIdx = SK.GetRequest(h.request())->groupRequestIndex;
+ double offset = SS.explodeDistance * (requestIdx + 1);
+ return SK.GetEntity(workplane)->Normal()->NormalN().ScaledBy(offset);
+ } else {
+ return Vector::From(0, 0, 0);
+ }
+}
+
+Vector Entity::PointGetDrawNum() const {
+ // As per EntityBase::PointGetNum but specifically for when drawing/rendering the point
+ // (and not when solving), so we can potentially draw it somewhere different
+ return PointGetNum().Plus(ExplodeOffset());
+}
+
void Entity::Draw(DrawAs how, Canvas *canvas) {
if(!(how == DrawAs::HOVERED || how == DrawAs::SELECTED) &&
!IsVisible()) return;
pointStroke.unit = Canvas::Unit::PX;
Canvas::hStroke hcsPoint = canvas->GetStroke(pointStroke);
+ Vector p = PointGetDrawNum();
if(free) {
Canvas::Stroke analyzeStroke = Style::Stroke(Style::ANALYZE);
analyzeStroke.width = 14.0;
analyzeStroke.layer = Canvas::Layer::FRONT;
Canvas::hStroke hcsAnalyze = canvas->GetStroke(analyzeStroke);
- canvas->DrawPoint(PointGetNum(), hcsAnalyze);
+ canvas->DrawPoint(p, hcsAnalyze);
}
- canvas->DrawPoint(PointGetNum(), hcsPoint);
+ canvas->DrawPoint(p, hcsPoint);
return;
}
tail = camera.projRight.ScaledBy(w/s).Plus(
camera.projUp. ScaledBy(h/s)).Minus(camera.offset);
} else {
- tail = SK.GetEntity(point[0])->PointGetNum();
+ tail = SK.GetEntity(point[0])->PointGetDrawNum();
}
tail = camera.AlignToPixelGrid(tail);
case Type::TTF_TEXT: {
// Generate the rational polynomial curves, then piecewise linearize
// them, and display those.
- if(!canvas->DrawBeziers(*GetOrGenerateBezierCurves(), hcs)) {
- canvas->DrawEdges(*GetOrGenerateEdges(), hcs);
+ // Calculating the draw offset, if necessary.
+ const bool shouldExplode = ShouldDrawExploded();
+ Vector explodeOffset;
+ SBezierList offsetBeziers = {};
+ SBezierList *beziers = GetOrGenerateBezierCurves();
+ if(shouldExplode) {
+ explodeOffset = ExplodeOffset();
+ for(const SBezier& b : beziers->l) {
+ SBezier offset = b.TransformedBy(explodeOffset, Quaternion::IDENTITY, 1.0);
+ offsetBeziers.l.Add(&offset);
+ }
+ beziers = &offsetBeziers;
+ }
+
+ SEdgeList *edges = nullptr;
+ SEdgeList offsetEdges = {};
+
+ if(!canvas->DrawBeziers(*beziers, hcs)) {
+ edges = GetOrGenerateEdges();
+ if(shouldExplode) {
+ for(const SEdge &e : edges->l) {
+ offsetEdges.AddEdge(e.a.Plus(explodeOffset), e.b.Plus(explodeOffset), e.auxA, e.auxB, e.tag);
+ }
+ edges = &offsetEdges;
+ }
+ canvas->DrawEdges(*edges, hcs);
}
if(type == Type::CIRCLE) {
Entity *dist = SK.GetEntity(distance);
Canvas::Stroke analyzeStroke = Style::Stroke(Style::ANALYZE);
analyzeStroke.layer = Canvas::Layer::FRONT;
Canvas::hStroke hcsAnalyze = canvas->GetStroke(analyzeStroke);
- if(!canvas->DrawBeziers(*GetOrGenerateBezierCurves(), hcsAnalyze)) {
- canvas->DrawEdges(*GetOrGenerateEdges(), hcsAnalyze);
+ if(!canvas->DrawBeziers(*beziers, hcsAnalyze)) {
+ canvas->DrawEdges(*edges, hcsAnalyze);
}
}
}
}
+ offsetBeziers.Clear();
+ offsetEdges.Clear();
return;
}
case Type::IMAGE: {
Canvas::hFill hf = canvas->GetFill(fill);
Vector v[4] = {};
for(int i = 0; i < 4; i++) {
- v[i] = SK.GetEntity(point[i])->PointGetNum();
+ v[i] = SK.GetEntity(point[i])->PointGetDrawNum();
}
Vector iu = v[3].Minus(v[0]);
Vector iv = v[1].Minus(v[0]);
#include "solvespace.h"
#include <type_traits>
+#include <vector>
/// Trait indicating which types are handle types and should get the associated operators.
/// Specialize for each handle type and inherit from std::true_type.
}
};
+template<class T, class H> class IdList;
+
// Comparison functor used by IdList and related classes
template <class T, class H>
struct CompareId {
- bool operator()(T const& lhs, T const& rhs) const {
- return lhs.h.v < rhs.h.v;
+
+ CompareId(const IdList<T, H> *list) {
+ idlist = list;
+ }
+
+ bool operator()(int lhs, T const& rhs) const {
+ return idlist->elemstore[lhs].h.v < rhs.h.v;
+ }
+ bool operator()(int lhs, H rhs) const {
+ return idlist->elemstore[lhs].h.v < rhs.v;
}
- bool operator()(T const& lhs, H rhs) const {
- return lhs.h.v < rhs.v;
+ bool operator()(T *lhs, int rhs) const {
+ return lhs->h.v < idlist->elemstore[rhs].h.v;
}
+
+private:
+ const IdList<T, H> *idlist;
};
// A list, where each element has an integer identifier. The list is kept
// id.
template <class T, class H>
class IdList {
- T *elem = nullptr;
- int elemsAllocated = 0;
+ std::vector<T> elemstore;
+ std::vector<int> elemidx;
+ std::vector<int> freelist;
public:
- int n = 0;
+ int n = 0; // PAR@@@@@ make this private to see all interesting and suspicious places in SoveSpace ;-)
+ friend struct CompareId<T, H>;
using Compare = CompareId<T, H>;
- bool IsEmpty() const {
- return n == 0;
- }
+ struct iterator {
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef int difference_type;
+ typedef T *pointer;
+ typedef T &reference;
+
+ public:
+ T &operator*() const noexcept { return *elem; }
+ const T *operator->() const noexcept { return elem; }
+
+ bool operator==(const iterator &p) const { return p.position == position; }
+ bool operator!=(const iterator &p) const { return !operator==(p); }
+
+ iterator &operator++() {
+ ++position;
+ if(position >= (int)list->elemidx.size()) {
+ elem = nullptr; // PAR@@@@ Remove just debugging
+ } else if(0 <= position) {
+ elem = &(list->elemstore[list->elemidx[position]]);
+ }
+ return *this;
+ }
- void AllocForOneMore() {
- if(n >= elemsAllocated) {
- ReserveMore((elemsAllocated + 32)*2 - n);
+ // Needed for std:find_if of gcc used in entity.cpp GenerateEquations
+ difference_type operator-(const iterator &rhs) const noexcept {
+ return position - rhs.position;
}
+
+ iterator(IdList<T, H> *l) : position(0), list(l) {
+ if(list) {
+ if(list->elemstore.size() && list->elemidx.size()) {
+ elem = &(list->elemstore[list->elemidx[position]]);
+ }
+ }
+ };
+ iterator(IdList<T, H> *l, int pos) : position(pos), list(l) {
+ if(position >= (int)list->elemidx.size()) {
+ elem = nullptr;
+ } else if(0 <= position) {
+ elem = &((list->elemstore)[list->elemidx[position]]);
+ }
+ };
+
+ private:
+ int position;
+ T *elem;
+ IdList<T, H> *list;
+ };
+
+
+ bool IsEmpty() const {
+ return n == 0;
}
uint32_t MaximumId() {
if(IsEmpty()) {
return 0;
} else {
- return Last()->h.v;
+ return elemstore[elemidx.back()].h.v;
}
}
H AddAndAssignId(T *t) {
t->h.v = (MaximumId() + 1);
- AllocForOneMore();
- // Copy-construct at the end of the list.
- new(&elem[n]) T(*t);
+ // Add at the end of the list.
+ elemstore.push_back(*t);
+ elemidx.push_back(elemstore.size()-1);
++n;
return t->h;
}
- T * LowerBound(T const& t) {
- if(IsEmpty()) {
- return nullptr;
- }
- auto it = std::lower_bound(begin(), end(), t, Compare());
- return it;
- }
-
- T * LowerBound(H const& h) {
- if(IsEmpty()) {
- return nullptr;
- }
- auto it = std::lower_bound(begin(), end(), h, Compare());
- return it;
- }
-
- int LowerBoundIndex(T const& t) {
- if(IsEmpty()) {
- return 0;
- }
- auto it = LowerBound(t);
- auto idx = std::distance(begin(), it);
- auto i = static_cast<int>(idx);
- return i;
- }
void ReserveMore(int howMuch) {
- if(n + howMuch > elemsAllocated) {
- elemsAllocated = n + howMuch;
- T *newElem = (T *)::operator new[]((size_t)elemsAllocated*sizeof(T));
- for(int i = 0; i < n; i++) {
- new(&newElem[i]) T(std::move(elem[i]));
- elem[i].~T();
- }
- ::operator delete[](elem);
- elem = newElem;
- }
+ elemstore.reserve(elemstore.size() + howMuch);
+ elemidx.reserve(elemidx.size() + howMuch);
+ // freelist.reserve(freelist.size() + howMuch); // PAR@@@@ maybe we should - not much more RAM
}
void Add(T *t) {
- AllocForOneMore();
-
// Look to see if we already have something with the same handle value.
ssassert(FindByIdNoOops(t->h) == nullptr, "Handle isn't unique");
- // Copy-construct at the end of the list.
- new(&elem[n]) T(*t);
+ // Find out where the added element should be.
+ auto pos = std::lower_bound(elemidx.begin(), elemidx.end(), *t, Compare(this));
+
+ if(freelist.empty()) { // Add a new element to the store
+ elemstore.push_back(*t);
+ // Insert a pointer to the element at the correct position
+ if(elemidx.empty()) {
+ // The list is empty so pos, begin and end are all null.
+ // insert does not work in this case.
+ elemidx.push_back(elemstore.size()-1);
+ } else {
+ elemidx.insert(pos, elemstore.size() - 1);
+ }
+ } else { // Use the last element from the freelist
+ // Insert an index to the element at the correct position
+ elemidx.insert(pos, freelist.back());
+ // Remove the element from the freelist
+ freelist.pop_back();
+
+ // Copy-construct to the element storage.
+ elemstore[*pos] = T(*t);
+ // *elemptr[pos] = *t; // PAR@@@@@@ maybe this?
+ }
+
++n;
- // The item we just added is trivially sorted, so "merge"
- std::inplace_merge(begin(), end() - 1, end(), Compare());
}
T *FindById(H h) {
T *t = FindByIdNoOops(h);
- ssassert(t != NULL, "Cannot find handle");
+ ssassert(t != nullptr, "Cannot find handle");
return t;
}
- int IndexOf(H h) {
- if(IsEmpty()) {
- return -1;
- }
- auto it = LowerBound(h);
- auto idx = std::distance(begin(), it);
- if (idx < n) {
- return idx;
- }
- return -1;
- }
-
T *FindByIdNoOops(H h) {
if(IsEmpty()) {
return nullptr;
}
- auto it = LowerBound(h);
- if (it == nullptr || it == end()) {
+ auto it = std::lower_bound(elemidx.begin(), elemidx.end(), h, Compare(this));
+ if(it == elemidx.end()) {
return nullptr;
+ } else {
+ if(elemstore[*it].h.v != h.v) {
+ return nullptr;
+ }
+ return &elemstore[*it];
}
- if (it->h.v == h.v) {
- return it;
- }
- return nullptr;
- }
-
- T *First() {
- return (IsEmpty()) ? NULL : &(elem[0]);
- }
- T *Last() {
- return (IsEmpty()) ? NULL : &(elem[n-1]);
- }
- T *NextAfter(T *prev) {
- if(IsEmpty() || !prev) return NULL;
- if(prev - First() == (n - 1)) return NULL;
- return prev + 1;
}
- T &Get(size_t i) { return elem[i]; }
- T const &Get(size_t i) const { return elem[i]; }
+ T &Get(size_t i) { return elemstore[elemidx[i]]; }
T &operator[](size_t i) { return Get(i); }
- T const &operator[](size_t i) const { return Get(i); }
- T *begin() { return IsEmpty() ? nullptr : &elem[0]; }
- T *end() { return IsEmpty() ? nullptr : &elem[0] + n; }
- const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; }
- const T *end() const { return IsEmpty() ? nullptr : &elem[0] + n; }
- const T *cbegin() const { return begin(); }
- const T *cend() const { return end(); }
+ iterator begin() { return IsEmpty() ? nullptr : iterator(this); }
+ iterator end() { return IsEmpty() ? nullptr : iterator(this, elemidx.size()); }
void ClearTags() {
for(auto &elt : *this) { elt.tag = 0; }
int src, dest;
dest = 0;
for(src = 0; src < n; src++) {
- if(elem[src].tag) {
+ if(elemstore[elemidx[src]].tag) {
// this item should be deleted
- elem[src].Clear();
+ elemstore[elemidx[src]].Clear();
+// elemstore[elemidx[src]].~T(); // Clear below calls the destructors
+ freelist.push_back(elemidx[src]);
+ elemidx[src] = 0xDEADBEEF; // PAR@@@@@ just for debugging, not needed, remove later
} else {
if(src != dest) {
- elem[dest] = elem[src];
+ elemidx[dest] = elemidx[src];
}
dest++;
}
}
- for(int i = dest; i < n; i++)
- elem[i].~T();
n = dest;
- // and elemsAllocated is untouched, because we didn't resize
+ elemidx.resize(n); // Clear left over elements at the end.
}
- void RemoveById(H h) {
+ void RemoveById(H h) { // PAR@@@@@ this can be optimized
ClearTags();
FindById(h)->tag = 1;
RemoveTagged();
void MoveSelfInto(IdList<T,H> *l) {
l->Clear();
- std::swap(l->elem, elem);
- std::swap(l->elemsAllocated, elemsAllocated);
+ std::swap(l->elemstore, elemstore);
+ std::swap(l->elemidx, elemidx);
+ std::swap(l->freelist, freelist);
std::swap(l->n, n);
}
void DeepCopyInto(IdList<T,H> *l) {
l->Clear();
- l->elem = (T *)::operator new[](elemsAllocated * sizeof(elem[0]));
- for(int i = 0; i < n; i++)
- new(&l->elem[i]) T(elem[i]);
- l->elemsAllocated = elemsAllocated;
+
+ for(auto const &it : elemstore) {
+ l->elemstore.push_back(it);
+ }
+
+ for(auto const &it : elemidx) {
+ l->elemidx.push_back(it);
+ }
+
l->n = n;
}
void Clear() {
- for(int i = 0; i < n; i++) {
- elem[i].Clear();
- elem[i].~T();
+ for(auto &it : elemidx) {
+ elemstore[it].Clear();
+// elemstore[it].~T(); // clear below calls the destructors
}
- if(elem) ::operator delete[](elem);
- elem = NULL;
- elemsAllocated = n = 0;
+ freelist.clear();
+ elemidx.clear();
+ elemstore.clear();
+ n = 0;
}
};
for(auto &entity : SK.entity) {
Entity *e = &entity;
if(!e->IsVisible()) continue;
- if(e->construction) continue;
if(SS.exportPwlCurves || sm || fabs(SS.exportOffset) > LENGTH_EPS)
{
// And calculate lighting for the triangle
Vector n = tt.Normal().WithMagnitude(1);
- double lighting = SS.ambientIntensity +
+ double lighting = min(1.0, SS.ambientIntensity +
max(0.0, (SS.lightIntensity[0])*(n.Dot(l0))) +
- max(0.0, (SS.lightIntensity[1])*(n.Dot(l1)));
+ max(0.0, (SS.lightIntensity[1])*(n.Dot(l1))));
double r = min(1.0, tt.meta.color.redF() * lighting),
g = min(1.0, tt.meta.color.greenF() * lighting),
b = min(1.0, tt.meta.color.blueF() * lighting);
if(sblss) {
SBezierLoopSet *sbls;
for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) {
- SBezierLoop *sbl;
- sbl = sbls->l.First();
- if(!sbl) continue;
- b = sbl->l.First();
- if(!b || !Style::Exportable(b->auxA)) continue;
-
- hStyle hs = { (uint32_t)b->auxA };
- Style *stl = Style::Get(hs);
- double lineWidth = Style::WidthMm(b->auxA)*s;
- RgbaColor strokeRgb = Style::Color(hs, /*forExport=*/true);
- RgbaColor fillRgb = Style::FillColor(hs, /*forExport=*/true);
-
- StartPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs);
- for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
+ for(SBezierLoop *sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
+ b = sbl->l.First();
+ if(!b || !Style::Exportable(b->auxA)) continue;
+
+ hStyle hs = { (uint32_t)b->auxA };
+ Style *stl = Style::Get(hs);
+ double lineWidth = Style::WidthMm(b->auxA)*s;
+ RgbaColor strokeRgb = Style::Color(hs, /*forExport=*/true);
+ RgbaColor fillRgb = Style::FillColor(hs, /*forExport=*/true);
+
+ StartPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs);
for(b = sbl->l.First(); b; b = sbl->l.NextAfter(b)) {
Bezier(b);
}
+ FinishPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs);
}
- FinishPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs);
}
}
FinishAndCloseFile();
SPointList spl = {};
STriangle *tr;
Vector bndl, bndh;
+
+ const std::string THREE_FN("three-r111.min.js");
+ const std::string HAMMER_FN("hammer-2.0.8.js");
+ const std::string CONTROLS_FN("SolveSpaceControls.js");
+
const char htmlbegin[] = R"(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"></meta>
<title>Three.js Solvespace Mesh</title>
- <script id="three-r76.js">%s</script>
- <script id="hammer-2.0.8.js">%s</script>
- <script id="SolveSpaceControls.js">%s</script>
+ <script id="%s">%s</script>
+ <script id="%s">%s</script>
+ <script id="%s">%s</script>
<style type="text/css">
body { margin: 0; overflow: hidden; }
</style>
if(filename.HasExtension("html")) {
fprintf(f, htmlbegin,
- LoadStringFromGzip("threejs/three-r76.js.gz").c_str(),
- LoadStringFromGzip("threejs/hammer-2.0.8.js.gz").c_str(),
- LoadString("threejs/SolveSpaceControls.js").c_str());
+ THREE_FN.c_str(),
+ LoadStringFromGzip("threejs/" + THREE_FN + ".gz").c_str(),
+ HAMMER_FN.c_str(),
+ LoadStringFromGzip("threejs/" + HAMMER_FN + ".gz").c_str(),
+ CONTROLS_FN.c_str(),
+ LoadString("threejs/" + CONTROLS_FN).c_str());
}
fprintf(f, "var solvespace_model_%s = {\n"
advancedFaces = {};
- SSurface *ss;
- for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) {
- if(ss->trim.IsEmpty())
+ for(SSurface &ss : shell->surface) {
+ if(ss.trim.IsEmpty())
continue;
// Get all of the loops of Beziers that trim our surface (with each
// Bezier split so that we use the section as t goes from 0 to 1), and
// the piecewise linearization of those loops in xyz space.
SBezierList sbl = {};
- ss->MakeSectionEdgesInto(shell, NULL, &sbl);
+ ss.MakeSectionEdgesInto(shell, NULL, &sbl);
// Apply the export scale factor.
- ss->ScaleSelfBy(1.0/SS.exportScale);
+ ss.ScaleSelfBy(1.0/SS.exportScale);
sbl.ScaleSelfBy(1.0/SS.exportScale);
- ExportSurface(ss, &sbl);
+ ExportSurface(&ss, &sbl);
sbl.Clear();
}
}
if(writer->constraint) {
- Constraint *c;
- for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) {
- if(!writer->NeedToOutput(c)) continue;
- switch(c->type) {
+ for(Constraint &c : *writer->constraint) {
+ if(!writer->NeedToOutput(&c)) continue;
+ switch(c.type) {
case Constraint::Type::PT_PT_DISTANCE: {
- Vector ap = SK.GetEntity(c->ptA)->PointGetNum();
- Vector bp = SK.GetEntity(c->ptB)->PointGetNum();
- Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset);
+ Vector ap = SK.GetEntity(c.ptA)->PointGetNum();
+ Vector bp = SK.GetEntity(c.ptB)->PointGetNum();
+ Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c.disp.offset);
writeAlignedDimension(xfrm(ap), xfrm(bp), xfrm(ref),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
break;
}
case Constraint::Type::PT_LINE_DISTANCE: {
- Vector pt = SK.GetEntity(c->ptA)->PointGetNum();
- Entity *line = SK.GetEntity(c->entityA);
+ Vector pt = SK.GetEntity(c.ptA)->PointGetNum();
+ Entity *line = SK.GetEntity(c.entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
Vector dl = lB.Minus(lA);
if(pt.Equals(closest)) break;
- Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c->disp.offset);
+ Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c.disp.offset);
Vector refClosest = ref.ClosestPointOnLine(lA, dl);
double ddl = dl.Dot(dl);
Vector xdl = xfrm(lB).Minus(xfrm(lA));
writeLinearDimension(xfrm(pt), xfrm(refClosest), xfrm(ref),
- xfrm(ref), c->Label(),
+ xfrm(ref), c.Label(),
atan2(xdl.y, xdl.x) / PI * 180.0 + 90.0, 0.0,
- c->GetStyle(), c->valA);
+ c.GetStyle(), c.valA);
break;
}
case Constraint::Type::DIAMETER: {
- Entity *circle = SK.GetEntity(c->entityA);
+ Entity *circle = SK.GetEntity(c.entityA);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
Vector n = q.RotationN().WithMagnitude(1);
double r = circle->CircleGetRadiusNum();
- Vector ref = center.Plus(c->disp.offset);
+ Vector ref = center.Plus(c.disp.offset);
// Force the label into the same plane as the circle.
ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));
Vector rad = ref.Minus(center).WithMagnitude(r);
- if(/*isRadius*/c->other) {
+ if(/*isRadius*/c.other) {
writeRadialDimension(
xfrm(center), xfrm(center.Plus(rad)),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
} else {
writeDiametricDimension(
xfrm(center.Minus(rad)), xfrm(center.Plus(rad)),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
}
break;
}
case Constraint::Type::ANGLE: {
- Entity *a = SK.GetEntity(c->entityA);
- Entity *b = SK.GetEntity(c->entityB);
+ Entity *a = SK.GetEntity(c.entityA);
+ Entity *b = SK.GetEntity(c.entityB);
Vector a0 = a->VectorGetStartPoint();
Vector b0 = b->VectorGetStartPoint();
Vector da = a->VectorGetNum();
Vector db = b->VectorGetNum();
- if(/*otherAngle*/c->other) {
+ if(/*otherAngle*/c.other) {
a0 = a0.Plus(da);
da = da.ScaledBy(-1);
}
bool skew = false;
- Vector ref = c->disp.offset;
+ Vector ref = c.disp.offset;
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da), b0, b0.Plus(db),
&skew);
- if(!skew) ref = pi.Plus(c->disp.offset);
+ if(!skew) ref = pi.Plus(c.disp.offset);
Vector norm = da.Cross(db);
Vector dna = norm.Cross(da).WithMagnitude(1.0);
Vector bisect = da.WithMagnitude(1.0).ScaledBy(cos(thetaf / 2.0)).Plus(
dna.ScaledBy(sin(thetaf / 2.0)));
- ref = pi.Plus(bisect.WithMagnitude(c->disp.offset.Magnitude()));
+ ref = pi.Plus(bisect.WithMagnitude(c.disp.offset.Magnitude()));
// Get lines again to write exact line.
a0 = a->VectorGetStartPoint();
writeAngularDimension(
xfrm(a0), xfrm(a0.Plus(da)), xfrm(b0), xfrm(b0.Plus(db)), xfrm(ref),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
break;
}
case Constraint::Type::COMMENT: {
- Style *st = SK.style.FindById(c->GetStyle());
- writeText(xfrm(c->disp.offset), c->Label(),
- Style::TextHeight(c->GetStyle()) / SS.GW.scale,
- st->textAngle, st->textOrigin, c->GetStyle());
+ Style *st = SK.style.FindById(c.GetStyle());
+ writeText(xfrm(c.disp.offset), c.Label(),
+ Style::TextHeight(c.GetStyle()) / SS.GW.scale,
+ st->textAngle, st->textOrigin, c.GetStyle());
break;
}
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
fprintf(f, "stroke-width:%f;\r\n", sw);
fprintf(f, "}\r\n");
- for(auto &style : SK.style) {
- Style *s = &style;
- RgbaColor strokeRgb = Style::Color(s->h, /*forExport=*/true);
- StipplePattern pattern = Style::PatternType(s->h);
- double stippleScale = Style::StippleScaleMm(s->h);
+ auto export_style = [&](hStyle hs) {
+ Style *s = Style::Get(hs);
+ RgbaColor strokeRgb = Style::Color(hs, /*forExport=*/true);
+ RgbaColor fillRgb = Style::FillColor(hs, /*forExport=*/true);
+ StipplePattern pattern = Style::PatternType(hs);
+ double stippleScale = Style::StippleScaleMm(hs);
- fprintf(f, ".s%x {\r\n", s->h.v);
+ fprintf(f, ".s%x {\r\n", hs.v);
fprintf(f, "stroke:#%02x%02x%02x;\r\n", strokeRgb.red, strokeRgb.green, strokeRgb.blue);
// don't know why we have to take a half of the width
- fprintf(f, "stroke-width:%f;\r\n", Style::WidthMm(s->h.v) / 2.0);
+ fprintf(f, "stroke-width:%f;\r\n", Style::WidthMm(hs.v) / 2.0);
fprintf(f, "stroke-linecap:round;\r\n");
fprintf(f, "stroke-linejoin:round;\r\n");
std::string patternStr = MakeStipplePattern(pattern, stippleScale, ',',
if(!patternStr.empty()) {
fprintf(f, "stroke-dasharray:%s;\r\n", patternStr.c_str());
}
- fprintf(f, "fill:none;\r\n");
+ if(s->filled) {
+ fprintf(f, "fill:#%02x%02x%02x;\r\n", fillRgb.red, fillRgb.green, fillRgb.blue);
+ }
+ else {
+ fprintf(f, "fill:none;\r\n");
+ }
fprintf(f, "}\r\n");
+ };
+
+ export_style({Style::NO_STYLE});
+ for(auto &style : SK.style) {
+ Style *s = &style;
+ export_style(s->h);
}
fprintf(f, "]]></style>\r\n");
}
SS.MmToString(pt->p.x).c_str(), SS.MmToString(pt->p.y).c_str(),
SS.MmToString(SS.gCode.feed).c_str());
}
- // Move up to a clearance plane 5mm above the work.
+ // Move up to a clearance plane above the work.
fprintf(f, "G00 Z%s\r\n",
- SS.MmToString(SS.gCode.depth < 0 ? +5 : -5).c_str());
+ SS.MmToString(SS.gCode.safeHeight).c_str());
}
}
ssassert(false, "Unexpected operation");
}
-uint64_t Expr::ParamsUsed() const {
- uint64_t r = 0;
- if(op == Op::PARAM) r |= ((uint64_t)1 << (parh.v % 61));
- if(op == Op::PARAM_PTR) r |= ((uint64_t)1 << (parp->h.v % 61));
+void Expr::ParamsUsedList(std::vector<hParam> *list) const {
+ if(op == Op::PARAM || op == Op::PARAM_PTR) {
+ // leaf: just add ourselves if we aren't already there
+ hParam param = (op == Op::PARAM) ? parh : parp->h;
+ if(list->end() != std::find_if(list->begin(), list->end(),
+ [=](const hParam &p) { return p.v == param.v; })) {
+ // We found ourselves in the list already, early out.
+ return;
+ }
+ list->push_back(param);
+ return;
+ }
int c = Children();
- if(c >= 1) r |= a->ParamsUsed();
- if(c >= 2) r |= b->ParamsUsed();
- return r;
+ if(c >= 1) {
+ a->ParamsUsedList(list);
+ if(c >= 2) b->ParamsUsedList(list);
+ }
}
bool Expr::DependsOn(hParam p) const {
bool Expr::Tol(double a, double b) {
return fabs(a - b) < 0.001;
}
+
+bool Expr::IsZeroConst() const {
+ return op == Op::CONSTANT && EXACT(v == 0.0);
+}
+
Expr *Expr::FoldConstants() {
Expr *n = AllocExpr();
*n = *this;
Expr *PartialWrt(hParam p) const;
double Eval() const;
- uint64_t ParamsUsed() const;
+ void ParamsUsedList(std::vector<hParam> *list) const;
bool DependsOn(hParam p) const;
static bool Tol(double a, double b);
+ bool IsZeroConst() const;
Expr *FoldConstants();
void Substitute(hParam oldh, hParam newh);
}
SShell *s = &g->runningShell;
- SSurface *srf;
- for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) {
+ for(SSurface &srf : s->surface) {
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
- srf->h.v, srf->color.ToPackedInt(), srf->face, srf->degm, srf->degn);
- for(i = 0; i <= srf->degm; i++) {
- for(j = 0; j <= srf->degn; j++) {
+ srf.h.v, srf.color.ToPackedInt(), srf.face, srf.degm, srf.degn);
+ for(i = 0; i <= srf.degm; i++) {
+ for(j = 0; j <= srf.degn; j++) {
fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n",
- i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]);
+ i, j, CO(srf.ctrl[i][j]), srf.weight[i][j]);
}
}
STrimBy *stb;
- for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) {
+ for(stb = srf.trim.First(); stb; stb = srf.trim.NextAfter(stb)) {
fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n",
stb->curve.v, stb->backwards ? 1 : 0,
CO(stb->start), CO(stb->finish));
fprintf(fh, "AddSurface\n");
}
- SCurve *sc;
- for(sc = s->curve.First(); sc; sc = s->curve.NextAfter(sc)) {
+ for(SCurve &sc : s->curve) {
fprintf(fh, "Curve %08x %d %d %08x %08x\n",
- sc->h.v,
- sc->isExact ? 1 : 0, sc->exact.deg,
- sc->surfA.v, sc->surfB.v);
+ sc.h.v,
+ sc.isExact ? 1 : 0, sc.exact.deg,
+ sc.surfA.v, sc.surfB.v);
- if(sc->isExact) {
- for(i = 0; i <= sc->exact.deg; i++) {
+ if(sc.isExact) {
+ for(i = 0; i <= sc.exact.deg; i++) {
fprintf(fh, "CCtrl %d %.20f %.20f %.20f Weight %.20f\n",
- i, CO(sc->exact.ctrl[i]), sc->exact.weight[i]);
+ i, CO(sc.exact.ctrl[i]), sc.exact.weight[i]);
}
}
SCurvePt *scpt;
- for(scpt = sc->pts.First(); scpt; scpt = sc->pts.NextAfter(scpt)) {
+ for(scpt = sc.pts.First(); scpt; scpt = sc.pts.NextAfter(scpt)) {
fprintf(fh, "CurvePt %d %.20f %.20f %.20f\n",
scpt->vertex ? 1 : 0, CO(scpt->p));
}
}
bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel) {
+ bool fileIsEmpty = true;
allConsistent = false;
fileLoadError = false;
char line[1024];
while(fgets(line, (int)sizeof(line), fh)) {
+ fileIsEmpty = false;
+
char *s = strchr(line, '\n');
if(s) *s = '\0';
// We should never get files with \r characters in them, but mailers
fclose(fh);
+ if(fileIsEmpty) {
+ Error(_("The file is empty. It may be corrupt."));
+ NewFile();
+ }
+
if(fileLoadError) {
Error(_("Unrecognized data in file. This file may be corrupt, or "
"from a newer version of the program."));
SMesh *m, SShell *sh)
{
if(strcmp(filename.Extension().c_str(), "emn")==0) {
- return LinkIDF(filename, le, m, sh);
+ return LinkIDF(filename, le, m, sh);
+ } else if(strcmp(filename.Extension().c_str(), "stl")==0) {
+ return LinkStl(filename, le, m, sh);
} else {
return LoadEntitiesFromSlvs(filename, le, m, sh);
}
return false;
}
}
+ if(g.IsTriangleMeshAssembly())
+ g.forceToMesh = true;
} else if(linkMap.count(g.linkFile) == 0) {
dbp("Missing file for group: %s", g.name.c_str());
// The file was moved; prompt the user for its new location.
if(PruneGroups(hg))
goto pruned;
+ int groupRequestIndex = 0;
for(auto &req : SK.request) {
Request *r = &req;
if(r->group != hg) continue;
+ r->groupRequestIndex = groupRequestIndex++;
r->Generate(&(SK.entity), &(SK.param));
}
}
SolveResult SolveSpaceUI::TestRankForGroup(hGroup hg, int *rank) {
- WriteEqSystemForGroup(hg);
Group *g = SK.GetGroup(hg);
+ // If we don't calculate dof or redundant is allowed, there is
+ // no point to solve rank because this result is not meaningful
+ if(g->suppressDofCalculation || g->allowRedundant) return SolveResult::OKAY;
+ WriteEqSystemForGroup(hg);
SolveResult result = sys.SolveRank(g, rank);
FreeAllTemporary();
return result;
{ 1, N_("Show Snap &Grid"), Command::SHOW_GRID, '>', KC, mView },
{ 1, N_("Darken Inactive Solids"), Command::DIM_SOLID_MODEL, 0, KC, mView },
{ 1, N_("Use &Perspective Projection"), Command::PERSPECTIVE_PROJ, '`', KC, mView },
+{ 1, N_("Show E&xploded View"), Command::EXPLODE_SKETCH, '\\', KC, mView },
{ 1, N_("Dimension &Units"), Command::NONE, 0, KN, NULL },
{ 2, N_("Dimensions in &Millimeters"), Command::UNITS_MM, 0, KR, mView },
{ 2, N_("Dimensions in M&eters"), Command::UNITS_METERS, 0, KR, mView },
{ 2, N_("Dimensions in &Inches"), Command::UNITS_INCHES, 0, KR, mView },
+{ 2, N_("Dimensions in &Feet and Inches"), Command::UNITS_FEET_INCHES, 0, KR, mView },
{ 1, NULL, Command::NONE, 0, KN, NULL },
{ 1, N_("Show &Toolbar"), Command::SHOW_TOOLBAR, 0, KC, mView },
{ 1, N_("Show Property Bro&wser"), Command::SHOW_TEXT_WND, '\t', KC, mView },
{ 1, NULL, Command::NONE, 0, KN, NULL },
{ 1, N_("&On Point / Curve / Plane"), Command::ON_ENTITY, 'o', KN, mCon },
{ 1, N_("E&qual Length / Radius / Angle"), Command::EQUAL, 'q', KN, mCon },
-{ 1, N_("Length Ra&tio"), Command::RATIO, 'z', KN, mCon },
-{ 1, N_("Length Diff&erence"), Command::DIFFERENCE, 'j', KN, mCon },
+{ 1, N_("Length / Arc Ra&tio"), Command::RATIO, 'z', KN, mCon },
+{ 1, N_("Length / Arc Diff&erence"), Command::DIFFERENCE, 'j', KN, mCon },
{ 1, N_("At &Midpoint"), Command::AT_MIDPOINT, 'm', KN, mCon },
{ 1, N_("S&ymmetric"), Command::SYMMETRIC, 'y', KN, mCon },
{ 1, N_("Para&llel / Tangent"), Command::PARALLEL, 'l', KN, mCon },
{ 0, N_("&Help"), Command::NONE, 0, KN, mHelp },
{ 1, N_("&Language"), Command::LOCALE, 0, KN, mHelp },
{ 1, N_("&Website / Manual"), Command::WEBSITE, 0, KN, mHelp },
+{ 1, N_("&Go to GitHub commit"), Command::GITHUB, 0, KN, mHelp },
#ifndef __APPLE__
{ 1, N_("&About"), Command::ABOUT, 0, KN, mHelp },
#endif
dimSolidModelMenuItem = menuItem;
} else if(Menu[i].cmd == Command::PERSPECTIVE_PROJ) {
perspectiveProjMenuItem = menuItem;
+ } else if(Menu[i].cmd == Command::EXPLODE_SKETCH) {
+ explodeMenuItem = menuItem;
} else if(Menu[i].cmd == Command::SHOW_TOOLBAR) {
showToolbarMenuItem = menuItem;
} else if(Menu[i].cmd == Command::SHOW_TEXT_WND) {
unitsMetersMenuItem = menuItem;
} else if(Menu[i].cmd == Command::UNITS_INCHES) {
unitsInchesMenuItem = menuItem;
+ } else if(Menu[i].cmd == Command::UNITS_FEET_INCHES) {
+ unitsFeetInchesMenuItem = menuItem;
} else if(Menu[i].cmd == Command::SEL_WORKPLANE) {
inWorkplaneMenuItem = menuItem;
} else if(Menu[i].cmd == Command::FREE_IN_3D) {
void GraphicsWindow::PopulateRecentFiles() {
PopulateMenuWithPathnames(openRecentMenu, SS.recentFiles, [](const Platform::Path &path) {
+ // OkayToStartNewFile could mutate recentFiles, which will invalidate path (which is a
+ // reference into the recentFiles vector), so take a copy of it here.
+ Platform::Path pathCopy(path);
if(!SS.OkayToStartNewFile()) return;
- SS.Load(path);
+ SS.Load(pathCopy);
});
PopulateMenuWithPathnames(linkRecentMenu, SS.recentFiles, [](const Platform::Path &path) {
showEdges = true;
showMesh = false;
showOutlines = false;
+ showFacesDrawing = false;
+ showFacesNonDrawing = true;
drawOccludedAs = DrawOccludedAs::INVISIBLE;
showTextWindow = true;
using namespace std::placeholders;
// Do this first, so that if it causes an onRender event we don't try to paint without
// a canvas.
- window->SetMinContentSize(720, 670);
+ window->SetMinContentSize(720, /*ToolbarDrawOrHitTest 636*/ 32 * 18 + 3 * 16 + 8 + 4);
window->onClose = std::bind(&SolveSpaceUI::MenuFile, Command::EXIT);
window->onRender = std::bind(&GraphicsWindow::Paint, this);
window->onKeyboardEvent = std::bind(&GraphicsWindow::KeyboardEvent, this, _1);
return scale;
}
+
+void GraphicsWindow::ZoomToMouse(double zoomMultiplyer) {
+ double offsetRight = offset.Dot(projRight);
+ double offsetUp = offset.Dot(projUp);
+
+ double width, height;
+ window->GetContentSize(&width, &height);
+
+ double righti = currentMousePosition.x / scale - offsetRight;
+ double upi = currentMousePosition.y / scale - offsetUp;
+
+ // zoomMultiplyer of 1 gives a default zoom factor of 1.2x: zoomMultiplyer * 1.2
+ // zoom = adjusted zoom negative zoomMultiplyer will zoom out, positive will zoom in
+ //
+
+ scale *= exp(0.1823216 * zoomMultiplyer); // ln(1.2) = 0.1823216
+
+ double rightf = currentMousePosition.x / scale - offsetRight;
+ double upf = currentMousePosition.y / scale - offsetUp;
+
+ offset = offset.Plus(projRight.ScaledBy(rightf - righti));
+ offset = offset.Plus(projUp.ScaledBy(upf - upi));
+
+ if(SS.TW.shown.screen == TextWindow::Screen::EDIT_VIEW) {
+ if(havePainted) {
+ SS.ScheduleShowTW();
+ }
+ }
+ havePainted = false;
+ Invalidate();
+}
+
+
void GraphicsWindow::MenuView(Command id) {
switch(id) {
case Command::ZOOM_IN:
- SS.GW.scale *= 1.2;
- SS.ScheduleShowTW();
+ SS.GW.ZoomToMouse(1);
break;
case Command::ZOOM_OUT:
- SS.GW.scale /= 1.2;
- SS.ScheduleShowTW();
+ SS.GW.ZoomToMouse(-1);
break;
case Command::ZOOM_TO_FIT:
}
break;
+ case Command::EXPLODE_SKETCH:
+ SS.explode = !SS.explode;
+ SS.GW.EnsureValidActives();
+ SS.MarkGroupDirty(SS.GW.activeGroup, true);
+ break;
+
case Command::ONTO_WORKPLANE:
if(SS.GW.LockedInWorkplane()) {
SS.GW.AnimateOntoWorkplane();
SS.GW.EnsureValidActives();
break;
+ case Command::UNITS_FEET_INCHES:
+ SS.viewUnits = Unit::FEET_INCHES;
+ SS.ScheduleShowTW();
+ SS.GW.EnsureValidActives();
+ break;
+
case Command::UNITS_MM:
SS.viewUnits = Unit::MM;
SS.ScheduleShowTW();
case Unit::MM:
case Unit::METERS:
case Unit::INCHES:
+ case Unit::FEET_INCHES:
break;
default:
SS.viewUnits = Unit::MM;
unitsMmMenuItem->SetActive(SS.viewUnits == Unit::MM);
unitsMetersMenuItem->SetActive(SS.viewUnits == Unit::METERS);
unitsInchesMenuItem->SetActive(SS.viewUnits == Unit::INCHES);
+ unitsFeetInchesMenuItem->SetActive(SS.viewUnits == Unit::FEET_INCHES);
if(SS.TW.window) SS.TW.window->SetVisible(SS.GW.showTextWindow);
showTextWndMenuItem->SetActive(SS.GW.showTextWindow);
showGridMenuItem->SetActive(SS.GW.showSnapGrid);
dimSolidModelMenuItem->SetActive(SS.GW.dimSolidModel);
perspectiveProjMenuItem->SetActive(SS.usePerspectiveProj);
+ explodeMenuItem->SetActive(SS.explode);
showToolbarMenuItem->SetActive(SS.showToolbar);
fullScreenMenuItem->SetActive(SS.GW.window->IsFullScreen());
}
void GraphicsWindow::DeleteTaggedRequests() {
- Request *r;
// Delete any requests that were affected by this deletion.
- for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) {
- if(r->workplane == Entity::FREE_IN_3D) continue;
- if(!r->workplane.isFromRequest()) continue;
- Request *wrkpl = SK.GetRequest(r->workplane.request());
+ for(Request &r : SK.request) {
+ if(r.workplane == Entity::FREE_IN_3D) continue;
+ if(!r.workplane.isFromRequest()) continue;
+ Request *wrkpl = SK.GetRequest(r.workplane.request());
if(wrkpl->tag)
- r->tag = 1;
+ r.tag = 1;
}
// Rewrite any point-coincident constraints that were affected by this
// deletion.
- for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) {
- if(!r->tag) continue;
- FixConstraintsForRequestBeingDeleted(r->h);
+ for(Request &r : SK.request) {
+ if(!r.tag) continue;
+ FixConstraintsForRequestBeingDeleted(r.h);
}
// and then delete the tagged requests.
SK.request.RemoveTagged();
SS.centerOfMass.draw = false;
// This clears the marks drawn to indicate which points are
// still free to drag.
- Param *p;
- for(p = SK.param.First(); p; p = SK.param.NextAfter(p)) {
- p->free = false;
+ for(Param &p : SK.param) {
+ p.free = false;
}
if(SS.exportMode) {
SS.exportMode = false;
break;
case Command::SELECT_ALL: {
- Entity *e;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != SS.GW.activeGroup) continue;
- if(e->IsFace() || e->IsDistance()) continue;
- if(!e->IsVisible()) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != SS.GW.activeGroup) continue;
+ if(e.IsFace() || e.IsDistance()) continue;
+ if(!e.IsVisible()) continue;
- SS.GW.MakeSelected(e->h);
+ SS.GW.MakeSelected(e.h);
}
SS.GW.Invalidate();
SS.ScheduleShowTW();
}
case Command::SELECT_CHAIN: {
- Entity *e;
int newlySelected = 0;
bool didSomething;
do {
didSomething = false;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != SS.GW.activeGroup) continue;
- if(!e->HasEndpoints()) continue;
- if(!e->IsVisible()) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != SS.GW.activeGroup) continue;
+ if(!e.HasEndpoints()) continue;
+ if(!e.IsVisible()) continue;
- Vector st = e->EndpointStart(),
- fi = e->EndpointFinish();
+ Vector st = e.EndpointStart(),
+ fi = e.EndpointFinish();
bool onChain = false, alreadySelected = false;
List<Selection> *ls = &(SS.GW.selection);
for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) {
if(!s->entity.v) continue;
- if(s->entity == e->h) {
+ if(s->entity == e.h) {
alreadySelected = true;
continue;
}
}
}
if(onChain && !alreadySelected) {
- SS.GW.MakeSelected(e->h);
+ SS.GW.MakeSelected(e.h);
newlySelected++;
didSomething = true;
}
break;
case Command::CONSTRUCTION: {
+ // if we are drawing
+ if(SS.GW.pending.operation == Pending::DRAGGING_NEW_POINT ||
+ SS.GW.pending.operation == Pending::DRAGGING_NEW_LINE_POINT ||
+ SS.GW.pending.operation == Pending::DRAGGING_NEW_ARC_POINT ||
+ SS.GW.pending.operation == Pending::DRAGGING_NEW_CUBIC_POINT ||
+ SS.GW.pending.operation == Pending::DRAGGING_NEW_RADIUS) {
+ for(auto &hr : SS.GW.pending.requests) {
+ Request* r = SK.GetRequest(hr);
+ r->construction = !(r->construction);
+ SS.MarkGroupDirty(r->group);
+ }
+ SS.GW.Invalidate();
+ break;
+ }
SS.GW.GroupSelection();
if(SS.GW.gs.entities == 0) {
Error(_("No entities are selected. Select entities before "
SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE);
}
+ if(v == &showFaces) {
+ if(g->type == Group::Type::DRAWING_WORKPLANE || g->type == Group::Type::DRAWING_3D) {
+ showFacesDrawing = showFaces;
+ } else {
+ showFacesNonDrawing = showFaces;
+ }
+ }
+
Invalidate(/*clearPersistent=*/true);
SS.ScheduleShowTW();
}
g.predef.negateV = wrkplg->predef.negateV;
} else if(wrkplg->subtype == Subtype::WORKPLANE_BY_POINT_ORTHO) {
g.predef.q = wrkplg->predef.q;
+ } else if(wrkplg->subtype == Subtype::WORKPLANE_BY_POINT_NORMAL) {
+ g.predef.q = wrkplg->predef.q;
+ g.predef.entityB = wrkplg->predef.entityB;
} else ssassert(false, "Unexpected workplane subtype");
}
+ } else if(gs.anyNormals == 1 && gs.points == 1 && gs.n == 2) {
+ g.subtype = Subtype::WORKPLANE_BY_POINT_NORMAL;
+ g.predef.entityB = gs.anyNormal[0];
+ g.predef.q = SK.GetEntity(gs.anyNormal[0])->NormalGetNum();
+ g.predef.origin = gs.point[0];
+ //} else if(gs.faces == 1 && gs.points == 1 && gs.n == 2) {
+ // g.subtype = Subtype::WORKPLANE_BY_POINT_FACE;
+ // g.predef.q = SK.GetEntity(gs.face[0])->NormalGetNum();
+ // g.predef.origin = gs.point[0];
} else {
Error(_("Bad selection for new sketch in workplane. This "
"group can be created with:\n\n"
" * a point (through the point, orthogonal to coordinate axes)\n"
" * a point and two line segments (through the point, "
- "parallel to the lines)\n"
+ "parallel to the lines)\n"
+ " * a point and a normal (through the point, "
+ "orthogonal to the normal)\n"
+ /*" * a point and a face (through the point, "
+ "parallel to the face)\n"*/
" * a workplane (copy of the workplane)\n"));
return;
}
}
bool Group::IsForcedToMesh() const {
- return forceToMesh || IsForcedToMeshBySource();
+ return forceToMesh || IsTriangleMeshAssembly() || IsForcedToMeshBySource();
+}
+
+bool Group::IsTriangleMeshAssembly() const {
+ return type == Type::LINKED && linkFile.Extension() == "stl";
}
std::string Group::DescriptionString() {
}
void Group::Activate() {
- if(type == Type::EXTRUDE || type == Type::LINKED || type == Type::LATHE ||
- type == Type::REVOLVE || type == Type::HELIX || type == Type::TRANSLATE || type == Type::ROTATE) {
- SS.GW.showFaces = true;
+ if(type == Type::DRAWING_WORKPLANE || type == Type::DRAWING_3D) {
+ SS.GW.showFaces = SS.GW.showFacesDrawing;
} else {
- SS.GW.showFaces = false;
+ SS.GW.showFaces = SS.GW.showFacesNonDrawing;
}
SS.MarkGroupDirty(h); // for good measure; shouldn't be needed
SS.ScheduleShowTW();
} else if(subtype == Subtype::WORKPLANE_BY_POINT_ORTHO) {
// Already given, numerically.
q = predef.q;
+ } else if(subtype == Subtype::WORKPLANE_BY_POINT_NORMAL) {
+ q = SK.GetEntity(predef.entityB)->NormalGetNum();
} else ssassert(false, "Unexpected workplane subtype");
Entity normal = {};
normal.type = Entity::Type::NORMAL_N_COPY;
normal.numNormal = q;
+
normal.point[0] = h.entity(2);
normal.group = h;
normal.h = h.entity(1);
AddEq(l, (EC(axis.z))->Minus(EP(6)), 5);
#undef EC
#undef EP
+ if(type == Type::HELIX) {
+ if(valB != 0.0) {
+ AddEq(l, Expr::From(h.param(7))->Times(Expr::From(PI))->
+ Minus(Expr::From(h.param(3))->Times(Expr::From(valB))), 6);
+ }
+ }
} else if(type == Type::EXTRUDE) {
if(predef.entityB != Entity::FREE_IN_3D) {
// The extrusion path is locked along a line, normal to the
el->Add(&en);
}
+bool Group::ShouldDrawExploded() const {
+ return SS.explode && h == SS.GW.activeGroup && type == Type::DRAWING_WORKPLANE && !SS.exportMode;
+}
}
void SShell::RemapFaces(Group *g, int remap) {
- SSurface *ss;
- for(ss = surface.First(); ss; ss = surface.NextAfter(ss)){
- hEntity face = { ss->face };
+ for(SSurface &ss : surface){
+ hEntity face = { ss.face };
if(face == Entity::NO_ENTITY) continue;
face = g->Remap(face, remap);
- ss->face = face.v;
+ ss.face = face.v;
}
}
// So these are the sides
if(ss->degm != 1 || ss->degn != 1) continue;
- Entity *e;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != opA) continue;
- if(e->type != Entity::Type::LINE_SEGMENT) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != opA) continue;
+ if(e.type != Entity::Type::LINE_SEGMENT) continue;
- Vector a = SK.GetEntity(e->point[0])->PointGetNum(),
- b = SK.GetEntity(e->point[1])->PointGetNum();
+ Vector a = SK.GetEntity(e.point[0])->PointGetNum(),
+ b = SK.GetEntity(e.point[1])->PointGetNum();
a = a.Plus(ttop);
b = b.Plus(ttop);
// Could get taken backwards, so check all cases.
(a.Equals(ss->ctrl[0][1]) && b.Equals(ss->ctrl[1][1])) ||
(b.Equals(ss->ctrl[0][1]) && a.Equals(ss->ctrl[1][1])))
{
- face = Remap(e->h, REMAP_LINE_TO_FACE);
+ face = Remap(e.h, REMAP_LINE_TO_FACE);
ss->face = face.v;
break;
}
}
//////////////////////////////////////////////////////////////////////////////
-// Functions for linking an IDF file - we need to create entites that
+// Functions for linking an IDF file - we need to create entities that
// get remapped into a linked group similar to linking .slvs files
//////////////////////////////////////////////////////////////////////////////
return en.h;
}
-static hEntity newLine(EntityList *el, int *id, hEntity p0, hEntity p1) {
+static hEntity newLine(EntityList *el, int *id, hEntity p0, hEntity p1, bool keepout) {
Entity en = {};
en.type = Entity::Type::LINE_SEGMENT;
en.point[0] = p0;
en.extraPoints = 0;
en.timesApplied = 0;
en.group.v = 493;
- en.construction = false;
- en.style.v = Style::ACTIVE_GRP;
+ en.construction = keepout;
+ en.style.v = keepout? Style::CONSTRUCTION : Style::ACTIVE_GRP;
en.actVisible = true;
en.forceHidden = false;
return en.h;
}
-static hEntity newArc(EntityList *el, int *id, hEntity p0, hEntity p1, hEntity pc, hEntity hnorm) {
+static hEntity newArc(EntityList *el, int *id, hEntity p0, hEntity p1, hEntity pc, hEntity hnorm, bool keepout) {
Entity en = {};
en.type = Entity::Type::ARC_OF_CIRCLE;
en.point[0] = pc;
en.extraPoints = 0;
en.timesApplied = 0;
en.group.v = 403;
- en.construction = false;
- en.style.v = Style::ACTIVE_GRP;
+ en.construction = keepout;
+ en.style.v = keepout? Style::CONSTRUCTION : Style::ACTIVE_GRP;
en.actVisible = true;
en.forceHidden = false; *id = *id+1;
return en.h;
}
-static hEntity newCircle(EntityList *el, int *id, hEntity p0, hEntity hdist, hEntity hnorm) {
+static hEntity newCircle(EntityList *el, int *id, hEntity p0, hEntity hdist, hEntity hnorm, bool keepout) {
Entity en = {};
en.type = Entity::Type::CIRCLE;
en.point[0] = p0;
en.extraPoints = 0;
en.timesApplied = 0;
en.group.v = 399;
- en.construction = false;
- en.style.v = Style::ACTIVE_GRP;
+ en.construction = keepout;
+ en.style.v = keepout? Style::CONSTRUCTION : Style::ACTIVE_GRP;
en.actVisible = true;
en.forceHidden = false;
// Positive angles are counter clockwise, negative are clockwise. An angle of 360
// indicates a circle centered at x1,y1 passing through x2,y2 and is a complete loop.
static void CreateEntity(EntityList *el, int *id, hEntity h0, hEntity h1, hEntity hnorm,
- Vector p0, Vector p1, double angle) {
+ Vector p0, Vector p1, double angle, bool keepout) {
if (angle == 0.0) {
//line
if(p0.Equals(p1)) return;
- newLine(el, id, h0, h1);
+ newLine(el, id, h0, h1, keepout);
} else if(angle == 360.0) {
// circle
double d = p1.Minus(p0).Magnitude();
hEntity hd = newDistance(el, id, d);
- newCircle(el, id, h1, hd, hnorm);
+ newCircle(el, id, h1, hd, hnorm, keepout);
} else {
// arc
}
Vector c = m.Minus(perp.ScaledBy(dist));
hEntity hc = newPoint(el, id, c, /*visible=*/false);
- newArc(el, id, h0, h1, hc, hnorm);
+ newArc(el, id, h0, h1, hc, hnorm, keepout);
}
}
namespace SolveSpace {
// Here we read the important section of an IDF file. SolveSpace Entities are directly created by
-// the funcions above, which is only OK because of the way linking works. For example points do
+// the functions above, which is only OK because of the way linking works. For example points do
// not have handles for solver parameters (coordinates), they only have their actPoint values
-// set (or actNormal or actDistance). These are incompete entites and would be a problem if
+// set (or actNormal or actDistance). These are incomplete entities and would be a problem if
// they were part of the sketch, but they are not. After making a list of them here, a new group
// gets created from copies of these. Those copies are complete and part of the sketch group.
bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *sh) {
double board_thickness = 10.0;
double scale = 1.0; //mm
- bool topEntities, bottomEntities;
-
+ bool topEntities = false;
+ bool bottomEntities = false;
+
Quaternion normal = Quaternion::From(Vector::From(1,0,0), Vector::From(0,1,0));
hEntity hnorm = newNormal(el, &entityCount, normal);
} else if (line.find(".BOARD_OUTLINE") == 0) {
section = board_outline;
record_number = 1;
-// no keepouts for now - they should also be shown as construction?
-// } else if (line.find(".ROUTE_KEEPOUT") == 0) {
-// section = routing_keepout;
-// record_number = 1;
+ } else if (line.find(".ROUTE_KEEPOUT") == 0) {
+ section = routing_keepout;
+ record_number = 1;
} else if(line.find(".DRILLED_HOLES") == 0) {
section = drilled_holes;
record_number = 1;
bool vis = (ang == 360.0);
if (bottomEntities) {
hEntity hp = newPoint(el, &entityCount, point, /*visible=*/vis);
- CreateEntity(el, &entityCount, hprev, hp, hnorm, pprev, point, ang);
+ CreateEntity(el, &entityCount, hprev, hp, hnorm, pprev, point, ang,
+ (section == routing_keepout) );
pprev = point;
hprev = hp;
}
if (topEntities) {
hEntity hp = newPoint(el, &entityCount, pTop, /*visible=*/vis);
- CreateEntity(el, &entityCount, hprevTop, hp, hnorm, pprevTop, pTop, ang);
+ CreateEntity(el, &entityCount, hprevTop, hp, hnorm, pprevTop, pTop,
+ ang, (section == routing_keepout) );
pprevTop = pTop;
hprevTop = hp;
}
Vector cent = Vector::From(x,y,0.0);
hEntity hcent = newPoint(el, &entityCount, cent);
hEntity hdist = newDistance(el, &entityCount, d/2);
- newCircle(el, &entityCount, hcent, hdist, hnorm);
+ newCircle(el, &entityCount, hcent, hdist, hnorm, false);
// and again for the top
Vector cTop = Vector::From(x,y,board_thickness);
hcent = newPoint(el, &entityCount, cTop);
hdist = newDistance(el, &entityCount, d/2);
- newCircle(el, &entityCount, hcent, hdist, hnorm);
+ newCircle(el, &entityCount, hcent, hdist, hnorm, false);
// create the curves for the extrusion
Vector pt = Vector::From(x+d/2, y, 0.0);
MakeBeziersForArcs(&sbl, cent, pt, pt, normal, 360.0);
--- /dev/null
+//-----------------------------------------------------------------------------
+// Triangle mesh file reader. Reads an STL file triangle mesh and creates
+// a SovleSpace SMesh from it. Supports only Linking, not import.
+//
+// Copyright 2020 Paul Kahler.
+//-----------------------------------------------------------------------------
+#include "solvespace.h"
+#include "sketch.h"
+#include <vector>
+
+#define MIN_POINT_DISTANCE 0.001
+
+// we will check for duplicate vertices and keep all their normals
+class vertex {
+public:
+ Vector p;
+ std::vector<Vector> normal;
+};
+
+static bool isEdgeVertex(vertex &v) {
+ unsigned int i,j;
+ bool result = false;
+ for(i=0;i<v.normal.size();i++) {
+ for(j=i;j<v.normal.size();j++) {
+ if(v.normal[i].Dot(v.normal[j]) < 0.9) {
+ result = true;
+ }
+ }
+ }
+ return result;
+}
+// This function has poor performance, used inside a loop it is O(n**2)
+static void addUnique(std::vector<vertex> &lv, Vector &p, Vector &n) {
+ unsigned int i;
+ for(i=0; i<lv.size(); i++) {
+ if(lv[i].p.Equals(p, MIN_POINT_DISTANCE)) {
+ break;
+ }
+ }
+ if(i==lv.size()) {
+ vertex v;
+ v.p = p;
+ lv.push_back(v);
+ }
+ // we could improve a little by only storing unique normals
+ lv[i].normal.push_back(n);
+};
+
+// Make a new point - type doesn't matter since we will make a copy later
+static hEntity newPoint(EntityList *el, int *id, Vector p) {
+ Entity en = {};
+ en.type = Entity::Type::POINT_N_COPY;
+ en.extraPoints = 0;
+ en.timesApplied = 0;
+ en.group.v = 462;
+ en.actPoint = p;
+ en.construction = false;
+ en.style.v = Style::DATUM;
+ en.actVisible = true;
+ en.forceHidden = false;
+
+ en.h.v = *id + en.group.v*65536;
+ *id = *id+1;
+ el->Add(&en);
+ return en.h;
+}
+
+// check if a vertex is unique and add it via newPoint if it is.
+static void addVertex(EntityList *el, Vector v) {
+ if(el->n < 15000) {
+ int id = el->n;
+ newPoint(el, &id, v);
+ }
+}
+
+static hEntity newNormal(EntityList *el, int *id, Quaternion normal, hEntity p) {
+ // normals have parameters, but we don't need them to make a NORMAL_N_COPY from this
+ Entity en = {};
+ en.type = Entity::Type::NORMAL_N_COPY;
+ en.extraPoints = 0;
+ en.timesApplied = 0;
+ en.group.v = 472;
+ en.actNormal = normal;
+ en.construction = false;
+ en.style.v = Style::NORMALS;
+ // to be visible we need to add a point.
+// en.point[0] = newPoint(el, id, Vector::From(0,0,0));
+ en.point[0] = p;
+ en.actVisible = true;
+ en.forceHidden = false;
+
+ *id = *id+1;
+ en.h.v = *id + en.group.v*65536;
+ el->Add(&en);
+ return en.h;
+}
+
+static hEntity newLine(EntityList *el, int *id, hEntity p0, hEntity p1) {
+ Entity en = {};
+ en.type = Entity::Type::LINE_SEGMENT;
+ en.point[0] = p0;
+ en.point[1] = p1;
+ en.extraPoints = 0;
+ en.timesApplied = 0;
+ en.group.v = 493;
+ en.construction = true;
+ en.style.v = Style::CONSTRUCTION;
+ en.actVisible = true;
+ en.forceHidden = false;
+
+ en.h.v = *id + en.group.v*65536;
+ *id = *id + 1;
+ el->Add(&en);
+ return en.h;
+}
+
+namespace SolveSpace {
+
+bool LinkStl(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *sh) {
+ dbp("\nLink STL triangle mesh.");
+ el->Clear();
+ std::string data;
+ if(!ReadFile(filename, &data)) {
+ Error("Couldn't read from '%s'", filename.raw.c_str());
+ return false;
+ }
+
+ std::stringstream f(data);
+
+ char str[80] = {};
+ f.read(str, 80);
+
+ if(0==memcmp("solid", str, 5)) {
+ // just returning false will trigger the warning that linked file is not present
+ // best solution is to add an importer for text STL.
+ Message(_("Text-formated STL files are not currently supported"));
+ return false;
+ }
+
+ uint32_t n;
+ uint32_t color;
+
+ f.read((char*)&n, 4);
+ dbp("%d triangles", n);
+
+ float x,y,z;
+ float xn,yn,zn;
+
+ std::vector<vertex> verts = {};
+
+ for(uint32_t i = 0; i<n; i++) {
+ STriangle tr = {};
+
+ // read the triangle normal
+ f.read((char*)&xn, 4);
+ f.read((char*)&yn, 4);
+ f.read((char*)&zn, 4);
+ tr.an = Vector::From(xn,yn,zn);
+ tr.bn = tr.an;
+ tr.cn = tr.an;
+
+ f.read((char*)&x, 4);
+ f.read((char*)&y, 4);
+ f.read((char*)&z, 4);
+ tr.a.x = x;
+ tr.a.y = y;
+ tr.a.z = z;
+
+ f.read((char*)&x, 4);
+ f.read((char*)&y, 4);
+ f.read((char*)&z, 4);
+ tr.b.x = x;
+ tr.b.y = y;
+ tr.b.z = z;
+
+ f.read((char*)&x, 4);
+ f.read((char*)&y, 4);
+ f.read((char*)&z, 4);
+ tr.c.x = x;
+ tr.c.y = y;
+ tr.c.z = z;
+
+ f.read((char*)&color,2);
+ if(color & 0x8000) {
+ tr.meta.color.red = (color >> 7) & 0xf8;
+ tr.meta.color.green = (color >> 2) & 0xf8;
+ tr.meta.color.blue = (color << 3);
+ tr.meta.color.alpha = 255;
+ } else {
+ tr.meta.color.red = 90;
+ tr.meta.color.green = 120;
+ tr.meta.color.blue = 140;
+ tr.meta.color.alpha = 255;
+ }
+
+ m->AddTriangle(&tr);
+ Vector normal = tr.Normal().WithMagnitude(1.0);
+ addUnique(verts, tr.a, normal);
+ addUnique(verts, tr.b, normal);
+ addUnique(verts, tr.c, normal);
+ }
+ dbp("%d vertices", verts.size());
+
+ int id = 1;
+
+ //add the STL origin and normals
+ hEntity origin = newPoint(el, &id, Vector::From(0.0, 0.0, 0.0));
+ newNormal(el, &id, Quaternion::From(Vector::From(1,0,0),Vector::From(0,1,0)), origin);
+ newNormal(el, &id, Quaternion::From(Vector::From(0,1,0),Vector::From(0,0,1)), origin);
+ newNormal(el, &id, Quaternion::From(Vector::From(0,0,1),Vector::From(1,0,0)), origin);
+
+ BBox box = {};
+ box.minp = verts[0].p;
+ box.maxp = verts[0].p;
+
+ // determine the bounding box for all vertexes
+ for(unsigned int i=1; i<verts.size(); i++) {
+ box.Include(verts[i].p);
+ }
+
+ hEntity p[8];
+ p[0] = newPoint(el, &id, Vector::From(box.minp.x, box.minp.y, box.minp.z));
+ p[1] = newPoint(el, &id, Vector::From(box.maxp.x, box.minp.y, box.minp.z));
+ p[2] = newPoint(el, &id, Vector::From(box.minp.x, box.maxp.y, box.minp.z));
+ p[3] = newPoint(el, &id, Vector::From(box.maxp.x, box.maxp.y, box.minp.z));
+ p[4] = newPoint(el, &id, Vector::From(box.minp.x, box.minp.y, box.maxp.z));
+ p[5] = newPoint(el, &id, Vector::From(box.maxp.x, box.minp.y, box.maxp.z));
+ p[6] = newPoint(el, &id, Vector::From(box.minp.x, box.maxp.y, box.maxp.z));
+ p[7] = newPoint(el, &id, Vector::From(box.maxp.x, box.maxp.y, box.maxp.z));
+
+ newLine(el, &id, p[0], p[1]);
+ newLine(el, &id, p[0], p[2]);
+ newLine(el, &id, p[3], p[1]);
+ newLine(el, &id, p[3], p[2]);
+
+ newLine(el, &id, p[4], p[5]);
+ newLine(el, &id, p[4], p[6]);
+ newLine(el, &id, p[7], p[5]);
+ newLine(el, &id, p[7], p[6]);
+
+ newLine(el, &id, p[0], p[4]);
+ newLine(el, &id, p[1], p[5]);
+ newLine(el, &id, p[2], p[6]);
+ newLine(el, &id, p[3], p[7]);
+
+ for(unsigned int i=0; i<verts.size(); i++) {
+ // create point entities for edge vertexes
+ if(isEdgeVertex(verts[i])) {
+ addVertex(el, verts[i].p);
+ }
+ }
+
+ return true;
+}
+
+}
case SLVS_C_PT_ON_FACE: t = Constraint::Type::PT_ON_FACE; break;
case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::Type::EQUAL_LENGTH_LINES; break;
case SLVS_C_LENGTH_RATIO: t = Constraint::Type::LENGTH_RATIO; break;
+case SLVS_C_ARC_ARC_LEN_RATIO: t = Constraint::Type::ARC_ARC_LEN_RATIO; break;
+case SLVS_C_ARC_LINE_LEN_RATIO: t = Constraint::Type::ARC_LINE_LEN_RATIO; break;
case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::Type::EQ_LEN_PT_LINE_D; break;
case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::Type::EQ_PT_LN_DISTANCES; break;
case SLVS_C_EQUAL_ANGLE: t = Constraint::Type::EQUAL_ANGLE; break;
case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::Type::EQUAL_LINE_ARC_LEN; break;
case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::Type::LENGTH_DIFFERENCE; break;
+case SLVS_C_ARC_ARC_DIFFERENCE: t = Constraint::Type::ARC_ARC_DIFFERENCE; break;
+case SLVS_C_ARC_LINE_DIFFERENCE:t = Constraint::Type::ARC_LINE_DIFFERENCE; break;
case SLVS_C_SYMMETRIC: t = Constraint::Type::SYMMETRIC; break;
case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::Type::SYMMETRIC_HORIZ; break;
case SLVS_C_SYMMETRIC_VERT: t = Constraint::Type::SYMMETRIC_VERT; break;
Request *r = SK.GetRequest(hr);
if(r->group != SS.GW.activeGroup) return;
- Entity *e;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(!(e->h.isFromRequest())) continue;
- if(e->h.request() != hr) continue;
+ for(Entity &e : SK.entity) {
+ if(!(e.h.isFromRequest())) continue;
+ if(e.h.request() != hr) continue;
- if(e->type != Entity::Type::POINT_IN_2D &&
- e->type != Entity::Type::POINT_IN_3D)
+ if(e.type != Entity::Type::POINT_IN_2D &&
+ e.type != Entity::Type::POINT_IN_3D)
{
continue;
}
// This is a point generated by the request being deleted; so fix
// the constraints for that.
- FixConstraintsForPointBeingDeleted(e->h);
+ FixConstraintsForPointBeingDeleted(e.h);
}
}
void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
List<hEntity> ld = {};
- Constraint *c;
SK.constraint.ClearTags();
- for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
- if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
- if(c->group != SS.GW.activeGroup) continue;
+ for(Constraint &c : SK.constraint) {
+ if(c.type != Constraint::Type::POINTS_COINCIDENT) continue;
+ if(c.group != SS.GW.activeGroup) continue;
- if(c->ptA == hpt) {
- ld.Add(&(c->ptB));
- c->tag = 1;
+ if(c.ptA == hpt) {
+ ld.Add(&(c.ptB));
+ c.tag = 1;
}
- if(c->ptB == hpt) {
- ld.Add(&(c->ptA));
- c->tag = 1;
+ if(c.ptB == hpt) {
+ ld.Add(&(c.ptA));
+ c.tag = 1;
}
}
// Remove constraints without waiting for regeneration; this way
// happens to exist, then constrain that point coincident to hpt.
//-----------------------------------------------------------------------------
void GraphicsWindow::ParametricCurve::ConstrainPointIfCoincident(hEntity hpt) {
- Entity *e, *pt;
+ Entity *pt;
pt = SK.GetEntity(hpt);
Vector ev, ptv;
ptv = pt->PointGetNum();
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->h == pt->h) continue;
- if(!e->IsPoint()) continue;
- if(e->group != pt->group) continue;
- if(e->workplane != pt->workplane) continue;
+ for(Entity &e : SK.entity) {
+ if(e.h == pt->h) continue;
+ if(!e.IsPoint()) continue;
+ if(e.group != pt->group) continue;
+ if(e.workplane != pt->workplane) continue;
- ev = e->PointGetNum();
+ ev = e.PointGetNum();
if(!ev.Equals(ptv)) continue;
- Constraint::ConstrainCoincident(hpt, e->h);
+ Constraint::ConstrainCoincident(hpt, e.h);
break;
}
}
Vector pos = p->PointGetNum();
UpdateDraggedNum(&pos, mx, my);
p->PointForceTo(pos);
+
+ SS.ScheduleShowTW();
}
void GraphicsWindow::UpdateDraggedNum(Vector *pos, double mx, double my) {
shiftDown = !shiftDown;
}
- if(SS.showToolbar) {
+ // Not passing right-button and middle-button drags to the toolbar avoids
+ // some cosmetic issues with trackpad pans/rotates implemented with
+ // simulated right-button drag events causing spurious hover events.
+ if(SS.showToolbar && !middleDown) {
if(ToolbarMouseMoved((int)x, (int)y)) {
hover.Clear();
return;
hEntity dragEntity = ChooseFromHoverToDrag().entity;
if(dragEntity.v) e = SK.GetEntity(dragEntity);
if(e && e->type != Entity::Type::WORKPLANE) {
- Entity *e = SK.GetEntity(dragEntity);
+ if(!hoverWasSelectedOnMousedown) {
+ // The user clicked an unselected entity, which
+ // means they're dragging just the hovered thing,
+ // not the full selection. So clear all the selection
+ // except that entity.
+ ClearSelection();
+ MakeSelected(dragEntity);
+ }
if(e->type == Entity::Type::CIRCLE && selection.n <= 1) {
// Drag the radius.
- ClearSelection();
pending.circle = dragEntity;
pending.operation = Pending::DRAGGING_RADIUS;
} else if(e->IsNormal()) {
- ClearSelection();
pending.normal = dragEntity;
pending.operation = Pending::DRAGGING_NORMAL;
} else {
- if(!hoverWasSelectedOnMousedown) {
- // The user clicked an unselected entity, which
- // means they're dragging just the hovered thing,
- // not the full selection. So clear all the selection
- // except that entity.
- ClearSelection();
- MakeSelected(e->h);
- }
StartDraggingBySelection();
- if(!hoverWasSelectedOnMousedown) {
- // And then clear the selection again, since they
- // probably didn't want that selected if they just
- // were dragging it.
- ClearSelection();
- }
hover.Clear();
pending.operation = Pending::DRAGGING_POINTS;
}
return;
}
+ if(pending.operation == Pending::DRAGGING_POINTS && ctrlDown) {
+ SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
+ SS.extraLine.ptB = UnProjectPoint(mp);
+ SS.extraLine.draw = true;
+ }
+
// We're currently dragging something; so do that. But if we haven't
// painted since the last time we solved, do nothing, because there's
// no sense solving a frame and not displaying it.
if(!havePainted) {
- if(pending.operation == Pending::DRAGGING_POINTS && ctrlDown) {
- SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
- SS.extraLine.ptB = UnProjectPoint(mp);
- SS.extraLine.draw = true;
- }
return;
}
HitTestMakeSelection(mp);
SS.MarkGroupDirtyByEntity(pending.point);
orig.mouse = mp;
- Invalidate();
break;
case Pending::DRAGGING_POINTS:
// Don't start dragging the position about the normal
// until we're a little ways out, to get a reasonable
// reference pos
- orig.mouse = mp;
- break;
+ qt = Quaternion::IDENTITY;
+ } else {
+ double theta = atan2(orig.mouse.y-orig.mouseOnButtonDown.y,
+ orig.mouse.x-orig.mouseOnButtonDown.x);
+ theta -= atan2(y-orig.mouseOnButtonDown.y,
+ x-orig.mouseOnButtonDown.x);
+
+ Vector gn = projRight.Cross(projUp);
+ qt = Quaternion::From(gn, -theta);
}
- double theta = atan2(orig.mouse.y-orig.mouseOnButtonDown.y,
- orig.mouse.x-orig.mouseOnButtonDown.x);
- theta -= atan2(y-orig.mouseOnButtonDown.y,
- x-orig.mouseOnButtonDown.x);
-
- Vector gn = projRight.Cross(projUp);
- qt = Quaternion::From(gn, -theta);
-
- SS.extraLine.draw = true;
- SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
- SS.extraLine.ptB = UnProjectPoint(mp);
} else {
double dx = -(x - orig.mouse.x);
double dy = -(y - orig.mouse.y);
qt = Quaternion::From(projUp, -s*dx).Times(
Quaternion::From(projRight, s*dy));
}
- orig.mouse = mp;
// Now apply this rotation to the points being dragged.
List<hEntity> *lhe = &(pending.points);
p = qt.Rotate(p);
p = p.Plus(SS.extraLine.ptA);
e->PointForceTo(p);
- SS.MarkGroupDirtyByEntity(e->h);
+ } else {
+ UpdateDraggedPoint(*he, x, y);
}
- continue;
+ } else {
+ Quaternion q = e->PointGetQuaternion();
+ Vector p = e->PointGetNum();
+ q = qt.Times(q);
+ e->PointForceQuaternionTo(q);
+ // Let's rotate about the selected point; so fix up the
+ // translation so that that point didn't move.
+ e->PointForceTo(p);
}
-
- Quaternion q = e->PointGetQuaternion();
- Vector p = e->PointGetNum();
- q = qt.Times(q);
- e->PointForceQuaternionTo(q);
- // Let's rotate about the selected point; so fix up the
- // translation so that that point didn't move.
- e->PointForceTo(p);
SS.MarkGroupDirtyByEntity(e->h);
}
} else {
UpdateDraggedPoint(*he, x, y);
SS.MarkGroupDirtyByEntity(*he);
}
- orig.mouse = mp;
}
+ orig.mouse = mp;
break;
case Pending::DRAGGING_NEW_CUBIC_POINT: {
SK.GetEntity(circle->distance)->DistanceForceTo(r);
SS.MarkGroupDirtyByEntity(pending.circle);
+ SS.ScheduleShowTW();
break;
}
}
if(pending.operation == Pending::DRAGGING_NEW_LINE_POINT ||
- pending.operation == Pending::DRAGGING_NEW_CUBIC_POINT)
+ pending.operation == Pending::DRAGGING_NEW_CUBIC_POINT ||
+ pending.operation == Pending::DRAGGING_NEW_ARC_POINT ||
+ pending.operation == Pending::DRAGGING_NEW_RADIUS ||
+ pending.operation == Pending::DRAGGING_NEW_POINT
+ )
{
// Special case; use a right click to stop drawing lines, since
// a left click would draw another one. This is quicker and more
- // intuitive than hitting escape. Likewise for new cubic segments.
+ // intuitive than hitting escape. Likewise for other entities
+ // for consistency.
ClearPending();
return;
}
if(gs.points == 1) {
Entity *p = SK.GetEntity(gs.point[0]);
- Constraint *c;
+ Constraint *c = nullptr;
IdList<Constraint,hConstraint> *lc = &(SK.constraint);
- for(c = lc->First(); c; c = lc->NextAfter(c)) {
- if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
- if(c->ptA == p->h || c->ptB == p->h) {
+ for(Constraint &ci : *lc) {
+ if(ci.type != Constraint::Type::POINTS_COINCIDENT) continue;
+ if(ci.ptA == p->h || ci.ptB == p->h) {
+ c = &ci;
break;
}
}
SS.UndoRemember();
SK.constraint.ClearTags();
- Constraint *c;
- for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
- if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
- if(c->ptA == p->h || c->ptB == p->h) {
- c->tag = 1;
+ for(Constraint &c : SK.constraint) {
+ if(c.type != Constraint::Type::POINTS_COINCIDENT) continue;
+ if(c.ptA == p->h || c.ptB == p->h) {
+ c.tag = 1;
}
}
SK.constraint.RemoveTagged();
break;
case MouseEvent::Type::SCROLL_VERT:
- this->MouseScroll(event.x, event.y, event.shiftDown ? event.scrollDelta / 10 : event.scrollDelta);
+ this->MouseScroll(event.shiftDown ? event.scrollDelta / 10 : event.scrollDelta);
break;
case MouseEvent::Type::LEAVE:
ConstrainPointByHovered(hr.entity(1), &mouse);
ClearSuper();
+ AddToPending(hr);
pending.operation = Pending::DRAGGING_NEW_RADIUS;
pending.circle = hr.entity(0);
void GraphicsWindow::MouseLeftUp(double mx, double my, bool shiftDown, bool ctrlDown) {
orig.mouseDown = false;
- hoverWasSelectedOnMousedown = false;
switch(pending.operation) {
case Pending::DRAGGING_POINTS:
- SS.extraLine.draw = false;
- // fall through
case Pending::DRAGGING_CONSTRAINT:
case Pending::DRAGGING_NORMAL:
case Pending::DRAGGING_RADIUS:
+ if(!hoverWasSelectedOnMousedown) {
+ // And then clear the selection again, since they
+ // probably didn't want that selected if they just
+ // were dragging it.
+ ClearSelection();
+ }
+ hoverWasSelectedOnMousedown = false;
+ SS.extraLine.draw = false;
ClearPending();
Invalidate();
break;
value /= 2;
// Try showing value with default number of digits after decimal first.
- if(c->type == Constraint::Type::LENGTH_RATIO) {
+ if(c->type == Constraint::Type::LENGTH_RATIO || c->type == Constraint::Type::ARC_ARC_LEN_RATIO || c->type == Constraint::Type::ARC_LINE_LEN_RATIO) {
editValue = ssprintf("%.3f", value);
} else if(c->type == Constraint::Type::ANGLE) {
editValue = SS.DegreeToString(value);
} else {
- editValue = SS.MmToString(value);
+ editValue = SS.MmToString(value, true);
value /= SS.MmPerUnit();
}
// If that's not enough to represent it exactly, show the value with as many
case Constraint::Type::PT_LINE_DISTANCE:
case Constraint::Type::PT_FACE_DISTANCE:
case Constraint::Type::PT_PLANE_DISTANCE:
- case Constraint::Type::LENGTH_DIFFERENCE: {
+ case Constraint::Type::LENGTH_DIFFERENCE:
+ case Constraint::Type::ARC_ARC_DIFFERENCE:
+ case Constraint::Type::ARC_LINE_DIFFERENCE: {
// The sign is not displayed to the user, but this is a signed
// distance internally. To flip the sign, the user enters a
// negative distance.
}
case Constraint::Type::ANGLE:
case Constraint::Type::LENGTH_RATIO:
+ case Constraint::Type::ARC_ARC_LEN_RATIO:
+ case Constraint::Type::ARC_LINE_LEN_RATIO:
// These don't get the units conversion for distance, and
// they're always positive
c->valA = fabs(e->Eval());
}
}
-void GraphicsWindow::MouseScroll(double x, double y, double delta) {
- double offsetRight = offset.Dot(projRight);
- double offsetUp = offset.Dot(projUp);
-
- double righti = x/scale - offsetRight;
- double upi = y/scale - offsetUp;
-
- // The default zoom factor is 1.2x for one scroll wheel click (delta==1).
+void GraphicsWindow::MouseScroll(double zoomMultiplyer) {
// To support smooth scrolling where scroll wheel events come in increments
// smaller (or larger) than 1 we do:
- // scale *= exp(ln(1.2) * delta);
+ // scale *= exp(ln(1.2) * zoomMultiplyer);
// to ensure that the same total scroll delta always results in the same
// total zoom irrespective of in how many increments the zoom was applied.
// For example if we scroll a total delta of a+b in two events vs. one then
// while
// scale * a * b != scale * (a+b)
// So this constant is ln(1.2) = 0.1823216 to make the default zoom 1.2x
- scale *= exp(0.1823216 * delta);
-
- double rightf = x/scale - offsetRight;
- double upf = y/scale - offsetUp;
-
- offset = offset.Plus(projRight.ScaledBy(rightf - righti));
- offset = offset.Plus(projUp.ScaledBy(upf - upi));
-
- if(SS.TW.shown.screen == TextWindow::Screen::EDIT_VIEW) {
- if(havePainted) {
- SS.ScheduleShowTW();
- }
- }
- havePainted = false;
- Invalidate();
+ ZoomToMouse(zoomMultiplyer);
}
void GraphicsWindow::MouseLeave() {
// Copyright 2016 whitequark
//-----------------------------------------------------------------------------
#include "solvespace.h"
+#include "config.h"
static void ShowUsage(const std::string &cmd) {
fprintf(stderr, "Usage: %s <command> <options> <filename> [filename...]", cmd.c_str());
Whether to export the background colour in vector formats. Defaults to off.
Commands:
+ version
+ Prints the current solvespace version.
thumbnail --output <pattern> --size <size> --view <direction>
[--chord-tol <tolerance>]
Outputs a rendered view of the sketch, like the SolveSpace GUI would.
};
unsigned width = 0, height = 0;
- if(args[1] == "thumbnail") {
+ if(args[1] == "version") {
+ fprintf(stderr, "SolveSpace version %s \n\n", PACKAGE_VERSION);
+ return false;
+ } else if(args[1] == "thumbnail") {
auto ParseSize = [&](size_t &argn) {
if(argn + 1 < args.size() && args[argn] == "--size") {
argn++;
};
std::vector<FileFilter> SolveSpaceLinkFileFilters = {
+ { CN_("file-type", "ALL"), { "slvs", "emn", "stl" } },
{ CN_("file-type", "SolveSpace models"), { "slvs" } },
{ CN_("file-type", "IDF circuit board"), { "emn" } },
+ { CN_("file-type", "STL triangle mesh"), { "stl" } },
};
std::vector<FileFilter> RasterFileFilters = {
#ifndef SOLVESPACE_GUI_H
#define SOLVESPACE_GUI_H
+namespace SolveSpace {
class RgbaColor;
namespace Platform {
void ClearGui();
}
+} // namespace SolveSpace
#endif
#if defined(HAVE_SPACEWARE)
# include <spnav.h>
-# include <gdk/gdkx.h>
+# include <gdk/gdk.h>
+# if defined(GDK_WINDOWING_X11)
+# include <gdk/gdkx.h>
+# endif
+# if defined(GDK_WINDOWING_WAYLAND)
+# include <gdk/gdkwayland.h>
+# endif
+# if GTK_CHECK_VERSION(3, 20, 0)
+# include <gdkmm/seat.h>
+# else
+# include <gdkmm/devicemanager.h>
+# endif
#endif
#include "solvespace.h"
}
return false;
};
+ // Note: asan warnings about new-delete-type-mismatch are false positives here:
+ // https://gitlab.gnome.org/GNOME/gtkmm/-/issues/65
+ // Pass new_delete_type_mismatch=0 to ASAN_OPTIONS to disable those warnings.
+ // Unfortunately they won't go away until upgrading to gtkmm4
_connection = Glib::signal_timeout().connect(handler, milliseconds);
}
};
}
void SetCursor(Cursor cursor) override {
- Gdk::CursorType gdkCursorType;
+ std::string cursor_name;
switch(cursor) {
- case Cursor::POINTER: gdkCursorType = Gdk::ARROW; break;
- case Cursor::HAND: gdkCursorType = Gdk::HAND1; break;
+ case Cursor::POINTER: cursor_name = "default"; break;
+ case Cursor::HAND: cursor_name = "pointer"; break;
default: ssassert(false, "Unexpected cursor");
}
auto gdkWindow = gtkWindow.get_gl_widget().get_window();
if(gdkWindow) {
- gdkWindow->set_cursor(Gdk::Cursor::create(gdkCursorType));
+ gdkWindow->set_cursor(Gdk::Cursor::create(gdkWindow->get_display(), cursor_name.c_str()));
+// gdkWindow->get_display()
}
}
void Open3DConnexion() {}
void Close3DConnexion() {}
-#if defined(HAVE_SPACEWARE) && defined(GDK_WINDOWING_X11)
-static GdkFilterReturn GdkSpnavFilter(GdkXEvent *gdkXEvent, GdkEvent *gdkEvent, gpointer data) {
- XEvent *xEvent = (XEvent *)gdkXEvent;
- WindowImplGtk *window = (WindowImplGtk *)data;
-
- spnav_event spnavEvent;
- if(!spnav_x11_event(xEvent, &spnavEvent)) {
- return GDK_FILTER_CONTINUE;
- }
-
+#if defined(HAVE_SPACEWARE) && (defined(GDK_WINDOWING_X11) || defined(GDK_WINDOWING_WAYLAND))
+static void ProcessSpnavEvent(WindowImplGtk *window, const spnav_event &spnavEvent, bool shiftDown, bool controlDown) {
switch(spnavEvent.type) {
case SPNAV_EVENT_MOTION: {
SixDofEvent event = {};
event.rotationX = (double)spnavEvent.motion.rx * 0.001;
event.rotationY = (double)spnavEvent.motion.ry * 0.001;
event.rotationZ = (double)spnavEvent.motion.rz * -0.001;
- event.shiftDown = xEvent->xmotion.state & ShiftMask;
- event.controlDown = xEvent->xmotion.state & ControlMask;
+ event.shiftDown = shiftDown;
+ event.controlDown = controlDown;
if(window->onSixDofEvent) {
window->onSixDofEvent(event);
}
}
switch(spnavEvent.button.bnum) {
case 0: event.button = SixDofEvent::Button::FIT; break;
- default: return GDK_FILTER_REMOVE;
+ default: return;
}
- event.shiftDown = xEvent->xmotion.state & ShiftMask;
- event.controlDown = xEvent->xmotion.state & ControlMask;
+ event.shiftDown = shiftDown;
+ event.controlDown = controlDown;
if(window->onSixDofEvent) {
window->onSixDofEvent(event);
}
break;
}
+}
+
+static GdkFilterReturn GdkSpnavFilter(GdkXEvent *gdkXEvent, GdkEvent *gdkEvent, gpointer data) {
+ XEvent *xEvent = (XEvent *)gdkXEvent;
+ WindowImplGtk *window = (WindowImplGtk *)data;
+ bool shiftDown = (xEvent->xmotion.state & ShiftMask) != 0;
+ bool controlDown = (xEvent->xmotion.state & ControlMask) != 0;
+
+ spnav_event spnavEvent;
+ if(spnav_x11_event(xEvent, &spnavEvent)) {
+ ProcessSpnavEvent(window, spnavEvent, shiftDown, controlDown);
+ return GDK_FILTER_REMOVE;
+ }
+ return GDK_FILTER_CONTINUE;
+}
+
+static gboolean ConsumeSpnavQueue(GIOChannel *, GIOCondition, gpointer data) {
+ WindowImplGtk *window = (WindowImplGtk *)data;
+ Glib::RefPtr<Gdk::Window> gdkWindow = window->gtkWindow.get_window();
+
+ // We don't get modifier state through the socket.
+ int x, y;
+ Gdk::ModifierType mask{};
+#if GTK_CHECK_VERSION(3, 20, 0)
+ Glib::RefPtr<Gdk::Device> device = gdkWindow->get_display()->get_default_seat()->get_pointer();
+#else
+ Glib::RefPtr<Gdk::Device> device = gdkWindow->get_display()->get_device_manager()->get_client_pointer();
+#endif
+ gdkWindow->get_device_position(device, x, y, mask);
+ bool shiftDown = (mask & Gdk::SHIFT_MASK) != 0;
+ bool controlDown = (mask & Gdk::CONTROL_MASK) != 0;
- return GDK_FILTER_REMOVE;
+ spnav_event spnavEvent;
+ while(spnav_poll_event(&spnavEvent)) {
+ ProcessSpnavEvent(window, spnavEvent, shiftDown, controlDown);
+ }
+ return TRUE;
}
void Request3DConnexionEventsForWindow(WindowRef window) {
std::static_pointer_cast<WindowImplGtk>(window);
Glib::RefPtr<Gdk::Window> gdkWindow = windowImpl->gtkWindow.get_window();
+#if defined(GDK_WINDOWING_X11)
if(GDK_IS_X11_DISPLAY(gdkWindow->get_display()->gobj())) {
- gdkWindow->add_filter(GdkSpnavFilter, windowImpl.get());
- spnav_x11_open(gdk_x11_get_default_xdisplay(),
- gdk_x11_window_get_xid(gdkWindow->gobj()));
+ if(spnav_x11_open(gdk_x11_get_default_xdisplay(),
+ gdk_x11_window_get_xid(gdkWindow->gobj())) != -1) {
+ gdkWindow->add_filter(GdkSpnavFilter, windowImpl.get());
+ } else if(spnav_open() != -1) {
+ g_io_add_watch(g_io_channel_unix_new(spnav_fd()), G_IO_IN,
+ ConsumeSpnavQueue, windowImpl.get());
+ }
+ }
+#endif
+#if defined(GDK_WINDOWING_WAYLAND)
+ if(GDK_IS_WAYLAND_DISPLAY(gdkWindow->get_display()->gobj())) {
+ if(spnav_open() != -1) {
+ g_io_add_watch(g_io_channel_unix_new(spnav_fd()), G_IO_IN,
+ ConsumeSpnavQueue, windowImpl.get());
+ }
}
+#endif
+
}
#else
void Request3DConnexionEventsForWindow(WindowRef window) {}
}
}
+//TODO: This is not getting called when the extension selection is changed.
void FilterChanged() {
std::string extension = GetExtension();
if(extension.empty())
return;
Platform::Path path = GetFilename();
- SetCurrentName(path.WithExtension(extension).FileName());
+ if(gtkChooser->get_action() != Gtk::FILE_CHOOSER_ACTION_OPEN) {
+ SetCurrentName(path.WithExtension(extension).FileName());
+ }
}
void FreezeChoices(SettingsRef settings, const std::string &key) override {
}
void PopUp() override {
- [NSMenu popUpContextMenu:nsMenu withEvent:[NSApp currentEvent] forView:nil];
+ NSEvent* event = [NSApp currentEvent];
+ [NSMenu popUpContextMenu:nsMenu withEvent:event forView:event.window.contentView];
}
void Clear() override {
- (void)didEdit:(NSString *)text;
@property double scrollerMin;
-@property double scrollerMax;
+@property double scrollerSize;
+@property double pageSize;
+
@end
@implementation SSView
{
NSTrackingArea *trackingArea;
NSTextField *editor;
+ double magnificationGestureCurrentZ;
+ double rotationGestureCurrent;
+ Point2d trackpadPositionShift;
+ bool inTrackpadScrollGesture;
+ Platform::Window::Kind kind;
}
@synthesize acceptsFirstResponder;
-- (id)initWithFrame:(NSRect)frameRect {
+- (id)initWithKind:(Platform::Window::Kind)aKind {
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
0
};
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
- if(self = [super initWithFrame:frameRect pixelFormat:pixelFormat]) {
+ if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat:pixelFormat]) {
self.wantsBestResolutionOpenGLSurface = YES;
self.wantsLayer = YES;
editor = [[NSTextField alloc] init];
editor.bezeled = NO;
editor.target = self;
editor.action = @selector(didEdit:);
+
+ inTrackpadScrollGesture = false;
+ kind = aKind;
+ if(kind == Platform::Window::Kind::TOPLEVEL) {
+ NSGestureRecognizer *mag = [[NSMagnificationGestureRecognizer alloc] initWithTarget:self
+ action:@selector(magnifyGesture:)];
+ [self addGestureRecognizer:mag];
+
+ NSRotationGestureRecognizer* rot = [[NSRotationGestureRecognizer alloc] initWithTarget:self
+ action:@selector(rotateGesture:)];
+ [self addGestureRecognizer:rot];
+ }
}
return self;
}
- (Platform::MouseEvent)convertMouseEvent:(NSEvent *)nsEvent {
Platform::MouseEvent event = {};
- NSPoint nsPoint = [self convertPoint:nsEvent.locationInWindow fromView:self];
+ NSPoint nsPoint = [self convertPoint:nsEvent.locationInWindow fromView:nil];
event.x = nsPoint.x;
- event.y = self.bounds.size.height - nsPoint.y;
+ event.y = nsPoint.y;
NSUInteger nsFlags = [nsEvent modifierFlags];
if(nsFlags & NSEventModifierFlagShift) event.shiftDown = true;
using Platform::MouseEvent;
MouseEvent event = [self convertMouseEvent:nsEvent];
+ if(nsEvent.subtype == NSEventSubtypeTabletPoint && kind == Platform::Window::Kind::TOPLEVEL) {
+ // This is how Cocoa represents 2 finger trackpad drag gestures, rather than going via
+ // NSPanGestureRecognizer which is how you might expect this to work... We complicate this
+ // further by also handling shift-two-finger-drag to mean rotate. Fortunately we're using
+ // shift in the same way as right-mouse-button MouseEvent does (to converts a pan to a
+ // rotate) so we get the rotate support for free. It's a bit ugly having to fake mouse
+ // events and track the deviation from the actual mouse cursor with trackpadPositionShift,
+ // but in lieu of an event API that allows us to request a rotate/pan with relative
+ // coordinates, it's the best we can do.
+ event.button = MouseEvent::Button::RIGHT;
+ // Make sure control (actually cmd) isn't passed through, ctrl-right-click-drag has special
+ // meaning as rotate which we don't want to inadvertently trigger.
+ event.controlDown = false;
+ if(nsEvent.scrollingDeltaX == 0 && nsEvent.scrollingDeltaY == 0) {
+ // Cocoa represents the point where the user lifts their fingers off (and any inertial
+ // scrolling has finished) by an event with scrollingDeltaX and scrollingDeltaY both 0.
+ // Sometimes you also get a zero scroll at the start of a two-finger-rotate (probably
+ // reflecting the internal implementation of that being a cancelled possible pan
+ // gesture), which is why this conditional is structured the way it is.
+ if(inTrackpadScrollGesture) {
+ event.x += trackpadPositionShift.x;
+ event.y += trackpadPositionShift.y;
+ event.type = MouseEvent::Type::RELEASE;
+ receiver->onMouseEvent(event);
+ inTrackpadScrollGesture = false;
+ trackpadPositionShift = Point2d::From(0, 0);
+ }
+ return;
+ } else if(!inTrackpadScrollGesture) {
+ inTrackpadScrollGesture = true;
+ trackpadPositionShift = Point2d::From(0, 0);
+ event.type = MouseEvent::Type::PRESS;
+ receiver->onMouseEvent(event);
+ // And drop through
+ }
+
+ trackpadPositionShift.x += nsEvent.scrollingDeltaX;
+ trackpadPositionShift.y += nsEvent.scrollingDeltaY;
+ event.type = MouseEvent::Type::MOTION;
+ event.x += trackpadPositionShift.x;
+ event.y += trackpadPositionShift.y;
+ receiver->onMouseEvent(event);
+ return;
+ }
+
event.type = MouseEvent::Type::SCROLL_VERT;
bool isPrecise = [nsEvent hasPreciseScrollingDeltas];
event.scrollDelta = [nsEvent scrollingDeltaY] / (isPrecise ? 50 : 5);
- if(receiver->onMouseEvent) {
- receiver->onMouseEvent(event);
- }
+ receiver->onMouseEvent(event);
}
- (void)mouseExited:(NSEvent *)nsEvent {
[super keyUp:nsEvent];
}
+- (void)magnifyGesture:(NSMagnificationGestureRecognizer *)gesture {
+ // The onSixDofEvent API doesn't allow us to specify the scaling's origin, so for expediency
+ // we fake out a scrollwheel MouseEvent with a suitably-scaled scrollDelta with a bit of
+ // absolute-to-relative positioning conversion tracked using magnificationGestureCurrentZ.
+
+ if(gesture.state == NSGestureRecognizerStateBegan) {
+ magnificationGestureCurrentZ = 0.0;
+ }
+
+ // Magic number to make gesture.magnification align roughly with what scrollDelta expects
+ constexpr double kScale = 10.0;
+ double z = ((double)gesture.magnification * kScale);
+ double zdelta = z - magnificationGestureCurrentZ;
+ magnificationGestureCurrentZ = z;
+
+ using Platform::MouseEvent;
+ MouseEvent event = {};
+ event.type = MouseEvent::Type::SCROLL_VERT;
+ NSPoint nsPoint = [gesture locationInView:self];
+ event.x = nsPoint.x;
+ event.y = nsPoint.y;
+ event.scrollDelta = zdelta;
+ if(receiver->onMouseEvent) {
+ receiver->onMouseEvent(event);
+ }
+}
+
+- (void)rotateGesture:(NSRotationGestureRecognizer *)gesture {
+ if(gesture.state == NSGestureRecognizerStateBegan) {
+ rotationGestureCurrent = 0.0;
+ }
+ double rotation = gesture.rotation;
+ double rotationDelta = rotation - rotationGestureCurrent;
+ rotationGestureCurrent = rotation;
+
+ using Platform::SixDofEvent;
+ SixDofEvent event = {};
+ event.type = SixDofEvent::Type::MOTION;
+ event.rotationZ = rotationDelta;
+ if(receiver->onSixDofEvent) {
+ receiver->onSixDofEvent(event);
+ }
+}
+
@synthesize editing;
- (void)startEditing:(NSString *)text at:(NSPoint)origin withHeight:(double)fontHeight
}
@synthesize scrollerMin;
-@synthesize scrollerMax;
+@synthesize scrollerSize;
+@synthesize pageSize;
- (void)didScroll:(NSScroller *)sender {
+ double pos;
+ switch(sender.hitPart) {
+ case NSScrollerKnob:
+ case NSScrollerKnobSlot:
+ pos = receiver->GetScrollbarPosition();
+ break;
+ case NSScrollerDecrementPage:
+ pos = receiver->GetScrollbarPosition() - pageSize;
+ break;
+ case NSScrollerIncrementPage:
+ pos = receiver->GetScrollbarPosition() + pageSize;
+ break;
+ default:
+ return;
+ }
+
if(receiver->onScrollbarAdjusted) {
- double pos = scrollerMin + [sender doubleValue] * (scrollerMax - scrollerMin);
receiver->onScrollbarAdjusted(pos);
}
}
NSString *nsToolTip;
WindowImplCocoa(Window::Kind kind, std::shared_ptr<WindowImplCocoa> parentWindow) {
- ssView = [[SSView alloc] init];
+ ssView = [[SSView alloc] initWithKind:kind];
ssView.translatesAutoresizingMaskIntoConstraints = NO;
ssView.receiver = this;
void ConfigureScrollbar(double min, double max, double pageSize) override {
ssView.scrollerMin = min;
- ssView.scrollerMax = max - pageSize;
- [nsScroller setKnobProportion:(pageSize / (ssView.scrollerMax - ssView.scrollerMin))];
+ ssView.scrollerSize = max + 1 - min;
+ ssView.pageSize = pageSize;
+ nsScroller.knobProportion = pageSize / ssView.scrollerSize;
+ nsScroller.hidden = pageSize >= ssView.scrollerSize;
}
double GetScrollbarPosition() override {
+ // Platform::Window scrollbar positions are in the range [min, max+1 - pageSize] inclusive,
+ // and Cocoa scrollbars are from 0.0 to 1.0 inclusive, so we have to apply some scaling and
+ // transforming. (scrollerSize is max+1-min, see ConfigureScrollbar above)
return ssView.scrollerMin +
- [nsScroller doubleValue] * (ssView.scrollerMax - ssView.scrollerMin);
+ nsScroller.doubleValue * (ssView.scrollerSize - ssView.pageSize);
}
void SetScrollbarPosition(double pos) override {
- if(pos > ssView.scrollerMax)
- pos = ssView.scrollerMax;
- if(GetScrollbarPosition() == pos)
- return;
- [nsScroller setDoubleValue:(pos / (ssView.scrollerMax - ssView.scrollerMin))];
+ nsScroller.doubleValue = (pos - ssView.scrollerMin) / ( ssView.scrollerSize - ssView.pageSize);
}
void Invalidate() override {
- (IBAction)preferences:(id)sender;
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+
+@property BOOL exiting;
+
@end
@implementation SSApplicationDelegate
+
+@synthesize exiting;
+
+- (id)init {
+ if (self = [super init]) {
+ self.exiting = false;
+ }
+ return self;
+}
+
- (IBAction)preferences:(id)sender {
if (!SS.GW.showTextWindow) {
SolveSpace::SS.GW.MenuView(SolveSpace::Command::SHOW_TEXT_WND);
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
- [[[NSApp mainWindow] delegate] windowShouldClose:[NSApp mainWindow]];
- return NSTerminateCancel;
+ if(!SS.unsaved) {
+ return NSTerminateNow;
+ } else {
+ [self performSelectorOnMainThread:@selector(applicationTerminatePrompt) withObject:nil
+ waitUntilDone:NO modes:@[NSDefaultRunLoopMode, NSModalPanelRunLoopMode]];
+ return NSTerminateLater;
+ }
+}
+
+- (void)applicationWillTerminate:(NSNotification *)notification {
+ if(!exiting) {
+ // Prevent the Platform::ExitGui() call from SolveSpaceUI::Exit()
+ // triggering another terminate
+ exiting = true;
+ // Now let SS save settings etc
+ SS.Exit();
+ }
}
- (void)applicationTerminatePrompt {
- SolveSpace::SS.MenuFile(SolveSpace::Command::EXIT);
+ [NSApp replyToApplicationShouldTerminate:SS.OkayToStartNewFile()];
}
@end
ssDelegate = [[SSApplicationDelegate alloc] init];
NSApplication.sharedApplication.delegate = ssDelegate;
+ // Setting this prevents "Show Tab Bar" and "Show All Tabs" items from being
+ // automagically added to the View menu
+ NSWindow.allowsAutomaticWindowTabbing = NO;
+
+ // And this prevents the duplicate "Enter Full Screen" menu item, see
+ // https://stackoverflow.com/questions/52154977/how-to-get-rid-of-enter-full-screen-menu-item
+ [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];
+
[NSBundle.mainBundle loadNibNamed:@"MainMenu" owner:nil topLevelObjects:nil];
NSArray *languages = NSLocale.preferredLanguages;
}
void ExitGui() {
- [NSApp setDelegate:nil];
- [NSApp terminate:nil];
+ if(!ssDelegate.exiting) {
+ ssDelegate.exiting = true;
+ [NSApp terminate:nil];
+ }
}
void ClearGui() {}
return newLabel;
}
-static int Clamp(int x, int a, int b) {
+static int Clamp(int x, int a, int b, int brda, int brdb) {
+ // If we are outside of an edge of the monitor
+ // and a "border" is requested "move in" from that edge
+ // by "b/brdX" (the "b" parameter is the resolution)
+ if((x <= a) && (brda)) {
+ a += b / brda; // yes "b/brda" since b is the size
+ }
+
+ if(((x >= b) && brdb)) {
+ b -= b / brdb;
+ }
+
return max(a, min(x, b));
}
return 0;
}
} else if(wParam == VK_ESCAPE) {
- sscheck(SendMessageW(hWindow, msg, wParam, lParam));
+ window->HideEditor();
return 0;
}
}
sscheck(GetMonitorInfo(MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST), &mi));
// If it somehow ended up off-screen, then put it back.
+ // and make it visible by at least this portion of the screen
+ const LONG movein = 40;
+
RECT mrc = mi.rcMonitor;
- rc.left = Clamp(rc.left, mrc.left, mrc.right);
- rc.right = Clamp(rc.right, mrc.left, mrc.right);
- rc.top = Clamp(rc.top, mrc.top, mrc.bottom);
- rc.bottom = Clamp(rc.bottom, mrc.top, mrc.bottom);
+ rc.left = Clamp(rc.left, mrc.left, mrc.right, 0, movein);
+ rc.right = Clamp(rc.right, mrc.left, mrc.right, movein, 0);
+ rc.top = Clamp(rc.top, mrc.top, mrc.bottom, 0, movein);
+ rc.bottom = Clamp(rc.bottom, mrc.top, mrc.bottom, movein, 0);
// And make sure the minimum size is respected. (We can freeze a size smaller
// than minimum size if the DPI changed between runs.)
ofn.nMaxFile = sizeof(filenameWC) / sizeof(wchar_t);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT;
- if(isSaveDialog) {
- SetTitle(C_("title", "Save File"));
- } else {
- SetTitle(C_("title", "Open File"));
- }
}
void SetTitle(std::string title) override {
}
bool RunModal() override {
- if(GetFilename().IsEmpty()) {
- SetFilename(Path::From(_("untitled")));
- }
-
if(isSaveDialog) {
+ SetTitle(C_("title", "Save File"));
+ if(GetFilename().IsEmpty()) {
+ SetFilename(Path::From(_("untitled")));
+ }
return GetSaveFileNameW(&ofn) == TRUE;
} else {
+ SetTitle(C_("title", "Open File"));
return GetOpenFileNameW(&ofn) == TRUE;
}
}
#ifndef SOLVESPACE_PLATFORM_H
#define SOLVESPACE_PLATFORM_H
+namespace SolveSpace {
namespace Platform {
// UTF-8 ⟷ UTF-16 conversion, for Windows.
void *AllocTemporary(size_t size);
void FreeAllTemporary();
-}
+} // namespace Platform
+} // namespace SolveSpace
#endif
void SurfaceRenderer::DrawPixmap(std::shared_ptr<const Pixmap> pm,
const Vector &o, const Vector &u, const Vector &v,
const Point2d &ta, const Point2d &tb, hFill hcf) {
- ssassert(false, "Not implemented");
+ dbp("Not implemented");
}
void SurfaceRenderer::InvalidatePixmap(std::shared_ptr<const Pixmap> pm) {
- ssassert(false, "Not implemented");
+ dbp("Not implemented");
}
//-----------------------------------------------------------------------------
static std::shared_ptr<Pixmap> ReadPngIntoPixmap(png_struct *png_ptr, png_info *info_ptr,
bool flip) {
- png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL);
+ png_read_png(png_ptr, info_ptr,
+ PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_SCALE_16, NULL);
std::shared_ptr<Pixmap> pixmap = std::make_shared<Pixmap>();
pixmap->width = png_get_image_width(png_ptr, info_ptr);
// Find the hex representation in the (sorted) Unifont file.
auto first = unifontData.cbegin(),
last = unifontData.cend();
- while(first <= last) {
+ while(first < last) {
auto mid = first + (last - first) / 2;
while(mid != unifontData.cbegin()) {
if(*mid == '\n') {
if(foundCodepoint < codepoint) {
first = mid + 1;
while(first != unifontData.cend()) {
- if(*first == '\n') break;
+ if(*first == '\n') {
+ first++;
+ break;
+ }
first++;
}
continue; // and last stays the same
#ifndef SOLVESPACE_RESOURCE_H
#define SOLVESPACE_RESOURCE_H
+#include <functional>
+#include <map>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace SolveSpace {
+
class Camera;
class Point2d;
class Pixmap;
class Vector;
class RgbaColor;
+namespace Platform {
+ class Path;
+} // namespace Platform
std::string LoadString(const std::string &name);
std::string LoadStringFromGzip(const std::string &name);
const std::function<void(Vector, Vector)> &traceEdge, const Camera &camera);
};
+}
#endif
bool suppress;
bool relaxConstraints;
bool allowRedundant;
+ bool suppressDofCalculation;
bool allDimsReference;
double scale;
// For drawings in 2d
WORKPLANE_BY_POINT_ORTHO = 6000,
WORKPLANE_BY_LINE_SEGMENTS = 6001,
+ WORKPLANE_BY_POINT_NORMAL = 6002,
+ //WORKPLANE_BY_POINT_FACE = 6003,
+ //WORKPLANE_BY_FACE = 6004,
// For extrudes, translates, and rotates
ONE_SIDED = 7000,
TWO_SIDED = 7001
void Generate(EntityList *entity, ParamList *param);
bool IsSolvedOkay();
void TransformImportedBy(Vector t, Quaternion q);
+ bool IsTriangleMeshAssembly() const;
bool IsForcedToMeshBySource() const;
bool IsForcedToMesh() const;
// When a request generates entities from entities, and the source
void DrawPolyError(Canvas *canvas);
void DrawFilledPaths(Canvas *canvas);
void DrawContourAreaLabels(Canvas *canvas);
+ bool ShouldDrawExploded() const;
SPolygon GetPolygon();
std::string font;
Platform::Path file;
double aspectRatio;
+ int groupRequestIndex;
static hParam AddParam(ParamList *param, hParam hp);
void Generate(EntityList *entity, ParamList *param);
beziers.l.Clear();
edges.l.Clear();
}
+
+ bool ShouldDrawExploded() const;
+ Vector ExplodeOffset() const;
+ Vector PointGetDrawNum() const;
};
class EntReqTable {
bool free;
// Used only in the solver
- hParam substd;
+ Param *substd;
static const hParam NO_PARAM;
CURVE_CURVE_TANGENT = 125,
EQUAL_RADIUS = 130,
WHERE_DRAGGED = 200,
-
+ ARC_ARC_LEN_RATIO = 210,
+ ARC_LINE_LEN_RATIO = 211,
+ ARC_ARC_DIFFERENCE = 212,
+ ARC_LINE_DIFFERENCE = 213,
COMMENT = 1000
};
Vector p0, Vector p1, Vector pt, double salient);
void DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs,
Vector a0, Vector da, Vector b0, Vector db,
- Vector offset, Vector *ref, bool trim);
+ Vector offset, Vector *ref, bool trim, Vector explodeOffset);
void DoArrow(Canvas *canvas, Canvas::hStroke hcs,
Vector p, Vector dir, Vector n, double width, double angle, double da);
void DoLineWithArrows(Canvas *canvas, Canvas::hStroke hcs,
std::string DescriptionString() const;
+ bool ShouldDrawExploded() const;
+
static hConstraint AddConstraint(Constraint *c, bool rememberForUndo = true);
static void MenuConstrain(Command id);
static void DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA);
static hConstraint TryConstrain(Constraint::Type type, hEntity ptA, hEntity ptB,
hEntity entityA, hEntity entityB = Entity::NO_ENTITY,
bool other = false, bool other2 = false);
- static void ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc);
- static void ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic);
- static void ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB);
+ static bool ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc);
+ static bool ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic);
+ static bool ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB);
};
class hEquation {
RgbaColor color;
double width;
int zIndex;
+ bool exportable;
+ StipplePattern stippleType;
} Default;
static const Default Defaults[];
static std::string CnfColor(const std::string &prefix);
static std::string CnfWidth(const std::string &prefix);
+ static std::string CnfStippleType(const std::string &prefix);
+ static std::string CnfStippleScale(const std::string &prefix);
static std::string CnfTextHeight(const std::string &prefix);
static std::string CnfPrefixToName(const std::string &prefix);
+ static std::string CnfExportable(const std::string &prefix);
static void CreateAllDefaultStyles();
static void CreateDefaultStyle(hStyle h);
static bool Exportable(int hs);
static hStyle ForEntity(hEntity he);
static StipplePattern PatternType(hStyle hs);
+ static double StippleScale(hStyle hs);
static double StippleScaleMm(hStyle hs);
+ static std::string StipplePatternName(hStyle hs);
+ static std::string StipplePatternName(StipplePattern stippleType);
+ static StipplePattern StipplePatternFromString(std::string name);
std::string DescriptionString() const;
Platform::SettingsRef settings = Platform::GetSettings();
SS.tangentArcRadius = 10.0;
+ SS.explodeDistance = 1.0;
// Then, load the registry settings.
// Default list of colors for the model material
exportCanvas.dy = settings->ThawFloat("ExportCanvas_Dy", 5.0);
// Extra parameters when exporting G code
gCode.depth = settings->ThawFloat("GCode_Depth", 10.0);
+ gCode.safeHeight = settings->ThawFloat("GCode_SafeHeight", 5.0);
gCode.passes = settings->ThawInt("GCode_Passes", 1);
gCode.feed = settings->ThawFloat("GCode_Feed", 10.0);
gCode.plungeFeed = settings->ThawFloat("GCode_PlungeFeed", 10.0);
double SolveSpaceUI::MmPerUnit() {
switch(viewUnits) {
case Unit::INCHES: return 25.4;
+ case Unit::FEET_INCHES: return 25.4; // The 'unit' is still inches
case Unit::METERS: return 1000.0;
case Unit::MM: return 1.0;
}
const char *SolveSpaceUI::UnitName() {
switch(viewUnits) {
case Unit::INCHES: return "in";
+ case Unit::FEET_INCHES: return "in";
case Unit::METERS: return "m";
case Unit::MM: return "mm";
}
return "";
}
-std::string SolveSpaceUI::MmToString(double v) {
+std::string SolveSpaceUI::MmToString(double v, bool editable) {
v /= MmPerUnit();
+ // The syntax 2' 6" for feet and inches is not something we can (currently)
+ // parse back from a string so if editable is true, we treat FEET_INCHES the
+ // same as INCHES and just return the unadorned decimal number of inches.
+ if(viewUnits == Unit::FEET_INCHES && !editable) {
+ // Now convert v from inches to 64'ths of an inch, to make rounding easier.
+ v = floor((v + (1.0 / 128.0)) * 64.0);
+ int feet = (int)(v / (12.0 * 64.0));
+ v = v - (feet * 12.0 * 64.0);
+ // v is now the feet-less remainder in 1/64 inches
+ int inches = (int)(v / 64.0);
+ int numerator = (int)(v - ((double)inches * 64.0));
+ int denominator = 64;
+ // Divide down to smallest denominator where the numerator is still a whole number
+ while ((numerator != 0) && ((numerator & 1) == 0)) {
+ numerator /= 2;
+ denominator /= 2;
+ }
+ std::ostringstream str;
+ if(feet != 0) {
+ str << feet << "'-";
+ }
+ // For something like 0.5, show 1/2" rather than 0 1/2"
+ if(!(feet == 0 && inches == 0 && numerator != 0)) {
+ str << inches;
+ }
+ if(numerator != 0) {
+ str << " " << numerator << "/" << denominator;
+ }
+ str << "\"";
+ return str.str();
+ }
+
int digits = UnitDigitsAfterDecimal();
double minimum = 0.5 * pow(10,-digits);
while ((v < minimum) && (v > LENGTH_EPS)) {
}
static std::pair<int, std::string> SelectSIPrefixMm(int ord, int dim) {
// decide what units to use depending on the order of magnitude of the
-// measure in meters and the dimmension (1,2,3 lenear, area, volume)
+// measure in meters and the dimension (1,2,3 lenear, area, volume)
switch(dim) {
case 0:
case 1:
default:
dbp ("dimensions over 3 not supported");
break;
- }
+ }
return {0, "m"};
}
static std::pair<int, std::string> SelectSIPrefixInch(int deg) {
dim = 1;
}
- v /= pow((viewUnits == Unit::INCHES) ? 25.4 : 1000, dim);
+ bool inches = (viewUnits == Unit::INCHES) || (viewUnits == Unit::FEET_INCHES);
+ v /= pow(inches ? 25.4 : 1000, dim);
int vdeg = (int)(log10(fabs(v)));
std::string unit;
if(fabs(v) > 0.0) {
int sdeg = 0;
std::tie(sdeg, unit) =
- (viewUnits == Unit::INCHES)
+ inches
? SelectSIPrefixInch(vdeg/dim)
: SelectSIPrefixMm(vdeg, dim);
v /= pow(10.0, sdeg * dim);
}
+ if(viewUnits == Unit::FEET_INCHES && fabs(v) > pow(12.0, dim)) {
+ unit = "ft";
+ v /= pow(12.0, dim);
+ }
int pdeg = (int)ceil(log10(fabs(v) + 1e-10));
return ssprintf("%.*g%s%s%s", pdeg + UnitDigitsAfterDecimal(), v,
compact ? "" : " ", unit.c_str(), DimToString(dim));
return maxSegments;
}
int SolveSpaceUI::UnitDigitsAfterDecimal() {
- return (viewUnits == Unit::INCHES) ? afterDecimalInch : afterDecimalMm;
+ return (viewUnits == Unit::INCHES || viewUnits == Unit::FEET_INCHES) ?
+ afterDecimalInch : afterDecimalMm;
}
void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) {
- if(viewUnits == Unit::INCHES) {
+ if(viewUnits == Unit::INCHES || viewUnits == Unit::FEET_INCHES) {
afterDecimalInch = v;
} else {
afterDecimalMm = v;
SS.TW.stepDim.isDistance =
(c->type != Constraint::Type::ANGLE) &&
(c->type != Constraint::Type::LENGTH_RATIO) &&
- (c->type != Constraint::Type::LENGTH_DIFFERENCE);
+ (c->type != Constraint::Type::ARC_ARC_LEN_RATIO) &&
+ (c->type != Constraint::Type::ARC_LINE_LEN_RATIO) &&
+ (c->type != Constraint::Type::LENGTH_DIFFERENCE) &&
+ (c->type != Constraint::Type::ARC_ARC_DIFFERENCE) &&
+ (c->type != Constraint::Type::ARC_LINE_DIFFERENCE) ;
SS.TW.shown.constraint = c->h;
SS.TW.shown.screen = TextWindow::Screen::STEP_DIMENSION;
"law. For details, visit http://gnu.org/licenses/\n"
"\n"
"© 2008-%d Jonathan Westhues and other authors.\n"),
-PACKAGE_VERSION, 2021);
+PACKAGE_VERSION, 2022);
+ break;
+
+ case Command::GITHUB:
+ Platform::OpenInBrowser(GIT_HASH_URL);
break;
default: ssassert(false, "Unexpected menu ID");
GW.showGridMenuItem = NULL;
GW.dimSolidModelMenuItem = NULL;
GW.perspectiveProjMenuItem = NULL;
+ GW.explodeMenuItem = NULL;
GW.showToolbarMenuItem = NULL;
GW.showTextWndMenuItem = NULL;
GW.fullScreenMenuItem = NULL;
GW.unitsMmMenuItem = NULL;
GW.unitsMetersMenuItem = NULL;
GW.unitsInchesMenuItem = NULL;
+ GW.unitsFeetInchesMenuItem = NULL;
GW.inWorkplaneMenuItem = NULL;
GW.in3dMenuItem = NULL;
GW.undoMenuItem = NULL;
#ifndef SOLVESPACE_H
#define SOLVESPACE_H
+#include "resource.h"
+#include "platform/platform.h"
+#include "platform/gui.h"
+
#include <cctype>
#include <climits>
#include <cmath>
#include <unordered_set>
#include <vector>
+#define EIGEN_NO_DEBUG
+#undef Success
+#include <Eigen/SparseCore>
+
// We declare these in advance instead of simply using FT_Library
// (defined as typedef FT_LibraryRec_* FT_Library) because including
// freetype.h invokes indescribable horrors and we would like to avoid
static constexpr double VERY_POSITIVE = 1e10;
static constexpr double VERY_NEGATIVE = -1e10;
-#include "platform/platform.h"
-#include "platform/gui.h"
-#include "resource.h"
using Platform::AllocTemporary;
using Platform::FreeAllTemporary;
enum class Unit : uint32_t {
MM = 0,
INCHES,
- METERS
+ METERS,
+ FEET_INCHES
};
template<class Key, class T>
class System {
public:
- enum { MAX_UNKNOWNS = 1024 };
+ enum { MAX_UNKNOWNS = 2048 };
EntityList entity;
ParamList param;
// The system Jacobian matrix
struct {
// The corresponding equation for each row
- hEquation eq[MAX_UNKNOWNS];
+ std::vector<Equation *> eq;
// The corresponding parameter for each column
- hParam param[MAX_UNKNOWNS];
+ std::vector<hParam> param;
// We're solving AX = B
int m, n;
struct {
- Expr *sym[MAX_UNKNOWNS][MAX_UNKNOWNS];
- double num[MAX_UNKNOWNS][MAX_UNKNOWNS];
- } A;
-
- double scale[MAX_UNKNOWNS];
-
- // Some helpers for the least squares solve
- double AAt[MAX_UNKNOWNS][MAX_UNKNOWNS];
- double Z[MAX_UNKNOWNS];
+ // This only observes the Expr - does not own them!
+ Eigen::SparseMatrix<Expr *> sym;
+ Eigen::SparseMatrix<double> num;
+ } A;
- double X[MAX_UNKNOWNS];
+ Eigen::VectorXd scale;
+ Eigen::VectorXd X;
struct {
- Expr *sym[MAX_UNKNOWNS];
- double num[MAX_UNKNOWNS];
- } B;
+ // This only observes the Expr - does not own them!
+ std::vector<Expr *> sym;
+ Eigen::VectorXd num;
+ } B;
} mat;
- static const double RANK_MAG_TOLERANCE, CONVERGE_TOLERANCE;
+ static const double CONVERGE_TOLERANCE;
int CalculateRank();
- bool TestRank(int *rank = NULL);
- static bool SolveLinearSystem(double X[], double A[][MAX_UNKNOWNS],
- double B[], int N);
+ bool TestRank(int *dof = NULL);
+ static bool SolveLinearSystem(const Eigen::SparseMatrix<double> &A,
+ const Eigen::VectorXd &B, Eigen::VectorXd *X);
bool SolveLeastSquares();
bool WriteJacobian(int tag);
bool NewtonSolve(int tag);
void MarkParamsFree(bool findFree);
- int CalculateDof();
SolveResult Solve(Group *g, int *rank = NULL, int *dof = NULL,
List<hConstraint> *bad = NULL,
bool andFindBad = false, bool andFindFree = false);
void Clear();
+ Param *GetLastParamSubstitution(Param *p);
+ void SubstituteParamsByLast(Expr *e);
+ void SortSubstitutionByDragged(Param *p);
};
#include "ttf.h"
} exportCanvas;
struct {
double depth;
+ double safeHeight;
int passes;
double feed;
double plungeFeed;
int afterDecimalDegree;
bool useSIPrefixes;
int autosaveInterval; // in minutes
+ bool explode;
+ double explodeDistance;
- std::string MmToString(double v);
+ std::string MmToString(double v, bool editable=false);
std::string MmToStringSI(double v, int dim = 0);
std::string DegreeToString(double v);
double ExprToMm(Expr *e);
void ImportDxf(const Platform::Path &file);
void ImportDwg(const Platform::Path &file);
bool LinkIDF(const Platform::Path &filename, EntityList *le, SMesh *m, SShell *sh);
+bool LinkStl(const Platform::Path &filename, EntityList *le, SMesh *m, SShell *sh);
extern SolveSpaceUI SS;
extern Sketch SK;
}
}
-// We will be inserting other curve verticies into our curves to split them.
+// We will be inserting other curve vertices into our curves to split them.
// This is helpful when curved surfaces become tangent along a trim and the
// usual tests for curve-surface intersection don't split the curve at a vertex.
// This is faster than the previous version that split at surface corners and
SEdgeList inter = {};
SSurface *ss;
- SCurve *sc;
- for(sc = into->curve.First(); sc; sc = into->curve.NextAfter(sc)) {
- if(sc->source != SCurve::Source::INTERSECTION) continue;
+ for(SCurve &sc : into->curve) {
+ if(sc.source != SCurve::Source::INTERSECTION) continue;
if(opA) {
- if(sc->surfA != h) continue;
- ss = shb->surface.FindById(sc->surfB);
+ if(sc.surfA != h) continue;
+ ss = shb->surface.FindById(sc.surfB);
} else {
- if(sc->surfB != h) continue;
- ss = sha->surface.FindById(sc->surfA);
+ if(sc.surfB != h) continue;
+ ss = sha->surface.FindById(sc.surfA);
}
int i;
- for(i = 1; i < sc->pts.n; i++) {
- Vector a = sc->pts[i-1].p,
- b = sc->pts[i].p;
+ for(i = 1; i < sc.pts.n; i++) {
+ Vector a = sc.pts[i-1].p,
+ b = sc.pts[i].p;
Point2d auv, buv;
ss->ClosestPointTo(a, &(auv.x), &(auv.y));
bkwds = !bkwds;
}
if(bkwds) {
- inter.AddEdge(tb, ta, sc->h.v, 1);
+ inter.AddEdge(tb, ta, sc.h.v, 1);
} else {
- inter.AddEdge(ta, tb, sc->h.v, 0);
+ inter.AddEdge(ta, tb, sc.h.v, 0);
}
}
}
for(int i = 0; i< surface.n; i++) {
SSurface *sa = &surface[i];
- SSurface *sb;
- for(sb = agnst->surface.First(); sb; sb = agnst->surface.NextAfter(sb)){
+ for(SSurface &sb : agnst->surface){
// Intersect every surface from our shell against every surface
// from agnst; this will add zero or more curves to the curve
// list for into.
- sa->IntersectAgainst(sb, this, agnst, into);
+ sa->IntersectAgainst(&sb, this, agnst, into);
}
}
}
void SShell::CleanupAfterBoolean() {
- SSurface *ss;
- for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
- ss->edges.Clear();
+ for(SSurface &ss : surface) {
+ ss.edges.Clear();
}
}
// by their new IDs.
//-----------------------------------------------------------------------------
void SShell::RewriteSurfaceHandlesForCurves(SShell *a, SShell *b) {
- SCurve *sc;
- for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
- sc->surfA = sc->GetSurfaceA(a, b)->newH,
- sc->surfB = sc->GetSurfaceB(a, b)->newH;
+ for(SCurve &sc : curve) {
+ sc.surfA = sc.GetSurfaceA(a, b)->newH,
+ sc.surfB = sc.GetSurfaceB(a, b)->newH;
}
}
// First, copy over all the curves. Note which shell (a or b) each curve
// came from, but assign it a new ID.
curve.ReserveMore(a->curve.n + b->curve.n);
- SCurve *c, cn;
+ SCurve cn;
for(i = 0; i < 2; i++) {
ab = (i == 0) ? a : b;
- for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) {
- cn = SCurve::FromTransformationOf(c, t, q, 1.0);
+ for(SCurve &c : ab->curve) {
+ cn = SCurve::FromTransformationOf(&c, t, q, 1.0);
cn.source = (i == 0) ? SCurve::Source::A : SCurve::Source::B;
// surfA and surfB are wrong now, and we can't fix them until
// we've assigned IDs to the surfaces. So we'll get that later.
- c->newH = curve.AddAndAssignId(&cn);
+ c.newH = curve.AddAndAssignId(&cn);
}
}
// Likewise copy over all the surfaces.
surface.ReserveMore(a->surface.n + b->surface.n);
- SSurface *s, sn;
+ SSurface sn;
for(i = 0; i < 2; i++) {
ab = (i == 0) ? a : b;
- for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) {
- sn = SSurface::FromTransformationOf(s, t, q, 1.0, /*includingTrims=*/true);
+ for(SSurface &s : ab->surface) {
+ sn = SSurface::FromTransformationOf(&s, t, q, 1.0, /*includingTrims=*/true);
// All the trim curve IDs get rewritten; we know the new handles
// to the curves since we recorded them in the previous step.
STrimBy *stb;
for(stb = sn.trim.First(); stb; stb = sn.trim.NextAfter(stb)) {
stb->curve = ab->curve.FindById(stb->curve)->newH;
}
- s->newH = surface.AddAndAssignId(&sn);
+ s.newH = surface.AddAndAssignId(&sn);
}
}
b->MakeClassifyingBsps(NULL);
// Copy over all the original curves, splitting them so that a
- // piecwise linear segment never crosses a surface from the other
+ // piecewise linear segment never crosses a surface from the other
// shell.
a->CopyCurvesSplitAgainst(/*opA=*/true, b, this);
b->CopyCurvesSplitAgainst(/*opA=*/false, a, this);
// the surfaces in B (which is all of the intersection curves).
a->MakeIntersectionCurvesAgainst(b, this);
- SCurve *sc;
- for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
- SSurface *srfA = sc->GetSurfaceA(a, b),
- *srfB = sc->GetSurfaceB(a, b);
+ for(SCurve &sc : curve) {
+ SSurface *srfA = sc.GetSurfaceA(a, b),
+ *srfB = sc.GetSurfaceB(a, b);
- sc->RemoveShortSegments(srfA, srfB);
+ sc.RemoveShortSegments(srfA, srfB);
}
// And clean up the piecewise linear things we made as a calculation aid
continue;
}
- // if the curve is exact and points are >0.05 appart wrt t, point is there
+ // if the curve is exact and points are >0.05 apart wrt t, point is there
// deliberately regardless of chord tolerance (ex: small circles)
tprev = t = tnext = 0;
if (isExact) {
// All the references to this surface get replaced with the
// new srf
- SCurve *sc;
- for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
- if(sc->surfA == sj->h) sc->surfA = si->h;
- if(sc->surfB == sj->h) sc->surfB = si->h;
+ for(SCurve &sc : curve) {
+ if(sc.surfA == sj->h) sc.surfA = si->h;
+ if(sc.surfB == sj->h) sc.surfB = si->h;
}
}
List<SInter> *il,
bool asSegment, bool trimmed, bool inclTangent)
{
- SSurface *ss;
- for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
- ss->AllPointsIntersecting(a, b, il,
+ for(SSurface &ss : surface) {
+ ss.AllPointsIntersecting(a, b, il,
asSegment, trimmed, inclTangent);
}
}
// First, check for edge-on-edge
int edge_inters = 0;
Vector inter_surf_n[2], inter_edge_n[2];
- SSurface *srf;
- for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
- if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
+ for(SSurface &srf : surface) {
+ if(srf.LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
- SEdgeList *sel = &(srf->edges);
+ SEdgeList *sel = &(srf.edges);
SEdge *se;
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
if((ea.Equals(se->a) && eb.Equals(se->b)) ||
if(edge_inters < 2) {
// Edge-on-edge case
Point2d pm;
- srf->ClosestPointTo(p, &pm, /*mustConverge=*/false);
+ srf.ClosestPointTo(p, &pm, /*mustConverge=*/false);
// A vector normal to the surface, at the intersection point
- inter_surf_n[edge_inters] = srf->NormalAt(pm);
+ inter_surf_n[edge_inters] = srf.NormalAt(pm);
// A vector normal to the intersecting edge (but within the
// intersecting surface) at the intersection point, pointing
// out.
// are on surface) and for numerical stability, so we don't pick up
// the additional error from the line intersection.
- for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
- if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
+ for(SSurface &srf : surface) {
+ if(srf.LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
Point2d puv;
- srf->ClosestPointTo(p, &(puv.x), &(puv.y), /*mustConverge=*/false);
- Vector pp = srf->PointAt(puv);
+ srf.ClosestPointTo(p, &(puv.x), &(puv.y), /*mustConverge=*/false);
+ Vector pp = srf.PointAt(puv);
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
Point2d dummy = { 0, 0 };
- SBspUv::Class c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::Class::OUTSIDE;
+ SBspUv::Class c = (srf.bsp) ? srf.bsp->ClassifyPoint(puv, dummy, &srf) : SBspUv::Class::OUTSIDE;
if(c == SBspUv::Class::OUTSIDE) continue;
// Edge-on-face (unless edge-on-edge above superceded)
Point2d pin, pout;
- srf->ClosestPointTo(p.Plus(edge_n_in), &pin, /*mustConverge=*/false);
- srf->ClosestPointTo(p.Plus(edge_n_out), &pout, /*mustConverge=*/false);
+ srf.ClosestPointTo(p.Plus(edge_n_in), &pin, /*mustConverge=*/false);
+ srf.ClosestPointTo(p.Plus(edge_n_out), &pout, /*mustConverge=*/false);
- Vector surf_n_in = srf->NormalAt(pin),
- surf_n_out = srf->NormalAt(pout);
+ Vector surf_n_in = srf.NormalAt(pin),
+ surf_n_out = srf.NormalAt(pout);
*indir = ClassifyRegion(edge_n_in, surf_n_in, surf_n);
*outdir = ClassifyRegion(edge_n_out, surf_n_out, surf_n);
--- /dev/null
+//-----------------------------------------------------------------------------
+// Anything involving NURBS shells (i.e., shells); except
+// for the real math, which is in ratpoly.cpp.
+//
+// Copyright 2008-2013 Jonathan Westhues.
+//-----------------------------------------------------------------------------
+#include "../solvespace.h"
+
+typedef struct {
+ hSCurve hc;
+ hSSurface hs;
+} TrimLine;
+
+
+void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, RgbaColor color)
+{
+ // Make the extrusion direction consistent with respect to the normal
+ // of the sketch we're extruding.
+ if((t0.Minus(t1)).Dot(sbls->normal) < 0) {
+ swap(t0, t1);
+ }
+
+ // Define a coordinate system to contain the original sketch, and get
+ // a bounding box in that csys
+ Vector n = sbls->normal.ScaledBy(-1);
+ Vector u = n.Normal(0), v = n.Normal(1);
+ Vector orig = sbls->point;
+ double umax = VERY_NEGATIVE, umin = VERY_POSITIVE;
+ sbls->GetBoundingProjd(u, orig, &umin, &umax);
+ double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE;
+ sbls->GetBoundingProjd(v, orig, &vmin, &vmax);
+ // and now fix things up so that all u and v lie between 0 and 1
+ orig = orig.Plus(u.ScaledBy(umin));
+ orig = orig.Plus(v.ScaledBy(vmin));
+ u = u.ScaledBy(umax - umin);
+ v = v.ScaledBy(vmax - vmin);
+
+ // So we can now generate the top and bottom surfaces of the extrusion,
+ // planes within a translated (and maybe mirrored) version of that csys.
+ SSurface s0, s1;
+ s0 = SSurface::FromPlane(orig.Plus(t0), u, v);
+ s0.color = color;
+ s1 = SSurface::FromPlane(orig.Plus(t1).Plus(u), u.ScaledBy(-1), v);
+ s1.color = color;
+ hSSurface hs0 = surface.AddAndAssignId(&s0),
+ hs1 = surface.AddAndAssignId(&s1);
+
+ // Now go through the input curves. For each one, generate its surface
+ // of extrusion, its two translated trim curves, and one trim line. We
+ // go through by loops so that we can assign the lines correctly.
+ SBezierLoop *sbl;
+ for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
+ SBezier *sb;
+ List<TrimLine> trimLines = {};
+
+ for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
+ // Generate the surface of extrusion of this curve, and add
+ // it to the list
+ SSurface ss = SSurface::FromExtrusionOf(sb, t0, t1);
+ ss.color = color;
+ hSSurface hsext = surface.AddAndAssignId(&ss);
+
+ // Translate the curve by t0 and t1 to produce two trim curves
+ SCurve sc = {};
+ sc.isExact = true;
+ sc.exact = sb->TransformedBy(t0, Quaternion::IDENTITY, 1.0);
+ (sc.exact).MakePwlInto(&(sc.pts));
+ sc.surfA = hs0;
+ sc.surfB = hsext;
+ hSCurve hc0 = curve.AddAndAssignId(&sc);
+
+ sc = {};
+ sc.isExact = true;
+ sc.exact = sb->TransformedBy(t1, Quaternion::IDENTITY, 1.0);
+ (sc.exact).MakePwlInto(&(sc.pts));
+ sc.surfA = hs1;
+ sc.surfB = hsext;
+ hSCurve hc1 = curve.AddAndAssignId(&sc);
+
+ STrimBy stb0, stb1;
+ // The translated curves trim the flat top and bottom surfaces.
+ stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/false);
+ stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/true);
+ (surface.FindById(hs0))->trim.Add(&stb0);
+ (surface.FindById(hs1))->trim.Add(&stb1);
+
+ // The translated curves also trim the surface of extrusion.
+ stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/true);
+ stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/false);
+ (surface.FindById(hsext))->trim.Add(&stb0);
+ (surface.FindById(hsext))->trim.Add(&stb1);
+
+ // And form the trim line
+ Vector pt = sb->Finish();
+ sc = {};
+ sc.isExact = true;
+ sc.exact = SBezier::From(pt.Plus(t0), pt.Plus(t1));
+ (sc.exact).MakePwlInto(&(sc.pts));
+ hSCurve hl = curve.AddAndAssignId(&sc);
+ // save this for later
+ TrimLine tl;
+ tl.hc = hl;
+ tl.hs = hsext;
+ trimLines.Add(&tl);
+ }
+
+ int i;
+ for(i = 0; i < trimLines.n; i++) {
+ TrimLine *tl = &(trimLines[i]);
+ SSurface *ss = surface.FindById(tl->hs);
+
+ TrimLine *tlp = &(trimLines[WRAP(i-1, trimLines.n)]);
+
+ STrimBy stb;
+ stb = STrimBy::EntireCurve(this, tl->hc, /*backwards=*/true);
+ ss->trim.Add(&stb);
+ stb = STrimBy::EntireCurve(this, tlp->hc, /*backwards=*/false);
+ ss->trim.Add(&stb);
+
+ (curve.FindById(tl->hc))->surfA = ss->h;
+ (curve.FindById(tlp->hc))->surfB = ss->h;
+ }
+ trimLines.Clear();
+ }
+}
+
+bool SShell::CheckNormalAxisRelationship(SBezierLoopSet *sbls, Vector pt, Vector axis, double da, double dx)
+// Check that the direction of revolution/extrusion ends up parallel to the normal of
+// the sketch, on the side of the axis where the sketch is.
+{
+ SBezierLoop *sbl;
+ Vector pto;
+ double md = VERY_NEGATIVE;
+ for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
+ SBezier *sb;
+ for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
+ // Choose the point farthest from the axis; we'll get garbage
+ // if we choose a point that lies on the axis, for example.
+ // (And our surface will be self-intersecting if the sketch
+ // spans the axis, so don't worry about that.)
+ for(int i = 0; i <= sb->deg; i++) {
+ Vector p = sb->ctrl[i];
+ double d = p.DistanceToLine(pt, axis);
+ if(d > md) {
+ md = d;
+ pto = p;
+ }
+ }
+ }
+ }
+ Vector ptc = pto.ClosestPointOnLine(pt, axis),
+ up = axis.Cross(pto.Minus(ptc)).ScaledBy(da),
+ vp = up.Plus(axis.ScaledBy(dx));
+
+ return (vp.Dot(sbls->normal) > 0);
+}
+
+// sketch must not contain the axis of revolution as a non-construction line for helix
+void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
+ RgbaColor color, Group *group, double angles,
+ double anglef, double dists, double distf) {
+ int i0 = surface.n; // number of pre-existing surfaces
+ SBezierLoop *sbl;
+ // for testing - hard code the axial distance, and number of sections.
+ // distance will need to be parameters in the future.
+ double dist = distf - dists;
+ int sections = (int)(fabs(anglef - angles) / (PI / 2) + 1);
+ double wedge = (anglef - angles) / sections;
+ int startMapping = Group::REMAP_LATHE_START, endMapping = Group::REMAP_LATHE_END;
+
+ if(CheckNormalAxisRelationship(sbls, pt, axis, anglef-angles, distf-dists)) {
+ swap(angles, anglef);
+ swap(dists, distf);
+ dist = -dist;
+ wedge = -wedge;
+ swap(startMapping, endMapping);
+ }
+
+ // Define a coordinate system to contain the original sketch, and get
+ // a bounding box in that csys
+ Vector n = sbls->normal.ScaledBy(-1);
+ Vector u = n.Normal(0), v = n.Normal(1);
+ Vector orig = sbls->point;
+ double umax = VERY_NEGATIVE, umin = VERY_POSITIVE;
+ sbls->GetBoundingProjd(u, orig, &umin, &umax);
+ double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE;
+ sbls->GetBoundingProjd(v, orig, &vmin, &vmax);
+ // and now fix things up so that all u and v lie between 0 and 1
+ orig = orig.Plus(u.ScaledBy(umin));
+ orig = orig.Plus(v.ScaledBy(vmin));
+ u = u.ScaledBy(umax - umin);
+ v = v.ScaledBy(vmax - vmin);
+
+ // So we can now generate the end caps of the extrusion within
+ // a translated and rotated (and maybe mirrored) version of that csys.
+ SSurface s0, s1;
+ s0 = SSurface::FromPlane(orig.RotatedAbout(pt, axis, angles).Plus(axis.ScaledBy(dists)),
+ u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles));
+ s0.color = color;
+
+ hEntity face0 = group->Remap(Entity::NO_ENTITY, startMapping);
+ s0.face = face0.v;
+
+ s1 = SSurface::FromPlane(
+ orig.Plus(u).RotatedAbout(pt, axis, anglef).Plus(axis.ScaledBy(distf)),
+ u.ScaledBy(-1).RotatedAbout(axis, anglef), v.RotatedAbout(axis, anglef));
+ s1.color = color;
+
+ hEntity face1 = group->Remap(Entity::NO_ENTITY, endMapping);
+ s1.face = face1.v;
+
+ hSSurface hs0 = surface.AddAndAssignId(&s0);
+ hSSurface hs1 = surface.AddAndAssignId(&s1);
+
+ // Now we actually build and trim the swept surfaces. One loop at a time.
+ for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
+ int i, j;
+ SBezier *sb;
+ List<std::vector<hSSurface>> hsl = {};
+
+ // This is where all the NURBS are created and Remapped to the generating curve
+ for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
+ std::vector<hSSurface> revs(sections);
+ for(j = 0; j < sections; j++) {
+ if((dist == 0) && sb->deg == 1 &&
+ (sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
+ (sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS) {
+ // This is a line on the axis of revolution; it does
+ // not contribute a surface.
+ revs[j].v = 0;
+ } else {
+ SSurface ss = SSurface::FromRevolutionOf(
+ sb, pt, axis, angles + (wedge)*j, angles + (wedge) * (j + 1),
+ dists + j * dist / sections, dists + (j + 1) * dist / sections);
+ ss.color = color;
+ if(sb->entity != 0) {
+ hEntity he;
+ he.v = sb->entity;
+ hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE);
+ if(SK.entity.FindByIdNoOops(hface) != NULL) {
+ ss.face = hface.v;
+ }
+ }
+ revs[j] = surface.AddAndAssignId(&ss);
+ }
+ }
+ hsl.Add(&revs);
+ }
+ // Still the same loop. Need to create trim curves
+ for(i = 0; i < sbl->l.n; i++) {
+ std::vector<hSSurface> revs = hsl[i], revsp = hsl[WRAP(i - 1, sbl->l.n)];
+
+ sb = &(sbl->l[i]);
+
+ // we will need the grid t-values for this entire row of surfaces
+ List<double> t_values;
+ t_values = {};
+ if (revs[0].v) {
+ double ps = 0.0;
+ t_values.Add(&ps);
+ (surface.FindById(revs[0]))->MakeTriangulationGridInto(
+ &t_values, 0.0, 1.0, true, 0);
+ }
+ // we generate one more curve than we did surfaces
+ for(j = 0; j <= sections; j++) {
+ SCurve sc;
+ Quaternion qs = Quaternion::From(axis, angles + wedge * j);
+ // we want Q*(x - p) + p = Q*x + (p - Q*p)
+ Vector ts =
+ pt.Minus(qs.Rotate(pt)).Plus(axis.ScaledBy(dists + j * dist / sections));
+
+ // If this input curve generated a surface, then trim that
+ // surface with the rotated version of the input curve.
+ if(revs[0].v) { // not d[j] because crash on j==sections
+ sc = {};
+ sc.isExact = true;
+ sc.exact = sb->TransformedBy(ts, qs, 1.0);
+ // make the PWL for the curve based on t value list
+ for(int x = 0; x < t_values.n; x++) {
+ SCurvePt scpt;
+ scpt.tag = 0;
+ scpt.p = sc.exact.PointAt(t_values[x]);
+ scpt.vertex = (x == 0) || (x == (t_values.n - 1));
+ sc.pts.Add(&scpt);
+ }
+
+ // the surfaces already exists so trim with this curve
+ if(j < sections) {
+ sc.surfA = revs[j];
+ } else {
+ sc.surfA = hs1; // end cap
+ }
+
+ if(j > 0) {
+ sc.surfB = revs[j - 1];
+ } else {
+ sc.surfB = hs0; // staring cap
+ }
+
+ hSCurve hcb = curve.AddAndAssignId(&sc);
+
+ STrimBy stb;
+ stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
+ (surface.FindById(sc.surfA))->trim.Add(&stb);
+ stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
+ (surface.FindById(sc.surfB))->trim.Add(&stb);
+ } else if(j == 0) { // curve was on the rotation axis and is shared by the end caps.
+ sc = {};
+ sc.isExact = true;
+ sc.exact = sb->TransformedBy(ts, qs, 1.0);
+ (sc.exact).MakePwlInto(&(sc.pts));
+ sc.surfA = hs1; // end cap
+ sc.surfB = hs0; // staring cap
+ hSCurve hcb = curve.AddAndAssignId(&sc);
+
+ STrimBy stb;
+ stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
+ (surface.FindById(sc.surfA))->trim.Add(&stb);
+ stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
+ (surface.FindById(sc.surfB))->trim.Add(&stb);
+ }
+
+ // And if this input curve and the one after it both generated
+ // surfaces, then trim both of those by the appropriate
+ // curve based on the control points.
+ if((j < sections) && revs[j].v && revsp[j].v) {
+ SSurface *ss = surface.FindById(revs[j]);
+
+ sc = {};
+ sc.isExact = true;
+ sc.exact = SBezier::From(ss->ctrl[0][0], ss->ctrl[0][1], ss->ctrl[0][2]);
+ sc.exact.weight[1] = ss->weight[0][1];
+ double max_dt = 0.5;
+ if (sc.exact.deg > 1) max_dt = 0.125;
+ (sc.exact).MakePwlInto(&(sc.pts), 0.0, max_dt);
+ sc.surfA = revs[j];
+ sc.surfB = revsp[j];
+
+ hSCurve hcc = curve.AddAndAssignId(&sc);
+
+ STrimBy stb;
+ stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false);
+ (surface.FindById(sc.surfA))->trim.Add(&stb);
+ stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true);
+ (surface.FindById(sc.surfB))->trim.Add(&stb);
+ }
+ }
+ t_values.Clear();
+ }
+
+ hsl.Clear();
+ }
+
+ if(dist == 0) {
+ MakeFirstOrderRevolvedSurfaces(pt, axis, i0);
+ }
+}
+
+void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color,
+ Group *group) {
+ int i0 = surface.n; // number of pre-existing surfaces
+ SBezierLoop *sbl;
+
+ if(CheckNormalAxisRelationship(sbls, pt, axis, 1.0, 0.0)) {
+ axis = axis.ScaledBy(-1);
+ }
+
+ // Now we actually build and trim the surfaces.
+ for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
+ int i, j;
+ SBezier *sb;
+ List<std::vector<hSSurface>> hsl = {};
+
+ for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
+ std::vector<hSSurface> revs(4);
+ for(j = 0; j < 4; j++) {
+ if(sb->deg == 1 &&
+ (sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
+ (sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS)
+ {
+ // This is a line on the axis of revolution; it does
+ // not contribute a surface.
+ revs[j].v = 0;
+ } else {
+ SSurface ss = SSurface::FromRevolutionOf(sb, pt, axis, (PI / 2) * j,
+ (PI / 2) * (j + 1), 0.0, 0.0);
+ ss.color = color;
+ if(sb->entity != 0) {
+ hEntity he;
+ he.v = sb->entity;
+ hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE);
+ if(SK.entity.FindByIdNoOops(hface) != NULL) {
+ ss.face = hface.v;
+ }
+ }
+ revs[j] = surface.AddAndAssignId(&ss);
+ }
+ }
+ hsl.Add(&revs);
+ }
+
+ for(i = 0; i < sbl->l.n; i++) {
+ std::vector<hSSurface> revs = hsl[i],
+ revsp = hsl[WRAP(i-1, sbl->l.n)];
+
+ sb = &(sbl->l[i]);
+
+ for(j = 0; j < 4; j++) {
+ SCurve sc;
+ Quaternion qs = Quaternion::From(axis, (PI/2)*j);
+ // we want Q*(x - p) + p = Q*x + (p - Q*p)
+ Vector ts = pt.Minus(qs.Rotate(pt));
+
+ // If this input curve generate a surface, then trim that
+ // surface with the rotated version of the input curve.
+ if(revs[j].v) {
+ sc = {};
+ sc.isExact = true;
+ sc.exact = sb->TransformedBy(ts, qs, 1.0);
+ (sc.exact).MakePwlInto(&(sc.pts));
+ sc.surfA = revs[j];
+ sc.surfB = revs[WRAP(j-1, 4)];
+
+ hSCurve hcb = curve.AddAndAssignId(&sc);
+
+ STrimBy stb;
+ stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
+ (surface.FindById(sc.surfA))->trim.Add(&stb);
+ stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
+ (surface.FindById(sc.surfB))->trim.Add(&stb);
+ }
+
+ // And if this input curve and the one after it both generated
+ // surfaces, then trim both of those by the appropriate
+ // circle.
+ if(revs[j].v && revsp[j].v) {
+ SSurface *ss = surface.FindById(revs[j]);
+
+ sc = {};
+ sc.isExact = true;
+ sc.exact = SBezier::From(ss->ctrl[0][0],
+ ss->ctrl[0][1],
+ ss->ctrl[0][2]);
+ sc.exact.weight[1] = ss->weight[0][1];
+ (sc.exact).MakePwlInto(&(sc.pts));
+ sc.surfA = revs[j];
+ sc.surfB = revsp[j];
+
+ hSCurve hcc = curve.AddAndAssignId(&sc);
+
+ STrimBy stb;
+ stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false);
+ (surface.FindById(sc.surfA))->trim.Add(&stb);
+ stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true);
+ (surface.FindById(sc.surfB))->trim.Add(&stb);
+ }
+ }
+ }
+
+ hsl.Clear();
+ }
+
+ MakeFirstOrderRevolvedSurfaces(pt, axis, i0);
+}
+
+void SShell::MakeFirstOrderRevolvedSurfaces(Vector pt, Vector axis, int i0) {
+ int i;
+
+ for(i = i0; i < surface.n; i++) {
+ SSurface *srf = &(surface[i]);
+
+ // Revolution of a line; this is potentially a plane, which we can
+ // rewrite to have degree (1, 1).
+ if(srf->degm == 1 && srf->degn == 2) {
+ // close start, far start, far finish
+ Vector cs, fs, ff;
+ double d0, d1;
+ d0 = (srf->ctrl[0][0]).DistanceToLine(pt, axis);
+ d1 = (srf->ctrl[1][0]).DistanceToLine(pt, axis);
+
+ if(d0 > d1) {
+ cs = srf->ctrl[1][0];
+ fs = srf->ctrl[0][0];
+ ff = srf->ctrl[0][2];
+ } else {
+ cs = srf->ctrl[0][0];
+ fs = srf->ctrl[1][0];
+ ff = srf->ctrl[1][2];
+ }
+
+ // origin close, origin far
+ Vector oc = cs.ClosestPointOnLine(pt, axis),
+ of = fs.ClosestPointOnLine(pt, axis);
+
+ if(oc.Equals(of)) {
+ // This is a plane, not a (non-degenerate) cone.
+ Vector oldn = srf->NormalAt(0.5, 0.5);
+
+ Vector u = fs.Minus(of), v;
+
+ v = (axis.Cross(u)).WithMagnitude(1);
+
+ double vm = (ff.Minus(of)).Dot(v);
+ v = v.ScaledBy(vm);
+
+ srf->degm = 1;
+ srf->degn = 1;
+ srf->ctrl[0][0] = of;
+ srf->ctrl[0][1] = of.Plus(u);
+ srf->ctrl[1][0] = of.Plus(v);
+ srf->ctrl[1][1] = of.Plus(u).Plus(v);
+ srf->weight[0][0] = 1;
+ srf->weight[0][1] = 1;
+ srf->weight[1][0] = 1;
+ srf->weight[1][1] = 1;
+
+ if(oldn.Dot(srf->NormalAt(0.5, 0.5)) < 0) {
+ swap(srf->ctrl[0][0], srf->ctrl[1][0]);
+ swap(srf->ctrl[0][1], srf->ctrl[1][1]);
+ }
+ continue;
+ }
+
+ if(fabs(d0 - d1) < LENGTH_EPS) {
+ // This is a cylinder; so transpose it so that we'll recognize
+ // it as a surface of extrusion.
+ SSurface sn = *srf;
+
+ // Transposing u and v flips the normal, so reverse u to
+ // flip it again and put it back where we started.
+ sn.degm = 2;
+ sn.degn = 1;
+ int dm, dn;
+ for(dm = 0; dm <= 1; dm++) {
+ for(dn = 0; dn <= 2; dn++) {
+ sn.ctrl [dn][dm] = srf->ctrl [1-dm][dn];
+ sn.weight[dn][dm] = srf->weight[1-dm][dn];
+ }
+ }
+
+ *srf = sn;
+ continue;
+ }
+ }
+ }
+}
+
+void SShell::MakeFromCopyOf(SShell *a) {
+ ssassert(this != a, "Can't make from copy of self");
+ MakeFromTransformationOf(a,
+ Vector::From(0, 0, 0), Quaternion::IDENTITY, 1.0);
+}
+
+void SShell::MakeFromTransformationOf(SShell *a,
+ Vector t, Quaternion q, double scale)
+{
+ booleanFailed = false;
+ surface.ReserveMore(a->surface.n);
+ for(SSurface &s : a->surface) {
+ SSurface n;
+ n = SSurface::FromTransformationOf(&s, t, q, scale, /*includingTrims=*/true);
+ surface.Add(&n); // keeping the old ID
+ }
+
+ curve.ReserveMore(a->curve.n);
+ for(SCurve &c : a->curve) {
+ SCurve n;
+ n = SCurve::FromTransformationOf(&c, t, q, scale);
+ curve.Add(&n); // keeping the old ID
+ }
+}
+
+void SShell::MakeEdgesInto(SEdgeList *sel) {
+ for(SSurface &s : surface) {
+ s.MakeEdgesInto(this, sel, SSurface::MakeAs::XYZ);
+ }
+}
+
+void SShell::MakeSectionEdgesInto(Vector n, double d, SEdgeList *sel, SBezierList *sbl)
+{
+ for(SSurface &s : surface) {
+ if(s.CoincidentWithPlane(n, d)) {
+ s.MakeSectionEdgesInto(this, sel, sbl);
+ }
+ }
+}
+
+void SShell::TriangulateInto(SMesh *sm) {
+#pragma omp parallel for
+ for(int i=0; i<surface.n; i++) {
+ SSurface *s = &surface[i];
+ SMesh m;
+ s->TriangulateInto(this, &m);
+ #pragma omp critical
+ sm->MakeFromCopyOf(&m);
+ m.Clear();
+ }
+}
+
+bool SShell::IsEmpty() const {
+ return surface.IsEmpty();
+}
+
+void SShell::Clear() {
+ for(SSurface &s : surface) {
+ s.Clear();
+ }
+ surface.Clear();
+
+ for(SCurve &c : curve) {
+ c.Clear();
+ }
+ curve.Clear();
+}
trim.Clear();
}
-typedef struct {
- hSCurve hc;
- hSSurface hs;
-} TrimLine;
-void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, RgbaColor color)
-{
- // Make the extrusion direction consistent with respect to the normal
- // of the sketch we're extruding.
- if((t0.Minus(t1)).Dot(sbls->normal) < 0) {
- swap(t0, t1);
- }
-
- // Define a coordinate system to contain the original sketch, and get
- // a bounding box in that csys
- Vector n = sbls->normal.ScaledBy(-1);
- Vector u = n.Normal(0), v = n.Normal(1);
- Vector orig = sbls->point;
- double umax = VERY_NEGATIVE, umin = VERY_POSITIVE;
- sbls->GetBoundingProjd(u, orig, &umin, &umax);
- double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE;
- sbls->GetBoundingProjd(v, orig, &vmin, &vmax);
- // and now fix things up so that all u and v lie between 0 and 1
- orig = orig.Plus(u.ScaledBy(umin));
- orig = orig.Plus(v.ScaledBy(vmin));
- u = u.ScaledBy(umax - umin);
- v = v.ScaledBy(vmax - vmin);
-
- // So we can now generate the top and bottom surfaces of the extrusion,
- // planes within a translated (and maybe mirrored) version of that csys.
- SSurface s0, s1;
- s0 = SSurface::FromPlane(orig.Plus(t0), u, v);
- s0.color = color;
- s1 = SSurface::FromPlane(orig.Plus(t1).Plus(u), u.ScaledBy(-1), v);
- s1.color = color;
- hSSurface hs0 = surface.AddAndAssignId(&s0),
- hs1 = surface.AddAndAssignId(&s1);
-
- // Now go through the input curves. For each one, generate its surface
- // of extrusion, its two translated trim curves, and one trim line. We
- // go through by loops so that we can assign the lines correctly.
- SBezierLoop *sbl;
- for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
- SBezier *sb;
- List<TrimLine> trimLines = {};
-
- for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
- // Generate the surface of extrusion of this curve, and add
- // it to the list
- SSurface ss = SSurface::FromExtrusionOf(sb, t0, t1);
- ss.color = color;
- hSSurface hsext = surface.AddAndAssignId(&ss);
-
- // Translate the curve by t0 and t1 to produce two trim curves
- SCurve sc = {};
- sc.isExact = true;
- sc.exact = sb->TransformedBy(t0, Quaternion::IDENTITY, 1.0);
- (sc.exact).MakePwlInto(&(sc.pts));
- sc.surfA = hs0;
- sc.surfB = hsext;
- hSCurve hc0 = curve.AddAndAssignId(&sc);
-
- sc = {};
- sc.isExact = true;
- sc.exact = sb->TransformedBy(t1, Quaternion::IDENTITY, 1.0);
- (sc.exact).MakePwlInto(&(sc.pts));
- sc.surfA = hs1;
- sc.surfB = hsext;
- hSCurve hc1 = curve.AddAndAssignId(&sc);
-
- STrimBy stb0, stb1;
- // The translated curves trim the flat top and bottom surfaces.
- stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/false);
- stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/true);
- (surface.FindById(hs0))->trim.Add(&stb0);
- (surface.FindById(hs1))->trim.Add(&stb1);
-
- // The translated curves also trim the surface of extrusion.
- stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/true);
- stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/false);
- (surface.FindById(hsext))->trim.Add(&stb0);
- (surface.FindById(hsext))->trim.Add(&stb1);
-
- // And form the trim line
- Vector pt = sb->Finish();
- sc = {};
- sc.isExact = true;
- sc.exact = SBezier::From(pt.Plus(t0), pt.Plus(t1));
- (sc.exact).MakePwlInto(&(sc.pts));
- hSCurve hl = curve.AddAndAssignId(&sc);
- // save this for later
- TrimLine tl;
- tl.hc = hl;
- tl.hs = hsext;
- trimLines.Add(&tl);
- }
-
- int i;
- for(i = 0; i < trimLines.n; i++) {
- TrimLine *tl = &(trimLines[i]);
- SSurface *ss = surface.FindById(tl->hs);
-
- TrimLine *tlp = &(trimLines[WRAP(i-1, trimLines.n)]);
-
- STrimBy stb;
- stb = STrimBy::EntireCurve(this, tl->hc, /*backwards=*/true);
- ss->trim.Add(&stb);
- stb = STrimBy::EntireCurve(this, tlp->hc, /*backwards=*/false);
- ss->trim.Add(&stb);
-
- (curve.FindById(tl->hc))->surfA = ss->h;
- (curve.FindById(tlp->hc))->surfB = ss->h;
- }
- trimLines.Clear();
- }
-}
-
-bool SShell::CheckNormalAxisRelationship(SBezierLoopSet *sbls, Vector pt, Vector axis, double da, double dx)
-// Check that the direction of revolution/extrusion ends up parallel to the normal of
-// the sketch, on the side of the axis where the sketch is.
-{
- SBezierLoop *sbl;
- Vector pto;
- double md = VERY_NEGATIVE;
- for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
- SBezier *sb;
- for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
- // Choose the point farthest from the axis; we'll get garbage
- // if we choose a point that lies on the axis, for example.
- // (And our surface will be self-intersecting if the sketch
- // spans the axis, so don't worry about that.)
- for(int i = 0; i <= sb->deg; i++) {
- Vector p = sb->ctrl[i];
- double d = p.DistanceToLine(pt, axis);
- if(d > md) {
- md = d;
- pto = p;
- }
- }
- }
- }
- Vector ptc = pto.ClosestPointOnLine(pt, axis),
- up = axis.Cross(pto.Minus(ptc)).ScaledBy(da),
- vp = up.Plus(axis.ScaledBy(dx));
-
- return (vp.Dot(sbls->normal) > 0);
-}
-
-// sketch must not contain the axis of revolution as a non-construction line for helix
-void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
- RgbaColor color, Group *group, double angles,
- double anglef, double dists, double distf) {
- int i0 = surface.n; // number of pre-existing surfaces
- SBezierLoop *sbl;
- // for testing - hard code the axial distance, and number of sections.
- // distance will need to be parameters in the future.
- double dist = distf - dists;
- int sections = (int)(fabs(anglef - angles) / (PI / 2) + 1);
- double wedge = (anglef - angles) / sections;
- int startMapping = Group::REMAP_LATHE_START, endMapping = Group::REMAP_LATHE_END;
-
- if(CheckNormalAxisRelationship(sbls, pt, axis, anglef-angles, distf-dists)) {
- swap(angles, anglef);
- swap(dists, distf);
- dist = -dist;
- wedge = -wedge;
- swap(startMapping, endMapping);
- }
-
- // Define a coordinate system to contain the original sketch, and get
- // a bounding box in that csys
- Vector n = sbls->normal.ScaledBy(-1);
- Vector u = n.Normal(0), v = n.Normal(1);
- Vector orig = sbls->point;
- double umax = VERY_NEGATIVE, umin = VERY_POSITIVE;
- sbls->GetBoundingProjd(u, orig, &umin, &umax);
- double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE;
- sbls->GetBoundingProjd(v, orig, &vmin, &vmax);
- // and now fix things up so that all u and v lie between 0 and 1
- orig = orig.Plus(u.ScaledBy(umin));
- orig = orig.Plus(v.ScaledBy(vmin));
- u = u.ScaledBy(umax - umin);
- v = v.ScaledBy(vmax - vmin);
-
- // So we can now generate the end caps of the extrusion within
- // a translated and rotated (and maybe mirrored) version of that csys.
- SSurface s0, s1;
- s0 = SSurface::FromPlane(orig.RotatedAbout(pt, axis, angles).Plus(axis.ScaledBy(dists)),
- u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles));
- s0.color = color;
-
- hEntity face0 = group->Remap(Entity::NO_ENTITY, startMapping);
- s0.face = face0.v;
-
- s1 = SSurface::FromPlane(
- orig.Plus(u).RotatedAbout(pt, axis, anglef).Plus(axis.ScaledBy(distf)),
- u.ScaledBy(-1).RotatedAbout(axis, anglef), v.RotatedAbout(axis, anglef));
- s1.color = color;
-
- hEntity face1 = group->Remap(Entity::NO_ENTITY, endMapping);
- s1.face = face1.v;
-
- hSSurface hs0 = surface.AddAndAssignId(&s0);
- hSSurface hs1 = surface.AddAndAssignId(&s1);
-
- // Now we actually build and trim the swept surfaces. One loop at a time.
- for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
- int i, j;
- SBezier *sb;
- List<std::vector<hSSurface>> hsl = {};
-
- // This is where all the NURBS are created and Remapped to the generating curve
- for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
- std::vector<hSSurface> revs(sections);
- for(j = 0; j < sections; j++) {
- if((dist == 0) && sb->deg == 1 &&
- (sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
- (sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS) {
- // This is a line on the axis of revolution; it does
- // not contribute a surface.
- revs[j].v = 0;
- } else {
- SSurface ss = SSurface::FromRevolutionOf(
- sb, pt, axis, angles + (wedge)*j, angles + (wedge) * (j + 1),
- dists + j * dist / sections, dists + (j + 1) * dist / sections);
- ss.color = color;
- if(sb->entity != 0) {
- hEntity he;
- he.v = sb->entity;
- hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE);
- if(SK.entity.FindByIdNoOops(hface) != NULL) {
- ss.face = hface.v;
- }
- }
- revs[j] = surface.AddAndAssignId(&ss);
- }
- }
- hsl.Add(&revs);
- }
- // Still the same loop. Need to create trim curves
- for(i = 0; i < sbl->l.n; i++) {
- std::vector<hSSurface> revs = hsl[i], revsp = hsl[WRAP(i - 1, sbl->l.n)];
-
- sb = &(sbl->l[i]);
-
- // we will need the grid t-values for this entire row of surfaces
- List<double> t_values;
- t_values = {};
- if (revs[0].v) {
- double ps = 0.0;
- t_values.Add(&ps);
- (surface.FindById(revs[0]))->MakeTriangulationGridInto(
- &t_values, 0.0, 1.0, true, 0);
- }
- // we generate one more curve than we did surfaces
- for(j = 0; j <= sections; j++) {
- SCurve sc;
- Quaternion qs = Quaternion::From(axis, angles + wedge * j);
- // we want Q*(x - p) + p = Q*x + (p - Q*p)
- Vector ts =
- pt.Minus(qs.Rotate(pt)).Plus(axis.ScaledBy(dists + j * dist / sections));
-
- // If this input curve generated a surface, then trim that
- // surface with the rotated version of the input curve.
- if(revs[0].v) { // not d[j] because crash on j==sections
- sc = {};
- sc.isExact = true;
- sc.exact = sb->TransformedBy(ts, qs, 1.0);
- // make the PWL for the curve based on t value list
- for(int x = 0; x < t_values.n; x++) {
- SCurvePt scpt;
- scpt.tag = 0;
- scpt.p = sc.exact.PointAt(t_values[x]);
- scpt.vertex = (x == 0) || (x == (t_values.n - 1));
- sc.pts.Add(&scpt);
- }
-
- // the surfaces already exists so trim with this curve
- if(j < sections) {
- sc.surfA = revs[j];
- } else {
- sc.surfA = hs1; // end cap
- }
-
- if(j > 0) {
- sc.surfB = revs[j - 1];
- } else {
- sc.surfB = hs0; // staring cap
- }
-
- hSCurve hcb = curve.AddAndAssignId(&sc);
-
- STrimBy stb;
- stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
- (surface.FindById(sc.surfA))->trim.Add(&stb);
- stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
- (surface.FindById(sc.surfB))->trim.Add(&stb);
- } else if(j == 0) { // curve was on the rotation axis and is shared by the end caps.
- sc = {};
- sc.isExact = true;
- sc.exact = sb->TransformedBy(ts, qs, 1.0);
- (sc.exact).MakePwlInto(&(sc.pts));
- sc.surfA = hs1; // end cap
- sc.surfB = hs0; // staring cap
- hSCurve hcb = curve.AddAndAssignId(&sc);
-
- STrimBy stb;
- stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
- (surface.FindById(sc.surfA))->trim.Add(&stb);
- stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
- (surface.FindById(sc.surfB))->trim.Add(&stb);
- }
-
- // And if this input curve and the one after it both generated
- // surfaces, then trim both of those by the appropriate
- // curve based on the control points.
- if((j < sections) && revs[j].v && revsp[j].v) {
- SSurface *ss = surface.FindById(revs[j]);
-
- sc = {};
- sc.isExact = true;
- sc.exact = SBezier::From(ss->ctrl[0][0], ss->ctrl[0][1], ss->ctrl[0][2]);
- sc.exact.weight[1] = ss->weight[0][1];
- double max_dt = 0.5;
- if (sc.exact.deg > 1) max_dt = 0.125;
- (sc.exact).MakePwlInto(&(sc.pts), 0.0, max_dt);
- sc.surfA = revs[j];
- sc.surfB = revsp[j];
-
- hSCurve hcc = curve.AddAndAssignId(&sc);
-
- STrimBy stb;
- stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false);
- (surface.FindById(sc.surfA))->trim.Add(&stb);
- stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true);
- (surface.FindById(sc.surfB))->trim.Add(&stb);
- }
- }
- t_values.Clear();
- }
-
- hsl.Clear();
- }
-
- if(dist == 0) {
- MakeFirstOrderRevolvedSurfaces(pt, axis, i0);
- }
-}
-
-void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color,
- Group *group) {
- int i0 = surface.n; // number of pre-existing surfaces
- SBezierLoop *sbl;
-
- if(CheckNormalAxisRelationship(sbls, pt, axis, 1.0, 0.0)) {
- axis = axis.ScaledBy(-1);
- }
-
- // Now we actually build and trim the surfaces.
- for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
- int i, j;
- SBezier *sb;
- List<std::vector<hSSurface>> hsl = {};
-
- for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
- std::vector<hSSurface> revs(4);
- for(j = 0; j < 4; j++) {
- if(sb->deg == 1 &&
- (sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
- (sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS)
- {
- // This is a line on the axis of revolution; it does
- // not contribute a surface.
- revs[j].v = 0;
- } else {
- SSurface ss = SSurface::FromRevolutionOf(sb, pt, axis, (PI / 2) * j,
- (PI / 2) * (j + 1), 0.0, 0.0);
- ss.color = color;
- if(sb->entity != 0) {
- hEntity he;
- he.v = sb->entity;
- hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE);
- if(SK.entity.FindByIdNoOops(hface) != NULL) {
- ss.face = hface.v;
- }
- }
- revs[j] = surface.AddAndAssignId(&ss);
- }
- }
- hsl.Add(&revs);
- }
-
- for(i = 0; i < sbl->l.n; i++) {
- std::vector<hSSurface> revs = hsl[i],
- revsp = hsl[WRAP(i-1, sbl->l.n)];
-
- sb = &(sbl->l[i]);
-
- for(j = 0; j < 4; j++) {
- SCurve sc;
- Quaternion qs = Quaternion::From(axis, (PI/2)*j);
- // we want Q*(x - p) + p = Q*x + (p - Q*p)
- Vector ts = pt.Minus(qs.Rotate(pt));
-
- // If this input curve generate a surface, then trim that
- // surface with the rotated version of the input curve.
- if(revs[j].v) {
- sc = {};
- sc.isExact = true;
- sc.exact = sb->TransformedBy(ts, qs, 1.0);
- (sc.exact).MakePwlInto(&(sc.pts));
- sc.surfA = revs[j];
- sc.surfB = revs[WRAP(j-1, 4)];
-
- hSCurve hcb = curve.AddAndAssignId(&sc);
-
- STrimBy stb;
- stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
- (surface.FindById(sc.surfA))->trim.Add(&stb);
- stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
- (surface.FindById(sc.surfB))->trim.Add(&stb);
- }
-
- // And if this input curve and the one after it both generated
- // surfaces, then trim both of those by the appropriate
- // circle.
- if(revs[j].v && revsp[j].v) {
- SSurface *ss = surface.FindById(revs[j]);
-
- sc = {};
- sc.isExact = true;
- sc.exact = SBezier::From(ss->ctrl[0][0],
- ss->ctrl[0][1],
- ss->ctrl[0][2]);
- sc.exact.weight[1] = ss->weight[0][1];
- (sc.exact).MakePwlInto(&(sc.pts));
- sc.surfA = revs[j];
- sc.surfB = revsp[j];
-
- hSCurve hcc = curve.AddAndAssignId(&sc);
-
- STrimBy stb;
- stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false);
- (surface.FindById(sc.surfA))->trim.Add(&stb);
- stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true);
- (surface.FindById(sc.surfB))->trim.Add(&stb);
- }
- }
- }
-
- hsl.Clear();
- }
-
- MakeFirstOrderRevolvedSurfaces(pt, axis, i0);
-}
-
-void SShell::MakeFirstOrderRevolvedSurfaces(Vector pt, Vector axis, int i0) {
- int i;
-
- for(i = i0; i < surface.n; i++) {
- SSurface *srf = &(surface[i]);
-
- // Revolution of a line; this is potentially a plane, which we can
- // rewrite to have degree (1, 1).
- if(srf->degm == 1 && srf->degn == 2) {
- // close start, far start, far finish
- Vector cs, fs, ff;
- double d0, d1;
- d0 = (srf->ctrl[0][0]).DistanceToLine(pt, axis);
- d1 = (srf->ctrl[1][0]).DistanceToLine(pt, axis);
-
- if(d0 > d1) {
- cs = srf->ctrl[1][0];
- fs = srf->ctrl[0][0];
- ff = srf->ctrl[0][2];
- } else {
- cs = srf->ctrl[0][0];
- fs = srf->ctrl[1][0];
- ff = srf->ctrl[1][2];
- }
-
- // origin close, origin far
- Vector oc = cs.ClosestPointOnLine(pt, axis),
- of = fs.ClosestPointOnLine(pt, axis);
-
- if(oc.Equals(of)) {
- // This is a plane, not a (non-degenerate) cone.
- Vector oldn = srf->NormalAt(0.5, 0.5);
-
- Vector u = fs.Minus(of), v;
-
- v = (axis.Cross(u)).WithMagnitude(1);
-
- double vm = (ff.Minus(of)).Dot(v);
- v = v.ScaledBy(vm);
-
- srf->degm = 1;
- srf->degn = 1;
- srf->ctrl[0][0] = of;
- srf->ctrl[0][1] = of.Plus(u);
- srf->ctrl[1][0] = of.Plus(v);
- srf->ctrl[1][1] = of.Plus(u).Plus(v);
- srf->weight[0][0] = 1;
- srf->weight[0][1] = 1;
- srf->weight[1][0] = 1;
- srf->weight[1][1] = 1;
-
- if(oldn.Dot(srf->NormalAt(0.5, 0.5)) < 0) {
- swap(srf->ctrl[0][0], srf->ctrl[1][0]);
- swap(srf->ctrl[0][1], srf->ctrl[1][1]);
- }
- continue;
- }
-
- if(fabs(d0 - d1) < LENGTH_EPS) {
- // This is a cylinder; so transpose it so that we'll recognize
- // it as a surface of extrusion.
- SSurface sn = *srf;
-
- // Transposing u and v flips the normal, so reverse u to
- // flip it again and put it back where we started.
- sn.degm = 2;
- sn.degn = 1;
- int dm, dn;
- for(dm = 0; dm <= 1; dm++) {
- for(dn = 0; dn <= 2; dn++) {
- sn.ctrl [dn][dm] = srf->ctrl [1-dm][dn];
- sn.weight[dn][dm] = srf->weight[1-dm][dn];
- }
- }
-
- *srf = sn;
- continue;
- }
- }
- }
-}
-
-void SShell::MakeFromCopyOf(SShell *a) {
- ssassert(this != a, "Can't make from copy of self");
- MakeFromTransformationOf(a,
- Vector::From(0, 0, 0), Quaternion::IDENTITY, 1.0);
-}
-
-void SShell::MakeFromTransformationOf(SShell *a,
- Vector t, Quaternion q, double scale)
-{
- booleanFailed = false;
- surface.ReserveMore(a->surface.n);
- SSurface *s;
- for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) {
- SSurface n;
- n = SSurface::FromTransformationOf(s, t, q, scale, /*includingTrims=*/true);
- surface.Add(&n); // keeping the old ID
- }
-
- curve.ReserveMore(a->curve.n);
- SCurve *c;
- for(c = a->curve.First(); c; c = a->curve.NextAfter(c)) {
- SCurve n;
- n = SCurve::FromTransformationOf(c, t, q, scale);
- curve.Add(&n); // keeping the old ID
- }
-}
-
-void SShell::MakeEdgesInto(SEdgeList *sel) {
- SSurface *s;
- for(s = surface.First(); s; s = surface.NextAfter(s)) {
- s->MakeEdgesInto(this, sel, SSurface::MakeAs::XYZ);
- }
-}
-
-void SShell::MakeSectionEdgesInto(Vector n, double d, SEdgeList *sel, SBezierList *sbl)
-{
- SSurface *s;
- for(s = surface.First(); s; s = surface.NextAfter(s)) {
- if(s->CoincidentWithPlane(n, d)) {
- s->MakeSectionEdgesInto(this, sel, sbl);
- }
- }
-}
-
-void SShell::TriangulateInto(SMesh *sm) {
-#pragma omp parallel for
- for(int i=0; i<surface.n; i++) {
- SSurface *s = &surface[i];
- SMesh m;
- s->TriangulateInto(this, &m);
- #pragma omp critical
- sm->MakeFromCopyOf(&m);
- m.Clear();
- }
-}
-
-bool SShell::IsEmpty() const {
- return surface.IsEmpty();
-}
-
-void SShell::Clear() {
- SSurface *s;
- for(s = surface.First(); s; s = surface.NextAfter(s)) {
- s->Clear();
- }
- surface.Clear();
-
- SCurve *c;
- for(c = curve.First(); c; c = curve.NextAfter(c)) {
- c->Clear();
- }
- curve.Clear();
-}
// Now we have to piecewise linearize the curve. If there's already an
// identical curve in the shell, then follow that pwl exactly, otherwise
// calculate from scratch.
- SCurve split, *existing = NULL, *se;
+ SCurve split, *existing = NULL;
SBezier sbrev = *sb;
sbrev.Reverse();
bool backwards = false;
#pragma omp critical(into)
{
- for(se = into->curve.First(); se; se = into->curve.NextAfter(se)) {
- if(se->isExact) {
- if(sb->Equals(&(se->exact))) {
- existing = se;
+ for(SCurve &se : into->curve) {
+ if(se.isExact) {
+ if(sb->Equals(&(se.exact))) {
+ existing = &se;
break;
}
- if(sbrev.Equals(&(se->exact))) {
- existing = se;
+ if(sbrev.Equals(&(se.exact))) {
+ existing = &se;
backwards = true;
break;
}
shext = agnstA;
}
bool foundExact = false;
- SCurve *sc;
- for(sc = shext->curve.First(); sc; sc = shext->curve.NextAfter(sc)) {
- if(sc->source == SCurve::Source::INTERSECTION) continue;
- if(!sc->isExact) continue;
- if((sc->surfA != sext->h) && (sc->surfB != sext->h)) continue;
+ for(SCurve &sc : shext->curve) {
+ if(sc.source == SCurve::Source::INTERSECTION) continue;
+ if(!sc.isExact) continue;
+ if((sc.surfA != sext->h) && (sc.surfB != sext->h)) continue;
// we have a curve belonging to the curved surface and not the plane.
// does it lie completely in the plane?
- if(splane->ContainsPlaneCurve(sc)) {
- SBezier bezier = sc->exact;
+ if(splane->ContainsPlaneCurve(&sc)) {
+ SBezier bezier = sc.exact;
AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into);
foundExact = true;
}
void SShell::MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
SEdgeList *el, SShell *useCurvesFrom)
{
- SSurface *ss;
- for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
- if(proto->CoincidentWith(ss, sameNormal)) {
- ss->MakeEdgesInto(this, el, SSurface::MakeAs::XYZ, useCurvesFrom);
+ for(SSurface &ss : surface) {
+ if(proto->CoincidentWith(&ss, sameNormal)) {
+ ss.MakeEdgesInto(this, el, SSurface::MakeAs::XYZ, useCurvesFrom);
}
}
if (i == l.n-1) {
end = true;
}
- if (end) { // triangulate the fan and tag the verticies
+ if (end) { // triangulate the fan and tag the vertices
if (j > 3) {
Vector center = l[pstart+1].p.Plus(l[pstart+j-1].p).ScaledBy(0.5);
for (int x=0; x<j; x++) {
srf->MakeTriangulationGridInto(&lj, 0, 1, /*swapped=*/false, 0);
// force 2nd order grid to have at least 4 segments in each direction
- if ((li.n < 5) && (srf->degm>1)) { // 4 segments minimun
+ if ((li.n < 5) && (srf->degm>1)) { // 4 segments minimum
li.Clear();
li.Add(&v[0]);li.Add(&v[1]);li.Add(&v[2]);li.Add(&v[3]);li.Add(&v[4]);
}
- if ((lj.n < 5) && (srf->degn>1)) { // 4 segments minimun
+ if ((lj.n < 5) && (srf->degn>1)) { // 4 segments minimum
lj.Clear();
lj.Add(&v[0]);lj.Add(&v[1]);lj.Add(&v[2]);lj.Add(&v[3]);lj.Add(&v[4]);
}
if (!bottom[j]) // add our own bottom edge
holes.AddEdge(a, b);
} else {
- if (prev_flag) // add our left neighbots right edge
+ if (prev_flag) // add our left neighbors right edge
holes.AddEdge(a, d);
if (bottom[j]) // add our bottom neighbors top edge
holes.AddEdge(b, a);
#include "solvespace.h"
const Style::Default Style::Defaults[] = {
- { { ACTIVE_GRP }, "ActiveGrp", RGBf(1.0, 1.0, 1.0), 1.5, 4 },
- { { CONSTRUCTION }, "Construction", RGBf(0.1, 0.7, 0.1), 1.5, 0 },
- { { INACTIVE_GRP }, "InactiveGrp", RGBf(0.5, 0.3, 0.0), 1.5, 3 },
- { { DATUM }, "Datum", RGBf(0.0, 0.8, 0.0), 1.5, 0 },
- { { SOLID_EDGE }, "SolidEdge", RGBf(0.8, 0.8, 0.8), 1.0, 2 },
- { { CONSTRAINT }, "Constraint", RGBf(1.0, 0.1, 1.0), 1.0, 0 },
- { { SELECTED }, "Selected", RGBf(1.0, 0.0, 0.0), 1.5, 0 },
- { { HOVERED }, "Hovered", RGBf(1.0, 1.0, 0.0), 1.5, 0 },
- { { CONTOUR_FILL }, "ContourFill", RGBf(0.0, 0.1, 0.1), 1.0, 0 },
- { { NORMALS }, "Normals", RGBf(0.0, 0.4, 0.4), 1.0, 0 },
- { { ANALYZE }, "Analyze", RGBf(0.0, 1.0, 1.0), 3.0, 0 },
- { { DRAW_ERROR }, "DrawError", RGBf(1.0, 0.0, 0.0), 8.0, 0 },
- { { DIM_SOLID }, "DimSolid", RGBf(0.1, 0.1, 0.1), 1.0, 0 },
- { { HIDDEN_EDGE }, "HiddenEdge", RGBf(0.8, 0.8, 0.8), 1.0, 1 },
- { { OUTLINE }, "Outline", RGBf(0.8, 0.8, 0.8), 3.0, 5 },
- { { 0 }, NULL, RGBf(0.0, 0.0, 0.0), 0.0, 0 }
+ { { ACTIVE_GRP }, "ActiveGrp", RGBf(1.0, 1.0, 1.0), 1.5, 4, true, StipplePattern::CONTINUOUS },
+ { { CONSTRUCTION }, "Construction", RGBf(0.1, 0.7, 0.1), 1.5, 0, false, StipplePattern::CONTINUOUS },
+ { { INACTIVE_GRP }, "InactiveGrp", RGBf(0.5, 0.3, 0.0), 1.5, 3, true, StipplePattern::CONTINUOUS },
+ { { DATUM }, "Datum", RGBf(0.0, 0.8, 0.0), 1.5, 0, true, StipplePattern::CONTINUOUS },
+ { { SOLID_EDGE }, "SolidEdge", RGBf(0.8, 0.8, 0.8), 1.0, 2, true, StipplePattern::CONTINUOUS },
+ { { CONSTRAINT }, "Constraint", RGBf(1.0, 0.1, 1.0), 1.0, 0, true, StipplePattern::CONTINUOUS },
+ { { SELECTED }, "Selected", RGBf(1.0, 0.0, 0.0), 1.5, 0, true, StipplePattern::CONTINUOUS },
+ { { HOVERED }, "Hovered", RGBf(1.0, 1.0, 0.0), 1.5, 0, true, StipplePattern::CONTINUOUS },
+ { { CONTOUR_FILL }, "ContourFill", RGBf(0.0, 0.1, 0.1), 1.0, 0, true, StipplePattern::CONTINUOUS },
+ { { NORMALS }, "Normals", RGBf(0.0, 0.4, 0.4), 1.0, 0, true, StipplePattern::CONTINUOUS },
+ { { ANALYZE }, "Analyze", RGBf(0.0, 1.0, 1.0), 3.0, 0, true, StipplePattern::CONTINUOUS },
+ { { DRAW_ERROR }, "DrawError", RGBf(1.0, 0.0, 0.0), 8.0, 0, true, StipplePattern::CONTINUOUS },
+ { { DIM_SOLID }, "DimSolid", RGBf(0.1, 0.1, 0.1), 1.0, 0, true, StipplePattern::CONTINUOUS },
+ { { HIDDEN_EDGE }, "HiddenEdge", RGBf(0.8, 0.8, 0.8), 1.0, 1, true, StipplePattern::DASH },
+ { { OUTLINE }, "Outline", RGBf(0.8, 0.8, 0.8), 3.0, 5, true, StipplePattern::CONTINUOUS },
+ { { 0 }, NULL, RGBf(0.0, 0.0, 0.0), 0.0, 0, true, StipplePattern::CONTINUOUS }
};
std::string Style::CnfColor(const std::string &prefix) {
std::string Style::CnfWidth(const std::string &prefix) {
return "Style_" + prefix + "_Width";
}
+std::string Style::CnfStippleType(const std::string &prefix) {
+ return "Style_" + prefix + "_StippleType";
+}
+std::string Style::CnfStippleScale(const std::string &prefix) {
+ return "Style_" + prefix + "_StippleScale";
+}
std::string Style::CnfTextHeight(const std::string &prefix) {
return "Style_" + prefix + "_TextHeight";
}
+std::string Style::CnfExportable(const std::string &prefix) {
+ return "Style_" + prefix + "_Exportable";
+}
std::string Style::CnfPrefixToName(const std::string &prefix) {
std::string name = "#def-";
s->textOrigin = TextOrigin::NONE;
s->textAngle = 0;
s->visible = true;
- s->exportable = true;
+ s->exportable = (factory)
+ ? d->exportable
+ : settings->ThawBool(CnfExportable(d->cnfPrefix), d->exportable);
s->filled = false;
s->fillColor = RGBf(0.3, 0.3, 0.3);
- s->stippleType = (d->h.v == Style::HIDDEN_EDGE) ? StipplePattern::DASH
- : StipplePattern::CONTINUOUS;
- s->stippleScale = 15.0;
+ s->stippleType = (factory)
+ ? d->stippleType
+ : Style::StipplePatternFromString(
+ settings->ThawString(CnfStippleType(d->cnfPrefix),
+ StipplePatternName(d->stippleType)));
+ s->stippleScale = (factory)
+ ? 15.0
+ : settings->ThawFloat(CnfStippleScale(d->cnfPrefix), 15.0);
s->zIndex = d->zIndex;
}
for(d = &(Defaults[0]); d->h.v; d++) {
settings->FreezeColor(CnfColor(d->cnfPrefix), Color(d->h));
settings->FreezeFloat(CnfWidth(d->cnfPrefix), (float)Width(d->h));
+ settings->FreezeString(CnfStippleType(d->cnfPrefix), StipplePatternName(d->h));
+ settings->FreezeFloat(CnfStippleScale(d->cnfPrefix), (float)StippleScale(d->h));
settings->FreezeFloat(CnfTextHeight(d->cnfPrefix), (float)TextHeight(d->h));
+ settings->FreezeBool(CnfExportable(d->cnfPrefix), Exportable(d->h.v));
}
}
return hs;
}
+StipplePattern Style::StipplePatternFromString(std::string name) {
+ std::transform(name.begin(), name.end(), name.begin(), ::tolower);
+ if(name == "continuous") {
+ return StipplePattern::CONTINUOUS;
+ } else if(name == "shortdash") {
+ return StipplePattern::SHORT_DASH;
+ } else if(name == "dash") {
+ return StipplePattern::DASH;
+ } else if(name == "longdash") {
+ return StipplePattern::LONG_DASH;
+ } else if(name == "dashdot") {
+ return StipplePattern::DASH_DOT;
+ } else if(name == "dashdotdot") {
+ return StipplePattern::DASH_DOT_DOT;
+ } else if(name == "dot") {
+ return StipplePattern::DOT;
+ } else if(name == "freehand") {
+ return StipplePattern::FREEHAND;
+ } else if(name == "zigzag") {
+ return StipplePattern::ZIGZAG;
+ }
+
+ return StipplePattern::CONTINUOUS;
+}
+
StipplePattern Style::PatternType(hStyle hs) {
Style *s = Get(hs);
return s->stippleType;
}
+std::string Style::StipplePatternName(hStyle hs) {
+ Style *s = Get(hs);
+ return StipplePatternName(s->stippleType);
+}
+
+std::string Style::StipplePatternName(StipplePattern stippleType) {
+ switch(stippleType) {
+ case StipplePattern::CONTINUOUS: return "Continuous";
+ case StipplePattern::SHORT_DASH: return "ShortDash";
+ case StipplePattern::DASH: return "Dash";
+ case StipplePattern::LONG_DASH: return "LongDash";
+ case StipplePattern::DASH_DOT: return "DashDot";
+ case StipplePattern::DASH_DOT_DOT: return "DashDotDot";
+ case StipplePattern::DOT: return "Dot";
+ case StipplePattern::FREEHAND: return "FreeHand";
+ case StipplePattern::ZIGZAG: return "ZigZag";
+ }
+
+ return "Continuous";
+}
+
+double Style::StippleScale(hStyle hs) {
+ Style *s = Get(hs);
+ return s->stippleScale;
+}
+
double Style::StippleScaleMm(hStyle hs) {
Style *s = Get(hs);
if(s->widthAs == UnitsAs::MM) {
void TextWindow::ScreenLoadFactoryDefaultStyles(int link, uint32_t v) {
Style::LoadFactoryDefaults();
SS.TW.GoToScreen(Screen::LIST_OF_STYLES);
+ SS.GW.persistentDirty = true;
}
void TextWindow::ScreenCreateCustomStyle(int link, uint32_t v) {
Printf(true, "%Ft color style-name");
bool darkbg = false;
- Style *s;
- for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) {
+ for(Style &s : SK.style) {
Printf(false, "%Bp %Bz %Bp %Fl%Ll%f%D%s%E",
darkbg ? 'd' : 'a',
- &s->color,
+ &s.color,
darkbg ? 'd' : 'a',
- ScreenShowStyleInfo, s->h.v,
- s->DescriptionString().c_str());
+ ScreenShowStyleInfo, s.h.v,
+ s.DescriptionString().c_str());
darkbg = !darkbg;
}
if(units == Style::UnitsAs::PIXELS) {
edit_value = ssprintf("%.2f", val);
} else {
- edit_value = SS.MmToString(val);
+ edit_value = SS.MmToString(val, true);
}
SS.TW.ShowEditControl(col, edit_value);
SS.TW.edit.style = hs;
((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::TOP) ? RADIO_TRUE : RADIO_FALSE);
}
- if(s->h.v >= Style::FIRST_CUSTOM) {
- Printf(false, "");
+ Printf(false, "");
+ if(s->h.v >= Style::FIRST_CUSTOM) {
Printf(false, " %Fd%D%f%Lv%s show these objects on screen%E",
s->h.v, &ScreenChangeStyleYesNo,
s->visible ? CHECK_TRUE : CHECK_FALSE);
+ }
- Printf(false, " %Fd%D%f%Le%s export these objects%E",
- s->h.v, &ScreenChangeStyleYesNo,
- s->exportable ? CHECK_TRUE : CHECK_FALSE);
+ Printf(false, " %Fd%D%f%Le%s export these objects%E",
+ s->h.v, &ScreenChangeStyleYesNo,
+ s->exportable ? CHECK_TRUE : CHECK_FALSE);
+ if(s->h.v >= Style::FIRST_CUSTOM) {
Printf(false, "");
Printf(false, "To assign lines or curves to this style,");
Printf(false, "right-click them on the drawing.");
//-----------------------------------------------------------------------------
#include "solvespace.h"
-// This tolerance is used to determine whether two (linearized) constraints
-// are linearly dependent. If this is too small, then we will attempt to
-// solve truly inconsistent systems and fail. But if it's too large, then
-// we will give up on legitimate systems like a skinny right angle triangle by
-// its hypotenuse and long side.
-const double System::RANK_MAG_TOLERANCE = 1e-4;
+#include <Eigen/Core>
+#include <Eigen/SparseQR>
// The solver will converge all unknowns to within this tolerance. This must
// always be much less than LENGTH_EPS, and in practice should be much less.
const double System::CONVERGE_TOLERANCE = (LENGTH_EPS/(1e2));
-bool System::WriteJacobian(int tag) {
-
- int j = 0;
- for(auto &p : param) {
- if(j >= MAX_UNKNOWNS)
- return false;
+constexpr size_t LikelyPartialCountPerEq = 10;
- if(p.tag != tag)
- continue;
- mat.param[j] = p.h;
- j++;
+bool System::WriteJacobian(int tag) {
+ // Clear all
+ mat.param.clear();
+ mat.eq.clear();
+ mat.A.sym.setZero();
+ mat.B.sym.clear();
+
+ for(Param &p : param) {
+ if(p.tag != tag) continue;
+ mat.param.push_back(p.h);
}
- mat.n = j;
-
- int i = 0;
+ mat.n = mat.param.size();
- for(auto &e : eq) {
- if(i >= MAX_UNKNOWNS) return false;
-
- if(e.tag != tag)
- continue;
-
- mat.eq[i] = e.h;
- Expr *f = e.e->DeepCopyWithParamsAsPointers(¶m, &(SK.param));
- f = f->FoldConstants();
+ for(Equation &e : eq) {
+ if(e.tag != tag) continue;
+ mat.eq.push_back(&e);
+ }
+ mat.m = mat.eq.size();
+ mat.A.sym.resize(mat.m, mat.n);
+ mat.A.sym.reserve(Eigen::VectorXi::Constant(mat.n, LikelyPartialCountPerEq));
+
+ // Fill the param id to index map
+ std::map<uint32_t, int> paramToIndex;
+ for(int j = 0; j < mat.n; j++) {
+ paramToIndex[mat.param[j].v] = j;
+ }
- // Hash table (61 bits) to accelerate generation of zero partials.
- uint64_t scoreboard = f->ParamsUsed();
- for(j = 0; j < mat.n; j++) {
- Expr *pd;
- if(scoreboard & ((uint64_t)1 << (mat.param[j].v % 61)) &&
- f->DependsOn(mat.param[j]))
- {
- pd = f->PartialWrt(mat.param[j]);
- pd = pd->FoldConstants();
- pd = pd->DeepCopyWithParamsAsPointers(¶m, &(SK.param));
- } else {
- pd = Expr::From(0.0);
- }
- mat.A.sym[i][j] = pd;
+ if(mat.eq.size() >= MAX_UNKNOWNS) {
+ return false;
+ }
+ std::vector<hParam> paramsUsed;
+ // In some experimenting, this is almost always the right size.
+ // Value is usually between 0 and 20, comes from number of constraints?
+ mat.B.sym.reserve(mat.eq.size());
+ for(size_t i = 0; i < mat.eq.size(); i++) {
+ Equation *e = mat.eq[i];
+ if(e->tag != tag) continue;
+ // Simplify (fold) then deep-copy the current equation.
+ Expr *f = e->e->FoldConstants();
+ f = f->DeepCopyWithParamsAsPointers(¶m, &(SK.param));
+
+ paramsUsed.clear();
+ f->ParamsUsedList(¶msUsed);
+
+ for(hParam &p : paramsUsed) {
+ // Find the index of this parameter
+ auto it = paramToIndex.find(p.v);
+ if(it == paramToIndex.end()) continue;
+ // this is the parameter index
+ const int j = it->second;
+ // compute partial derivative of f
+ Expr *pd = f->PartialWrt(p);
+ pd = pd->FoldConstants();
+ if(pd->IsZeroConst())
+ continue;
+ mat.A.sym.insert(i, j) = pd;
}
- mat.B.sym[i] = f;
- i++;
+ paramsUsed.clear();
+ mat.B.sym.push_back(f);
}
- mat.m = i;
-
return true;
}
void System::EvalJacobian() {
- int i, j;
- for(i = 0; i < mat.m; i++) {
- for(j = 0; j < mat.n; j++) {
- mat.A.num[i][j] = (mat.A.sym[i][j])->Eval();
+ using namespace Eigen;
+ mat.A.num.setZero();
+ mat.A.num.resize(mat.m, mat.n);
+ const int size = mat.A.sym.outerSize();
+
+ for(int k = 0; k < size; k++) {
+ for(SparseMatrix <Expr *>::InnerIterator it(mat.A.sym, k); it; ++it) {
+ double value = it.value()->Eval();
+ if(EXACT(value == 0.0)) continue;
+ mat.A.num.insert(it.row(), it.col()) = value;
}
}
+ mat.A.num.makeCompressed();
}
bool System::IsDragged(hParam p) {
- hParam *pp;
- for(pp = dragged.First(); pp; pp = dragged.NextAfter(pp)) {
- if(p == *pp) return true;
+ const auto b = dragged.begin();
+ const auto e = dragged.end();
+ return e != std::find(b, e, p);
+}
+
+Param *System::GetLastParamSubstitution(Param *p) {
+ Param *current = p;
+ while(current->substd != NULL) {
+ current = current->substd;
+ if(current == p) {
+ // Break the loop
+ current->substd = NULL;
+ break;
+ }
+ }
+ return current;
+}
+
+void System::SortSubstitutionByDragged(Param *p) {
+ std::vector<Param *> subsParams;
+ Param *by = NULL;
+ Param *current = p;
+ while(current != NULL) {
+ subsParams.push_back(current);
+ if(IsDragged(current->h)) {
+ by = current;
+ }
+ current = current->substd;
+ }
+ if(by == NULL) by = p;
+ for(Param *p : subsParams) {
+ if(p == by) continue;
+ p->substd = by;
+ p->tag = VAR_SUBSTITUTED;
+ }
+ by->substd = NULL;
+ by->tag = 0;
+}
+
+void System::SubstituteParamsByLast(Expr *e) {
+ ssassert(e->op != Expr::Op::PARAM_PTR, "Expected an expression that refer to params via handles");
+
+ if(e->op == Expr::Op::PARAM) {
+ Param *p = param.FindByIdNoOops(e->parh);
+ if(p != NULL) {
+ Param *s = GetLastParamSubstitution(p);
+ if(s != NULL) {
+ e->parh = s->h;
+ }
+ }
+ } else {
+ int c = e->Children();
+ if(c >= 1) {
+ SubstituteParamsByLast(e->a);
+ if(c >= 2) SubstituteParamsByLast(e->b);
+ }
}
- return false;
}
void System::SolveBySubstitution() {
continue;
}
- if(IsDragged(a)) {
- // A is being dragged, so A should stay, and B should go
- std::swap(a, b);
+ if(a.v == b.v) {
+ teq.tag = EQ_SUBSTITUTED;
+ continue;
}
- for(auto &req : eq) {
- req.e->Substitute(a, b); // A becomes B, B unchanged
- }
- for(auto &rp : param) {
- if(rp.substd == a) {
- rp.substd = b;
+ Param *pa = param.FindById(a);
+ Param *pb = param.FindById(b);
+
+ // Take the last substitution of parameter a
+ // This resulted in creation of substitution chains
+ Param *last = GetLastParamSubstitution(pa);
+ last->substd = pb;
+ last->tag = VAR_SUBSTITUTED;
+
+ if(pb->substd != NULL) {
+ // Break the loops
+ GetLastParamSubstitution(pb);
+ // if b loop was broken
+ if(pb->substd == NULL) {
+ // Clear substitution
+ pb->tag = 0;
}
}
- Param *ptr = param.FindById(a);
- ptr->tag = VAR_SUBSTITUTED;
- ptr->substd = b;
-
teq.tag = EQ_SUBSTITUTED;
}
}
-}
-//-----------------------------------------------------------------------------
-// Calculate the rank of the Jacobian matrix, by Gram-Schimdt orthogonalization
-// in place. A row (~equation) is considered to be all zeros if its magnitude
-// is less than the tolerance RANK_MAG_TOLERANCE.
-//-----------------------------------------------------------------------------
-int System::CalculateRank() {
- // Actually work with magnitudes squared, not the magnitudes
- double rowMag[MAX_UNKNOWNS] = {};
- double tol = RANK_MAG_TOLERANCE*RANK_MAG_TOLERANCE;
+ //
+ for(Param &p : param) {
+ SortSubstitutionByDragged(&p);
+ }
- int i, iprev, j;
- int rank = 0;
+ // Substitute all the equations
+ for(auto &req : eq) {
+ SubstituteParamsByLast(req.e);
+ }
- for(i = 0; i < mat.m; i++) {
- // Subtract off this row's component in the direction of any
- // previous rows
- for(iprev = 0; iprev < i; iprev++) {
- if(rowMag[iprev] <= tol) continue; // ignore zero rows
-
- double dot = 0;
- for(j = 0; j < mat.n; j++) {
- dot += (mat.A.num[iprev][j]) * (mat.A.num[i][j]);
- }
- for(j = 0; j < mat.n; j++) {
- mat.A.num[i][j] -= (dot/rowMag[iprev])*mat.A.num[iprev][j];
- }
- }
- // Our row is now normal to all previous rows; calculate the
- // magnitude of what's left
- double mag = 0;
- for(j = 0; j < mat.n; j++) {
- mag += (mat.A.num[i][j]) * (mat.A.num[i][j]);
- }
- if(mag > tol) {
- rank++;
- }
- rowMag[i] = mag;
+ // Substitute all the parameters with last substitutions
+ for(auto &p : param) {
+ if(p.substd == NULL) continue;
+ p.substd = GetLastParamSubstitution(p.substd);
}
+}
- return rank;
+//-----------------------------------------------------------------------------
+// Calculate the rank of the Jacobian matrix
+//-----------------------------------------------------------------------------
+int System::CalculateRank() {
+ using namespace Eigen;
+ if(mat.n == 0 || mat.m == 0) return 0;
+ SparseQR <SparseMatrix<double>, COLAMDOrdering<int>> solver;
+ solver.compute(mat.A.num);
+ int result = solver.rank();
+ return result;
}
-bool System::TestRank(int *rank) {
+bool System::TestRank(int *dof) {
EvalJacobian();
int jacobianRank = CalculateRank();
- if(rank) *rank = jacobianRank;
+ // We are calculating dof based on real rank, not mat.m.
+ // Using this approach we can calculate real dof even when redundant is allowed.
+ if(dof != NULL) *dof = mat.n - jacobianRank;
return jacobianRank == mat.m;
}
-bool System::SolveLinearSystem(double X[], double A[][MAX_UNKNOWNS],
- double B[], int n)
+bool System::SolveLinearSystem(const Eigen::SparseMatrix <double> &A,
+ const Eigen::VectorXd &B, Eigen::VectorXd *X)
{
- // Gaussian elimination, with partial pivoting. It's an error if the
- // matrix is singular, because that means two constraints are
- // equivalent.
- int i, j, ip, jp, imax = 0;
- double max, temp;
-
- for(i = 0; i < n; i++) {
- // We are trying eliminate the term in column i, for rows i+1 and
- // greater. First, find a pivot (between rows i and N-1).
- max = 0;
- for(ip = i; ip < n; ip++) {
- if(fabs(A[ip][i]) > max) {
- imax = ip;
- max = fabs(A[ip][i]);
- }
- }
- // Don't give up on a singular matrix unless it's really bad; the
- // assumption code is responsible for identifying that condition,
- // so we're not responsible for reporting that error.
- if(fabs(max) < 1e-20) continue;
-
- // Swap row imax with row i
- for(jp = 0; jp < n; jp++) {
- swap(A[i][jp], A[imax][jp]);
- }
- swap(B[i], B[imax]);
-
- // For rows i+1 and greater, eliminate the term in column i.
- for(ip = i+1; ip < n; ip++) {
- temp = A[ip][i]/A[i][i];
-
- for(jp = i; jp < n; jp++) {
- A[ip][jp] -= temp*(A[i][jp]);
- }
- B[ip] -= temp*B[i];
- }
- }
-
- // We've put the matrix in upper triangular form, so at this point we
- // can solve by back-substitution.
- for(i = n - 1; i >= 0; i--) {
- if(fabs(A[i][i]) < 1e-20) continue;
-
- temp = B[i];
- for(j = n - 1; j > i; j--) {
- temp -= X[j]*A[i][j];
- }
- X[i] = temp / A[i][i];
- }
-
- return true;
+ if(A.outerSize() == 0) return true;
+ using namespace Eigen;
+ SparseQR<SparseMatrix<double>, COLAMDOrdering<int>> solver;
+ //SimplicialLDLT<SparseMatrix<double>> solver;
+ solver.compute(A);
+ *X = solver.solve(B);
+ return (solver.info() == Success);
}
bool System::SolveLeastSquares() {
- int r, c, i;
-
+ using namespace Eigen;
// Scale the columns; this scale weights the parameters for the least
// squares solve, so that we can encourage the solver to make bigger
// changes in some parameters, and smaller in others.
- for(c = 0; c < mat.n; c++) {
+ mat.scale = VectorXd::Ones(mat.n);
+ for(int c = 0; c < mat.n; c++) {
if(IsDragged(mat.param[c])) {
// It's least squares, so this parameter doesn't need to be all
// that big to get a large effect.
- mat.scale[c] = 1/20.0;
- } else {
- mat.scale[c] = 1;
- }
- for(r = 0; r < mat.m; r++) {
- mat.A.num[r][c] *= mat.scale[c];
+ mat.scale[c] = 1 / 20.0;
}
}
- // Write A*A'
- for(r = 0; r < mat.m; r++) {
- for(c = 0; c < mat.m; c++) { // yes, AAt is square
- double sum = 0;
- for(i = 0; i < mat.n; i++) {
- sum += mat.A.num[r][i]*mat.A.num[c][i];
- }
- mat.AAt[r][c] = sum;
+ const int size = mat.A.num.outerSize();
+ for(int k = 0; k < size; k++) {
+ for(SparseMatrix<double>::InnerIterator it(mat.A.num, k); it; ++it) {
+ it.valueRef() *= mat.scale[it.col()];
}
}
- if(!SolveLinearSystem(mat.Z, mat.AAt, mat.B.num, mat.m)) return false;
+ SparseMatrix<double> AAt = mat.A.num * mat.A.num.transpose();
+ AAt.makeCompressed();
+ VectorXd z(mat.n);
- // And multiply that by A' to get our solution.
- for(c = 0; c < mat.n; c++) {
- double sum = 0;
- for(i = 0; i < mat.m; i++) {
- sum += mat.A.num[i][c]*mat.Z[i];
- }
- mat.X[c] = sum * mat.scale[c];
+ if(!SolveLinearSystem(AAt, mat.B.num, &z)) return false;
+
+ mat.X = mat.A.num.transpose() * z;
+
+ for(int c = 0; c < mat.n; c++) {
+ mat.X[c] *= mat.scale[c];
}
return true;
}
int i;
// Evaluate the functions at our operating point.
+ mat.B.num = Eigen::VectorXd(mat.m);
for(i = 0; i < mat.m; i++) {
mat.B.num[i] = (mat.B.sym[i])->Eval();
}
{
WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g);
- int i;
bool rankOk;
/*
+ int x;
dbp("%d equations", eq.n);
- for(i = 0; i < eq.n; i++) {
- dbp(" %.3f = %s = 0", eq[i].e->Eval(), eq[i].e->Print());
+ for(x = 0; x < eq.n; x++) {
+ dbp(" %.3f = %s = 0", eq[x].e->Eval(), eq[x].e->Print());
}
dbp("%d parameters", param.n);
- for(i = 0; i < param.n; i++) {
- dbp(" param %08x at %.3f", param[i].h.v, param[i].val);
+ for(x = 0; x < param.n; x++) {
+ dbp(" param %08x at %.3f", param[x].h.v, param[x].val);
} */
// All params and equations are assigned to group zero.
param.ClearTags();
eq.ClearTags();
- // Solving by substitution eliminates duplicate e.g. H/V constraints, which can cause rank test
- // to succeed even on overdefined systems, which will fail later.
- if(!forceDofCheck) {
+ // Since we are suppressing dof calculation or allowing redundant, we
+ // can't / don't want to catch result of dof checking without substitution
+ if(g->suppressDofCalculation || g->allowRedundant || !forceDofCheck) {
SolveBySubstitution();
}
if(!WriteJacobian(0)) {
return SolveResult::TOO_MANY_UNKNOWNS;
}
-
- rankOk = TestRank(rank);
+ // Clear dof value in order to have indication when dof is actually not calculated
+ if(dof != NULL) *dof = -1;
+ // We are suppressing or allowing redundant, so we no need to catch unsolveable + redundant
+ rankOk = (!g->suppressDofCalculation && !g->allowRedundant) ? TestRank(dof) : true;
// And do the leftovers as one big system
if(!NewtonSolve(0)) {
goto didnt_converge;
}
- rankOk = TestRank(rank);
+ // Here we are want to calculate dof even when redundant is allowed, so just handle suppressing
+ rankOk = (!g->suppressDofCalculation) ? TestRank(dof) : true;
if(!rankOk) {
if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad, forceDofCheck);
} else {
- // This is not the full Jacobian, but any substitutions or single-eq
- // solves removed one equation and one unknown, therefore no effect
- // on the number of DOF.
- if(dof) *dof = CalculateDof();
MarkParamsFree(andFindFree);
}
// System solved correctly, so write the new values back in to the
for(auto &p : param) {
double val;
if(p.tag == VAR_SUBSTITUTED) {
- val = param.FindById(p.substd)->val;
+ val = p.substd->val;
} else {
val = p.val;
}
didnt_converge:
SK.constraint.ClearTags();
// Not using range-for here because index is used in additional ways
- for(i = 0; i < eq.n; i++) {
+ for(size_t i = 0; i < mat.eq.size(); i++) {
if(fabs(mat.B.num[i]) > CONVERGE_TOLERANCE || IsReasonable(mat.B.num[i])) {
// This constraint is unsatisfied.
- if(!mat.eq[i].isFromConstraint()) continue;
+ if(!mat.eq[i]->h.isFromConstraint()) continue;
- hConstraint hc = mat.eq[i].constraint();
+ hConstraint hc = mat.eq[i]->h.constraint();
ConstraintBase *c = SK.constraint.FindByIdNoOops(hc);
if(!c) continue;
// Don't double-show constraints that generated multiple
return SolveResult::TOO_MANY_UNKNOWNS;
}
- bool rankOk = TestRank(rank);
+ bool rankOk = TestRank(dof);
if(!rankOk) {
- if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad, /*forceDofCheck=*/true);
+ // When we are testing with redundant allowed, we don't want to have additional info
+ // about redundants since this test is working only for single redundant constraint
+ if(!g->suppressDofCalculation && !g->allowRedundant) {
+ if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad, true);
+ }
} else {
- if(dof) *dof = CalculateDof();
MarkParamsFree(andFindFree);
}
return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY;
param.Clear();
eq.Clear();
dragged.Clear();
+ mat.A.num.setZero();
+ mat.A.sym.setZero();
}
void System::MarkParamsFree(bool find) {
}
}
-int System::CalculateDof() {
- return mat.n - mat.m;
-}
-
sprintf(sdof, "%-3d", dof);
}
}
+ std::string suffix;
+ if(g->forceToMesh || g->IsTriangleMeshAssembly()) {
+ suffix = " (∆)";
+ }
+
bool ref = (g->h == Group::HGROUP_REFERENCES);
Printf(false,
"%Bp%Fd "
"%Ft%s%Fb%D%f%Ll%s%E "
"%Fb%s%D%f%Ll%s%E "
"%Fp%D%f%s%Ll%s%E "
- "%Fl%Ll%D%f%s",
+ "%Fp%Ll%D%f%s%E%s",
// Alternate between light and dark backgrounds, for readability
backgroundParity ? 'd' : 'a',
// Link that activates the group
ok ? ((warn && SS.checkClosedContour) ? "err" : sdof) : "",
ok ? "" : "ERR",
// Link to a screen that gives more details on the group
- g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str());
+ g->suppress ? 'g' : 'l',
+ g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str(),
+ suffix.c_str());
if(active) afterActive = true;
backgroundParity = !backgroundParity;
case 'e': g->allowRedundant = !(g->allowRedundant); break;
+ case 'D': g->suppressDofCalculation = !(g->suppressDofCalculation); break;
+
case 'v': g->visible = !(g->visible); break;
case 'd': g->allDimsReference = !(g->allDimsReference); break;
SS.TW.edit.meaning = Edit::GROUP_SCALE;
SS.TW.edit.group.v = v;
}
+void TextWindow::ScreenChangeHelixPitch(int link, uint32_t v) {
+ Group *g = SK.GetGroup(SS.TW.shown.group);
+ double pitch = g->valB/SS.MmPerUnit();
+ SS.TW.ShowEditControl(3, ssprintf("%.8f", pitch));
+ SS.TW.edit.meaning = Edit::HELIX_PITCH;
+ SS.TW.edit.group.v = v;
+}
+void TextWindow::ScreenChangePitchOption(int link, uint32_t v) {
+ Group *g = SK.GetGroup(SS.TW.shown.group);
+ if(g->valB == 0.0) {
+ g->valB = SK.GetParam(g->h.param(7))->val * PI /
+ (SK.GetParam(g->h.param(3))->val);
+ } else {
+ g->valB = 0.0;
+ }
+ SS.GW.Invalidate();
+}
void TextWindow::ScreenDeleteGroup(int link, uint32_t v) {
SS.UndoRemember();
}
Printf(false, "");
+ if(g->type == Group::Type::HELIX) {
+ Printf(false, "%Ft pitch - length per turn%E");
+
+ if (fabs(g->valB) != 0.0) {
+ Printf(false, " %Ba %# %Fl%Ll%f%D[change]%E",
+ g->valB / SS.MmPerUnit(),
+ &TextWindow::ScreenChangeHelixPitch, g->h.v);
+ } else {
+ Printf(false, " %Ba %# %E",
+ SK.GetParam(g->h.param(7))->val * PI /
+ ( (SK.GetParam(g->h.param(3))->val) * SS.MmPerUnit() ),
+ &TextWindow::ScreenChangeHelixPitch, g->h.v);
+ }
+ Printf(false, " %Fd%f%LP%s fixed",
+ &TextWindow::ScreenChangePitchOption,
+ g->valB != 0 ? CHECK_TRUE : CHECK_FALSE);
+
+ Printf(false, ""); // blank line
+ }
+
if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::LATHE ||
g->type == Group::Type::REVOLVE || g->type == Group::Type::LINKED ||
g->type == Group::Type::HELIX) {
&TextWindow::ScreenChangeGroupOption,
g->visible ? CHECK_TRUE : CHECK_FALSE);
- if(!g->IsForcedToMeshBySource()) {
+ if(!g->IsForcedToMeshBySource() && !g->IsTriangleMeshAssembly()) {
Printf(false, " %f%Lf%Fd%s force NURBS surfaces to triangle mesh",
&TextWindow::ScreenChangeGroupOption,
g->forceToMesh ? CHECK_TRUE : CHECK_FALSE);
&TextWindow::ScreenChangeGroupOption,
g->allowRedundant ? CHECK_TRUE : CHECK_FALSE);
+ Printf(false, " %f%LD%Fd%s suppress dof calculation (improves solver performance)",
+ &TextWindow::ScreenChangeGroupOption,
+ g->suppressDofCalculation ? CHECK_TRUE : CHECK_FALSE);
+
Printf(false, " %f%Ld%Fd%s treat all dimensions as reference",
&TextWindow::ScreenChangeGroupOption,
g->allDimsReference ? CHECK_TRUE : CHECK_FALSE);
}
if(g->solved.timeout) {
- Printf(true, "%FxSome items in list have been ommitted%Fd");
+ Printf(true, "%FxSome items in list have been omitted%Fd");
Printf(false, "%Fxbecause the operation timed out.%Fd");
}
SS.TW.edit.meaning = Edit::STEP_DIM_FINISH;
std::string edit_value;
if(SS.TW.stepDim.isDistance) {
- edit_value = SS.MmToString(SS.TW.stepDim.finish);
+ edit_value = SS.MmToString(SS.TW.stepDim.finish, true);
} else {
edit_value = ssprintf("%.3f", SS.TW.stepDim.finish);
}
switch(link) {
case 'r': {
SS.TW.edit.meaning = Edit::TANGENT_ARC_RADIUS;
- SS.TW.ShowEditControl(3, SS.MmToString(SS.tangentArcRadius));
+ SS.TW.ShowEditControl(3, SS.MmToString(SS.tangentArcRadius, true));
break;
}
}
break;
+ case Edit::HELIX_PITCH: // stored in valB
+ if(Expr *e = Expr::From(s, /*popUpError=*/true)) {
+ double ev = e->Eval();
+ Group *g = SK.GetGroup(edit.group);
+ g->valB = ev * SS.MmPerUnit();
+ SS.MarkGroupDirty(g->h);
+ }
+ break;
+
case Edit::GROUP_COLOR: {
Vector rgb;
if(sscanf(s.c_str(), "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) {
{ 'r', RGBi( 0, 0, 0) }, // Reverse : black
{ 'x', RGBi(255, 20, 20) }, // Error : red
{ 'i', RGBi( 0, 255, 255) }, // Info : cyan
- { 'g', RGBi(160, 160, 160) },
+ { 'g', RGBi(128, 128, 128) }, // Disabled : gray
{ 'b', RGBi(200, 200, 200) },
{ 0, RGBi( 0, 0, 0) }
};
using namespace std::placeholders;
window->onClose = []() {
+ SS.TW.HideEditControl();
SS.GW.showTextWindow = false;
SS.GW.EnsureValidActives();
};
rows = 0;
}
-// This message was addded when someone had too many fonts for the text window
-// Scrolling seemed to be broken, but was actaully at the MAX_ROWS.
+// This message was added when someone had too many fonts for the text window
+// Scrolling seemed to be broken, but was actually at the MAX_ROWS.
static const char* endString = " **** End of Text Screen ****";
void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
double width, height;
window->GetContentSize(&width, &height);
- int x = 17, y = (int)(height - 52);
+ int x = 17, y = (int)(height - 21); // 20 is the menu bar height
- // When changing these values, also change the asReference drawing code in drawentity.cpp.
+ // When changing these values, also change the asReference drawing code in drawentity.cpp
+ // as well as the "window->SetMinContentSize(720, 636);" in graphicswin.cpp
int fudge = 8;
- int h = 32*18 + 3*16 + fudge;
+ int h = 32*18 + 3*16 + fudge; // Toolbar height = 18 icons * 32 pixels + 3 dividers * 16 pixels + fudge
+
+ if(h < y) {
+ // If there is enough vertical space leave up to 32 pixels between the menu bar and the toolbar.
+ y -= ((y - h) < 32) ? y - h : 32;
+ }
+
int aleft = 0, aright = 66, atop = y+16+fudge/2, abot = y+16-h;
bool withinToolbar =
#include FT_ADVANCES_H
/* Yecch. Irritatingly, you need to do this nonsense to get the error string table,
- since nobody thought to put this exact function into FreeType itsself. */
+ since nobody thought to put this exact function into FreeType itself. */
#undef __FTERRORS_H__
#define FT_ERRORDEF(e, v, s) { (e), (s) },
#define FT_ERROR_START_LIST
SHOW_GRID,
DIM_SOLID_MODEL,
PERSPECTIVE_PROJ,
+ EXPLODE_SKETCH,
ONTO_WORKPLANE,
NEAREST_ORTHO,
NEAREST_ISO,
SHOW_TOOLBAR,
SHOW_TEXT_WND,
UNITS_INCHES,
+ UNITS_FEET_INCHES,
UNITS_MM,
UNITS_METERS,
FULL_SCREEN,
// Help
LOCALE,
WEBSITE,
+ GITHUB,
ABOUT,
};
EXPORT_OFFSET = 110,
CANVAS_SIZE = 111,
G_CODE_DEPTH = 112,
- G_CODE_PASSES = 113,
- G_CODE_FEED = 114,
- G_CODE_PLUNGE_FEED = 115,
- AUTOSAVE_INTERVAL = 116,
- LIGHT_AMBIENT = 117,
- FIND_CONSTRAINT_TIMEOUT = 118,
+ G_CODE_SAFE_HEIGHT = 113,
+ G_CODE_PASSES = 114,
+ G_CODE_FEED = 115,
+ G_CODE_PLUNGE_FEED = 116,
+ AUTOSAVE_INTERVAL = 117,
+ LIGHT_AMBIENT = 118,
+ FIND_CONSTRAINT_TIMEOUT = 119,
+ EXPLODE_DISTANCE = 120,
// For TTF text
TTF_TEXT = 300,
// For the step dimension screen
VIEW_PROJ_RIGHT = 702,
VIEW_PROJ_UP = 703,
// For tangent arc
- TANGENT_ARC_RADIUS = 800
+ TANGENT_ARC_RADIUS = 800,
+ // For helix pitch
+ HELIX_PITCH = 802
};
struct {
bool showAgain;
static void ScreenChangeExprA(int link, uint32_t v);
static void ScreenChangeGroupName(int link, uint32_t v);
static void ScreenChangeGroupScale(int link, uint32_t v);
+ static void ScreenChangeHelixPitch(int link, uint32_t v);
+ static void ScreenChangePitchOption(int link, uint32_t v);
static void ScreenChangeLightDirection(int link, uint32_t v);
static void ScreenChangeLightIntensity(int link, uint32_t v);
static void ScreenChangeLightAmbient(int link, uint32_t v);
static void ScreenChangeExportMaxSegments(int link, uint32_t v);
static void ScreenChangeCameraTangent(int link, uint32_t v);
static void ScreenChangeGridSpacing(int link, uint32_t v);
+ static void ScreenChangeExplodeDistance(int link, uint32_t v);
static void ScreenChangeDigitsAfterDecimal(int link, uint32_t v);
static void ScreenChangeDigitsAfterDecimalDegree(int link, uint32_t v);
static void ScreenChangeUseSIPrefixes(int link, uint32_t v);
Platform::MenuItemRef showGridMenuItem;
Platform::MenuItemRef dimSolidModelMenuItem;
Platform::MenuItemRef perspectiveProjMenuItem;
+ Platform::MenuItemRef explodeMenuItem;
Platform::MenuItemRef showToolbarMenuItem;
Platform::MenuItemRef showTextWndMenuItem;
Platform::MenuItemRef fullScreenMenuItem;
Platform::MenuItemRef unitsMmMenuItem;
Platform::MenuItemRef unitsMetersMenuItem;
Platform::MenuItemRef unitsInchesMenuItem;
+ Platform::MenuItemRef unitsFeetInchesMenuItem;
Platform::MenuItemRef inWorkplaneMenuItem;
Platform::MenuItemRef in3dMenuItem;
void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin,
double *wmin, bool usePerspective,
const Camera &camera);
+ void ZoomToMouse(double delta);
void LoopOverPoints(const std::vector<Entity *> &entities,
const std::vector<Constraint *> &constraints,
const std::vector<hEntity> &faces,
bool showEdges;
bool showOutlines;
bool showFaces;
+ bool showFacesDrawing;
+ bool showFacesNonDrawing;
bool showMesh;
void ToggleBool(bool *v);
void MouseLeftDoubleClick(double x, double y);
void MouseMiddleOrRightDown(double x, double y);
void MouseRightUp(double x, double y);
- void MouseScroll(double x, double y, double delta);
+ void MouseScroll(double delta);
void MouseLeave();
bool KeyboardEvent(Platform::KeyboardEvent event);
void EditControlDone(const std::string &s);
Printf(false, "%Ba %Ftout%E (%3, %3, %3)", CO(n));
Printf(false, "");
- Printf(false, "The perspective may be changed in the");
- Printf(false, "configuration screen.");
+ Printf(false, "%Ft perspective factor (0 for parallel)%E");
+ Printf(false, "%Ba %# %Fl%Ll%f%D[change]%E",
+ SS.cameraTangent*1000,
+ &ScreenChangeCameraTangent, 0);
+
+ Printf(false, "");
+ Printf(false, "%Ft light direction intensity");
+ for(int i = 0; i < 2; i++) {
+ Printf(false, "%Bp #%d (%2,%2,%2)%Fl%D%f%Ll[c]%E "
+ "%2 %Fl%D%f%Ll[c]%E",
+ (i & 1) ? 'd' : 'a', i,
+ CO(SS.lightDir[i]), i, &ScreenChangeLightDirection,
+ SS.lightIntensity[i], i, &ScreenChangeLightIntensity);
+ }
+ Printf(false, "%Ba ambient lighting %2 %Fl%f%Ll[c]%E",
+ SS.ambientIntensity, &ScreenChangeLightAmbient);
+
+ Printf(false, "");
+ Printf(false, "%Ft explode distance%E");
+ Printf(false, "%Ba %s %Fl%Ll%f%D[change]%E",
+ SS.MmToString(SS.explodeDistance).c_str(),
+ &ScreenChangeExplodeDistance, 0);
+
}
void TextWindow::ScreenChangeViewScale(int link, uint32_t v) {
void TextWindow::ScreenChangeViewOrigin(int link, uint32_t v) {
std::string edit_value =
ssprintf("%s, %s, %s",
- SS.MmToString(-SS.GW.offset.x).c_str(),
- SS.MmToString(-SS.GW.offset.y).c_str(),
- SS.MmToString(-SS.GW.offset.z).c_str());
+ SS.MmToString(-SS.GW.offset.x, true).c_str(),
+ SS.MmToString(-SS.GW.offset.y, true).c_str(),
+ SS.MmToString(-SS.GW.offset.z, true).c_str());
SS.TW.edit.meaning = Edit::VIEW_ORIGIN;
SS.TW.ShowEditControl(3, edit_value);
SS.TW.ShowEditControl(10, edit_value);
}
+void TextWindow::ScreenChangeLightDirection(int link, uint32_t v) {
+ SS.TW.ShowEditControl(8, ssprintf("%.2f, %.2f, %.2f", CO(SS.lightDir[v])));
+ SS.TW.edit.meaning = Edit::LIGHT_DIRECTION;
+ SS.TW.edit.i = v;
+}
+
+void TextWindow::ScreenChangeLightIntensity(int link, uint32_t v) {
+ SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.lightIntensity[v]));
+ SS.TW.edit.meaning = Edit::LIGHT_INTENSITY;
+ SS.TW.edit.i = v;
+}
+
+void TextWindow::ScreenChangeLightAmbient(int link, uint32_t v) {
+ SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.ambientIntensity));
+ SS.TW.edit.meaning = Edit::LIGHT_AMBIENT;
+ SS.TW.edit.i = 0;
+}
+
+void TextWindow::ScreenChangeCameraTangent(int link, uint32_t v) {
+ SS.TW.ShowEditControl(3, ssprintf("%.3f", 1000*SS.cameraTangent));
+ SS.TW.edit.meaning = Edit::CAMERA_TANGENT;
+}
+
+void TextWindow::ScreenChangeExplodeDistance(int link, uint32_t v) {
+ SS.TW.ShowEditControl(3, SS.MmToString(SS.explodeDistance, true));
+ SS.TW.edit.meaning = Edit::EXPLODE_DISTANCE;
+}
+
bool TextWindow::EditControlDoneForView(const std::string &s) {
switch(edit.meaning) {
case Edit::VIEW_SCALE: {
AddParam
Param.h.v.=00040011
-Param.val=5.00000000000000000000
+Param.val=5.00000000000000088818
AddParam
Param.h.v.=00040013
AddParam
Param.h.v.=00060010
-Param.val=10.00000000000000000000
+Param.val=10.29878739785912600269
AddParam
Param.h.v.=00060011
AddParam
Param.h.v.=00060013
-Param.val=5.00000000000000000000
+Param.val=5.29878739785912422633
AddParam
Param.h.v.=00060014
AddParam
Param.h.v.=00070010
-Param.val=5.00000000000000000000
+Param.val=5.29878739785912422633
AddParam
Param.h.v.=00070011
AddParam
Param.h.v.=00070013
-Param.val=10.00000000000000000000
+Param.val=10.29878739785912600269
AddParam
Param.h.v.=00070014
Entity.construction=0
Entity.workplane.v=80020000
Entity.actPoint.x=-5.00000000000000000000
-Entity.actPoint.y=5.00000000000000000000
+Entity.actPoint.y=5.00000000000000088818
Entity.actVisible=1
AddEntity
Entity.type=2001
Entity.construction=0
Entity.workplane.v=80020000
-Entity.actPoint.x=10.00000000000000000000
+Entity.actPoint.x=10.29878739785912600269
Entity.actPoint.y=10.00000000000000000000
Entity.actVisible=1
AddEntity
Entity.type=2001
Entity.construction=0
Entity.workplane.v=80020000
-Entity.actPoint.x=5.00000000000000000000
+Entity.actPoint.x=5.29878739785912422633
Entity.actPoint.y=5.00000000000000000000
Entity.actVisible=1
AddEntity
Entity.type=2001
Entity.construction=0
Entity.workplane.v=80020000
-Entity.actPoint.x=5.00000000000000000000
+Entity.actPoint.x=5.29878739785912422633
Entity.actPoint.y=5.00000000000000000000
Entity.actVisible=1
AddEntity
Entity.type=2001
Entity.construction=0
Entity.workplane.v=80020000
-Entity.actPoint.x=10.00000000000000000000
+Entity.actPoint.x=10.29878739785912600269
Entity.actPoint.y=5.00000000000000000000
Entity.actVisible=1
AddEntity
--- /dev/null
+±²³SolveSpaceREVa
+
+
+Group.h.v=00000001
+Group.type=5000
+Group.name=#references
+Group.color=ff000000
+Group.skipFirst=0
+Group.predef.swapUV=0
+Group.predef.negateU=0
+Group.predef.negateV=0
+Group.visible=1
+Group.suppress=0
+Group.relaxConstraints=0
+Group.allowRedundant=0
+Group.allDimsReference=0
+Group.scale=1.00000000000000000000
+Group.remap={
+}
+AddGroup
+
+Group.h.v=00000002
+Group.type=5001
+Group.order=1
+Group.name=sketch-in-plane
+Group.activeWorkplane.v=80020000
+Group.color=ff000000
+Group.subtype=6000
+Group.skipFirst=0
+Group.predef.q.w=1.00000000000000000000
+Group.predef.origin.v=00010001
+Group.predef.swapUV=0
+Group.predef.negateU=0
+Group.predef.negateV=0
+Group.visible=1
+Group.suppress=0
+Group.relaxConstraints=0
+Group.allowRedundant=0
+Group.allDimsReference=0
+Group.scale=1.00000000000000000000
+Group.remap={
+}
+AddGroup
+
+Param.h.v.=00010010
+AddParam
+
+Param.h.v.=00010011
+AddParam
+
+Param.h.v.=00010012
+AddParam
+
+Param.h.v.=00010020
+Param.val=1.00000000000000000000
+AddParam
+
+Param.h.v.=00010021
+AddParam
+
+Param.h.v.=00010022
+AddParam
+
+Param.h.v.=00010023
+AddParam
+
+Param.h.v.=00020010
+AddParam
+
+Param.h.v.=00020011
+AddParam
+
+Param.h.v.=00020012
+AddParam
+
+Param.h.v.=00020020
+Param.val=0.50000000000000000000
+AddParam
+
+Param.h.v.=00020021
+Param.val=0.50000000000000000000
+AddParam
+
+Param.h.v.=00020022
+Param.val=0.50000000000000000000
+AddParam
+
+Param.h.v.=00020023
+Param.val=0.50000000000000000000
+AddParam
+
+Param.h.v.=00030010
+AddParam
+
+Param.h.v.=00030011
+AddParam
+
+Param.h.v.=00030012
+AddParam
+
+Param.h.v.=00030020
+Param.val=0.50000000000000000000
+AddParam
+
+Param.h.v.=00030021
+Param.val=-0.50000000000000000000
+AddParam
+
+Param.h.v.=00030022
+Param.val=-0.50000000000000000000
+AddParam
+
+Param.h.v.=00030023
+Param.val=-0.50000000000000000000
+AddParam
+
+Param.h.v.=00040010
+Param.val=-5.00000000000000000000
+AddParam
+
+Param.h.v.=00040011
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00040013
+Param.val=-10.00000000000000000000
+AddParam
+
+Param.h.v.=00040014
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00050010
+Param.val=-10.00000000000000000000
+AddParam
+
+Param.h.v.=00050011
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00050013
+Param.val=-5.00000000000000000000
+AddParam
+
+Param.h.v.=00050014
+Param.val=10.00000000000000000000
+AddParam
+
+Param.h.v.=00060010
+Param.val=10.00000000000000000000
+AddParam
+
+Param.h.v.=00060011
+Param.val=10.00000000000000000000
+AddParam
+
+Param.h.v.=00060013
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00060014
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00070010
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00070011
+Param.val=5.00000000000000000000
+AddParam
+
+Param.h.v.=00070013
+Param.val=10.00000000000000000000
+AddParam
+
+Param.h.v.=00070014
+Param.val=5.00000000000000000000
+AddParam
+
+Request.h.v=00000001
+Request.type=100
+Request.group.v=00000001
+Request.construction=0
+AddRequest
+
+Request.h.v=00000002
+Request.type=100
+Request.group.v=00000001
+Request.construction=0
+AddRequest
+
+Request.h.v=00000003
+Request.type=100
+Request.group.v=00000001
+Request.construction=0
+AddRequest
+
+Request.h.v=00000004
+Request.type=200
+Request.workplane.v=80020000
+Request.group.v=00000002
+Request.construction=0
+AddRequest
+
+Request.h.v=00000005
+Request.type=200
+Request.workplane.v=80020000
+Request.group.v=00000002
+Request.construction=0
+AddRequest
+
+Request.h.v=00000006
+Request.type=200
+Request.workplane.v=80020000
+Request.group.v=00000002
+Request.construction=0
+AddRequest
+
+Request.h.v=00000007
+Request.type=200
+Request.workplane.v=80020000
+Request.group.v=00000002
+Request.construction=0
+AddRequest
+
+Entity.h.v=00010000
+Entity.type=10000
+Entity.construction=0
+Entity.point[0].v=00010001
+Entity.normal.v=00010020
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00010001
+Entity.type=2000
+Entity.construction=1
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00010020
+Entity.type=3000
+Entity.construction=0
+Entity.point[0].v=00010001
+Entity.actNormal.w=1.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00020000
+Entity.type=10000
+Entity.construction=0
+Entity.point[0].v=00020001
+Entity.normal.v=00020020
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00020001
+Entity.type=2000
+Entity.construction=1
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00020020
+Entity.type=3000
+Entity.construction=0
+Entity.point[0].v=00020001
+Entity.actNormal.w=0.50000000000000000000
+Entity.actNormal.vx=0.50000000000000000000
+Entity.actNormal.vy=0.50000000000000000000
+Entity.actNormal.vz=0.50000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00030000
+Entity.type=10000
+Entity.construction=0
+Entity.point[0].v=00030001
+Entity.normal.v=00030020
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00030001
+Entity.type=2000
+Entity.construction=1
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00030020
+Entity.type=3000
+Entity.construction=0
+Entity.point[0].v=00030001
+Entity.actNormal.w=0.50000000000000000000
+Entity.actNormal.vx=-0.50000000000000000000
+Entity.actNormal.vy=-0.50000000000000000000
+Entity.actNormal.vz=-0.50000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00040000
+Entity.type=11000
+Entity.construction=0
+Entity.point[0].v=00040001
+Entity.point[1].v=00040002
+Entity.workplane.v=80020000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00040001
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=-5.00000000000000000000
+Entity.actPoint.y=5.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00040002
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=-10.00000000000000000000
+Entity.actPoint.y=5.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00050000
+Entity.type=11000
+Entity.construction=0
+Entity.point[0].v=00050001
+Entity.point[1].v=00050002
+Entity.workplane.v=80020000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00050001
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=-10.00000000000000000000
+Entity.actPoint.y=5.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00050002
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=-5.00000000000000000000
+Entity.actPoint.y=10.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00060000
+Entity.type=11000
+Entity.construction=0
+Entity.point[0].v=00060001
+Entity.point[1].v=00060002
+Entity.workplane.v=80020000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00060001
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=10.00000000000000000000
+Entity.actPoint.y=10.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00060002
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=5.00000000000000000000
+Entity.actPoint.y=5.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00070000
+Entity.type=11000
+Entity.construction=0
+Entity.point[0].v=00070001
+Entity.point[1].v=00070002
+Entity.workplane.v=80020000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00070001
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=5.00000000000000000000
+Entity.actPoint.y=5.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=00070002
+Entity.type=2001
+Entity.construction=0
+Entity.workplane.v=80020000
+Entity.actPoint.x=10.00000000000000000000
+Entity.actPoint.y=5.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=80020000
+Entity.type=10000
+Entity.construction=0
+Entity.point[0].v=80020002
+Entity.normal.v=80020001
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=80020001
+Entity.type=3010
+Entity.construction=0
+Entity.point[0].v=80020002
+Entity.actNormal.w=1.00000000000000000000
+Entity.actVisible=1
+AddEntity
+
+Entity.h.v=80020002
+Entity.type=2012
+Entity.construction=1
+Entity.actVisible=1
+AddEntity
+
+Constraint.h.v=00000001
+Constraint.type=20
+Constraint.group.v=00000002
+Constraint.workplane.v=80020000
+Constraint.ptA.v=00040002
+Constraint.ptB.v=00050001
+Constraint.other=0
+Constraint.other2=0
+Constraint.reference=0
+AddConstraint
+
+Constraint.h.v=00000002
+Constraint.type=20
+Constraint.group.v=00000002
+Constraint.workplane.v=80020000
+Constraint.ptA.v=00060002
+Constraint.ptB.v=00070001
+Constraint.other=0
+Constraint.other2=0
+Constraint.reference=0
+AddConstraint
+
+Constraint.h.v=00000003
+Constraint.type=54
+Constraint.group.v=00000002
+Constraint.workplane.v=80020000
+Constraint.entityA.v=00040000
+Constraint.entityB.v=00050000
+Constraint.entityC.v=00070000
+Constraint.entityD.v=00060000
+Constraint.other=0
+Constraint.other2=0
+Constraint.reference=0
+AddConstraint
+
TEST_CASE(normal_migrate_from_v20) {
CHECK_LOAD("normal_v20.slvs");
- CHECK_SAVE("normal.slvs");
+ CHECK_SAVE("normal_old_version.slvs");
}
TEST_CASE(normal_migrate_from_v22) {
CHECK_LOAD("normal_v22.slvs");
- CHECK_SAVE("normal.slvs");
+ CHECK_SAVE("normal_old_version.slvs");
}
TEST_CASE(other_roundtrip) {
TEST_CASE(normal_roundtrip) {
CHECK_LOAD("normal.slvs");
- // Can't render images through cairo for now.
- // CHECK_RENDER("normal.png");
+ CHECK_RENDER("normal.png");
CHECK_SAVE("normal.slvs");
}
TEST_CASE(linked_roundtrip) {
CHECK_LOAD("linked.slvs");
- // CHECK_RENDER("linked.png");
+ CHECK_RENDER("linked.png");
CHECK_SAVE("linked.slvs");
}