pax_global_header00006660000000000000000000000064147735561320014527gustar00rootroot0000000000000052 comment=d8c108f73de9d4045c5308cf8eb77370c8d5a02d dbus-fast-2.44.1/000077500000000000000000000000001477355613200135075ustar00rootroot00000000000000dbus-fast-2.44.1/.all-contributorsrc000066400000000000000000000004501477355613200173370ustar00rootroot00000000000000{ "projectName": "dbus-fast", "projectOwner": "bluetooth-devices", "repoType": "github", "repoHost": "https://github.com", "files": ["README.md"], "imageSize": 80, "commit": true, "commitConvention": "angular", "contributors": [], "contributorsPerLine": 7, "skipCi": true } dbus-fast-2.44.1/.editorconfig000066400000000000000000000004441477355613200161660ustar00rootroot00000000000000# http://editorconfig.org root = true [*] indent_style = space indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 end_of_line = lf [*.bat] indent_style = tab end_of_line = crlf [LICENSE] insert_final_newline = false [Makefile] indent_style = tab dbus-fast-2.44.1/.flake8000066400000000000000000000000561477355613200146630ustar00rootroot00000000000000[flake8] exclude = docs max-line-length = 180 dbus-fast-2.44.1/.github/000077500000000000000000000000001477355613200150475ustar00rootroot00000000000000dbus-fast-2.44.1/.github/ISSUE_TEMPLATE/000077500000000000000000000000001477355613200172325ustar00rootroot00000000000000dbus-fast-2.44.1/.github/ISSUE_TEMPLATE/1-bug_report.md000066400000000000000000000004221477355613200220600ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve labels: bug --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: **Additional context** Add any other context about the problem here. dbus-fast-2.44.1/.github/ISSUE_TEMPLATE/2-feature-request.md000066400000000000000000000006721477355613200230410ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project labels: enhancement --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Additional context** Add any other context or screenshots about the feature request here. dbus-fast-2.44.1/.github/dependabot.yml000066400000000000000000000013511477355613200176770ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" commit-message: prefix: "chore(deps-ci): " groups: github-actions: patterns: - "*" - package-ecosystem: "pip" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" dbus-fast-2.44.1/.github/labels.toml000066400000000000000000000035151477355613200172120ustar00rootroot00000000000000[breaking] color = "ffcc00" name = "breaking" description = "Breaking change." [bug] color = "d73a4a" name = "bug" description = "Something isn't working" [dependencies] color = "0366d6" name = "dependencies" description = "Pull requests that update a dependency file" [github_actions] color = "000000" name = "github_actions" description = "Update of github actions" [documentation] color = "1bc4a5" name = "documentation" description = "Improvements or additions to documentation" [duplicate] color = "cfd3d7" name = "duplicate" description = "This issue or pull request already exists" [enhancement] color = "a2eeef" name = "enhancement" description = "New feature or request" ["good first issue"] color = "7057ff" name = "good first issue" description = "Good for newcomers" ["help wanted"] color = "008672" name = "help wanted" description = "Extra attention is needed" [invalid] color = "e4e669" name = "invalid" description = "This doesn't seem right" [nochangelog] color = "555555" name = "nochangelog" description = "Exclude pull requests from changelog" [question] color = "d876e3" name = "question" description = "Further information is requested" [removed] color = "e99695" name = "removed" description = "Removed piece of functionalities." [tests] color = "bfd4f2" name = "tests" description = "CI, CD and testing related changes" [wontfix] color = "ffffff" name = "wontfix" description = "This will not be worked on" [discussion] color = "c2e0c6" name = "discussion" description = "Some discussion around the project" [hacktoberfest] color = "ffa663" name = "hacktoberfest" description = "Good issues for Hacktoberfest" [answered] color = "0ee2b6" name = "answered" description = "Automatically closes as answered after a delay" [waiting] color = "5f7972" name = "waiting" description = "Automatically closes if no answer after a delay" dbus-fast-2.44.1/.github/workflows/000077500000000000000000000000001477355613200171045ustar00rootroot00000000000000dbus-fast-2.44.1/.github/workflows/ci.yml000066400000000000000000000200541477355613200202230ustar00rootroot00000000000000name: CI on: push: branches: - main pull_request: concurrency: group: ${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5 with: python-version: "3.9" - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 # Make sure commit messages follow the conventional commits convention: # https://www.conventionalcommits.org commitlint: name: Lint Commit Messages runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6 test: strategy: fail-fast: false matrix: python-version: - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" os: - ubuntu-latest extension: - "skip_cython" - "use_cython" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install libs run: sudo apt-get install -y dbus-daemon python3-gi libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 - uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 - name: Set up Python uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5 with: python-version: ${{ matrix.python-version }} cache: "poetry" allow-prereleases: true - name: Install Dependencies run: | if [ "${{ matrix.extension }}" = "skip_cython" ]; then SKIP_CYTHON=1 poetry install --only=main,dev else REQUIRE_CYTHON=1 poetry install --only=main,dev fi - name: Test with Pytest run: dbus-run-session -- poetry run pytest --cov-report=xml --timeout=5 - name: Upload coverage to Codecov uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5 with: token: ${{ secrets.CODECOV_TOKEN }} test_big_endian: name: Big-endian s390x tests runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: uraimo/run-on-arch-action@1c358dc49363439f8c563ce8f93005f7fe76b849 # v3 name: Run commands id: runcmd with: arch: s390x distro: ubuntu_latest run: | apt-get -y update apt-get -y install git python3-pip python3-venv python3-poetry dbus-daemon python3-gi libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 git clone --depth 1 $GITHUB_SERVER_URL/$GITHUB_REPOSITORY cd dbus-fast git fetch origin --depth 1 $GITHUB_SHA git checkout $GITHUB_SHA REQUIRE_CYTHON=1 poetry install --only=main,dev dbus-run-session -- poetry run pytest --no-cov --timeout=100 benchmark: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install libs run: sudo apt-get install -y dbus-daemon python3-gi libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 - uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1 - name: Setup Python 3.13 uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5 with: python-version: 3.13 cache: "poetry" - name: Install Dependencies run: | REQUIRE_CYTHON=1 poetry install --only=main,dev shell: bash - name: Run benchmarks uses: CodSpeedHQ/action@0010eb0ca6e89b80c88e8edaaa07cfe5f3e6664d # v3 with: token: ${{ secrets.CODSPEED_TOKEN }} run: dbus-run-session -- poetry run pytest --no-cov -vvvvv --codspeed tests/benchmarks release: needs: - test - lint - commitlint runs-on: ubuntu-latest environment: release concurrency: release permissions: id-token: write contents: write outputs: released: ${{ steps.release.outputs.released }} newest_release_tag: ${{ steps.release_tag.outputs.newest_release_tag }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 ref: ${{ github.head_ref || github.ref_name }} # Do a dry run of PSR - name: Test release uses: python-semantic-release/python-semantic-release@26bb37cfab71a5a372e3db0f48a6eac57519a4a6 # v9.21.0 if: github.ref_name != 'main' with: root_options: --noop # On main branch: actual PSR + upload to PyPI & GitHub - name: Release uses: python-semantic-release/python-semantic-release@26bb37cfab71a5a372e3db0f48a6eac57519a4a6 # v9.21.0 id: release if: github.ref_name == 'main' with: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 if: steps.release.outputs.released == 'true' - name: Publish package distributions to GitHub Releases uses: python-semantic-release/upload-to-gh-release@0a92b5d7ebfc15a84f9801ebd1bf706343d43711 # main if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Install python-semantic-release run: python3 -m pip install python-semantic-release==7.34.6 - name: Get Release Tag id: release_tag shell: bash run: | echo "newest_release_tag=$(semantic-release print-version --current)" >> $GITHUB_OUTPUT build_wheels: needs: [release] if: needs.release.outputs.released == 'true' name: Build wheels on ${{ matrix.os }} with arch ${{ matrix.arch }} runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-24.04-arm, ubuntu-latest, macos-latest] musl: ["", "musllinux"] exclude: - os: macos-latest musl: "musllinux" steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: ref: "v${{ needs.release.outputs.newest_release_tag }}" fetch-depth: 0 # Used to host cibuildwheel - name: Set up Python uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5 - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.22.0 - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse # to supply options, put them in 'env', like: env: CIBW_SKIP: "*p36-* *p37-* *p38-* ${{ matrix.musl == 'musllinux' && '*manylinux*' || '*musllinux*' }}" CIBW_BEFORE_ALL_LINUX: apt-get install -y gcc || yum install -y gcc || apk add gcc CIBW_BUILD_VERBOSITY: 3 REQUIRE_CYTHON: 1 CIBW_ARCHS_LINUX: ${{ matrix.os == 'ubuntu-24.04-arm' && 'aarch64' || 'auto' }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: path: ./wheelhouse/*.whl name: wheels-${{ matrix.os }}-${{ matrix.musl }} upload_pypi: needs: [build_wheels] runs-on: ubuntu-latest environment: release permissions: id-token: write contents: write steps: - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 with: # unpacks default artifact into dist/ # if `name: artifact` is omitted, the action will create extra parent dir pattern: wheels-* path: dist merge-multiple: true - uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 dbus-fast-2.44.1/.github/workflows/hacktoberfest.yml000066400000000000000000000006071477355613200224560ustar00rootroot00000000000000name: Hacktoberfest on: schedule: # Run every day in October - cron: "0 0 * 10 *" # Run on the 1st of November to revert - cron: "0 13 1 11 *" jobs: hacktoberfest: runs-on: ubuntu-latest steps: - uses: browniebroke/hacktoberfest-labeler-action@4b84e14a51c188ef9fb917854ae8310440c27bae # v2.3.0 with: github_token: ${{ secrets.GH_PAT }} dbus-fast-2.44.1/.github/workflows/issue-manager.yml000066400000000000000000000014131477355613200223660ustar00rootroot00000000000000name: Issue Manager on: schedule: - cron: "0 0 * * *" issue_comment: types: - created issues: types: - labeled pull_request_target: types: - labeled workflow_dispatch: jobs: issue-manager: runs-on: ubuntu-latest steps: - uses: tiangolo/issue-manager@f94f76c8fa2c48bb2982a099c29a0caadb92917e # 0.5.1 with: token: ${{ secrets.GITHUB_TOKEN }} config: > { "answered": { "message": "Assuming the original issue was solved, it will be automatically closed now." }, "waiting": { "message": "Automatically closing. To re-open, please provide the additional information requested." } } dbus-fast-2.44.1/.github/workflows/labels.yml000066400000000000000000000011221477355613200210650ustar00rootroot00000000000000name: Sync Github labels on: push: branches: - main paths: - ".github/**" jobs: labels: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Set up Python uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5 with: python-version: 3.8 - name: Install labels run: pip install labels - name: Sync config with Github run: labels -u ${{ github.repository_owner }} -t ${{ secrets.GITHUB_TOKEN }} sync -f .github/labels.toml dbus-fast-2.44.1/.gitignore000066400000000000000000000040661477355613200155050ustar00rootroot00000000000000# Created by .ignore support plugin (hsz.mobi) ### Python template # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder .pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ dbus-fast-2.44.1/.gitpod.yml000066400000000000000000000003061477355613200155750ustar00rootroot00000000000000tasks: - command: | pip install poetry PIP_USER=false poetry install - command: | pip install pre-commit pre-commit install PIP_USER=false pre-commit install-hooks dbus-fast-2.44.1/.idea/000077500000000000000000000000001477355613200144675ustar00rootroot00000000000000dbus-fast-2.44.1/.idea/dbus-fast.iml000066400000000000000000000005151477355613200170630ustar00rootroot00000000000000 dbus-fast-2.44.1/.idea/watcherTasks.xml000066400000000000000000000052531477355613200176610ustar00rootroot00000000000000 dbus-fast-2.44.1/.idea/workspace.xml000066400000000000000000000027251477355613200172150ustar00rootroot00000000000000 dbus-fast-2.44.1/.pre-commit-config.yaml000066400000000000000000000031131477355613200177660ustar00rootroot00000000000000# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks exclude: "CHANGELOG.md" default_stages: [pre-commit] ci: autofix_commit_msg: "chore(pre-commit.ci): auto fixes" autoupdate_commit_msg: "chore(pre-commit.ci): pre-commit autoupdate" repos: - repo: https://github.com/commitizen-tools/commitizen rev: v4.4.1 hooks: - id: commitizen stages: [commit-msg] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: debug-statements - id: check-builtin-literals - id: check-case-conflict - id: check-json - id: check-toml - id: check-xml - id: check-yaml - id: detect-private-key - id: end-of-file-fixer - id: trailing-whitespace - id: debug-statements - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0-alpha.8 hooks: - id: prettier args: ["--tab-width", "2"] - repo: https://github.com/asottile/pyupgrade rev: v3.19.1 hooks: - id: pyupgrade args: [--py39-plus] - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.11.2 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format # - repo: https://github.com/codespell-project/codespell # rev: v2.2.1 # hooks: # - id: codespell # - repo: https://github.com/PyCQA/flake8 # rev: 5.0.4 # hooks: # - id: flake8 # - repo: https://github.com/pre-commit/mirrors-mypy # rev: v0.931 # hooks: # - id: mypy # additional_dependencies: [] dbus-fast-2.44.1/.readthedocs.yml000066400000000000000000000010061477355613200165720ustar00rootroot00000000000000# Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/source/conf.py # Set the version of Python and other tools you might need build: os: ubuntu-20.04 tools: python: "3.12" # Optionally declare the Python requirements required to build your docs python: install: - requirements: docs/requirements.txt - method: pip path: . dbus-fast-2.44.1/CHANGELOG.md000066400000000000000000003040301477355613200153200ustar00rootroot00000000000000# CHANGELOG ## v2.44.1 (2025-04-03) ### Bug Fixes - Correct documentation URLs in README ([#446](https://github.com/Bluetooth-Devices/dbus-fast/pull/446), [`0bd01fc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0bd01fc1aaab3509f5549f1b3eac322e7af6319b)) ## v2.44.0 (2025-04-01) ### Chores - Pin github actions to specific SHAs to mitigate supply chain attacks ([#442](https://github.com/Bluetooth-Devices/dbus-fast/pull/442), [`b69c865`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b69c865738af4e72f3e2113cf7362f41d13ce1ef)) - **deps-dev**: Bump pytest-asyncio from 0.25.3 to 0.26.0 ([#443](https://github.com/Bluetooth-Devices/dbus-fast/pull/443), [`3f63386`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3f633862a7f4d1dd9ae0c2412ec9cef495b69058)) - **deps-dev**: Bump setuptools from 76.0.0 to 78.0.1 ([#439](https://github.com/Bluetooth-Devices/dbus-fast/pull/439), [`33332d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/33332d9ec0bc980a68916457bcb59c04a3673a01)) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 78.0.1 to 78.1.0 ([#444](https://github.com/Bluetooth-Devices/dbus-fast/pull/444), [`f59d9f9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f59d9f92c795c7aa0c62000a0c7a6c0a86d89337)) - **pre-commit.ci**: Pre-commit autoupdate ([#440](https://github.com/Bluetooth-Devices/dbus-fast/pull/440), [`f00f224`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f00f224da36f5a4340ec6641853722f6d7243dfb)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ### Features - Use trusted publishing to upload wheels ([#445](https://github.com/Bluetooth-Devices/dbus-fast/pull/445), [`19df266`](https://github.com/Bluetooth-Devices/dbus-fast/commit/19df2666ab599eecb254a7e0c874fc7a5e0a5b01)) ## v2.43.0 (2025-03-23) ### Features - Improve unmarshall performance for SignatureType ([#436](https://github.com/Bluetooth-Devices/dbus-fast/pull/436), [`e0aeeac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e0aeeacf8db3819f7771be35880fbbc2696ef434)) ## v2.42.0 (2025-03-23) ### Features - Simplify code to unmarshall arrays ([#435](https://github.com/Bluetooth-Devices/dbus-fast/pull/435), [`958115f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/958115f77bee0b35fde11386f507d96ad26597cc)) ## v2.41.1 (2025-03-23) ### Bug Fixes - No change re-release ([#433](https://github.com/Bluetooth-Devices/dbus-fast/pull/433), [`f79930d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f79930d0c41845e78978bfcef02c35bdcba7e391)) ## v2.41.0 (2025-03-23) ### Chores - Add benchmark for interfaces added message ([#432](https://github.com/Bluetooth-Devices/dbus-fast/pull/432), [`1988984`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1988984398dac14daf93f11005b647b646bdf00a)) ### Features - Improve performance of unmarshalling boolean Variants ([#431](https://github.com/Bluetooth-Devices/dbus-fast/pull/431), [`888a3c3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/888a3c3ea57e1d8c5f415f2efdf7aa6eed5c9fcd)) * feat: improve performance of boolean Variants There are only two of these type and relatively common so we can use pre-constructed objects * chore: tweaks ## v2.40.0 (2025-03-23) ### Chores - Add socket unmarshall benchmark ([#428](https://github.com/Bluetooth-Devices/dbus-fast/pull/428), [`1802f35`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1802f35ce9267d8af728045ba47277779af7fea7)) * chore: add socket unmarshall benchmark * chore: bench multiple messages - Remove lower python bound from PyGObject ([#425](https://github.com/Bluetooth-Devices/dbus-fast/pull/425), [`28615ee`](https://github.com/Bluetooth-Devices/dbus-fast/commit/28615ee7eb00d7e50f68818f8c9915a1f570c8e5)) - **pre-commit.ci**: Pre-commit autoupdate ([#427](https://github.com/Bluetooth-Devices/dbus-fast/pull/427), [`bfc8151`](https://github.com/Bluetooth-Devices/dbus-fast/commit/bfc8151005e143c961421d4e2c5e05ac58964100)) * chore(pre-commit.ci): pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.1.0 → v0.11.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.0...v0.11.0) * chore(pre-commit.ci): auto fixes * chore: fix violations --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston ### Features - Improve unmarshaller performance for byte strings ([#430](https://github.com/Bluetooth-Devices/dbus-fast/pull/430), [`3b4bac5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3b4bac5524435e5669bd5f513a9175f71af7f7a9)) ## v2.39.6 (2025-03-17) ### Bug Fixes - Don't limit python upper bound ([#424](https://github.com/Bluetooth-Devices/dbus-fast/pull/424), [`9cafbb6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9cafbb6a0b70d975b73889ded99e2e0a6af2b467)) This requires all projects that depend on dbus-fast to have to set the same limit, which is an unnecessary burden. * fix: adjust pygobject pin to required python < 4 (see https://gitlab.gnome.org/GNOME/pygobject/-/merge_requests/418) --------- Co-authored-by: J. Nick Koston ### Chores - Remove workflow from previous failed attempt at testing big-endian ([#423](https://github.com/Bluetooth-Devices/dbus-fast/pull/423), [`20e102c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/20e102ca8f0606f6abe26fb35a30e94997740bcc)) ## v2.39.5 (2025-03-13) ### Bug Fixes - Upgrade to ruff 0.1.0 and fix violations ([#422](https://github.com/Bluetooth-Devices/dbus-fast/pull/422), [`7e4cab6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7e4cab6778e8cfb2894e638a7d47eff1cc191bff)) ## v2.39.4 (2025-03-13) ### Bug Fixes - Multiple calls on the root logger instead of module logger ([#421](https://github.com/Bluetooth-Devices/dbus-fast/pull/421), [`b7c4a31`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b7c4a3117e5978cb712469f75f49d5e2002614b8)) ### Chores - **deps-dev**: Bump setuptools from 75.8.2 to 76.0.0 ([#418](https://github.com/Bluetooth-Devices/dbus-fast/pull/418), [`128ba12`](https://github.com/Bluetooth-Devices/dbus-fast/commit/128ba128586ea740fa60d6be8ba311791b6dabb6)) - **pre-commit.ci**: Pre-commit autoupdate ([#420](https://github.com/Bluetooth-Devices/dbus-fast/pull/420), [`45acd54`](https://github.com/Bluetooth-Devices/dbus-fast/commit/45acd54868c12f784287fb19104a3bf6bc17d745)) ## v2.39.3 (2025-03-07) ### Bug Fixes - Ensure void methods that can raise exceptions are marked ([#417](https://github.com/Bluetooth-Devices/dbus-fast/pull/417), [`c433dab`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c433dab7b5622f3103607acb1acd7a91db841419)) ### Chores - Update aio package typing ([#416](https://github.com/Bluetooth-Devices/dbus-fast/pull/416), [`28888b9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/28888b9f49e063b122d6116309fbb3d0aec984f7)) ## v2.39.2 (2025-03-07) ### Bug Fixes - Correct size of uint32 with cython ([#415](https://github.com/Bluetooth-Devices/dbus-fast/pull/415), [`f64eb58`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f64eb58573e068ad731f6dc268dd903dee2e66af)) * chore: add more coverage for big endian systems * chore: fix overflow * fix: should have been unsigned int ## v2.39.1 (2025-03-07) ### Bug Fixes - Ensure proxy object tasks do not get garbage collected prematurely ([#409](https://github.com/Bluetooth-Devices/dbus-fast/pull/409), [`4fcdbed`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4fcdbed1e5ab828e95b2a16ac0058ebbe0a64f78)) ## v2.39.0 (2025-03-06) ### Chores - Enable some more ruff rules ([#414](https://github.com/Bluetooth-Devices/dbus-fast/pull/414), [`2bad648`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2bad648c61f139e168c083b05e183ceaa29005f8)) - Sort imports ([#413](https://github.com/Bluetooth-Devices/dbus-fast/pull/413), [`a589651`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a589651511e1787f0025d7ab440ed1617b133b48)) ### Features - Improve performance of signature lookups ([#412](https://github.com/Bluetooth-Devices/dbus-fast/pull/412), [`5068e41`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5068e41488e71499265e1fc3ea7d4210821e09a2)) - Added `SignatureTree` type in a few more places to avoid python lookups - Improved performance and reduced code to create `Variant` object ## v2.38.0 (2025-03-06) ### Chores - Remove unused boilerplate cruft ([#411](https://github.com/Bluetooth-Devices/dbus-fast/pull/411), [`a56381a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a56381a7a10b243061f29d0f90b3fd63d2e600e4)) ### Features - Improve performance of checking SignatureType tokens ([#410](https://github.com/Bluetooth-Devices/dbus-fast/pull/410), [`4887160`](https://github.com/Bluetooth-Devices/dbus-fast/commit/488716020e275ef777454724d2ab41cfc050b40a)) * feat: improve performance of checking SignatureType tokens * chore: fixes ## v2.37.1 (2025-03-06) ### Bug Fixes - Correctly handle big endian data ([#405](https://github.com/Bluetooth-Devices/dbus-fast/pull/405), [`0adab93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0adab935e3c5850647e640c777daf4273ea1efd9)) ### Chores - Add s390x tests ([#408](https://github.com/Bluetooth-Devices/dbus-fast/pull/408), [`81ce030`](https://github.com/Bluetooth-Devices/dbus-fast/commit/81ce03058a64e9fd304981ef9e05bf6415dc1fb3)) - Add more coverage for marshall ([#406](https://github.com/Bluetooth-Devices/dbus-fast/pull/406), [`ed38f69`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ed38f690f5926b17354810c51ac0dee900d9f01e)) - Fix type for hello message constant ([#407](https://github.com/Bluetooth-Devices/dbus-fast/pull/407), [`df5325a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/df5325a7ef80de544e16783deec3ea183e02d6ba)) core: fix type for hello message constant - Update deps ([#404](https://github.com/Bluetooth-Devices/dbus-fast/pull/404), [`6dca98d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6dca98d68af494641c91cf53949fe207188b99a3)) dependabot is still broken with poetry 2 - Updating certifi (2024.12.14 -> 2025.1.31) - Updating babel (2.16.0 -> 2.17.0) - Updating jinja2 (3.1.5 -> 3.1.6) - Updating coverage (7.6.10 -> 7.6.12) ## v2.37.0 (2025-03-06) ### Features - Add support for finding message handlers when interface is None ([#403](https://github.com/Bluetooth-Devices/dbus-fast/pull/403), [`bfd48a3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/bfd48a3a38cba0dc66d581eedd0da0b228bc1953)) ## v2.36.0 (2025-03-05) ### Chores - Add covdefaults ([#401](https://github.com/Bluetooth-Devices/dbus-fast/pull/401), [`dc3d8e7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dc3d8e7609f37a2f064a45ae525c5ce5711ea272)) - Upgrade typing on private modules ([#402](https://github.com/Bluetooth-Devices/dbus-fast/pull/402), [`640e1f8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/640e1f8d87a753d6721dae77ee94ff8702a2f508)) * chore: upgrade typing on private modules * chore: typing fixes ### Features - Refactor service bus handler lookup to avoid linear searches ([#400](https://github.com/Bluetooth-Devices/dbus-fast/pull/400), [`996659e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/996659e1b5fefeda7eb01259714a4a17fc224b9f)) ## v2.35.1 (2025-03-05) ### Bug Fixes - Reduce size of wheels ([#399](https://github.com/Bluetooth-Devices/dbus-fast/pull/399), [`6531b93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6531b93a5ba5447494818cf7f8c38454b1338052)) first attempt failed to change the correct constant in build_ext.py ## v2.35.0 (2025-03-05) ### Chores - **deps-ci**: Bump python-semantic-release/python-semantic-release from 9.17.0 to 9.21.0 in the github-actions group ([#394](https://github.com/Bluetooth-Devices/dbus-fast/pull/394), [`a7e1a90`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a7e1a907e360c1f3fc01a62a414693782f536e61)) chore(deps-ci): bump python-semantic-release/python-semantic-release Bumps the github-actions group with 1 update: [python-semantic-release/python-semantic-release](https://github.com/python-semantic-release/python-semantic-release). Updates `python-semantic-release/python-semantic-release` from 9.17.0 to 9.21.0 - [Release notes](https://github.com/python-semantic-release/python-semantic-release/releases) - [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.rst) - [Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v9.17.0...v9.21.0) --- updated-dependencies: - dependency-name: python-semantic-release/python-semantic-release dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump pytest from 8.3.4 to 8.3.5 ([#395](https://github.com/Bluetooth-Devices/dbus-fast/pull/395), [`0d0e600`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0d0e600a940fa4cb82473fec7bfb8706ed7ff7f7)) - **deps-dev**: Bump setuptools from 75.8.0 to 75.8.2 ([#396](https://github.com/Bluetooth-Devices/dbus-fast/pull/396), [`2623a74`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2623a7412afeb906b2863b05fefb0d94e8881dcb)) - **pre-commit.ci**: Pre-commit autoupdate ([#392](https://github.com/Bluetooth-Devices/dbus-fast/pull/392), [`3ef89bf`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3ef89bfbf45592401dae60bf93104e063f082160)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#397](https://github.com/Bluetooth-Devices/dbus-fast/pull/397), [`3dd7c35`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3dd7c358fad92ef7dcb42c361ebac367f10e3ce2)) updates: - [github.com/commitizen-tools/commitizen: v4.2.2 → v4.4.1](https://github.com/commitizen-tools/commitizen/compare/v4.2.2...v4.4.1) - [github.com/astral-sh/ruff-pre-commit: v0.9.7 → v0.9.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.7...v0.9.9) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ### Features - Reduce size of wheels ([#398](https://github.com/Bluetooth-Devices/dbus-fast/pull/398), [`a4c2743`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a4c2743420f619d8808413d8877b2c9badc5f3f0)) Compile with -g0 to reduce the binary size ## v2.34.0 (2025-02-24) ### Chores - **deps-dev**: Bump cython from 3.0.11 to 3.0.12 ([#391](https://github.com/Bluetooth-Devices/dbus-fast/pull/391), [`5f26f5d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5f26f5d58c5e0ed6251c66ab4724f27a383500a0)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#389](https://github.com/Bluetooth-Devices/dbus-fast/pull/389), [`c713bf3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c713bf3de994564c92628f92bdf341fbf813c8f4)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ### Features - Resync generic D-Bus errors ([#393](https://github.com/Bluetooth-Devices/dbus-fast/pull/393), [`e4f37ee`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e4f37ee10bd2af64716de0bd389db90b47373b76)) ## v2.33.0 (2025-02-05) ### Chores - **deps-dev**: Bump pytest-asyncio from 0.25.2 to 0.25.3 ([#385](https://github.com/Bluetooth-Devices/dbus-fast/pull/385), [`e6c75a6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e6c75a61828e260830720cff36a010e54b7efebe)) - **deps-dev**: Bump pytest-codspeed from 3.1.2 to 3.2.0 ([#384](https://github.com/Bluetooth-Devices/dbus-fast/pull/384), [`9f966af`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9f966af1dbeba8af6d7119877801e5140daf4002)) - **pre-commit.ci**: Pre-commit autoupdate ([#386](https://github.com/Bluetooth-Devices/dbus-fast/pull/386), [`0a9e4c5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0a9e4c5a2140f20f580c67bed2a68ff0ac524b62)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ### Features - Build macos arm wheels ([#387](https://github.com/Bluetooth-Devices/dbus-fast/pull/387), [`829e0fc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/829e0fc149957b3bf0fc0f4a89bb2e676e584f84)) ## v2.32.0 (2025-02-02) ### Features - Speed up marshalling messages ([#383](https://github.com/Bluetooth-Devices/dbus-fast/pull/383), [`d7213be`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d7213be28578b3effa3aeea85bab5de92bba224d)) ## v2.31.0 (2025-02-02) ### Features - Speed up bytearray creation in unmarshaller ([#382](https://github.com/Bluetooth-Devices/dbus-fast/pull/382), [`89026e3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/89026e3b597bd1a318114b6cf50e27d29d9cbca8)) ## v2.30.4 (2025-02-02) ### Bug Fixes - Docs build ([#381](https://github.com/Bluetooth-Devices/dbus-fast/pull/381), [`c21a2ac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c21a2ac15a09b2ebf79afa53439fbc45214d4dc0)) ## v2.30.3 (2025-02-02) ### Bug Fixes - Attempting to unmarshall some arrays twice ([#380](https://github.com/Bluetooth-Devices/dbus-fast/pull/380), [`586dc23`](https://github.com/Bluetooth-Devices/dbus-fast/commit/586dc233fdb2ebc7d627cb94b55d80a77631416f)) ### Chores - Bump the github-actions group with 9 updates ([#372](https://github.com/Bluetooth-Devices/dbus-fast/pull/372), [`94ba266`](https://github.com/Bluetooth-Devices/dbus-fast/commit/94ba26653987b7200cfb85ed92d46ea5d95a95a0)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston - Bump upload/download artifact to v4 ([#370](https://github.com/Bluetooth-Devices/dbus-fast/pull/370), [`29be224`](https://github.com/Bluetooth-Devices/dbus-fast/commit/29be224be7fd05970aa5473b8e86810c8978ab6c)) - Fix commitlint config ([#374](https://github.com/Bluetooth-Devices/dbus-fast/pull/374), [`b13712f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b13712f4c51810d9384b1fc924e61ad984800719)) - Fix release process ([#375](https://github.com/Bluetooth-Devices/dbus-fast/pull/375), [`de57a21`](https://github.com/Bluetooth-Devices/dbus-fast/commit/de57a21a3c22224032fd5e2672560a00e2fbcd12)) - Fix release upload ([#377](https://github.com/Bluetooth-Devices/dbus-fast/pull/377), [`eb56b64`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eb56b6464d9dc0c18465bf68030634f78a36fc5c)) - Fix semantic release fields ([#376](https://github.com/Bluetooth-Devices/dbus-fast/pull/376), [`4fe13e8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4fe13e88d1b636136e88ff6eacec0d6293280868)) - Update dependabot.yml prefix ([`c4e37b0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c4e37b077cb27d2916150aa57a90633b3eea3489)) - Update dependabot.yml to include actions ([`56c1595`](https://github.com/Bluetooth-Devices/dbus-fast/commit/56c1595be9f8047fd8f983e4baca9a92d5de0772)) - **deps-ci**: Bump the github-actions group with 2 updates ([#379](https://github.com/Bluetooth-Devices/dbus-fast/pull/379), [`1aab230`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1aab2304398de8a3dd7789efe4f82fb04eb54e37)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump pytest from 7.4.4 to 8.3.4 ([#334](https://github.com/Bluetooth-Devices/dbus-fast/pull/334), [`9ad3873`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9ad38730d57d92bf621d5ed799369b63e15aa1c0)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston - **deps-dev**: Bump pytest-asyncio from 0.23.8 to 0.25.2 ([#373](https://github.com/Bluetooth-Devices/dbus-fast/pull/373), [`922840b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/922840ba9d537a60b139f5becfd993fe84b1d50d)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#369](https://github.com/Bluetooth-Devices/dbus-fast/pull/369), [`9953959`](https://github.com/Bluetooth-Devices/dbus-fast/commit/995395953045969103361d08bf4f5de52ebe8790)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#378](https://github.com/Bluetooth-Devices/dbus-fast/pull/378), [`b58620a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b58620afd8e4981162677464689d2afd4474621d)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ## v2.30.2 (2025-01-17) ### Bug Fixes - Fetching release tag during build ([#368](https://github.com/Bluetooth-Devices/dbus-fast/pull/368), [`5a80415`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5a804159669c2caad9d1144120ebaeb602d9ad28)) ## v2.30.1 (2025-01-17) ### Bug Fixes - Wheel builds on aarch64 ([#367](https://github.com/Bluetooth-Devices/dbus-fast/pull/367), [`18132b9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/18132b99bcbada1f090ccfc1c0050caf0827cd11)) ## v2.30.0 (2025-01-17) ### Features - Migrate to using native arm runners for wheel builds ([#366](https://github.com/Bluetooth-Devices/dbus-fast/pull/366), [`bdf08d2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/bdf08d253bff9bc1edd7c9a5688b7d9e4eb73839)) ## v2.29.0 (2025-01-15) ### Bug Fixes - Void validate arguments/properties name ([#358](https://github.com/Bluetooth-Devices/dbus-fast/pull/358), [`f58f1a6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f58f1a6466d7ffb3a600774f8c36b5c93279437b)) ### Chores - **deps**: Bump sphinx from 7.1.2 to 7.4.7 ([#361](https://github.com/Bluetooth-Devices/dbus-fast/pull/361), [`0487639`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0487639ed702892a365f70991682f023aec29116)) - **deps-dev**: Bump pytest-codspeed from 3.1.1 to 3.1.2 ([#362](https://github.com/Bluetooth-Devices/dbus-fast/pull/362), [`e7750ca`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e7750caed5791aef0cbb8c62e82ccabf02f65df7)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump pytest-cov from 5.0.0 to 6.0.0 ([#363](https://github.com/Bluetooth-Devices/dbus-fast/pull/363), [`244ea83`](https://github.com/Bluetooth-Devices/dbus-fast/commit/244ea83a31631c54b3d97ad47b91786e1d02387f)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 75.7.0 to 75.8.0 ([#364](https://github.com/Bluetooth-Devices/dbus-fast/pull/364), [`8eee3a8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8eee3a82fdf2f2fde2dac52c4854b16e8bf0ac8d)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#365](https://github.com/Bluetooth-Devices/dbus-fast/pull/365), [`e006a1e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e006a1e861df6c3368f10600f6c390becae15c5c)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ### Features - **introspect**: Implement annotations ([#359](https://github.com/Bluetooth-Devices/dbus-fast/pull/359), [`5b61869`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b61869baec88cd1382419f4580c345473543493)) Co-authored-by: J. Nick Koston Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ## v2.28.0 (2025-01-07) ### Bug Fixes - Revert avoid building wheels if a release is not made ([#357](https://github.com/Bluetooth-Devices/dbus-fast/pull/357), [`ebdf07e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ebdf07ec9e875806c050c97027b6f7dca077bd7d)) ### Features - Improve performance of marshalling message headers ([#356](https://github.com/Bluetooth-Devices/dbus-fast/pull/356), [`e1aaf0a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e1aaf0a3969d595bc9d789cb5e40dfd59ef232c9)) - Improve performance of unmarshalling variants ([#354](https://github.com/Bluetooth-Devices/dbus-fast/pull/354), [`d376bb1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d376bb13ade9bac8b478a183a4a280d37d121ab9)) ## v2.27.0 (2025-01-07) ### Chores - Add marshall benchmark ([#353](https://github.com/Bluetooth-Devices/dbus-fast/pull/353), [`1164ca5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1164ca55dd7bb915bcac61e8a9b15ae009d51b66)) - Avoid building wheels if a release is not made ([#355](https://github.com/Bluetooth-Devices/dbus-fast/pull/355), [`f9ec254`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9ec25415064deb272e5664cd215f7dd31b869c0)) ### Features - Speed up marshalling messages ([#352](https://github.com/Bluetooth-Devices/dbus-fast/pull/352), [`b1e6551`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b1e6551de32bec5a8a5164540d44e1b1bfe86881)) ## v2.26.0 (2025-01-07) ### Features - Speed up constructing messages from the unmarshaller ([#344](https://github.com/Bluetooth-Devices/dbus-fast/pull/344), [`b162494`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b162494aa25fe4b23debdd9a44b49ea21c771ad1)) ## v2.25.0 (2025-01-07) ### Bug Fixes - Race in test_tcp_connection_with_forwarding ([#350](https://github.com/Bluetooth-Devices/dbus-fast/pull/350), [`4116261`](https://github.com/Bluetooth-Devices/dbus-fast/commit/41162618d4a78c193d91fb9525eb7d2763f17587)) ### Chores - Add codspeed badge ([#351](https://github.com/Bluetooth-Devices/dbus-fast/pull/351), [`1f7f52d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1f7f52dd89f7728c650f92182f14fe768f456621)) ### Features - Speed up unmarshalling headers ([#347](https://github.com/Bluetooth-Devices/dbus-fast/pull/347), [`5825758`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5825758991a5d5f476b082c0277e5ecb0767c7e5)) ## v2.24.6 (2025-01-07) ### Bug Fixes - Disable wheel builds for old python versions ([#346](https://github.com/Bluetooth-Devices/dbus-fast/pull/346), [`a249777`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a249777e03d71502cbbde5d20cab2f3685fb5adb)) ### Chores - Bump codecov action to v5 ([#343](https://github.com/Bluetooth-Devices/dbus-fast/pull/343), [`d1298de`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d1298de2a1e0f7aa6277835a55df1229c6552e8a)) ## v2.24.5 (2025-01-07) ### Bug Fixes - Ensure exceptions are logged when no reply is expected ([#342](https://github.com/Bluetooth-Devices/dbus-fast/pull/342), [`1c20dcc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1c20dcc50471b453d9b55bc2be197fd5b0c38a9c)) ### Chores - Add codspeed benchmarks ([#340](https://github.com/Bluetooth-Devices/dbus-fast/pull/340), [`5bf90b9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5bf90b9fb15e243801f7d39e7e57b52f5c694bcc)) - Drop Python 3.8 support as it has reached EOL ([#338](https://github.com/Bluetooth-Devices/dbus-fast/pull/338), [`42a786b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/42a786b23ff519d653d8accf7950b18604f3070a)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - Split wheel builds to speed up releases ([#341](https://github.com/Bluetooth-Devices/dbus-fast/pull/341), [`439b2da`](https://github.com/Bluetooth-Devices/dbus-fast/commit/439b2da8789d7e0ca0a70e4d4c074666248bd492)) - Switch to ruff ([#339](https://github.com/Bluetooth-Devices/dbus-fast/pull/339), [`eda3706`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eda37061c4b4068a2fd6b051f9becfc8ae7bba10)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **deps**: Bump sphinx-rtd-theme from 3.0.1 to 3.0.2 ([#332](https://github.com/Bluetooth-Devices/dbus-fast/pull/332), [`42ef44a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/42ef44a4aa38491b7608f84d84a6349aa11703e6)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx-rtd-theme from 3.0.1 to 3.0.2 ([#335](https://github.com/Bluetooth-Devices/dbus-fast/pull/335), [`663b371`](https://github.com/Bluetooth-Devices/dbus-fast/commit/663b37136f1b75245292d6bc6633e3184ff3d228)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#333](https://github.com/Bluetooth-Devices/dbus-fast/pull/333), [`b5c01a9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b5c01a926c95d6e65c2c597846596373393c88a2)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#336](https://github.com/Bluetooth-Devices/dbus-fast/pull/336), [`ea24a86`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ea24a86c1b2bb2b25da8e892a641bcd4e6b24b30)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#337](https://github.com/Bluetooth-Devices/dbus-fast/pull/337), [`471e680`](https://github.com/Bluetooth-Devices/dbus-fast/commit/471e68035470b2f6b29500347ec3e0443dc3648e)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ## v2.24.4 (2024-11-15) ### Bug Fixes - Exclude .c files from being shipped ([#331](https://github.com/Bluetooth-Devices/dbus-fast/pull/331), [`9c73022`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9c7302299ab002a1aec80062f0b9bd5c1bde46f9)) ### Chores - **deps**: Bump sphinx-rtd-theme from 2.0.0 to 3.0.0 ([#319](https://github.com/Bluetooth-Devices/dbus-fast/pull/319), [`f30bc57`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f30bc57bbad6e3fa2c62956233d171dfc9e7f3d9)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx-rtd-theme from 2.0.0 to 3.0.1 ([#322](https://github.com/Bluetooth-Devices/dbus-fast/pull/322), [`3131841`](https://github.com/Bluetooth-Devices/dbus-fast/commit/31318414720ecaa4b86ac8afbdb20066c9f43e07)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx-rtd-theme from 3.0.0 to 3.0.1 ([#326](https://github.com/Bluetooth-Devices/dbus-fast/pull/326), [`2831f9c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2831f9cc3633d4c6e47232f741213da2adbaf71a)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 75.1.0 to 75.2.0 ([#324](https://github.com/Bluetooth-Devices/dbus-fast/pull/324), [`fa3faa8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fa3faa86eec5568d74db2d1b8aa4c9af18b236f1)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 75.2.0 to 75.3.0 ([#328](https://github.com/Bluetooth-Devices/dbus-fast/pull/328), [`83bb550`](https://github.com/Bluetooth-Devices/dbus-fast/commit/83bb5502ed17a1d8256d27ef86079c3688d5a3cd)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#320](https://github.com/Bluetooth-Devices/dbus-fast/pull/320), [`46bc330`](https://github.com/Bluetooth-Devices/dbus-fast/commit/46bc3304a31149c3a0c4fdc3aa2047ea2232a22d)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston - **pre-commit.ci**: Pre-commit autoupdate ([#323](https://github.com/Bluetooth-Devices/dbus-fast/pull/323), [`9e2f17a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9e2f17a974fa7b2defdccc5038ace446567bb0b0)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#327](https://github.com/Bluetooth-Devices/dbus-fast/pull/327), [`4d3acc4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4d3acc49659779e6d3d2a57ed47ede49ce6b4208)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ## v2.24.3 (2024-10-05) ### Bug Fixes - Remove deprecated no_type_check_decorator ([#316](https://github.com/Bluetooth-Devices/dbus-fast/pull/316), [`0f04a79`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0f04a794f2e8b494c194e4f4856e43917bdda58a)) ### Chores - **deps**: Bump sphinx from 5.2.3 to 7.1.2 ([#312](https://github.com/Bluetooth-Devices/dbus-fast/pull/312), [`34d0d46`](https://github.com/Bluetooth-Devices/dbus-fast/commit/34d0d461c8764ae4aca0992909a22f03bf7d3133)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 74.1.2 to 75.1.0 ([#314](https://github.com/Bluetooth-Devices/dbus-fast/pull/314), [`aaa1e1e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/aaa1e1e0ea5a399897eaf185ce696f03d17ff4a9)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#317](https://github.com/Bluetooth-Devices/dbus-fast/pull/317), [`f2de447`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f2de4472dde27ca7dc1a83f049fbb89e0b2c6bb9)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ## v2.24.2 (2024-09-06) ### Bug Fixes - Ensure build uses cython3 ([#311](https://github.com/Bluetooth-Devices/dbus-fast/pull/311), [`2dabf2d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2dabf2ddcbbd7e46551521100734372a52458ce4)) ## v2.24.1 (2024-09-06) ### Bug Fixes - Add missing cython version pin to the build system ([#310](https://github.com/Bluetooth-Devices/dbus-fast/pull/310), [`1b7d28c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1b7d28cd1f1b78631335cc9945be218aacf6e3f6)) ### Chores - **deps**: Bump myst-parser from 1.0.0 to 3.0.1 ([#306](https://github.com/Bluetooth-Devices/dbus-fast/pull/306), [`8b3e95c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8b3e95c6cc6d9e8396d2ee6b1883df700fb3f23b)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx from 5.2.3 to 7.1.2 ([#307](https://github.com/Bluetooth-Devices/dbus-fast/pull/307), [`e393611`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e393611fbf44f5f0598c8f7762034356a893cdbb)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 73.0.1 to 74.0.0 ([#308](https://github.com/Bluetooth-Devices/dbus-fast/pull/308), [`757a742`](https://github.com/Bluetooth-Devices/dbus-fast/commit/757a7424d20efc61f2de1f5f447277fd17eb94ed)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> ## v2.24.0 (2024-08-26) ### Chores - **deps**: Bump myst-parser from 0.18.1 to 1.0.0 ([#296](https://github.com/Bluetooth-Devices/dbus-fast/pull/296), [`b225cca`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b225cca97a60a8c05b892d438b461904efc42fa2)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump myst-parser from 0.18.1 to 1.0.0 ([#304](https://github.com/Bluetooth-Devices/dbus-fast/pull/304), [`0b372ea`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0b372eac98e962c349d1933472d37085fb5abad7)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump myst-parser from 1.0.0 to 3.0.1 ([#305](https://github.com/Bluetooth-Devices/dbus-fast/pull/305), [`dae0088`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dae00881a7922af67a5d1076a31bc295d43f5e14)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx from 5.2.3 to 6.2.1 ([#300](https://github.com/Bluetooth-Devices/dbus-fast/pull/300), [`ad1e078`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ad1e078ee9d11ab8bcffe3df8e20f2d0337a2dd1)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx-rtd-theme from 1.0.0 to 2.0.0 ([#293](https://github.com/Bluetooth-Devices/dbus-fast/pull/293), [`95df9a6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/95df9a6265b62d9e7f0c243f1cf5b0e64a18f369)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps**: Bump sphinx-rtd-theme from 1.0.0 to 2.0.0 ([#302](https://github.com/Bluetooth-Devices/dbus-fast/pull/302), [`6e496eb`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6e496eb222ed3c20627c0fc7c2c3f2e5f0dfb807)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump pytest-cov from 3.0.0 to 5.0.0 ([#301](https://github.com/Bluetooth-Devices/dbus-fast/pull/301), [`84c7346`](https://github.com/Bluetooth-Devices/dbus-fast/commit/84c73467ac43218091320989b3e32f8a36840c23)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> ### Features - Use dbus-run-session to drop X11 dependency ([#299](https://github.com/Bluetooth-Devices/dbus-fast/pull/299), [`42f1d4a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/42f1d4a3f2515a301c12f8f485457a878d7df2dc)) ## v2.23.0 (2024-08-21) ### Chores - **deps-dev**: Bump certifi from 2024.6.2 to 2024.7.4 in the pip group across 1 directory ([#298](https://github.com/Bluetooth-Devices/dbus-fast/pull/298), [`705ad28`](https://github.com/Bluetooth-Devices/dbus-fast/commit/705ad28ce7bd5b455d643101ba9ad682d503360b)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump cython from 0.29.37 to 3.0.11 ([#292](https://github.com/Bluetooth-Devices/dbus-fast/pull/292), [`8b4cdef`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8b4cdefe3e20e8eccdbfbe6402e0593cc8134bbd)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump pytest-asyncio from 0.19.0 to 0.23.8 ([#294](https://github.com/Bluetooth-Devices/dbus-fast/pull/294), [`f946183`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9461831f49a1172af5a77df3138bdffbd94c61b)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **deps-dev**: Bump setuptools from 65.7.0 to 73.0.1 ([#295](https://github.com/Bluetooth-Devices/dbus-fast/pull/295), [`af4989b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/af4989b7f71eb9f77e92832901aeeeee4c7f8504)) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#286](https://github.com/Bluetooth-Devices/dbus-fast/pull/286), [`5d9bb92`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5d9bb92da6e363320b8afa5942e6f0b4a4ecd4d0)) * chore(pre-commit.ci): pre-commit autoupdate updates: - [github.com/commitizen-tools/commitizen: v2.32.4 → v3.27.0](https://github.com/commitizen-tools/commitizen/compare/v2.32.4...v3.27.0) - [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.6.0) - [github.com/pre-commit/mirrors-prettier: v2.7.1 → v4.0.0-alpha.8](https://github.com/pre-commit/mirrors-prettier/compare/v2.7.1...v4.0.0-alpha.8) - [github.com/asottile/pyupgrade: v2.37.3 → v3.16.0](https://github.com/asottile/pyupgrade/compare/v2.37.3...v3.16.0) - [github.com/PyCQA/isort: 5.12.0 → 5.13.2](https://github.com/PyCQA/isort/compare/5.12.0...5.13.2) - [github.com/psf/black: 22.8.0 → 24.4.2](https://github.com/psf/black/compare/22.8.0...24.4.2) * chore(pre-commit.ci): auto fixes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#287](https://github.com/Bluetooth-Devices/dbus-fast/pull/287), [`b508e1f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b508e1fc5fbd4f5200b1fa46c913569fc02f6f4e)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#288](https://github.com/Bluetooth-Devices/dbus-fast/pull/288), [`c960552`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c96055289d697b847e93ed4f4c7fc7c1893e1642)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#289](https://github.com/Bluetooth-Devices/dbus-fast/pull/289), [`398f643`](https://github.com/Bluetooth-Devices/dbus-fast/commit/398f643f718e15903183f480726d959e0d85c4da)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> - **pre-commit.ci**: Pre-commit autoupdate ([#290](https://github.com/Bluetooth-Devices/dbus-fast/pull/290), [`ee98f7c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ee98f7c4536e9020f1b28fc916c2bfeb52cc31ac)) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ### Features - Python 3.13 support ([#291](https://github.com/Bluetooth-Devices/dbus-fast/pull/291), [`45c0e74`](https://github.com/Bluetooth-Devices/dbus-fast/commit/45c0e7491da85ed754a86358bffa2260f96c240f)) ## v2.22.1 (2024-06-26) ### Bug Fixes - Wheel build exclude for pp37 ([#285](https://github.com/Bluetooth-Devices/dbus-fast/pull/285), [`c44eb2c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c44eb2cabd8a7c5156d9cb2228f058140c004c36)) ## v2.22.0 (2024-06-26) ### Chores - Drop python 3.7 support ([#284](https://github.com/Bluetooth-Devices/dbus-fast/pull/284), [`fa48bc0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fa48bc025c1edf30451a7c0fb4ec639d927d045c)) ### Features - Build wheels for aarch64 to allow use in embedded systems ([#283](https://github.com/Bluetooth-Devices/dbus-fast/pull/283), [`d0ac990`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d0ac990a7aa9eec14d8c9c9720e4894de6dcf9b5)) ## v2.21.3 (2024-05-20) ### Bug Fixes - Clear exception flag on disconnect future if its also sent to handlers ([#281](https://github.com/Bluetooth-Devices/dbus-fast/pull/281), [`be68a79`](https://github.com/Bluetooth-Devices/dbus-fast/commit/be68a79c523e7ff360a4f9914b41956b5f430d93)) ## v2.21.2 (2024-05-08) ### Bug Fixes - Introspection bogus child paths ([#280](https://github.com/Bluetooth-Devices/dbus-fast/pull/280), [`7da5d44`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7da5d44caacecd9af2f8198e7403d7d043c87579)) ## v2.21.1 (2024-01-16) ### Bug Fixes - Avoid expensive runtime inspection of known callables ([#277](https://github.com/Bluetooth-Devices/dbus-fast/pull/277), [`0271825`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0271825e7338dd8422975d9289768363b5b6b9de)) ## v2.21.0 (2023-12-12) ### Features - Speed up message callbacks ([#276](https://github.com/Bluetooth-Devices/dbus-fast/pull/276), [`2b8770b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2b8770b892ee75b851d5d58967e3a9e3149430dc)) ## v2.20.0 (2023-12-04) ### Features - Speed up run time constructed method handlers ([#275](https://github.com/Bluetooth-Devices/dbus-fast/pull/275), [`9f54fc3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9f54fc3194370bb4c6fd51c158b577adce1b517f)) ## v2.19.0 (2023-12-04) ### Features - Speed up ServiceInterface callbacks with cython methods ([#274](https://github.com/Bluetooth-Devices/dbus-fast/pull/274), [`0e57d79`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0e57d798a2f171f804603cb5a3659de08092e74b)) ## v2.18.0 (2023-12-04) ### Features - Small speed up to the aio message reader ([#273](https://github.com/Bluetooth-Devices/dbus-fast/pull/273), [`8ee18a1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8ee18a1355b247e3ef9c7ad5f561d7cc8f9cf4a2)) ## v2.17.0 (2023-12-04) ### Features - Reduce duplicate code in aio MessageBus ([#272](https://github.com/Bluetooth-Devices/dbus-fast/pull/272), [`502ab0d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/502ab0d47f667bb24cd7b3f1d8fa97e2d0345676)) ## v2.16.0 (2023-12-04) ### Features - Speed up sending messages with call on the MessageBus ([#271](https://github.com/Bluetooth-Devices/dbus-fast/pull/271), [`6d7f522`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6d7f522e1cc5181e75209e4c00109426baa335fc)) ## v2.15.0 (2023-11-22) ### Features - Make ErrorType enums compare as strings ([#269](https://github.com/Bluetooth-Devices/dbus-fast/pull/269), [`c6a8301`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c6a8301704162e1c4d07470c32ca0830f531b6d4)) The DBusError exception stores the error type as string. This makes the exception not directly compare to the ErrorType members (for example DBusError(ErrorType.FAILED, "").type != ErrorType.FAILED). This makes ErrorType also a string to make this comparision work. ## v2.14.0 (2023-11-10) ### Features - Add support for tuples to the marshaller ([#267](https://github.com/Bluetooth-Devices/dbus-fast/pull/267), [`0ccb7c5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ccb7c5d879fc787c12e35c659b0be88bcbed7fe)) ## v2.13.1 (2023-11-07) ### Bug Fixes - Re-release since the previous release ran out of space on PyPI ([#266](https://github.com/Bluetooth-Devices/dbus-fast/pull/266), [`1586221`](https://github.com/Bluetooth-Devices/dbus-fast/commit/158622157f547aba80bbd06579915d7a5e145d58)) ## v2.13.0 (2023-11-07) ### Features - Improve marshaller performance ([#264](https://github.com/Bluetooth-Devices/dbus-fast/pull/264), [`5bdb161`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5bdb161c0a70074e0466e9332dce9c27b497916b)) ## v2.12.1 (2023-11-07) ### Bug Fixes - Send reply test failure with cython ([#265](https://github.com/Bluetooth-Devices/dbus-fast/pull/265), [`e634fc2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e634fc2c701c25353f805dbe5fe52f67fa896b7d)) ## v2.12.0 (2023-10-18) ### Bug Fixes - Reduce size of wheels by excluding generated .c files ([#262](https://github.com/Bluetooth-Devices/dbus-fast/pull/262), [`dca4599`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dca459900e19e7340b68601d13422c83a7d67a19)) ### Features - Update for final cpython release ([#263](https://github.com/Bluetooth-Devices/dbus-fast/pull/263), [`460a072`](https://github.com/Bluetooth-Devices/dbus-fast/commit/460a072652793829b217720846fbf10f8e2ebadb)) ## v2.11.1 (2023-10-04) ### Bug Fixes - Marshall multi-byte strings correctly ([#261](https://github.com/Bluetooth-Devices/dbus-fast/pull/261), [`4de31a3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4de31a36463ff8e2d85225973c4553c15623afb6)) ### Chores - Add benchmark for GetValue ([#258](https://github.com/Bluetooth-Devices/dbus-fast/pull/258), [`2fc723e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2fc723eacb24802b87ca712c89b76f6f95a64f1a)) - Add more unmarshall tests ([#259](https://github.com/Bluetooth-Devices/dbus-fast/pull/259), [`4d3b666`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4d3b666564fae3b813f57b446fb43dd27691e16e)) - Add more unmarshall tests ([#260](https://github.com/Bluetooth-Devices/dbus-fast/pull/260), [`f9e5d1d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9e5d1d02025fee50f641ee2bb82607a494c06dd)) ## v2.11.0 (2023-09-27) ### Features - Speed up unpacking arrays ([#257](https://github.com/Bluetooth-Devices/dbus-fast/pull/257), [`5c8bfe5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5c8bfe5e15a1c5de150975ebdaf1677801397555)) ## v2.10.0 (2023-09-25) ### Features - Speed up constructing Variant objects ([#256](https://github.com/Bluetooth-Devices/dbus-fast/pull/256), [`0d7a665`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0d7a6652d797efcffaa0fa35039252c33522c15e)) ## v2.9.0 (2023-09-20) ### Features - Speed up unmarshalling message body ([#255](https://github.com/Bluetooth-Devices/dbus-fast/pull/255), [`5aed075`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5aed07516611692f935cac6fb612204c6f419fec)) ## v2.8.0 (2023-09-20) ### Features - Speed up unmarshalling Variants ([#254](https://github.com/Bluetooth-Devices/dbus-fast/pull/254), [`dd74a84`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dd74a8409db40abdaeba2fdcd578ae3998692470)) ## v2.7.0 (2023-09-13) ### Features - Speed up readers in the unmarshall path ([#253](https://github.com/Bluetooth-Devices/dbus-fast/pull/253), [`f9b61b8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9b61b8bc734b0179bde2c08e46c02de65f27e50)) ## v2.6.0 (2023-09-12) ### Features - Speed up first connection when using asyncio ([#251](https://github.com/Bluetooth-Devices/dbus-fast/pull/251), [`0b6ba93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0b6ba93f733a78f1fb52ddfa24163de44f09df53)) ## v2.5.0 (2023-09-12) ### Features - Speed up unmarshaller ([#250](https://github.com/Bluetooth-Devices/dbus-fast/pull/250), [`e4cae13`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e4cae13e1a25356437658a03ee60522a68a56d56)) ## v2.4.0 (2023-09-12) ### Chores - Bump cpython CI version ([#249](https://github.com/Bluetooth-Devices/dbus-fast/pull/249), [`16b31f9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/16b31f91e50e8def4b7ee7066be0bd375b123f0a)) ### Features - Add cython typing for ServiceInterface.name ([#248](https://github.com/Bluetooth-Devices/dbus-fast/pull/248), [`98c7e75`](https://github.com/Bluetooth-Devices/dbus-fast/commit/98c7e753755741967bad0618f056605bc2eaa743)) ## v2.3.0 (2023-09-11) ### Features - Speed up connect and disconnect ([#247](https://github.com/Bluetooth-Devices/dbus-fast/pull/247), [`8f39ba3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8f39ba3ada1dfdec8d7230c77e52ef802e91b23d)) ## v2.2.0 (2023-09-10) ### Features - Speed up unmarshalling by skipping unused unix_fds header ([#246](https://github.com/Bluetooth-Devices/dbus-fast/pull/246), [`5f5a150`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5f5a150ca01810bf3a2a90043f77ee7100c8242d)) ## v2.1.0 (2023-09-10) ### Features - Reduce overhead to reset between messages ([#245](https://github.com/Bluetooth-Devices/dbus-fast/pull/245), [`da30b04`](https://github.com/Bluetooth-Devices/dbus-fast/commit/da30b04a15aed08ba920fabd0abad372e953c394)) ## v2.0.1 (2023-09-08) ### Bug Fixes - Clean up address parsing and tests ([#244](https://github.com/Bluetooth-Devices/dbus-fast/pull/244), [`370791d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/370791da869040d4a0d92cde30c4d2d4d684bcdc)) ## v2.0.0 (2023-09-07) ### Features - Don't import backends by default ([#243](https://github.com/Bluetooth-Devices/dbus-fast/pull/243), [`091d421`](https://github.com/Bluetooth-Devices/dbus-fast/commit/091d421a94752f749999858540000e0ab8a83da4)) ## v1.95.2 (2023-09-07) ### Bug Fixes - Handling of None messages from notify callback ([#236](https://github.com/Bluetooth-Devices/dbus-fast/pull/236), [`14f52f2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/14f52f216d49fb52bf223d5d96306465bb61e49c)) Co-authored-by: Remy Noel Co-authored-by: J. Nick Koston ## v1.95.1 (2023-09-07) ### Bug Fixes - Handle multiple flag bits when unmarshalling ([#241](https://github.com/Bluetooth-Devices/dbus-fast/pull/241), [`6f6f5f8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6f6f5f86c020866a0c1ef5573547e25c63c8d3c3)) ### Chores - Add test coverage for issue 239 ([#240](https://github.com/Bluetooth-Devices/dbus-fast/pull/240), [`0386dc2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0386dc232274c6de0717e9a3f280d98379acbf45)) ## v1.95.0 (2023-09-06) ### Features - Small speed up to the unmarshaller ([#238](https://github.com/Bluetooth-Devices/dbus-fast/pull/238), [`b8d0e9b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b8d0e9be4c7eb7c16347e7bf57f8bf40d0c293d0)) ## v1.94.1 (2023-08-27) ### Bug Fixes - Rebuild wheels with cython 3.0.2 ([#235](https://github.com/Bluetooth-Devices/dbus-fast/pull/235), [`e8901a8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e8901a8f7d82a93ed2e72576859fde8f942a8889)) ## v1.94.0 (2023-08-24) ### Chores - Bump cpython 3.12 version in CI ([#233](https://github.com/Bluetooth-Devices/dbus-fast/pull/233), [`5364492`](https://github.com/Bluetooth-Devices/dbus-fast/commit/53644927b9a35d45cc07499d6bc5e6183f9239fb)) ### Features - Build cpython 3.12 wheels ([#234](https://github.com/Bluetooth-Devices/dbus-fast/pull/234), [`b38aa58`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b38aa58aa7b15cf4498edfefabf9a3df37804494)) ## v1.93.1 (2023-08-24) ### Bug Fixes - Avoid cythonizing SendReply ([#232](https://github.com/Bluetooth-Devices/dbus-fast/pull/232), [`d12266d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d12266ddef920a6064c716c4e71ff8414094d0fd)) ### Chores - Add more coverage for send_reply ([#231](https://github.com/Bluetooth-Devices/dbus-fast/pull/231), [`ed5c87f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ed5c87f49206d219e4d43d7091b1453ef9932ac4)) - Add send_reply tests ([#230](https://github.com/Bluetooth-Devices/dbus-fast/pull/230), [`a8b9e72`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a8b9e721d56c0b2283cd0cc3d3eb2a44d83bdc3d)) ## v1.93.0 (2023-08-21) ### Features - Improve performance of processing incoming messages ([#228](https://github.com/Bluetooth-Devices/dbus-fast/pull/228), [`ce61aea`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ce61aea37a55c9498f1800ec4bd68e8eaf7c7f48)) ## v1.92.0 (2023-08-18) ### Features - Reduce overhead to dispatch method handlers ([#227](https://github.com/Bluetooth-Devices/dbus-fast/pull/227), [`b222552`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b2225527ae57d1bccec21df950d621797d30732d)) ## v1.91.4 (2023-08-17) ### Bug Fixes - Subpath bad matching ([#202](https://github.com/Bluetooth-Devices/dbus-fast/pull/202), [`5d6f90b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5d6f90ba32c61b14368f80b91e1d3d9a6279126f)) Co-authored-by: Remy Noel Co-authored-by: J. Nick Koston ## v1.91.3 (2023-08-17) ### Bug Fixes - Messages could be sent out of order if they had to queue ([#225](https://github.com/Bluetooth-Devices/dbus-fast/pull/225), [`4051cf2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4051cf283f61bbfefc4d63c8933b3818483a2d1a)) ## v1.91.2 (2023-08-09) ### Bug Fixes - Avoid checking if a message expects a reply twice ([#223](https://github.com/Bluetooth-Devices/dbus-fast/pull/223), [`823e85f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/823e85fddc44ceff60558d490013b601ae4bdacd)) ## v1.91.1 (2023-08-09) ### Bug Fixes - Revert changes to _expects_reply from speed up to processing bluez passive data ([#222](https://github.com/Bluetooth-Devices/dbus-fast/pull/222), [`dfa9053`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dfa9053a03692d3e14032c7d4a4a375400262c78)) ## v1.91.0 (2023-08-09) ### Features - Speed up to processing bluez passive data ([#221](https://github.com/Bluetooth-Devices/dbus-fast/pull/221), [`8e7432d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8e7432d31b38fecbbed585c2d5ae510d24ff5af7)) ## v1.90.2 (2023-08-05) ### Bug Fixes - Spelling of `dbus_fast.auth.AuthAnnonymous` to `dbus_fast.auth.AuthAnonymous` ([#220](https://github.com/Bluetooth-Devices/dbus-fast/pull/220), [`6c2412f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6c2412f4ca214f1fc95046ab8118bf330aa646da)) ## v1.90.1 (2023-08-02) ### Bug Fixes - More cython3 optional fixes ([#219](https://github.com/Bluetooth-Devices/dbus-fast/pull/219), [`5b6cbc5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b6cbc560e6add5a0f3f20fc9d37716cb30e9121)) ## v1.90.0 (2023-08-02) ### Features - Remove async_timeout dependency ([#218](https://github.com/Bluetooth-Devices/dbus-fast/pull/218), [`7826897`](https://github.com/Bluetooth-Devices/dbus-fast/commit/78268973591985695cb3fa76dd502bb1ef1895ec)) ## v1.89.0 (2023-08-02) ### Features - Speed up Message creation and callbacks ([#217](https://github.com/Bluetooth-Devices/dbus-fast/pull/217), [`04d6451`](https://github.com/Bluetooth-Devices/dbus-fast/commit/04d64511579be08c7d416664c66d527a7d6d12b6)) ## v1.88.0 (2023-08-02) ### Features - Optimize passive bluez message unmarshaller ([#216](https://github.com/Bluetooth-Devices/dbus-fast/pull/216), [`e0e87ec`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e0e87ec16ce424dbae83114ca5da13406b913deb)) ## v1.87.6 (2023-08-01) ### Bug Fixes - Exception handler failure when exception is not DBusError ([#215](https://github.com/Bluetooth-Devices/dbus-fast/pull/215), [`d771bcf`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d771bcf6a2ed08486affe0e2c30bd8dd95ccbb5d)) ## v1.87.5 (2023-07-28) ### Bug Fixes - Result typing in ServiceInterface._handle_signal ([#214](https://github.com/Bluetooth-Devices/dbus-fast/pull/214), [`5bda04b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5bda04b089b5f089c90c333ca0db02d40d38a8ca)) ## v1.87.4 (2023-07-28) ### Bug Fixes - Avoid double buffering when using asyncio reader without negotiate_unix_fd ([#213](https://github.com/Bluetooth-Devices/dbus-fast/pull/213), [`c933be7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c933be709508e0504e97254247bec70eb9e8c6d4)) ## v1.87.3 (2023-07-27) ### Bug Fixes - Relax typing on _fn_result_to_body to allow Any ([#212](https://github.com/Bluetooth-Devices/dbus-fast/pull/212), [`2f5fc38`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2f5fc3800702f6eb680d94de94b997ed5d8b9b77)) ## v1.87.2 (2023-07-24) ### Bug Fixes - Typing on _fn_result_to_body was incorrect which was caused an exception with cython3 ([#210](https://github.com/Bluetooth-Devices/dbus-fast/pull/210), [`c40c7bc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c40c7bcc4a8bbbce73d4d090ac840f8fe95d943e)) ## v1.87.1 (2023-07-24) ### Bug Fixes - Cython3 compat ([#208](https://github.com/Bluetooth-Devices/dbus-fast/pull/208), [`43b3d48`](https://github.com/Bluetooth-Devices/dbus-fast/commit/43b3d48c8934a5274e4fae9b2c65c8ce6477a65b)) ## v1.87.0 (2023-07-24) ### Features - Initial cpython 3.12 support ([#207](https://github.com/Bluetooth-Devices/dbus-fast/pull/207), [`c755193`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c755193ee038e4d35ad25d5d02e0a1a8cecd9d6d)) ## v1.86.0 (2023-05-03) ### Chores - Update deps via poetry ([#201](https://github.com/Bluetooth-Devices/dbus-fast/pull/201), [`a17d6d0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a17d6d0fd08fde630942aa7f44a8fb452c48d761)) ### Features - Improve performance of reading from the socket during unmarshall ([#200](https://github.com/Bluetooth-Devices/dbus-fast/pull/200), [`e5d355f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e5d355ff407baf58a8e5b03c3e9ca25213a95e05)) ## v1.85.0 (2023-04-21) ### Features - Improve unmarshall performance ([#199](https://github.com/Bluetooth-Devices/dbus-fast/pull/199), [`3dc98be`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3dc98be7e948d61cd98b326ece4bc9eef7803684)) ## v1.84.2 (2023-02-20) ### Bug Fixes - Corrects Variant documentation ([#197](https://github.com/Bluetooth-Devices/dbus-fast/pull/197), [`9c6a472`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9c6a472100a471c8f41d495707182eca8d5d25a1)) Co-authored-by: J. Nick Koston ## v1.84.1 (2023-02-14) ### Bug Fixes - Missing c extensions with newer poetry ([#194](https://github.com/Bluetooth-Devices/dbus-fast/pull/194), [`72ddb15`](https://github.com/Bluetooth-Devices/dbus-fast/commit/72ddb156f0ac0fe0910ea41360f32f75a13cc7e4)) ### Chores - Bump isort to 5.12.0 to fix ci ([#195](https://github.com/Bluetooth-Devices/dbus-fast/pull/195), [`7b04136`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7b04136822be9e2bc892c0d70d1eca40fe0634e8)) - Bump python-semantic-release to fix CI ([#196](https://github.com/Bluetooth-Devices/dbus-fast/pull/196), [`6387f82`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6387f821e012c0b43e1e0637e3a8d2311c298662)) ## v1.84.0 (2023-01-07) ### Features - Add support for EXTERNAL auth without uid ([#193](https://github.com/Bluetooth-Devices/dbus-fast/pull/193), [`4939ef8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4939ef80e523af8a08900fe78abc2f3c54ec835e)) ## v1.83.1 (2022-12-24) ### Bug Fixes - Cleanup typing in marshaller and unmarshaller ([#190](https://github.com/Bluetooth-Devices/dbus-fast/pull/190), [`830183e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/830183e1887a7abb876813098f17e22550453569)) ## v1.83.0 (2022-12-23) ### Features - Allow hardcoding uid in auth ([#189](https://github.com/Bluetooth-Devices/dbus-fast/pull/189), [`091c262`](https://github.com/Bluetooth-Devices/dbus-fast/commit/091c262e2747be5170596ea9e84b2cd884d01762)) Closes https://github.com/Bluetooth-Devices/dbus-fast/issues/188 ## v1.82.0 (2022-12-09) ### Features - Avoid enum dunder overhead in message_bus calls ([#187](https://github.com/Bluetooth-Devices/dbus-fast/pull/187), [`b3c7d51`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b3c7d5139d4cfa5bcea2435b6acdb6e1e059ceb4)) ## v1.81.0 (2022-12-09) ### Chores - Add passive unmarshall benchmark ([#185](https://github.com/Bluetooth-Devices/dbus-fast/pull/185), [`5b0d9d0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b0d9d024aa2e2b2378bc801607c63d6ca7b6bbe)) ### Features - Speed up processing bluez passive advertisements ([#186](https://github.com/Bluetooth-Devices/dbus-fast/pull/186), [`fb0cc35`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fb0cc3584888bd307db3eb689f0dd81a025a1396)) ## v1.80.0 (2022-12-09) ### Features - Speed up checking if a message needs a reply ([#181](https://github.com/Bluetooth-Devices/dbus-fast/pull/181), [`d1366ac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d1366aca644d78f446f47b8fd607b82f73299fb8)) ## v1.79.0 (2022-12-09) ### Features - Add a cython pxd for services ([#180](https://github.com/Bluetooth-Devices/dbus-fast/pull/180), [`f3c9250`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f3c925079a1ea632ed850f71aaf26ba1e57f2ca8)) ## v1.78.0 (2022-12-08) ### Chores - Disable some more tests that segfault under py3.10 ([#179](https://github.com/Bluetooth-Devices/dbus-fast/pull/179), [`b23086b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b23086b25ddf57580cff4b86c8adb031e6203268)) ### Features - Simplify creation of SendReply in message_bus ([#178](https://github.com/Bluetooth-Devices/dbus-fast/pull/178), [`24faa00`](https://github.com/Bluetooth-Devices/dbus-fast/commit/24faa00062237cbee83ea118e4c11f319899538f)) ## v1.77.0 (2022-12-08) ### Features - Avoid replacing unix_fds if there are no unix_fds ([#176](https://github.com/Bluetooth-Devices/dbus-fast/pull/176), [`06647d7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/06647d7e49aa29b40146c7655f0edd4979a5500d)) ## v1.76.0 (2022-12-08) ### Chores - Disable flakey glib test on newer python ([#173](https://github.com/Bluetooth-Devices/dbus-fast/pull/173), [`7edfc38`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7edfc38b6314337dd0cec2bf92e9e07f0dfdfeba)) - Disable one more flakey glib test on py3.10 ([#174](https://github.com/Bluetooth-Devices/dbus-fast/pull/174), [`2fa7cdb`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2fa7cdb15653e8d6df079e24876419b2c896bf05)) ### Features - Only construct handlers once ([#175](https://github.com/Bluetooth-Devices/dbus-fast/pull/175), [`fb4d540`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fb4d5402ba254e62989cbd0e36c3ad510bb0d358)) ## v1.75.1 (2022-11-23) ### Bug Fixes - Fix remaining altdesktop links ([#169](https://github.com/Bluetooth-Devices/dbus-fast/pull/169), [`67255f7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/67255f7e01f7970e4acdd57c9a399f9452fc1d0c)) There were still a few links incorrectly pointing back to altdesktop/python-dbus-next on GitHub. ## v1.75.0 (2022-11-17) ### Features - Add unmarshaller cython typing for SignatureType and SignatureTree ([#168](https://github.com/Bluetooth-Devices/dbus-fast/pull/168), [`98d5c5a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/98d5c5aec2c800351666921c14aaa64741ca2831)) ## v1.74.2 (2022-11-17) ### Bug Fixes - Small fixes for typing with older python versions ([#167](https://github.com/Bluetooth-Devices/dbus-fast/pull/167), [`1e32f28`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1e32f284cd7a15da81d278ffa9f5abe34563aafc)) ## v1.74.1 (2022-11-16) ### Bug Fixes - Building via PEP 517 ([#166](https://github.com/Bluetooth-Devices/dbus-fast/pull/166), [`6694fda`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6694fda49f966814ebc900a52812b4c5e4ff1980)) ## v1.74.0 (2022-11-14) ### Features - Improve cdef types for marshaller ([#164](https://github.com/Bluetooth-Devices/dbus-fast/pull/164), [`9fb4440`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9fb4440b805fa5bf432fa1b23d9b1fac1de31b96)) ## v1.73.1 (2022-11-14) ### Bug Fixes - Allow non-string objects to be marshalled by write_string ([#163](https://github.com/Bluetooth-Devices/dbus-fast/pull/163), [`46f1d6b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/46f1d6bbc09860185db04c7985b9fd7c23e7a1bf)) ## v1.73.0 (2022-11-11) ### Chores - Add a test for unmarshalling a big endian message ([#156](https://github.com/Bluetooth-Devices/dbus-fast/pull/156), [`b329700`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b3297008bc3776c6220b66a0036cfdf2b636157d)) - Add big endian github workflow ([#155](https://github.com/Bluetooth-Devices/dbus-fast/pull/155), [`984738c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/984738c8030aff5e0a614a2b398ec690d21636fb)) thanks to https://til.simonwillison.net/docker/emulate-s390x-with-qemu - Make big endian workflow manual until we get it working properly ([#157](https://github.com/Bluetooth-Devices/dbus-fast/pull/157), [`9240bfd`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9240bfda6e280bc75d8f249ba3470202a0318913)) - Prepare marshaller to be able to generate big endian messages ([#154](https://github.com/Bluetooth-Devices/dbus-fast/pull/154), [`b2327c0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b2327c08558ba6a785064788c5fe448784d56be0)) ### Features - Reduce latency to process messages ([#161](https://github.com/Bluetooth-Devices/dbus-fast/pull/161), [`113f0c9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/113f0c9a325d538592555ae89e1df1ea29398aa9)) Improve `message_bus.py` `_process_message` performance with a `pxd` file ## v1.72.0 (2022-11-04) ### Chores - Add benchmark and tests for GetManagedObjects ([#150](https://github.com/Bluetooth-Devices/dbus-fast/pull/150), [`2d56622`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2d566224d34217cb720aacef1cc9a656f564901c)) ### Features - Add optimized reader for GetManagedObjects ([#152](https://github.com/Bluetooth-Devices/dbus-fast/pull/152), [`7ed453f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7ed453f31a654f8cc9b99eb17f872370f4b06a4e)) ## v1.71.0 (2022-11-04) ### Features - Small speed up to _unpack_variants ([#148](https://github.com/Bluetooth-Devices/dbus-fast/pull/148), [`ef7acdc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ef7acdcbe59123bfa3b17d5dafc9f8235ac0f360)) ## v1.70.0 (2022-11-04) ### Features - Use cimports for message marshalling ([#149](https://github.com/Bluetooth-Devices/dbus-fast/pull/149), [`ef7d9d4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ef7d9d440775cf0ddcb6b3bc6115b3884be35792)) ## v1.69.0 (2022-11-04) ### Features - Refactor message_reader to avoid python wrappers ([#147](https://github.com/Bluetooth-Devices/dbus-fast/pull/147), [`b81de45`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b81de4553fc1414476ff8a1c2b73db7b1a497841)) ## v1.68.0 (2022-11-04) ### Features - Use cimports for unmarshaller Variant and Message ([#146](https://github.com/Bluetooth-Devices/dbus-fast/pull/146), [`6418ed4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6418ed4bb69a835768596f66ab5b514ea48b82cc)) ## v1.67.0 (2022-11-03) ### Features - Optimize unmarshaller by dropping exception that was only used internally ([#145](https://github.com/Bluetooth-Devices/dbus-fast/pull/145), [`79d52a5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/79d52a50bd9651fa489e81935bda04d53285b2c1)) ## v1.66.0 (2022-11-03) ### Features - Speed up creating Variant objects ([#144](https://github.com/Bluetooth-Devices/dbus-fast/pull/144), [`2ff84e3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2ff84e3ac56f4348c8276515ac398fcbda8a0657)) ## v1.65.0 (2022-11-03) ### Features - Add cython def for unmarshaller read_sock for fd passing ([#143](https://github.com/Bluetooth-Devices/dbus-fast/pull/143), [`f438c36`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f438c369bd86956f50fb839ec4a0a8069de7d018)) ## v1.64.0 (2022-11-03) ### Features - Speed up marshalling headers ([#142](https://github.com/Bluetooth-Devices/dbus-fast/pull/142), [`7d6fb63`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7d6fb63dc011404955fc1219924cd2c6f6634ccd)) ## v1.63.0 (2022-11-03) ### Features - Speed up marshall align ([#137](https://github.com/Bluetooth-Devices/dbus-fast/pull/137), [`d7d301c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d7d301c773beb312be752accf7018a3dacecde02)) - Speed up marshall write_string and write_variant ([#138](https://github.com/Bluetooth-Devices/dbus-fast/pull/138), [`71cf524`](https://github.com/Bluetooth-Devices/dbus-fast/commit/71cf52430bd3ece01083309c5f0f5d934dca3d59)) ## v1.62.0 (2022-11-03) ### Chores - Add explicit test for workaround of python/cpython#98976 ([#135](https://github.com/Bluetooth-Devices/dbus-fast/pull/135), [`b486e32`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b486e3248baf7335f133ed3e67641df9a6beb091)) - Update pyproject.toml dependencies ([#136](https://github.com/Bluetooth-Devices/dbus-fast/pull/136), [`4a23e0e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4a23e0e0c5a1f4f52670f59433855dd87bf36371)) ### Features - Speed up marshaller by pre-packing bools ([#139](https://github.com/Bluetooth-Devices/dbus-fast/pull/139), [`c10a241`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c10a241dc5e889fd58323789dc4af45ec1e5616a)) ## v1.61.1 (2022-11-01) ### Bug Fixes - Re-release due to pypi not seeing the new version ([#134](https://github.com/Bluetooth-Devices/dbus-fast/pull/134), [`2f21ee8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2f21ee8b8d52975624c19b6593a96976fa19047b)) ### Chores - Adjust poetry for python 3.11 ([#133](https://github.com/Bluetooth-Devices/dbus-fast/pull/133), [`6d7391a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6d7391a8f865ad377e3edd2b47b42c296b267cab)) ## v1.61.0 (2022-11-01) ### Chores - Drop async-timeout dependency on Python >= 3.11 ([#132](https://github.com/Bluetooth-Devices/dbus-fast/pull/132), [`1b5c9e1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1b5c9e1cb94d19925776d91196cf1b657264c494)) ### Features - Add support and workarounds for cpython3.11 ([#31](https://github.com/Bluetooth-Devices/dbus-fast/pull/31), [`b53a467`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b53a4675d78f8e4e37be322ebda3eeec80f15723)) ## v1.60.0 (2022-10-31) ### Features - Speed up auth phase ([#131](https://github.com/Bluetooth-Devices/dbus-fast/pull/131), [`3eef636`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3eef6368268c2d46db3b31bf907959da36dbf2a4)) ## v1.59.2 (2022-10-31) ### Bug Fixes - Correctly fallback to pure python when cython is missing ([#130](https://github.com/Bluetooth-Devices/dbus-fast/pull/130), [`8ab1f9d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8ab1f9d0b380293294a0f847664e0c459061c2d9)) ## v1.59.1 (2022-10-29) ### Bug Fixes - Pass return value to SendReply.__exit__ ([#127](https://github.com/Bluetooth-Devices/dbus-fast/pull/127), [`f8c67ed`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f8c67ed00fa8fe58a85b6ba73b5fa5974f802004)) ### Chores - Add additional coverage for multiple messages in the same packet ([#126](https://github.com/Bluetooth-Devices/dbus-fast/pull/126), [`8f6a431`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8f6a431ea49fc168adf484732af5e10debdad93f)) ## v1.59.0 (2022-10-29) ### Features - Speed up decoding headers by avoiding unicode checks ([#125](https://github.com/Bluetooth-Devices/dbus-fast/pull/125), [`6121781`](https://github.com/Bluetooth-Devices/dbus-fast/commit/61217819fbbe073007a44db69328008941d6bb4c)) ## v1.58.0 (2022-10-29) ### Features - Add optimized parser for properties changed messages with service data ([#124](https://github.com/Bluetooth-Devices/dbus-fast/pull/124), [`c8a9452`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c8a945210ae3ea8d25e4547f70b25d61b778ffe1)) ## v1.57.0 (2022-10-29) ### Features - Add optimized parser for InterfacesRemoved ([#123](https://github.com/Bluetooth-Devices/dbus-fast/pull/123), [`09822a5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/09822a59ffad07b8dcb6d216d98e6dccbe338b06)) ## v1.56.0 (2022-10-29) ### Features - Optimize for interfaces added messages ([#122](https://github.com/Bluetooth-Devices/dbus-fast/pull/122), [`c05a27a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c05a27aef9395eb688385109c4ff7204d5103dda)) ## v1.55.0 (2022-10-29) ### Features - Add optimized reader for uint16 ([#121](https://github.com/Bluetooth-Devices/dbus-fast/pull/121), [`52881d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/52881d9054e35ae3d727c4adafd7e0958b1c99af)) ## v1.54.0 (2022-10-28) ### Features - Speed up unmarshaller with common signature trees ([#120](https://github.com/Bluetooth-Devices/dbus-fast/pull/120), [`5b32072`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b32072934a7269ffc7186aaaed77a0eb6872cd9)) Co-authored-by: David Lechner ## v1.53.0 (2022-10-28) ### Features - Add additional pxd defs for message ([#118](https://github.com/Bluetooth-Devices/dbus-fast/pull/118), [`3eb123b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3eb123b0366ed143d395e0609540c580398cd896)) ## v1.52.0 (2022-10-28) ### Chores - Fix ci ([#119](https://github.com/Bluetooth-Devices/dbus-fast/pull/119), [`3c773e1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3c773e118c78e6bc336d432eab57e36a0ed7213d)) ### Features - Small speed up to unpack_variants ([#117](https://github.com/Bluetooth-Devices/dbus-fast/pull/117), [`3c164a9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3c164a9291b9fb6e75aed0fc5aab1dfc7b79c376)) ## v1.51.0 (2022-10-27) ### Features - Inline cast uint32 and int16 to speed up unmarshall ([#115](https://github.com/Bluetooth-Devices/dbus-fast/pull/115), [`24dd9d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/24dd9d9742e8c779b9c8aa751ba8b2815b61b15b)) ## v1.50.0 (2022-10-27) ### Features - Speed up unmarshall ([#114](https://github.com/Bluetooth-Devices/dbus-fast/pull/114), [`e1836b2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e1836b2034ca4bfbb004027f98b42c68f6c6edce)) ## v1.49.0 (2022-10-26) ### Features - Speed up unmarshaller ([#113](https://github.com/Bluetooth-Devices/dbus-fast/pull/113), [`8f7f982`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8f7f982a75fe9c998e5a983090e361ba52e2e6a3)) ## v1.48.0 (2022-10-20) ### Features - Add typing to auth module ([#110](https://github.com/Bluetooth-Devices/dbus-fast/pull/110), [`e07e281`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e07e281ded44f9ded3002c34803f802146a9e3c9)) ## v1.47.0 (2022-10-19) ### Features - Speed up unmarshaller ([#109](https://github.com/Bluetooth-Devices/dbus-fast/pull/109), [`2443cf9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2443cf99909af02db040caeeded7024a020c50a5)) ## v1.46.0 (2022-10-19) ### Features - Speed up marshaller and add typing ([#108](https://github.com/Bluetooth-Devices/dbus-fast/pull/108), [`e8f568c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e8f568c074965bf7955f29cd89cf14f1b8dd5643)) ## v1.45.0 (2022-10-13) ### Features - Optimize signature readers for most common messages ([#107](https://github.com/Bluetooth-Devices/dbus-fast/pull/107), [`d5fb4d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d5fb4d9c8bf17c51762ea961d745c5db7d8d8a22)) ## v1.44.0 (2022-10-12) ### Features - Speed up unpack_variants ([#105](https://github.com/Bluetooth-Devices/dbus-fast/pull/105), [`a4fdda2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a4fdda271f7a96e267826ffa3f268ec02078ba73)) ## v1.43.0 (2022-10-12) ### Features - Improve aio message reader performance ([#104](https://github.com/Bluetooth-Devices/dbus-fast/pull/104), [`9fa697d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9fa697da65d449b7402aa7f2f26762b0d2e175c6)) ## v1.42.0 (2022-10-12) ### Features - Complete some more missing typing ([#103](https://github.com/Bluetooth-Devices/dbus-fast/pull/103), [`5787032`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5787032af7cae1ffffd1561390cdb02053776345)) ## v1.41.0 (2022-10-11) ### Features - Add more typing to unmarshaller ([#102](https://github.com/Bluetooth-Devices/dbus-fast/pull/102), [`e7048fa`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e7048fa38b63ea45e819930a51ca5744f86da73f)) ## v1.40.0 (2022-10-10) ### Features - Speed up unmarshaller ([#101](https://github.com/Bluetooth-Devices/dbus-fast/pull/101), [`a6a248b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a6a248b3b1dbbb06784f700b49a7fe92b30cc7b5)) ## v1.39.0 (2022-10-10) ### Features - Add additional typing ([#100](https://github.com/Bluetooth-Devices/dbus-fast/pull/100), [`cde1893`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cde1893dca1872d8b482a145337ee3bbf47c35b4)) ## v1.38.0 (2022-10-09) ### Features - Optimize for reading a{sv} messages and headers ([#98](https://github.com/Bluetooth-Devices/dbus-fast/pull/98), [`4648d29`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4648d29df4b616f49c06ca9fcbfbc27717d97135)) ## v1.37.0 (2022-10-09) ### Chores - Adjust unmarshall benchmarks since they are now fast enough to hit the margin of error ([#97](https://github.com/Bluetooth-Devices/dbus-fast/pull/97), [`0ee88e4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ee88e4018d4c436ffedb1a00136088606ba3977)) ### Features - Speed up empty array unmarshall ([#96](https://github.com/Bluetooth-Devices/dbus-fast/pull/96), [`2c6ee99`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2c6ee99b73dcfb2e2d45d2610a3fa10a4ff2136a)) ## v1.36.0 (2022-10-09) ### Features - Add cdef to unpack_variants ([#95](https://github.com/Bluetooth-Devices/dbus-fast/pull/95), [`dbf42c3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dbf42c370784236ff31e9324968f02a5efb58586)) ## v1.35.0 (2022-10-09) ### Features - Add unpack variants benchmark ([#94](https://github.com/Bluetooth-Devices/dbus-fast/pull/94), [`eb966fd`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eb966fd7cf3a3f05879c29f7eb98727dd117c317)) ## v1.34.0 (2022-10-09) ### Features - Add additional typing ([#93](https://github.com/Bluetooth-Devices/dbus-fast/pull/93), [`7326bdf`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7326bdf097310eafa21364dd46f6ebb72baa1a3d)) ## v1.33.0 (2022-10-09) ### Features - Improve performance of unmarshalling headers ([#88](https://github.com/Bluetooth-Devices/dbus-fast/pull/88), [`b6d4069`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b6d40691fd11ff8d4e46a57fd8cc97a9b6806089)) ## v1.32.0 (2022-10-08) ### Features - Speed up marshalling arrays ([#87](https://github.com/Bluetooth-Devices/dbus-fast/pull/87), [`f554345`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f554345b3640524300fbe406f4ac25dbf61a2274)) ## v1.31.0 (2022-10-08) ### Features - Speed up marshalling variants ([#86](https://github.com/Bluetooth-Devices/dbus-fast/pull/86), [`7847e26`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7847e26e6e6cfe172437544d7709dc0c87a65402)) ## v1.30.0 (2022-10-08) ### Features - Speed up aligning data during marshall ([#85](https://github.com/Bluetooth-Devices/dbus-fast/pull/85), [`07e6886`](https://github.com/Bluetooth-Devices/dbus-fast/commit/07e68862d93cd5dc470ad2a3ae6f8eaf12808271)) ## v1.29.1 (2022-10-07) ### Bug Fixes - Remove unused unmarshaller code ([#83](https://github.com/Bluetooth-Devices/dbus-fast/pull/83), [`3613ff8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3613ff846b8bb66000c65c778bb06596cd643b22)) ## v1.29.0 (2022-10-07) ### Features - Unpack header names as message kwargs ([#82](https://github.com/Bluetooth-Devices/dbus-fast/pull/82), [`7398a3f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7398a3fc4726fa20b34840967a6c3777eef12f52)) ## v1.28.1 (2022-10-07) ### Bug Fixes - Disconnect race in tests ([#79](https://github.com/Bluetooth-Devices/dbus-fast/pull/79), [`f2bb106`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f2bb10680a5d4e363ff8e7762fef25ec75ef8b14)) ## v1.28.0 (2022-10-07) ### Features - Speed up unmarshalling int16 types ([#81](https://github.com/Bluetooth-Devices/dbus-fast/pull/81), [`18213c0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/18213c0a00f162cbf74fa7fc0bbcf12c1109c347)) ## v1.27.0 (2022-10-07) ### Features - Cythonize headers in unmarshaller ([#80](https://github.com/Bluetooth-Devices/dbus-fast/pull/80), [`ae96be7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ae96be70f5e960d3feb726b7c769dff26b41c428)) ## v1.26.0 (2022-10-06) ### Bug Fixes - Incorrect pxd typing for for _marshall ([#75](https://github.com/Bluetooth-Devices/dbus-fast/pull/75), [`cf1f012`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cf1f0129baaac48d6a4804e8c6a0af5bc7ef8d16)) ### Features - Add cython defs for Variant class ([#74](https://github.com/Bluetooth-Devices/dbus-fast/pull/74), [`cd08f06`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cd08f063cc352c65d2330cbe09ca72a367c58806)) ## v1.25.0 (2022-10-05) ### Features - Add cython extension for messages ([#73](https://github.com/Bluetooth-Devices/dbus-fast/pull/73), [`8676f12`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8676f12a7e040d7c3f20584739a74ad1074a4717)) ## v1.24.0 (2022-10-04) ### Features - Add cython extension for signature ([#72](https://github.com/Bluetooth-Devices/dbus-fast/pull/72), [`0ad8801`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ad8801215093cdbf0f62fce5b953d9b01e9d524)) ## v1.23.0 (2022-10-04) ### Features - Speed up unmarshall performance ([#71](https://github.com/Bluetooth-Devices/dbus-fast/pull/71), [`f38e08f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f38e08fa7cc8d41e896663ab0f163aa37a472abe)) ## v1.22.0 (2022-10-03) ### Features - Speed up message bus matching ([#70](https://github.com/Bluetooth-Devices/dbus-fast/pull/70), [`cccfea3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cccfea30b9ec5417eecef5093ee02f7b7a254c45)) ## v1.21.17 (2022-10-02) ### Bug Fixes - Install python-semantic-release in wheel workflow ([#68](https://github.com/Bluetooth-Devices/dbus-fast/pull/68), [`cca0d6e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cca0d6e98a5934fee83ccafbd2ed47cf60a3ce99)) ## v1.21.16 (2022-10-02) ### Bug Fixes - Ensure we can get the latest version in the wheels build process ([#67](https://github.com/Bluetooth-Devices/dbus-fast/pull/67), [`ecd5a70`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ecd5a7036945ccdd79e3049a7f2904709544af51)) ## v1.21.15 (2022-10-02) ### Bug Fixes - Checkout main for wheels ([#66](https://github.com/Bluetooth-Devices/dbus-fast/pull/66), [`3051a93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3051a9322cc711cee24583dedf25cee31a31c3b3)) ## v1.21.14 (2022-10-02) ### Bug Fixes - Use semantic-release to find the latest tag for wheels ([#65](https://github.com/Bluetooth-Devices/dbus-fast/pull/65), [`b76eb97`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b76eb97188c204996d049d326b4d21c74bc3f325)) ## v1.21.13 (2022-10-02) ### Bug Fixes - Build wheels from the sha saved after release ([#64](https://github.com/Bluetooth-Devices/dbus-fast/pull/64), [`faee181`](https://github.com/Bluetooth-Devices/dbus-fast/commit/faee18172bb7bc72ade8a54f2a8bd0fae5e35018)) ## v1.21.12 (2022-10-02) ### Bug Fixes - Switch to on create instead of push ([#63](https://github.com/Bluetooth-Devices/dbus-fast/pull/63), [`af0ed88`](https://github.com/Bluetooth-Devices/dbus-fast/commit/af0ed889985425b33fbbe35e8c8a4d0427643367)) ## v1.21.11 (2022-10-02) ### Bug Fixes - Accept any tag to build wheels ([#62](https://github.com/Bluetooth-Devices/dbus-fast/pull/62), [`60fca54`](https://github.com/Bluetooth-Devices/dbus-fast/commit/60fca54d2a4da67e3211b9e3f421787154234041)) ## v1.21.10 (2022-10-02) ### Bug Fixes - Github action tag matching ([#61](https://github.com/Bluetooth-Devices/dbus-fast/pull/61), [`b95d0b8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b95d0b8ce63e03c972fef72354cd67c2062bea94)) ## v1.21.9 (2022-10-02) ### Bug Fixes - Build wheels on tag instead ([#60](https://github.com/Bluetooth-Devices/dbus-fast/pull/60), [`6166896`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6166896c49a1358c951057fcc73d4b91ac92e08b)) ## v1.21.8 (2022-10-02) ### Bug Fixes - Publish wheels when release happens ([#59](https://github.com/Bluetooth-Devices/dbus-fast/pull/59), [`45e8ac0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/45e8ac00c6473c5329b36d4f19f5eb846db19d31)) ## v1.21.7 (2022-10-02) ### Bug Fixes - Seperate wheels back out so it builds after ([#58](https://github.com/Bluetooth-Devices/dbus-fast/pull/58), [`c74c251`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c74c2519a12a0f9cbb8c1b12b8871df22dda047d)) ## v1.21.6 (2022-10-02) ### Bug Fixes - Language_level warning when running cythonize ([#57](https://github.com/Bluetooth-Devices/dbus-fast/pull/57), [`b7b441e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b7b441eeef8bfa1dc286c78435ff9bac9d072302)) ## v1.21.5 (2022-10-02) ### Bug Fixes - Cython build of unpack ([#56](https://github.com/Bluetooth-Devices/dbus-fast/pull/56), [`5df01ac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5df01ac1ba3dc0515ffa8d0b01c1d386ef726e91)) ## v1.21.4 (2022-10-02) ### Bug Fixes - Increase verbosity of wheel builds ([#55](https://github.com/Bluetooth-Devices/dbus-fast/pull/55), [`4779e7b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4779e7b825270268ae28b5fc1c4ddb45647c31c5)) ## v1.21.3 (2022-10-02) ### Bug Fixes - Make wheel build depend on release success ([#54](https://github.com/Bluetooth-Devices/dbus-fast/pull/54), [`49d98d0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/49d98d01c2a3736adcc5d088fdd447c45b9503de)) ## v1.21.2 (2022-10-02) ### Bug Fixes - Additional tweaks to publishing wheels ([#53](https://github.com/Bluetooth-Devices/dbus-fast/pull/53), [`05b9453`](https://github.com/Bluetooth-Devices/dbus-fast/commit/05b945317380ad3d50b2f9d9114a61a2c57d99f0)) ## v1.21.1 (2022-10-02) ### Bug Fixes - Wheel builds on released ([#52](https://github.com/Bluetooth-Devices/dbus-fast/pull/52), [`6259fb2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6259fb299722688ca19a41a61a7a783e9abdca8c)) ## v1.21.0 (2022-10-02) ### Chores - Add cibuildwheel action ([#50](https://github.com/Bluetooth-Devices/dbus-fast/pull/50), [`f6e4c3c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f6e4c3c8aef5af04645a8249c27b9e51cfd5ad01)) ### Features - Cythonize unpack_variants ([#51](https://github.com/Bluetooth-Devices/dbus-fast/pull/51), [`1587211`](https://github.com/Bluetooth-Devices/dbus-fast/commit/158721123fc56675f04b9081ef4107590a8c2b17)) ## v1.20.0 (2022-10-02) ### Bug Fixes - Add missing closes to tests ([#49](https://github.com/Bluetooth-Devices/dbus-fast/pull/49), [`d2ce4a1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d2ce4a18462b5e304bc75983be3fffa3c426affc)) ### Features - Add additional cython types to the unmarshaller ([#45](https://github.com/Bluetooth-Devices/dbus-fast/pull/45), [`0f279a5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0f279a5ea9cd440fdbdd7dbafc1a48b1cc3577d7)) ## v1.19.0 (2022-10-02) ### Features - Add additional cython types to marshaller ([#48](https://github.com/Bluetooth-Devices/dbus-fast/pull/48), [`ddba96a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ddba96a73107644e31af591d8b726472a7deb85b)) ## v1.18.0 (2022-10-01) ### Features - Add optional cython extension ([#44](https://github.com/Bluetooth-Devices/dbus-fast/pull/44), [`b737574`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b737574cf04f5c6b6f881fbdce2663119a6dc404)) ## v1.17.0 (2022-09-27) ### Features - Improve unmarshaller performance ([#43](https://github.com/Bluetooth-Devices/dbus-fast/pull/43), [`c4b4a03`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c4b4a038f8822b6be7b062184b8092b6249878bc)) ## v1.16.0 (2022-09-27) ### Features - Add benchmark for bluez properties messages ([#42](https://github.com/Bluetooth-Devices/dbus-fast/pull/42), [`076c5df`](https://github.com/Bluetooth-Devices/dbus-fast/commit/076c5df825221901d1565e45f8662d7d9009ffe9)) ## v1.15.3 (2022-09-27) ### Bug Fixes - Improve typing on proxy_object ([#41](https://github.com/Bluetooth-Devices/dbus-fast/pull/41), [`ac955b5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ac955b50ea2921b114f6a89c2e1d3fbf34698deb)) ## v1.15.2 (2022-09-27) ### Bug Fixes - More typing fixes ([#40](https://github.com/Bluetooth-Devices/dbus-fast/pull/40), [`a6b9581`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a6b9581d6228bf2cb4b93531677acc959e2d4dd1)) ## v1.15.1 (2022-09-26) ### Bug Fixes - Loosen async-timeout pin to 3.0.0 ([#39](https://github.com/Bluetooth-Devices/dbus-fast/pull/39), [`93b9a0a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/93b9a0a6ca91adb6c64d9316bd977a359c3be007)) ## v1.15.0 (2022-09-26) ### Features - Use async_timeout instead of asyncio.wait_for ([#38](https://github.com/Bluetooth-Devices/dbus-fast/pull/38), [`cb31780`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cb317802d654bbff7b09233b4cce6188179f1d45)) ## v1.14.0 (2022-09-25) ### Features - Speed up unmarshaller read_array ([#37](https://github.com/Bluetooth-Devices/dbus-fast/pull/37), [`18ea18d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/18ea18d7d224764b7f529cb6238ac524f0bd8318)) ## v1.13.0 (2022-09-24) ### Features - Improve unmarshall performance ([#35](https://github.com/Bluetooth-Devices/dbus-fast/pull/35), [`db436b7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/db436b7a10a38438a9a7f50349ddb41b112c3312)) ## v1.12.0 (2022-09-24) ### Features - Speed up unmarshall ([#34](https://github.com/Bluetooth-Devices/dbus-fast/pull/34), [`5a1e26f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5a1e26f4302ed1ff3a4582e6710e2c5f99cb4a32)) ## v1.11.0 (2022-09-24) ### Features - Speed up marshalling ([#32](https://github.com/Bluetooth-Devices/dbus-fast/pull/32), [`afcf5fe`](https://github.com/Bluetooth-Devices/dbus-fast/commit/afcf5fe1d9c1c4a632edc60b5d48d8af32d13159)) ## v1.10.0 (2022-09-24) ### Features - Improve writer performance with a deque ([#30](https://github.com/Bluetooth-Devices/dbus-fast/pull/30), [`09af56e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/09af56e14397d9bdf183239c30683c76b7e34801)) ## v1.9.0 (2022-09-24) ### Features - Improve asyncio write performance ([#29](https://github.com/Bluetooth-Devices/dbus-fast/pull/29), [`016e71e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/016e71ef6d7de4d9295f3ca170d7352ae233d74a)) ## v1.8.0 (2022-09-24) ### Features - Small speed ups to unmarshall message creation ([#27](https://github.com/Bluetooth-Devices/dbus-fast/pull/27), [`0bce72a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0bce72a76a6af0d7b3c731e08393652747e6c53a)) ## v1.7.0 (2022-09-21) ### Features - Handle kwargs in signal callback ([#26](https://github.com/Bluetooth-Devices/dbus-fast/pull/26), [`2e8076b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2e8076b14abf297b83eb2c81b0cacff405845d95)) ## v1.6.0 (2022-09-20) ### Bug Fixes - Disconnect connected buses at end of tests ([#25](https://github.com/Bluetooth-Devices/dbus-fast/pull/25), [`e438890`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e43889091bf7b21f6ffd27544d74cc1d57db22d2)) ### Features - Add unpack variants option ([#20](https://github.com/Bluetooth-Devices/dbus-fast/pull/20), [`cfad28b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cfad28bd2ba8dccf4c3a591461bb666871e4cbba)) ## v1.5.1 (2022-09-20) ### Bug Fixes - Marshall boolean correctly ([#23](https://github.com/Bluetooth-Devices/dbus-fast/pull/23), [`ca2a3c1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ca2a3c1aa86f1f0b6372929f099e8594dab2697f)) ## v1.5.0 (2022-09-19) ### Chores - Run gi tests in the CI ([#21](https://github.com/Bluetooth-Devices/dbus-fast/pull/21), [`f4d173e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f4d173e0426990cd0b8b1b813949cd5027684102)) ### Features - Allow varargs callback for signals ([#22](https://github.com/Bluetooth-Devices/dbus-fast/pull/22), [`a3379c7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a3379c74ad8f8da1eb15b6cd941d9bea6867b5f9)) ## v1.4.0 (2022-09-10) ### Features - Improve unmarshalling performance ([#18](https://github.com/Bluetooth-Devices/dbus-fast/pull/18), [`4362b93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4362b93fc84406adfa026b6573bc076327c71c5b)) ## v1.3.0 (2022-09-09) ### Features - Improve callback performance ([#16](https://github.com/Bluetooth-Devices/dbus-fast/pull/16), [`aee3da9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/aee3da9f20c36cf6379d1e69e63f33a88592f6fd)) ## v1.2.0 (2022-09-09) ### Chores - Add marshall benchmark ([#14](https://github.com/Bluetooth-Devices/dbus-fast/pull/14), [`e386e22`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e386e228c54914b0a1f8babe3659ea5629a3cb7d)) ### Features - Improve Marshaller performance ([#15](https://github.com/Bluetooth-Devices/dbus-fast/pull/15), [`a9e8866`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a9e8866c2a6a97227ff5f001cae5e2196260379c)) ## v1.1.9 (2022-09-09) ### Bug Fixes - Readme ([#13](https://github.com/Bluetooth-Devices/dbus-fast/pull/13), [`6bc87e0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6bc87e0f0717d4a4382e4bb36d064e22ff131751)) ## v1.1.8 (2022-09-09) ### Bug Fixes - Ensure the underlying socket is closed on disconnect ([#12](https://github.com/Bluetooth-Devices/dbus-fast/pull/12), [`6770a65`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6770a656bdddf6e090ebb6858bd046e4365ea32e)) ## v1.1.7 (2022-09-09) ### Bug Fixes - Copyrights in docs ([#10](https://github.com/Bluetooth-Devices/dbus-fast/pull/10), [`a97701e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a97701ec12e4049884af33abbde2b208c4e351d4)) ## v1.1.6 (2022-09-09) ### Bug Fixes - Docs deps not needed for production ([#9](https://github.com/Bluetooth-Devices/dbus-fast/pull/9), [`01f8ce7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/01f8ce77b945554f27723755caab550b6f246cb4)) ## v1.1.5 (2022-09-09) ### Bug Fixes - Readme ([#8](https://github.com/Bluetooth-Devices/dbus-fast/pull/8), [`7396b5f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7396b5f475e4b9299cf96930153a01425bb5bd3b)) ## v1.1.4 (2022-09-09) ### Bug Fixes - More rename ([#7](https://github.com/Bluetooth-Devices/dbus-fast/pull/7), [`116d5c6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/116d5c6feb863deff95f811d79199b09c79552f9)) ## v1.1.3 (2022-09-09) ### Bug Fixes - Docs ([#6](https://github.com/Bluetooth-Devices/dbus-fast/pull/6), [`ee473c0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ee473c05c5ff1ecc91f0c0167987e970eebf4c75)) ## v1.1.2 (2022-09-09) ### Bug Fixes - Docs ([#4](https://github.com/Bluetooth-Devices/dbus-fast/pull/4), [`ba8e5f1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ba8e5f127f2a4e20254a8d652165c348d0b9884f)) - Readme ([#5](https://github.com/Bluetooth-Devices/dbus-fast/pull/5), [`f628e87`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f628e87a1b859966dac03143a7a14422ef0d79a1)) ## v1.1.1 (2022-09-09) ### Bug Fixes - Docs lang ([#3](https://github.com/Bluetooth-Devices/dbus-fast/pull/3), [`538db98`](https://github.com/Bluetooth-Devices/dbus-fast/commit/538db98a3b7246e5d3ace256ac3b86c3dae5b63e)) ## v1.1.0 (2022-09-09) ### Chores - Build fixes ([`4927a1e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4927a1e79908dfc91b804475c80a59f13ded5c04)) - Ci fixes ([`fad09d6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fad09d60a8aea05efe1cf584da6c1b858227f272)) - Disable some linters ([`0ab9fab`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ab9fabe2fddec729dcac1bee1b2f671f6c3b539)) - Fix ci ([`d187573`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d18757378bb55112a0f39c4c6a8b86c29b60574e)) - Fix ci ([`988ff05`](https://github.com/Bluetooth-Devices/dbus-fast/commit/988ff0599454ac65e192bbbef6f61534c14bf346)) - Fix ci ([`6e10c51`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6e10c51d88b46e80fc9b10b082b5888167f9670b)) - Fix ci ([`2a2d486`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2a2d486494bde0001891f71821f588c8a25d9c4c)) - Fix ci ([`61e00c1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/61e00c1c0782288d1a12cefe784c4b860fd260d8)) - Initial commit ([`169581f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/169581f69121ef66a326fd100656756aee1baed9)) - Initial port ([`495bfac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/495bfac17fd7e56d292ddfde42e7e6570e04ab01)) - Rename ([`60308e0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/60308e0b0cb14e7a26631f632123db16e4cb09c0)) - Rename ([`36b08af`](https://github.com/Bluetooth-Devices/dbus-fast/commit/36b08afbff9ead520ec237f7259354185e513a0d)) - Rename ([`7e9609b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7e9609b0f5f95ba9e146bd73242de4e2fe5ad124)) ### Features - Speed up unmarshaller ([#1](https://github.com/Bluetooth-Devices/dbus-fast/pull/1), [`eca1d31`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eca1d317818d2b938ec3ed3172b1be76a44a93a4)) dbus-fast-2.44.1/CONTRIBUTING.md000066400000000000000000000074221477355613200157450ustar00rootroot00000000000000# Contributing Contributions are welcome, and they are greatly appreciated! Every little helps, and credit will always be given. You can contribute in many ways: ## Types of Contributions ### Report Bugs Report bugs to [our issue page][gh-issues]. If you are reporting a bug, please include: - Your operating system name and version. - Any details about your local setup that might be helpful in troubleshooting. - Detailed steps to reproduce the bug. ### Fix Bugs Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it. ### Implement Features Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it. ### Write Documentation dbus-fast could always use more documentation, whether as part of the official dbus-fast docs, in docstrings, or even on the web in blog posts, articles, and such. ### Submit Feedback The best way to send feedback [our issue page][gh-issues] on GitHub. If you are proposing a feature: - Explain in detail how it would work. - Keep the scope as narrow as possible, to make it easier to implement. - Remember that this is a volunteer-driven project, and that contributions are welcome 😊 ## Get Started! Ready to contribute? Here's how to set yourself up for local development. 1. Fork the repo on GitHub. 2. Clone your fork locally: ```shell $ git clone git@github.com:your_name_here/dbus-fast.git ``` 3. Install the project dependencies with [Poetry](https://python-poetry.org): ```shell $ poetry install ``` 4. Create a branch for local development: ```shell $ git checkout -b name-of-your-bugfix-or-feature ``` Now you can make your changes locally. 5. When you're done making changes, check that your changes pass our tests: ```shell $ poetry run pytest ``` 6. Linting is done through [pre-commit](https://pre-commit.com). Provided you have the tool installed globally, you can run them all as one-off: ```shell $ pre-commit run -a ``` Or better, install the hooks once and have them run automatically each time you commit: ```shell $ pre-commit install ``` 7. Commit your changes and push your branch to GitHub: ```shell $ git add . $ git commit -m "feat(something): your detailed description of your changes" $ git push origin name-of-your-bugfix-or-feature ``` Note: the commit message should follow [the conventional commits](https://www.conventionalcommits.org). We run [`commitlint` on CI](https://github.com/marketplace/actions/commit-linter) to validate it, and if you've installed pre-commit hooks at the previous step, the message will be checked at commit time. 8. Submit a pull request through the GitHub website or using the GitHub CLI (if you have it installed): ```shell $ gh pr create --fill ``` ## Pull Request Guidelines We like to have the pull request open as soon as possible, that's a great place to discuss any piece of work, even unfinished. You can use draft pull request if it's still a work in progress. Here are a few guidelines to follow: 1. Include tests for feature or bug fixes. 2. Update the documentation for significant features. 3. Ensure tests are passing on CI. ## Tips To run a subset of tests: ```shell $ pytest tests ``` ## Making a new release The deployment should be automated and can be triggered from the Semantic Release workflow in GitHub. The next version will be based on [the commit logs](https://python-semantic-release.readthedocs.io/en/latest/commit-log-parsing.html#commit-log-parsing). This is done by [python-semantic-release](https://python-semantic-release.readthedocs.io/en/latest/index.html) via a GitHub action. [gh-issues]: https://github.com/bluetooth-devices/dbus-fast/issues dbus-fast-2.44.1/LICENSE000066400000000000000000000020731477355613200145160ustar00rootroot00000000000000 MIT License Copyright (c) 2022 Bluetooth Devices Authors 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. dbus-fast-2.44.1/README.md000066400000000000000000000225611477355613200147740ustar00rootroot00000000000000# dbus-fast

CI Status Documentation Status Test coverage percentage

Poetry Ruff pre-commit CodSpeed Badge

PyPI Version Supported Python versions License

A faster version of dbus-next originally from the [great DBus next library](https://github.com/altdesktop/python-dbus-next) ❤️ ## Installation Install this via pip (or your favourite package manager): `pip install dbus-fast` [Documentation](https://dbus-fast.readthedocs.io/en/latest/) dbus-fast is a Python library for DBus that aims to be a performant fully featured high level library primarily geared towards integration of applications into Linux desktop and mobile environments. Desktop application developers can use this library for integrating their applications into desktop environments by implementing common DBus standard interfaces or creating custom plugin interfaces. Desktop users can use this library to create their own scripts and utilities to interact with those interfaces for customization of their desktop environment. dbus-fast plans to improve over other DBus libraries for Python in the following ways: - Zero dependencies and pure Python 3 - An optional cython extension is available to speed up (un)marshalling - Focus on performance - Support for multiple IO backends including asyncio and the GLib main loop. - Nonblocking IO suitable for GUI development. - Target the latest language features of Python for beautiful services and clients. - Complete implementation of the DBus type system without ever guessing types. - Integration tests for all features of the library. - Completely documented public API. ## Installing This library is available on PyPi as [dbus-fast](https://pypi.org/project/dbus-fast/). ``` pip3 install dbus-fast ``` ## The Client Interface To use a service on the bus, the library constructs a proxy object you can use to call methods, get and set properties, and listen to signals. For more information, see the [overview for the high-level client](https://dbus-fast.readthedocs.io/en/latest/high-level-client/index.html). This example connects to a media player and controls it with the [MPRIS](https://specifications.freedesktop.org/mpris-spec/latest/) DBus interface. ```python from dbus_fast.aio import MessageBus import asyncio async def main(): bus = await MessageBus().connect() # the introspection xml would normally be included in your project, but # this is convenient for development introspection = await bus.introspect('org.mpris.MediaPlayer2.vlc', '/org/mpris/MediaPlayer2') obj = bus.get_proxy_object('org.mpris.MediaPlayer2.vlc', '/org/mpris/MediaPlayer2', introspection) player = obj.get_interface('org.mpris.MediaPlayer2.Player') properties = obj.get_interface('org.freedesktop.DBus.Properties') # call methods on the interface (this causes the media player to play) await player.call_play() volume = await player.get_volume() print(f'current volume: {volume}, setting to 0.5') await player.set_volume(0.5) # listen to signals def on_properties_changed(interface_name, changed_properties, invalidated_properties): for changed, variant in changed_properties.items(): print(f'property changed: {changed} - {variant.value}') properties.on_properties_changed(on_properties_changed) await asyncio.Event().wait() asyncio.run(main()) ``` ## The Service Interface To define a service on the bus, use the `ServiceInterface` class and decorate class methods to specify DBus methods, properties, and signals with their type signatures. For more information, see the [overview for the high-level service](https://dbus-fast.readthedocs.io/en/latest/high-level-service/index.html). ```python from dbus_fast.service import ServiceInterface, method, dbus_property, signal, Variant from dbus_fast.aio MessageBus import asyncio class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) self._string_prop = 'kevin' @method() def Echo(self, what: 's') -> 's': return what @method() def GetVariantDict() -> 'a{sv}': return { 'foo': Variant('s', 'bar'), 'bat': Variant('x', -55), 'a_list': Variant('as', ['hello', 'world']) } @dbus_property() def string_prop(self) -> 's': return self._string_prop @string_prop.setter def string_prop_setter(self, val: 's'): self._string_prop = val @signal() def signal_simple(self) -> 's': return 'hello' async def main(): bus = await MessageBus().connect() interface = ExampleInterface('test.interface') bus.export('/test/path', interface) # now that we are ready to handle requests, we can request name from D-Bus await bus.request_name('test.name') # wait indefinitely await asyncio.Event().wait() asyncio.run(main()) ``` ## The Low-Level Interface The low-level interface works with DBus messages directly. For more information, see the [overview for the low-level interface](https://dbus-fast.readthedocs.io/en/latest/low-level-interface/index.html). ```python from dbus_fast.message import Message, MessageType from dbus_fast.aio import MessageBus import asyncio import json async def main(): bus = await MessageBus().connect() reply = await bus.call( Message(destination='org.freedesktop.DBus', path='/org/freedesktop/DBus', interface='org.freedesktop.DBus', member='ListNames')) if reply.message_type == MessageType.ERROR: raise Exception(reply.body[0]) print(json.dumps(reply.body[0], indent=2)) asyncio.run(main()) ``` ## Projects that use dbus-fast - [Bluetooth Adapters](https://github.com/bluetooth-devices/bluetooth-adapters) ## Contributing Contributions are welcome. Development happens on [Github](https://github.com/Bluetooth-Devices/dbus-fast). Before you commit, run `pre-commit run --all-files` to run the linter, code formatter, and the test suite. ## Copyright You can use this code under an MIT license (see LICENSE). - © 2019, Tony Crisci - © 2022, Bluetooth Devices authors ## Contributors ✨ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! ## Credits This package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage) project template. dbus-fast-2.44.1/bench/000077500000000000000000000000001477355613200145665ustar00rootroot00000000000000dbus-fast-2.44.1/bench/marshall.py000066400000000000000000000007101477355613200167410ustar00rootroot00000000000000import timeit from dbus_fast import Message message = Message( destination="org.bluez", path="/", interface="org.freedesktop.DBus.ObjectManager", member="GetManagedObjects", ) def marhsall_bluez_get_managed_objects_message(): message._marshall(False) count = 1000000 time = timeit.Timer(marhsall_bluez_get_managed_objects_message).timeit(count) print(f"Marshalling {count} bluez get managed objects messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall.py000066400000000000000000000017641477355613200173160ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller # cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py bluez_rssi_message = ( "6c04010134000000e25389019500000001016f00250000002f6f72672f626c75657a2f686369302f6465" "765f30385f33415f46325f31455f32425f3631000000020173001f0000006f72672e667265656465736b" "746f702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e" "67656400000000000000080167000873617b73767d617300000007017300040000003a312e3400000000" "110000006f72672e626c75657a2e446576696365310000000e0000000000000004000000525353490001" "6e00a7ff000000000000" ) stream = io.BytesIO(bytes.fromhex(bluez_rssi_message)) unmarshaller = Unmarshaller(stream) def unmarhsall_bluez_rssi_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count) print(f"Unmarshalling {count} bluetooth rssi messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_2.py000066400000000000000000000073211477355613200175320ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller bluez_properties_message = ( b"l\4\1\0014\0\0\0\16Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_08_3A_F2_1E_28_89\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1" b"s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\242\377\0\0\0\0\0\0" b"l\4\1\1\220\0\0\0\17Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_A4_C1_38_6E_9F_7C\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s" b"\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0k\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\250\377\0\0\20\0\0\0" b"ManufacturerData\0\5a{qv}\0;\0\0\0\1\0\2ay\0\0\0\t\0\0\0\1\1\1\3\361\234\\\0\1\0\0\0L\0\2ay\0\0\0\27\0\0\0\2\25" b"INTELLI_ROCKS_HWPu\362\377\302\0\0\0\0\0l\4\1\0014\0\0\0\20Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_F8" b"_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0" b"\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0" b"\0\0RSSI\0\1n\0\262\377\0\0\0\0\0\0l\4\1\0014\0\0\0\21Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_54_E6_" b"1B_F0_20_97\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0" b"\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0" b"RSSI\0\1n\0\254\377\0\0\0\0\0\0l\4\1\0014\0\0\0\22Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_D8_EF_2F_41" b"_B1_34\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10" b"\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0" b"\1n\0\244\377\0\0\0\0\0\0l\4\1\0014\0\0\0\23Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_66_6D\0" b"\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10" b"sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\236" b"\377\0\0\0\0\0\0l\4\1\0014\0\0\0\24Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_08_3A_F2_1E_32_69\0\0\0\2\1s" b"\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0" b"\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\246\377\0\0\0" b"\0\0\0l\4\1\0014\0\0\0\25Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_71_D1\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4" b"\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\232\377\0\0\0\0\0\0l\4\1\001" b"4\0\0\0\26Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_F8_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.D" b"Bus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0" b"\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\306\377\0\0\0\0\0\0" ) stream = io.BytesIO(bluez_properties_message) unmarshaller = Unmarshaller(stream) def unmarhsall_bluez_rssi_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count) print( f"Unmarshalling {count} bluetooth properties changed messages took {time} seconds" ) dbus-fast-2.44.1/bench/unmarshall_getmanagedobjects.py000066400000000000000000000011351477355613200230340ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller # cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py with open("tests/data/get_managed_objects.hex") as fp: msg = fp.read() stream = io.BytesIO(bytes.fromhex(msg)) unmarshaller = Unmarshaller(stream) def unmarhsall_bluez_get_managed_objects_message(): stream.seek(0) unmarshaller.unmarshall() count = 10000 time = timeit.Timer(unmarhsall_bluez_get_managed_objects_message).timeit(count) print(f"Unmarshalling {count} bluetooth GetManagedObjects messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_interfaces_added.py000066400000000000000000000035101477355613200226310ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller # cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py bluez_interfaces_added_message = ( b'l\4\1\1\240\2\0\0\227\272\23\0u\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0' b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\17\0\0\0InterfacesAdded\0\10" b"\1g\0\noa{sa{sv}}\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_2D_34" b"_60_26_36\0\0\0p\2\0\0#\0\0\0org.freedesktop.DBus.Introspectable\0\0\0\0\0\0\0\0\0" b"\21\0\0\0org.bluez.Device1\0\0\0\364\1\0\0\0\0\0\0\7\0\0\0Address\0\1s\0\0\21\0\0" b"\00058:2D:34:60:26:36\0\0\0\v\0\0\0AddressType\0\1s\0\0\6\0\0\0public\0\0\4\0\0\0" b"Name\0\1s\0\33\0\0\0Qingping Door/Window Sensor\0\0\0\0\0\5\0\0\0Alias\0\1s\0\0\0" b"\0\33\0\0\0Qingping Door/Window Sensor\0\6\0\0\0Paired\0\1b\0\0\0\0\0\0\0\0\0\0\0" b"\7\0\0\0Trusted\0\1b\0\0\0\0\0\0\0\0\0\0\7\0\0\0Blocked\0\1b\0\0\0\0\0\0\0\0\0\0\r" b"\0\0\0LegacyPairing\0\1b\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\316\377\0\0\t" b"\0\0\0Connected\0\1b\0\0\0\0\0\0\0\0\5\0\0\0UUIDs\0\2as\0\0\0\0\0\0\0\0\0\0\0\7\0" b"\0\0Adapter\0\1o\0\0\17\0\0\0/org/bluez/hci1\0\0\0\0\0\v\0\0\0ServiceData\0\5a{sv}" b"\0\0@\0\0\0\0\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\f\0" b"\0\0000X\326\3\0026&`4-X\10\20\0\0\0ServicesResolved\0\1b\0\0\0\0\0\0\0\0\0\37\0\0" b"\0org.freedesktop.DBus.Properties\0\0\0\0\0" ) stream = io.BytesIO(bluez_interfaces_added_message) unmarshaller = Unmarshaller(stream) def unmarshall_interfaces_added_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarshall_interfaces_added_message).timeit(count) print(f"Unmarshalling {count} bluetooth InterfacesAdded messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_interfaces_removed.py000066400000000000000000000017661477355613200232440ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller # cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py bluez_interfaces_removed_message = ( b'l\4\1\1\222\0\0\0\377@-\0~\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0' b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\21\0\0\0InterfacesRemoved" b"\0\0\0\0\0\0\0\10\1g\0\3oas\0\0\0\0\0\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0%\0\0\0" b"/org/bluez/hci0/dev_5F_13_47_38_26_55\0\0\0b\0\0\0\37\0\0\0org.freedesktop.DBus" b".Properties\0#\0\0\0org.freedesktop.DBus.Introspectable\0\21\0\0\0org.bluez.Dev" b"ice1\0" ) stream = io.BytesIO(bluez_interfaces_removed_message) unmarshaller = Unmarshaller(stream) def unmarshall_interfaces_removed_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarshall_interfaces_removed_message).timeit(count) print(f"Unmarshalling {count} bluetooth InterfacesRemoved messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_manufacturerdata.py000066400000000000000000000020521477355613200227130ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller # cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py bluez_mfr_data_message = ( b"l\4\1\1x\0\0\0\232\312\n\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_D0_C2_4E_08_AB_57\0\0\0\2\1s" b"\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0" b"\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0T\0\0\0\0\0\0\0\4\0\0\0" b"RSSI\0\1n\0\252\377\0\0\20\0\0\0ManufacturerData\0\5a{qv}\0$\0\0\0u\0\2ay\0\0\0\30\0\0\0B\4\1\1p\320" b"\302N\10\253W\322\302N\10\253V\1\0\0\0\0\0\0\0\0\0\0l\4\1\0014\0\0\0\233\312\n\0\225\0\0\0\1\1o\0%\0" ) stream = io.BytesIO(bluez_mfr_data_message) unmarshaller = Unmarshaller(stream) def unmarshall_mfr_data_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarshall_mfr_data_message).timeit(count) print(f"Unmarshalling {count} bluetooth ManufacturerData messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_passive.py000066400000000000000000000020771477355613200210460ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller bluez_passive_message = ( b"l\1\1\1*\0\0\0\205D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472597302272\0\0\0\6\1s\0\7\0\0" b"\0:1.1450\0\2\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10" b"\1g\0\1o\0\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci0/dev_58_D3_49_E6_02_6E\0l\1\1\1*\0\0\0" b"\206D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472593362560\0\0\0\6\1s\0\7\0\0\0:1.1450\0\2" b"\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10\1g\0\1o\0\0" b"\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_D3_49_E6_02_6E\0" ) stream = io.BytesIO(bluez_passive_message) unmarshaller = Unmarshaller(stream) def unmarhsall_bluez_rssi_message(): stream.seek(0) unmarshaller.unmarshall() unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count) print(f"Unmarshalling {count} bluetooth passive messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_servicedata.py000066400000000000000000000022711477355613200216620ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller # cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py bluez_properties_changed_message = ( b"l\4\1\1\334\0\0\0@\236.\0\226\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_58_2D_34_60_DA_1F" b"\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged" b"\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0\21\0\0\0org.bluez.Devi" b"ce1\0\0\0\270\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\301\377\0\0\v\0\0\0ServiceData\0\5a{sv}" b"\0\0\210\0\0\0\0\0\0\0$\0\0\0000000fdcd-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\24\0" b"\0\0\10\22\37\332`4-X\2\1U\17\1\315\t\4\5\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f" b"9b34fb\0\2ay\0\0\0\0\f\0\0\0000X\203\n\2\37\332`4-X\10\0\0\0\0" ) stream = io.BytesIO(bluez_properties_changed_message) unmarshaller = Unmarshaller(stream) def unmarshall_properties_changed_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarshall_properties_changed_message).timeit(count) print(f"Unmarshalling {count} bluetooth PropertiesChanged messages took {time} seconds") dbus-fast-2.44.1/bench/unmarshall_write_value.py000066400000000000000000000014671477355613200217240ustar00rootroot00000000000000import io import timeit from dbus_fast._private.unmarshaller import Unmarshaller bluez_passive_message = ( b"l\1\0\1(\0\0\0F\1\0\0\255\0\0\0\1\1o\0:\0\0\0/org/bluez/hci0/dev_BD_24_6F_" b"85_AA_61/service001a/char001b\0\0\0\0\0\0\2\1s\0\35\0\0\0org.bluez.GattCha" b"racteristic1\0\0\0\3\1s\0\n\0\0\0WriteValue\0\0\0\0\0\0\6\1s\0\t\0\0\0org." b"bluez\0\0\0\0\0\0\0\10\1g\0\7aya{sv}\0\0\0\0\3\0\0\0\357\1w\0\30\0\0\0\0\0" b"\0\0\4\0\0\0type\0\1s\0\7\0\0\0command\0" ) stream = io.BytesIO(bluez_passive_message) unmarshaller = Unmarshaller(stream) def unmarhsall_bluez_rssi_message(): stream.seek(0) unmarshaller.unmarshall() count = 3000000 time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count) print(f"Unmarshalling {count} bluetooth write value messages took {time} seconds") dbus-fast-2.44.1/bench/unpack_variants.py000066400000000000000000000044651477355613200203410ustar00rootroot00000000000000import timeit from dbus_fast import Variant, unpack_variants # cythonize -X language_level=3 -a -i src/dbus_fast/unpack.py message = { "/org/bluez/hci0": { "org.bluez.Adapter1": { "Address": Variant("s", "00:E0:4C:2A:25:63"), "AddressType": Variant("s", "public"), "Alias": Variant("s", "BlueZ 5.63"), "Class": Variant("u", 2883584), "Discoverable": Variant("b", False), "DiscoverableTimeout": Variant("u", 180), "Discovering": Variant("b", True), "Modalias": Variant("s", "usb:v1D6Bp0246d053F"), "Name": Variant("s", "BlueZ 5.63"), "Pairable": Variant("b", False), "PairableTimeout": Variant("u", 0), "Powered": Variant("b", True), "Roles": Variant("as", ["central", "peripheral"]), "UUIDs": Variant( "as", [ "0000110e-0000-1000-8000-00805f9b34fb", "0000110a-0000-1000-8000-00805f9b34fb", "00001200-0000-1000-8000-00805f9b34fb", "0000110b-0000-1000-8000-00805f9b34fb", "00001108-0000-1000-8000-00805f9b34fb", "0000110c-0000-1000-8000-00805f9b34fb", "00001800-0000-1000-8000-00805f9b34fb", "00001801-0000-1000-8000-00805f9b34fb", "0000180a-0000-1000-8000-00805f9b34fb", "00001112-0000-1000-8000-00805f9b34fb", ], ), }, "org.bluez.GattManager1": {}, "org.bluez.LEAdvertisingManager1": { "ActiveInstances": Variant("y", 0), "SupportedIncludes": Variant( "as", ["tx-power", "appearance", "local-name"] ), "SupportedInstances": Variant("y", 4), "SupportedSecondaryChannels": Variant("as", ["1M", "2M", "Coded"]), }, "org.bluez.Media1": {}, "org.bluez.NetworkServer1": {}, "org.freedesktop.DBus.Introspectable": {}, "org.freedesktop.DBus.Properties": {}, }, } def unpack_managed_objects(): unpack_variants(message) count = 3000000 time = timeit.Timer(unpack_managed_objects).timeit(count) print(f"Unpacked {count} get managed objects messages took {time} seconds") dbus-fast-2.44.1/build_ext.py000066400000000000000000000032111477355613200160350ustar00rootroot00000000000000"""Build optional cython modules.""" import logging import os from distutils.command.build_ext import build_ext _LOGGER = logging.getLogger(__name__) try: from setuptools import Extension except ImportError: from distutils.core import Extension TO_CYTHONIZE = [ "src/dbus_fast/aio/message_reader.py", "src/dbus_fast/message.py", "src/dbus_fast/message_bus.py", "src/dbus_fast/service.py", "src/dbus_fast/signature.py", "src/dbus_fast/unpack.py", "src/dbus_fast/_private/address.py", "src/dbus_fast/_private/marshaller.py", "src/dbus_fast/_private/unmarshaller.py", ] EXTENSIONS = [ Extension( ext.removeprefix("src/").removesuffix(".py").replace("/", "."), [ext], language="c", extra_compile_args=["-O3", "-g0"], ) for ext in TO_CYTHONIZE ] class BuildExt(build_ext): def build_extensions(self): try: super().build_extensions() except Exception: _LOGGER.debug("Failed to build extensions", exc_info=True) def build(setup_kwargs): if os.environ.get("SKIP_CYTHON"): return try: from Cython.Build import cythonize setup_kwargs.update( { "ext_modules": cythonize( EXTENSIONS, compiler_directives={"language_level": "3"}, # Python 3 ), "cmdclass": {"build_ext": BuildExt}, } ) setup_kwargs["exclude_package_data"] = { pkg: ["*.c"] for pkg in setup_kwargs["packages"] } except Exception: if os.environ.get("REQUIRE_CYTHON"): raise dbus-fast-2.44.1/commitlint.config.mjs000066400000000000000000000003621477355613200176460ustar00rootroot00000000000000export default { extends: ["@commitlint/config-conventional"], rules: { "header-max-length": [0, "always", Infinity], "body-max-line-length": [0, "always", Infinity], "footer-max-line-length": [0, "always", Infinity], }, }; dbus-fast-2.44.1/docs/000077500000000000000000000000001477355613200144375ustar00rootroot00000000000000dbus-fast-2.44.1/docs/Makefile000066400000000000000000000011751477355613200161030ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) dbus-fast-2.44.1/docs/make.bat000066400000000000000000000013741477355613200160510ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd dbus-fast-2.44.1/docs/requirements.txt000066400000000000000000000001261477355613200177220ustar00rootroot00000000000000myst-parser==4.0.0 Sphinx==8.1.3 sphinx-rtd-theme==3.0.2 sphinxcontrib-fulltoc==1.2.0 dbus-fast-2.44.1/docs/source/000077500000000000000000000000001477355613200157375ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/Makefile000066400000000000000000000011371477355613200174010ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = dbus-fast SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) dbus-fast-2.44.1/docs/source/_static/000077500000000000000000000000001477355613200173655ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/_static/.gitignore000066400000000000000000000000001477355613200213430ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/_static/.gitkeep000066400000000000000000000000001477355613200210040ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/_templates/000077500000000000000000000000001477355613200200745ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/_templates/.gitignore000066400000000000000000000000001477355613200220520ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/authentication.rst000066400000000000000000000005651477355613200215160ustar00rootroot00000000000000Authentication ============== Classes for the DBus `authentication protocol `_ for us with :class:`MessageBus ` implementations. .. autoclass:: dbus_fast.auth.Authenticator .. autoclass:: dbus_fast.auth.AuthExternal .. autoclass:: dbus_fast.auth.AuthAnonymous dbus-fast-2.44.1/docs/source/changelog.md000066400000000000000000000000451477355613200202070ustar00rootroot00000000000000```{include} ../../CHANGELOG.md ``` dbus-fast-2.44.1/docs/source/conf.py000066400000000000000000000117201477355613200172370ustar00rootroot00000000000000# # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + "/..")) from dbus_fast.__version__ import __author__, __copyright__, __title__, __version__ _project_slug = __title__.replace("_", "-") # -- Project information ----------------------------------------------------- project = _project_slug copyright = __copyright__ author = __author__ # The short X.Y version version = __version__ # The full version, including alpha/beta/rc tags release = __version__ # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.githubpages", "sphinxcontrib.fulltoc", ] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = ".rst" # The master toctree document. master_doc = "index" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = "alabaster" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = "dbus-fastdoc" # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, "dbus-fast.tex", "dbus-fast Documentation", __author__, "manual"), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [(master_doc, _project_slug, "dbus-fast Documentation", [author], 1)] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, _project_slug, "dbus-fast Documentation", author, _project_slug, "One line description of project.", "Miscellaneous", ), ] # -- Extension configuration ------------------------------------------------- dbus-fast-2.44.1/docs/source/constants.rst000066400000000000000000000012421477355613200205040ustar00rootroot00000000000000Constants ========= .. autoclass:: dbus_fast.BusType :members: :undoc-members: .. autoclass:: dbus_fast.MessageType :members: :undoc-members: .. autoclass:: dbus_fast.MessageFlag :members: :undoc-members: .. autoclass:: dbus_fast.NameFlag :members: :undoc-members: .. autoclass:: dbus_fast.RequestNameReply :members: :undoc-members: .. autoclass:: dbus_fast.ReleaseNameReply :members: :undoc-members: .. autoclass:: dbus_fast.PropertyAccess :members: :undoc-members: .. autoclass:: dbus_fast.ArgDirection :members: :undoc-members: .. autoclass:: dbus_fast.ErrorType :members: :undoc-members: dbus-fast-2.44.1/docs/source/contributing.md000066400000000000000000000000501477355613200207630ustar00rootroot00000000000000```{include} ../../CONTRIBUTING.md ``` dbus-fast-2.44.1/docs/source/errors.rst000066400000000000000000000012051477355613200200030ustar00rootroot00000000000000Errors ====== .. autoclass:: dbus_fast.DBusError :members: :undoc-members: .. autoclass:: dbus_fast.SignatureBodyMismatchError .. autoclass:: dbus_fast.InvalidSignatureError .. autoclass:: dbus_fast.InvalidAddressError .. autoclass:: dbus_fast.AuthError .. autoclass:: dbus_fast.InvalidMessageError .. autoclass:: dbus_fast.InvalidIntrospectionError .. autoclass:: dbus_fast.InterfaceNotFoundError .. autoclass:: dbus_fast.SignalDisabledError .. autoclass:: dbus_fast.InvalidBusNameError .. autoclass:: dbus_fast.InvalidObjectPathError .. autoclass:: dbus_fast.InvalidInterfaceNameError .. autoclass:: dbus_fast.InvalidMemberNameError dbus-fast-2.44.1/docs/source/high-level-client/000077500000000000000000000000001477355613200212375ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/high-level-client/aio-proxy-interface.rst000066400000000000000000000002141477355613200256530ustar00rootroot00000000000000aio.ProxyInterface ================== .. autoclass:: dbus_fast.aio.ProxyInterface :members: :undoc-members: :show-inheritance: dbus-fast-2.44.1/docs/source/high-level-client/aio-proxy-object.rst000066400000000000000000000002031477355613200251570ustar00rootroot00000000000000aio.ProxyObject =============== .. autoclass:: dbus_fast.aio.ProxyObject :members: :undoc-members: :show-inheritance: dbus-fast-2.44.1/docs/source/high-level-client/base-proxy-interface.rst000066400000000000000000000002021477355613200260120ustar00rootroot00000000000000BaseProxyInterface ================== .. autoclass:: dbus_fast.proxy_object.BaseProxyInterface :members: :undoc-members: dbus-fast-2.44.1/docs/source/high-level-client/base-proxy-object.rst000066400000000000000000000001711477355613200253250ustar00rootroot00000000000000BaseProxyObject =============== .. autoclass:: dbus_fast.proxy_object.BaseProxyObject :members: :undoc-members: dbus-fast-2.44.1/docs/source/high-level-client/glib-proxy-interface.rst000066400000000000000000000002171477355613200260230ustar00rootroot00000000000000glib.ProxyInterface =================== .. autoclass:: dbus_fast.glib.ProxyInterface :members: :undoc-members: :show-inheritance: dbus-fast-2.44.1/docs/source/high-level-client/glib-proxy-object.rst000066400000000000000000000002061477355613200253270ustar00rootroot00000000000000glib.ProxyObject ================ .. autoclass:: dbus_fast.glib.ProxyObject :members: :undoc-members: :show-inheritance: dbus-fast-2.44.1/docs/source/high-level-client/index.rst000066400000000000000000000117511477355613200231050ustar00rootroot00000000000000The High Level Client ===================== .. toctree:: :maxdepth: 2 base-proxy-object base-proxy-interface aio-proxy-object aio-proxy-interface glib-proxy-object glib-proxy-interface DBus interfaces are defined with an XML-based `introspection data format `_ which is exposed over the standard `org.freedesktop.DBus.Introspectable `_ interface. Calling the ``Introspect`` at a particular object path may return XML data similar to this: .. code-block:: xml The object at this path (a ``node``) may contain interfaces and child nodes. Nodes like this are represented in the library by a :class:`ProxyObject `. The interfaces contained in the nodes are represented by a :class:`ProxyInterface `. The proxy interface exposes the methods, signals, and properties specified by the interface definition. The proxy object is obtained by the :class:`MessageBus ` through the :func:`get_proxy_object() ` method. This method takes the name of the client to send messages to, the path exported by that client that is expected to export the node, and the XML introspection data. If you can, it is recommended to include the XML in your project and pass it to that method as a string. But you may also use the :func:`introspect() ` method of the message bus to get this data dynamically at runtime. Once you have a proxy object, use the :func:`get_proxy_interface() ` method to create an interface passing the name of the interface to get. Each message bus has its own implementation of the proxy interface which behaves slightly differently. This is an example of how to use a proxy interface for the asyncio :class:`MessageBus `. If any file descriptors are sent or received (DBus type ``h``), the variable refers to the file descriptor itself. You are responsible for closing any file descriptors sent or received by the bus. You must set the ``negotiate_unix_fd`` flag to ``True`` in the ``MessageBus`` constructor to use unix file descriptors. :example: .. code-block:: python3 from dbus_fast.aio import MessageBus from dbus_fast import Variant bus = await MessageBus().connect() with open('introspection.xml', 'r') as f: introspection = f.read() # alternatively, get the data dynamically: # introspection = await bus.introspect('com.example.name', # '/com/example/sample_object0') proxy_object = bus.get_proxy_object('com.example.name', '/com/example/sample_object0', introspection) interface = proxy_object.get_interface('com.example.SampleInterface0') # Use call_[METHOD] in snake case to call methods, passing the # in args and receiving the out args. The `baz` returned will # be type 'a{us}' which translates to a Python dict with `int` # keys and `str` values. baz = await interface.call_frobate(5, 'hello') # `bar` will be a Variant. bar = await interface.call_bazify([-5, 5, 5]) await interface.call_mogrify([5, 5, [ Variant('s', 'foo') ]) # Listen to signals by defining a callback that takes the args # specified by the signal definition and registering it on the # interface with on_[SIGNAL] in snake case. def changed_notify(new_value): print(f'The new value is: {new_value}') interface.on_changed(changed_notify) # Use get_[PROPERTY] and set_[PROPERTY] with the property in # snake case to get and set the property. bar_value = await interface.get_bar() await interface.set_bar(105) await bus.wait_for_disconnect() dbus-fast-2.44.1/docs/source/high-level-service/000077500000000000000000000000001477355613200214215ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/high-level-service/index.rst000066400000000000000000000127021477355613200232640ustar00rootroot00000000000000The High Level Service ====================== .. toctree:: :maxdepth: 2 service-interface The high level service interface provides everything you need to export interfaces on the bus. When you export an interface on your :class:`MessageBus `, clients can send you messages to call methods, get and set properties, and listen to your signals. If you're exposing a service for general use, you can request a well-known name for your connection with :func:`MessageBus.request_name() ` so users have a predictable name to use to send messages your client. Services are defined by subclassing :class:`ServiceInterface ` and definining members as methods on the class with the decorator methods :func:`@method() `, :func:`@dbus_property() `, and :func:`@signal() `. The parameters of the decorated class methods must be annotated with DBus type strings to indicate the types of values they expect. See the documentation on `the type system `_ for more information on how DBus types are mapped to Python values with signature strings. The decorator methods themselves take arguments that affect how the member is exported on the bus, such as the name of the member or the access permissions of a property. A class method decorated with ``@method()`` will be called when a client calls the method over DBus. The parameters given to the class method will be provided by the calling client and will conform to the parameter type annotations. The value returned by the class method will be returned to the client and must conform to the return type annotation specified by the user. If the return annotation specifies more than one type, the values must be returned in a ``list``. When :class:`aio.MessageBus` is used, methods can be coroutines. A class method decorated with ``@dbus_property()`` will be exposed as a DBus property getter. This decoration works the same as a standard Python ``@property``. The getter will be called when a client gets the property through the standard properties interface with ``org.freedesktop.DBus.Properties.Get``. Define a property setter with ``@method_name.setter`` taking the new value as a parameter. The setter will be called when the client sets the property through ``org.freedesktop.DBus.Properties.Set``. When :class:`aio.MessageBus` is used, property getters and setters can be coroutines, although this will cause some functionality of the Python ``@property`` annotation to be lost. A class method decorated with ``@signal()`` will be exposed as a DBus signal. The value returned by the class method will be emitted as a signal and broadcast to clients who are listening to the signal. The returned value must conform to the return annotation of the class method as a DBus signature string. If the signal has more than one argument, they must be returned within a ``list``. A class method decorated with ``@method()`` or ``@dbus_property()`` may throw a :class:`DBusError ` to return a detailed error to the client if something goes wrong. After the service interface is defined, call :func:`MessageBus.export() ` on a connected message bus and the service will be made available on the given object path. If any file descriptors are sent or received (DBus type ``h``), the variable refers to the file descriptor itself. You are responsible for closing any file descriptors sent or received by the bus. You must set the ``negotiate_unix_fd`` flag to ``True`` in the ``MessageBus`` constructor to use unix file descriptors. :example: .. code-block:: python3 from dbus_fast.aio import MessageBus from dbus_fast.service import (ServiceInterface, method, dbus_property, signal) from dbus_fast import Variant, DBusError import asyncio class ExampleInterface(ServiceInterface): def __init__(self): super().__init__('com.example.SampleInterface0') self._bar = 105 @method() def Frobate(self, foo: 'i', bar: 's') -> 'a{us}': print(f'called Frobate with foo={foo} and bar={bar}') return { 1: 'one', 2: 'two' } @method() async def Bazify(self, bar: '(iiu)') -> 'vv': print(f'called Bazify with bar={bar}') return [Variant('s', 'example'), Variant('s', 'bazify')] @method() def Mogrify(self, bar: '(iiav)'): raise DBusError('com.example.error.CannotMogrify', 'it is not possible to mogrify') @signal() def Changed(self) -> 'b': return True @dbus_property() def Bar(self) -> 'y': return self._bar @Bar.setter def Bar(self, val: 'y'): if self._bar == val: return self._bar = val self.emit_properties_changed({'Bar': self._bar}) async def main(): bus = await MessageBus().connect() interface = ExampleInterface() bus.export('/com/example/sample0', interface) await bus.request_name('com.example.name') # emit the changed signal after two seconds. await asyncio.sleep(2) interface.changed() await bus.wait_for_disconnect() asyncio.run(main()) dbus-fast-2.44.1/docs/source/high-level-service/service-interface.rst000066400000000000000000000004051477355613200255500ustar00rootroot00000000000000ServiceInterface ================ .. autoclass:: dbus_fast.service.ServiceInterface :members: :undoc-members: .. autodecorator:: dbus_fast.service.dbus_property .. autodecorator:: dbus_fast.service.method .. autodecorator:: dbus_fast.service.signal dbus-fast-2.44.1/docs/source/index.md000066400000000000000000000003511477355613200173670ustar00rootroot00000000000000# Welcome to dbus-fast documentation! ```{toctree} :caption: Installation & Usage :maxdepth: 2 installation usage ``` ```{toctree} :caption: Project Info :maxdepth: 2 changelog contributing ``` ```{include} ../../README.md ``` dbus-fast-2.44.1/docs/source/index.rst000066400000000000000000000051771477355613200176120ustar00rootroot00000000000000Python DBus-Fast Documentation ============================== .. module:: dbus_fast .. toctree:: :maxdepth: 3 :caption: Reference: type-system/index.rst high-level-client/index.rst high-level-service/index.rst low-level-interface/index.rst message-bus/index.rst introspection validators constants errors authentication Overview ++++++++ Python DBus-Fast is a library for the `DBus message bus system `_ for interprocess communcation in a Linux desktop or mobile environment. Desktop application developers can use this library for integrating their applications into desktop environments by implementing common DBus standard interfaces or creating custom plugin interfaces. Desktop users can use this library to create their own scripts and utilities to interact with those interfaces for customization of their desktop environment. While other libraries for DBus exist for Python, this library offers the following improvements: - Zero dependencies and pure Python 3. - Support for multiple main loop backends including asyncio and the GLib main loop. - Nonblocking IO suitable for GUI development. - Target the latest language features of Python for beautiful services and clients. - Complete implementation of the DBus type system without ever guessing types. - Integration tests for all features of the library. - Completely documented public API. The library offers three core interfaces: - `The High Level Client `_ - Communicate with an existing interface exported on the bus by another client through a proxy object. - `The High Level Service `_ - Export a service interface for your application other clients can connect to for interaction with your application at runtime. - `The Low Level Interface `_ - Work with DBus messages directly for applications that work with the DBus daemon directly or to build your own high level abstractions. Installation ++++++++++++ This library is available on PyPi as `dbus-fast `_. .. code-block:: bash pip3 install dbus-fast Contributing ++++++++++++ Development for this library happens on `Github `_. Report bugs or request features there. Contributions are welcome. License ++++++++ This library is available under an `MIT License `_. © 2022, Bluetooth Devices authors © 2019, Tony Crisci Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` dbus-fast-2.44.1/docs/source/installation.md000066400000000000000000000002641477355613200207640ustar00rootroot00000000000000# Installation The package is published on [PyPI](https://pypi.org/project/deezer-python/) and can be installed with `pip` (or any equivalent): ```bash pip install dbus-fast ``` dbus-fast-2.44.1/docs/source/introspection.rst000066400000000000000000000010021477355613200213620ustar00rootroot00000000000000Introspection ============= .. autoclass:: dbus_fast.introspection.Node :members: :undoc-members: .. autoclass:: dbus_fast.introspection.Interface :members: :undoc-members: .. autoclass:: dbus_fast.introspection.Property :members: :undoc-members: .. autoclass:: dbus_fast.introspection.Method :members: :undoc-members: .. autoclass:: dbus_fast.introspection.Signal :members: :undoc-members: .. autoclass:: dbus_fast.introspection.Arg :members: :undoc-members: dbus-fast-2.44.1/docs/source/low-level-interface/000077500000000000000000000000001477355613200216035ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/low-level-interface/index.rst000066400000000000000000000074301477355613200234500ustar00rootroot00000000000000The Low Level Interface ======================= .. toctree:: :maxdepth: 2 message The low-level interface allows you to work with messages directly through the :class:`MessageBus ` with the :class:`Message ` class. This might be useful in the following cases: - Implementing an application that works with DBus directly like ``dbus-send(1)`` or ``dbus-monitor(1)``. - Creating a new implementation of the :class:`BaseMessageBus `. - Creating clients or services that use an alternative to the standard DBus interfaces. The primary methods and classes of the low-level interface are: - :class:`Message ` - :func:`MessageBus.send() ` - :func:`MessageBus.add_message_handler() ` - :func:`MessageBus.remove_message_handler() ` - :func:`MessageBus.next_serial() ` - :func:`aio.MessageBus.call() ` - :func:`glib.MessageBus.call() ` - :func:`glib.MessageBus.call_sync() ` Mixed use of the low and high level interfaces on the same bus connection is not recommended. :example: Call a standard interface .. code-block:: python3 bus = await MessageBus().connect() msg = Message(destination='org.freedesktop.DBus', path='/org/freedesktop/DBus', interface='org.freedesktop.DBus', member='ListNames', serial=bus.next_serial()) reply = await bus.call(msg) assert reply.message_type == MessageType.METHOD_RETURN print(reply.body[0]) :example: A custom method handler. Note that to receive these messages, you must `add a match rule `_ for the types of messages you want to receive. .. code-block:: python3 bus = await MessageBus().connect() reply = await bus.call( Message(destination='org.freedesktop.DBus', path='/org/freedesktop/DBus', member='AddMatch', signature='s', body=["member='MyMember', interface='com.test.interface'"])) assert reply.message_type == MessageType.METHOD_RETURN def message_handler(msg): if msg.interface == 'com.test.interface' and msg.member == 'MyMember': return Message.new_method_return(msg, 's', ['got it']) bus.add_message_handler(message_handler) await bus.wait_for_disconnect() :example: Emit a signal .. code-block:: python3 bus = await MessageBus().connect() await bus.send(Message.new_signal('/com/test/path', 'com.test.interface', 'SomeSignal', 's', ['a signal'])) :example: Send a file descriptor. The message format will be the same when received on the client side. You are responsible for closing any file descriptor that is sent or received by the bus. You must set the ``negotiate_unix_fd`` flag to ``True`` in the ``MessageBus`` constructor to use unix file descriptors. .. code-block:: python3 bus = await MessageBus().connect(negotiate_unix_fd=True) fd = os.open('/dev/null', os.O_RDONLY) msg = Message(destination='org.test.destination', path='/org/test/destination', interface='org.test.interface', member='TestMember', signature='h', body=[0], unix_fds=[fd]) await bus.send(msg) dbus-fast-2.44.1/docs/source/low-level-interface/message.rst000066400000000000000000000001241477355613200237560ustar00rootroot00000000000000Message ======= .. autoclass:: dbus_fast.Message :members: :undoc-members: dbus-fast-2.44.1/docs/source/message-bus/000077500000000000000000000000001477355613200201525ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/message-bus/aio-message-bus.rst000066400000000000000000000002041477355613200236610ustar00rootroot00000000000000aio.MessageBus ============== .. autoclass:: dbus_fast.aio.MessageBus :members: :inherited-members: :show-inheritance: dbus-fast-2.44.1/docs/source/message-bus/base-message-bus.rst000066400000000000000000000001411477355613200240230ustar00rootroot00000000000000BaseMessageBus ============== .. autoclass:: dbus_fast.message_bus.BaseMessageBus :members: dbus-fast-2.44.1/docs/source/message-bus/glib-message-bus.rst000066400000000000000000000002071477355613200240310ustar00rootroot00000000000000glib.MessageBus =============== .. autoclass:: dbus_fast.glib.MessageBus :members: :inherited-members: :show-inheritance: dbus-fast-2.44.1/docs/source/message-bus/index.rst000066400000000000000000000020721477355613200220140ustar00rootroot00000000000000The Message Bus =============== .. toctree:: :maxdepth: 2 base-message-bus.rst aio-message-bus.rst glib-message-bus.rst The message bus manages a connection to the DBus daemon. It's capable of sending and receiving messages and wiring up the classes of the high level interfaces. There are currently two implementations of the message bus depending on what main loop implementation you want to use. Use :class:`aio.MessageBus ` if you are using an asyncio main loop. Use :class:`glib.MessageBus ` if you are using a GLib main loop. For standalone applications, the asyncio message bus is preferable because it has a nice async/await api in place of the callback/synchronous interface of the GLib message bus. If your application is using other libraries that use the GLib main loop, such as a GTK application, the GLib implementation will be needed. However neither library is a requirement. For more information on how to use the message bus, see the documentation for the specific interfaces you plan to use. dbus-fast-2.44.1/docs/source/type-system/000077500000000000000000000000001477355613200202425ustar00rootroot00000000000000dbus-fast-2.44.1/docs/source/type-system/index.rst000066400000000000000000000233071477355613200221100ustar00rootroot00000000000000The Type System =============== .. toctree:: :maxdepth: 2 variant signature-tree signature-type Values that are sent or received over the message bus always have an associated signature that specifies the types of those values. For the high-level client and service, these signatures are specified in XML data which is advertised in a `standard DBus interface `__. The high-level client dynamically creates classes based on this introspection data with methods and signals with arguments based on the type signature. The high-level service does the inverse by introspecting the class to create the introspection XML data which is advertised on the bus for clients. Each token in the signature is mapped to a Python type as shown in the table below. +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | Name | Token | Python | Notes | | | | Type | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | BYTE | y | int | An integer 0-255. In an array, it has type ``bytes``. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | BOOLEAN | b | bool | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | INT16 | n | int | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | UINT16 | q | int | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | INT32 | i | int | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | UINT32 | u | int | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | INT64 | x | int | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | UINT64 | t | int | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | DOUBLE | d | float | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | STRING | s | str | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | OBJECT_PATH | o | str | Must be a valid object path. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | SIGNATURE | g | str | Must be a valid signature. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | UNIX_FD | h | int | In the low-level interface, an index pointing to a file descriptor | | | | | in the ``unix_fds`` member of the :class:`Message `. | | | | | In the high-level interface, it is the file descriptor itself. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | ARRAY | a | list | Must be followed by a complete type which specifies the child type. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | STRUCT | ( | list | Types in the Python ``list`` must match the types between the parens. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | VARIANT | v | :class:`Variant ` | This class is provided by the library. | | | | | | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ | DICT_ENTRY | { | dict | Must be included in an array to be a ``dict``. | +-------------+-------+--------------------------------------+-------------------------------------------------------------------------+ The types ``a``, ``(``, ``v``, and ``{`` are container types that hold other values. Examples of container types and Python examples are in the table below. +-----------+--------------------------------------+-------------------------------------------------------+ | Signature | Example | Notes | +===========+======================================+=======================================================+ | ``(su)`` | ``[ 'foo', 5 ]`` | Each element in the array must match the | | | | corresponding type of the struct member. | +-----------+--------------------------------------+-------------------------------------------------------+ | ``as`` | ``[ 'foo', 'bar' ]`` | The child type comes immediately after the ``a``. | | | | The array can have any number of elements, but | | | | they all must match the child type. | +-----------+--------------------------------------+-------------------------------------------------------+ | ``a{su}`` | ``{ 'foo': 5 }`` | An "array of dict entries" is represented by a | | | | ``dict``. The type after ``{`` is the key type and | | | | the type before the ``}`` is the value type. | +-----------+--------------------------------------+-------------------------------------------------------+ | ``ay`` | ``b'\0x62\0x75\0x66'`` | Special case: an array of bytes is represented by | | | | Python ``bytes``. | | | | | | | | | | | | | | | | | +-----------+--------------------------------------+-------------------------------------------------------+ | ``v`` | ``Variant('as', ['hello'])`` | Signature must be a single type. A variant may hold a | | | | container type. | | | | | | | | | | | | | +-----------+--------------------------------------+-------------------------------------------------------+ | ``(asv)`` | ``[ ['foo'], Variant('s', 'bar') ]`` | Containers may be nested. | +-----------+--------------------------------------+-------------------------------------------------------+ For more information on the DBus type system, see `the specification `__. dbus-fast-2.44.1/docs/source/type-system/signature-tree.rst000066400000000000000000000001461477355613200237330ustar00rootroot00000000000000SignatureTree ============= .. autoclass:: dbus_fast.SignatureTree :members: :undoc-members: dbus-fast-2.44.1/docs/source/type-system/signature-type.rst000066400000000000000000000002071477355613200237530ustar00rootroot00000000000000SignatureType ============== .. autoclass:: dbus_fast.SignatureType :members: :undoc-members: :exclude-members: signature dbus-fast-2.44.1/docs/source/type-system/variant.rst000066400000000000000000000001241477355613200224350ustar00rootroot00000000000000Variant ======= .. autoclass:: dbus_fast.Variant :members: :undoc-members: dbus-fast-2.44.1/docs/source/usage.md000066400000000000000000000001371477355613200173660ustar00rootroot00000000000000# Usage To use this package, import it: ```python import dbus_fast ``` TODO: Document usage dbus-fast-2.44.1/docs/source/validators.rst000066400000000000000000000006571477355613200206510ustar00rootroot00000000000000Validators ========== .. autofunction:: dbus_fast.is_bus_name_valid .. autofunction:: dbus_fast.is_member_name_valid .. autofunction:: dbus_fast.is_object_path_valid .. autofunction:: dbus_fast.is_interface_name_valid .. autofunction:: dbus_fast.assert_bus_name_valid .. autofunction:: dbus_fast.assert_member_name_valid .. autofunction:: dbus_fast.assert_object_path_valid .. autofunction:: dbus_fast.assert_interface_name_valid dbus-fast-2.44.1/examples/000077500000000000000000000000001477355613200153255ustar00rootroot00000000000000dbus-fast-2.44.1/examples/aio-list-names.py000077500000000000000000000012351477355613200205250ustar00rootroot00000000000000#!/usr/bin/env python3 import os import sys sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/..")) import asyncio import json from dbus_fast import Message, MessageType from dbus_fast.aio import MessageBus async def main(): bus = await MessageBus().connect() reply = await bus.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="ListNames", ) ) if reply.message_type == MessageType.ERROR: raise Exception(reply.body[0]) print(json.dumps(reply.body[0], indent=2)) asyncio.run(main()) dbus-fast-2.44.1/examples/aio-tcp-notification.py000077500000000000000000000023121477355613200217200ustar00rootroot00000000000000#!/usr/bin/env python3 # In order for this to work a local tcp connection to the DBus a port # must be opened to forward to the dbus socket file. The easiest way # to achieve this is using "socat": # socat TCP-LISTEN:55556,reuseaddr,fork,range=127.0.0.1/32 UNIX-CONNECT:$(echo $DBUS_SESSION_BUS_ADDRESS | sed 's/unix:path=//g') # For actual DBus transport over network the authentication might # be a further problem. More information here: # https://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms import os import sys sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/..")) import asyncio from dbus_fast.aio import MessageBus async def main(): bus = await MessageBus(bus_address="tcp:host=127.0.0.1,port=55556").connect() introspection = await bus.introspect( "org.freedesktop.Notifications", "/org/freedesktop/Notifications" ) obj = bus.get_proxy_object( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", introspection ) notification = obj.get_interface("org.freedesktop.Notifications") await notification.call_notify( "test.py", 0, "", "DBus Test", "Test notification", [""], dict(), 5000 ) asyncio.run(main()) dbus-fast-2.44.1/examples/dbus-next-send.py000077500000000000000000000067121477355613200205500ustar00rootroot00000000000000#!/usr/bin/env python3 import os import sys sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/..")) import asyncio import json from argparse import OPTIONAL, ArgumentParser from dbus_fast import BusType, Message, MessageType, Variant from dbus_fast.aio import MessageBus from dbus_fast.validators import ( is_bus_name_valid, is_interface_name_valid, is_member_name_valid, is_object_path_valid, ) parser = ArgumentParser() parser.add_argument("--system", help="Use the system bus", action="store_true") parser.add_argument("--session", help="Use the session bus", action="store_true") parser.add_argument( "--dest", help="The destination address for the message", required=True ) parser.add_argument("--signature", help="The signature for the message body") parser.add_argument( "--type", help="The type of message to send", choices=[e.name for e in MessageType], default=MessageType.METHOD_CALL.name, nargs=OPTIONAL, ) parser.add_argument("object_path", help="The object path for the message") parser.add_argument("interface.member", help="The interface and member for the message") parser.add_argument( "body", help="The JSON encoded body of the message. Must match the signature", nargs=OPTIONAL, ) args = parser.parse_args() def exit_error(message): parser.print_usage() print() print(message) sys.exit(1) interface_member = vars(args)["interface.member"].split(".") if len(interface_member) < 2: exit_error( f"Expecting an interface and member separated by a dot: {vars(args)['interface.member']}" ) destination = args.dest member = interface_member[-1] interface = ".".join(interface_member[: len(interface_member) - 1]) object_path = args.object_path signature = args.signature body = args.body message_type = MessageType[args.type] signature = args.signature bus_type = BusType.SESSION if args.system: bus_type = BusType.SYSTEM if message_type is not MessageType.METHOD_CALL: exit_error("only message type METHOD_CALL is supported right now") if not is_bus_name_valid(destination): exit_error(f"got invalid bus name: {destination}") if not is_object_path_valid(object_path): exit_error(f"got invalid object path: {object_path}") if not is_interface_name_valid(interface): exit_error(f"got invalid interface name: {interface}") if not is_member_name_valid(member): exit_error(f"got invalid member name: {member}") if body is None: body = [] signature = "" else: try: body = json.loads(body) except json.JSONDecodeError as e: exit_error(f"could not parse body as JSON: ({e})") if type(body) is not list: exit_error("body must be an array of arguments") if not signature: exit_error("--signature is a required argument when passing a message body") async def main(): bus = await MessageBus(bus_type=bus_type).connect() message = Message( destination=destination, member=member, interface=interface, path=object_path, signature=signature, body=body, ) result = await bus.call(message) ret = 0 if result.message_type is MessageType.ERROR: print(f"Error: {result.error_name}", file=sys.stderr) ret = 1 def default(o): if type(o) is Variant: return [o.signature, o.value] raise json.JSONDecodeError() print(json.dumps(result.body, indent=2, default=default)) sys.exit(ret) asyncio.run(main()) dbus-fast-2.44.1/examples/example-service.py000077500000000000000000000031751477355613200210010ustar00rootroot00000000000000#!/usr/bin/env python3 import os import sys sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/..")) import asyncio from dbus_fast import Variant from dbus_fast.aio.message_bus import MessageBus from dbus_fast.service import ServiceInterface, dbus_property, method, signal class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) self._string_prop = "kevin" @method() def Echo(self, what: "s") -> "s": return what @method() def EchoMultiple(self, what1: "s", what2: "s") -> "ss": return [what1, what2] @method() def GetVariantDict(self) -> "a{sv}": # noqa: F722 return { "foo": Variant("s", "bar"), "bat": Variant("x", -55), "a_list": Variant("as", ["hello", "world"]), } @dbus_property(name="StringProp") def string_prop(self) -> "s": return self._string_prop @string_prop.setter def string_prop_setter(self, val: "s"): self._string_prop = val @signal() def signal_simple(self) -> "s": return "hello" @signal() def signal_multiple(self) -> "ss": return ["hello", "world"] async def main(): name = "dbus.next.example.service" path = "/example/path" interface_name = "example.interface" bus = await MessageBus().connect() interface = ExampleInterface(interface_name) bus.export("/example/path", interface) await bus.request_name(name) print( f'service up on name: "{name}", path: "{path}", interface: "{interface_name}"' ) await bus.wait_for_disconnect() asyncio.run(main()) dbus-fast-2.44.1/examples/glib-list-names.py000077500000000000000000000012171477355613200206720ustar00rootroot00000000000000#!/usr/bin/env python3 import os import sys sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/..")) import json import signal from gi.repository import GLib from dbus_fast import Message from dbus_fast.glib import MessageBus main = GLib.MainLoop() bus = MessageBus().connect_sync() def reply_handler(reply, err): main.quit() if err: raise err print(json.dumps(reply.body[0], indent=2)) bus.call( Message( "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", ), reply_handler, ) signal.signal(signal.SIGINT, signal.SIG_DFL) main.run() dbus-fast-2.44.1/examples/mpris.py000077500000000000000000000024471477355613200170430ustar00rootroot00000000000000#!/usr/bin/env python3 import os import sys sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/..")) import asyncio from dbus_fast.aio import MessageBus async def main(): bus = await MessageBus().connect() # the introspection xml would normally be included in your project, but # this is convenient for development introspection = await bus.introspect( "org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2" ) obj = bus.get_proxy_object( "org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2", introspection ) player = obj.get_interface("org.mpris.MediaPlayer2.Player") properties = obj.get_interface("org.freedesktop.DBus.Properties") # call methods on the interface (this causes the media player to play) await player.call_play() volume = await player.get_volume() print(f"current volume: {volume}, setting to 0.5") await player.set_volume(0.5) # listen to signals def on_properties_changed( interface_name, changed_properties, invalidated_properties ): for changed, variant in changed_properties.items(): print(f"property changed: {changed} - {variant.value}") properties.on_properties_changed(on_properties_changed) await bus.wait_for_disconnect() asyncio.run(main()) dbus-fast-2.44.1/poetry.lock000066400000000000000000003107361477355613200157150ustar00rootroot00000000000000# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "alabaster" version = "0.7.16" description = "A light, configurable Sphinx theme" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, ] [[package]] name = "babel" version = "2.17.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, ] [package.extras] dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] [[package]] name = "certifi" version = "2025.1.31" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" groups = ["docs"] files = [ {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, ] [[package]] name = "cffi" version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" groups = ["dev"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] pycparser = "*" [[package]] name = "charset-normalizer" version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" groups = ["docs"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" groups = ["dev", "docs"] markers = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] name = "covdefaults" version = "2.3.0" description = "A coverage plugin to provide sensible default settings" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ {file = "covdefaults-2.3.0-py2.py3-none-any.whl", hash = "sha256:2832961f6ffcfe4b57c338bc3418a3526f495c26fb9c54565409c5532f7c41be"}, {file = "covdefaults-2.3.0.tar.gz", hash = "sha256:4e99f679f12d792bc62e5510fa3eb59546ed47bd569e36e4fddc4081c9c3ebf7"}, ] [package.dependencies] coverage = ">=6.0.2" [[package]] name = "coverage" version = "7.7.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "coverage-7.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a538a23119d1e2e2ce077e902d02ea3d8e0641786ef6e0faf11ce82324743944"}, {file = "coverage-7.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1586ad158523f4133499a4f322b230e2cfef9cc724820dbd58595a5a236186f4"}, {file = "coverage-7.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6c96d69928a3a6767fab8dc1ce8a02cf0156836ccb1e820c7f45a423570d98"}, {file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f18d47641282664276977c604b5a261e51fefc2980f5271d547d706b06a837f"}, {file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a1e18a85bd066c7c556d85277a7adf4651f259b2579113844835ba1a74aafd"}, {file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:70f0925c4e2bfc965369f417e7cc72538fd1ba91639cf1e4ef4b1a6b50439b3b"}, {file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b0fac2088ec4aaeb5468b814bd3ff5e5978364bfbce5e567c44c9e2854469f6c"}, {file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3e212a894d8ae07fde2ca8b43d666a6d49bbbddb10da0f6a74ca7bd31f20054"}, {file = "coverage-7.7.0-cp310-cp310-win32.whl", hash = "sha256:f32b165bf6dfea0846a9c9c38b7e1d68f313956d60a15cde5d1709fddcaf3bee"}, {file = "coverage-7.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:a2454b12a3f12cc4698f3508912e6225ec63682e2ca5a96f80a2b93cef9e63f3"}, {file = "coverage-7.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a0a207c87a9f743c8072d059b4711f8d13c456eb42dac778a7d2e5d4f3c253a7"}, {file = "coverage-7.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d673e3add00048215c2cc507f1228a7523fd8bf34f279ac98334c9b07bd2656"}, {file = "coverage-7.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f81fe93dc1b8e5673f33443c0786c14b77e36f1025973b85e07c70353e46882b"}, {file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8c7524779003d59948c51b4fcbf1ca4e27c26a7d75984f63488f3625c328b9b"}, {file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c124025430249118d018dcedc8b7426f39373527c845093132196f2a483b6dd"}, {file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e7f559c36d5cdc448ee13e7e56ed7b6b5d44a40a511d584d388a0f5d940977ba"}, {file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:37cbc7b0d93dfd133e33c7ec01123fbb90401dce174c3b6661d8d36fb1e30608"}, {file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7d2a65876274acf544703e943c010b60bd79404e3623a1e5d52b64a6e2728de5"}, {file = "coverage-7.7.0-cp311-cp311-win32.whl", hash = "sha256:f5a2f71d6a91238e7628f23538c26aa464d390cbdedf12ee2a7a0fb92a24482a"}, {file = "coverage-7.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:ae8006772c6b0fa53c33747913473e064985dac4d65f77fd2fdc6474e7cd54e4"}, {file = "coverage-7.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:056d3017ed67e7ddf266e6f57378ece543755a4c9231e997789ab3bd11392c94"}, {file = "coverage-7.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33c1394d8407e2771547583b66a85d07ed441ff8fae5a4adb4237ad39ece60db"}, {file = "coverage-7.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fbb7a0c3c21908520149d7751cf5b74eb9b38b54d62997b1e9b3ac19a8ee2fe"}, {file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb356e7ae7c2da13f404bf8f75be90f743c6df8d4607022e759f5d7d89fe83f8"}, {file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce730d484038e97f27ea2dbe5d392ec5c2261f28c319a3bb266f6b213650135"}, {file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa4dff57fc21a575672176d5ab0ef15a927199e775c5e8a3d75162ab2b0c7705"}, {file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b667b91f4f714b17af2a18e220015c941d1cf8b07c17f2160033dbe1e64149f0"}, {file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:693d921621a0c8043bfdc61f7d4df5ea6d22165fe8b807cac21eb80dd94e4bbd"}, {file = "coverage-7.7.0-cp312-cp312-win32.whl", hash = "sha256:52fc89602cde411a4196c8c6894afb384f2125f34c031774f82a4f2608c59d7d"}, {file = "coverage-7.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ce8cf59e09d31a4915ff4c3b94c6514af4c84b22c4cc8ad7c3c546a86150a92"}, {file = "coverage-7.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4545485fef7a8a2d8f30e6f79ce719eb154aab7e44217eb444c1d38239af2072"}, {file = "coverage-7.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1393e5aa9441dafb0162c36c8506c648b89aea9565b31f6bfa351e66c11bcd82"}, {file = "coverage-7.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316f29cc3392fa3912493ee4c83afa4a0e2db04ff69600711f8c03997c39baaa"}, {file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ffde1d6bc2a92f9c9207d1ad808550873748ac2d4d923c815b866baa343b3f"}, {file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:416e2a8845eaff288f97eaf76ab40367deafb9073ffc47bf2a583f26b05e5265"}, {file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5efdeff5f353ed3352c04e6b318ab05c6ce9249c25ed3c2090c6e9cadda1e3b2"}, {file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:57f3bd0d29bf2bd9325c0ff9cc532a175110c4bf8f412c05b2405fd35745266d"}, {file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ab7090f04b12dc6469882ce81244572779d3a4b67eea1c96fb9ecc8c607ef39"}, {file = "coverage-7.7.0-cp313-cp313-win32.whl", hash = "sha256:180e3fc68ee4dc5af8b33b6ca4e3bb8aa1abe25eedcb958ba5cff7123071af68"}, {file = "coverage-7.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:55143aa13c49491f5606f05b49ed88663446dce3a4d3c5d77baa4e36a16d3573"}, {file = "coverage-7.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc41374d2f27d81d6558f8a24e5c114580ffefc197fd43eabd7058182f743322"}, {file = "coverage-7.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:89078312f06237417adda7c021c33f80f7a6d2db8572a5f6c330d89b080061ce"}, {file = "coverage-7.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b2f144444879363ea8834cd7b6869d79ac796cb8f864b0cfdde50296cd95816"}, {file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e6347d1ed882b1159ffea172cb8466ee46c665af4ca397edbf10ff53e9ffaf"}, {file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb203c0afffaf1a8f5b9659a013f8f16a1b2cad3a80a8733ceedc968c0cf4c57"}, {file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ad0edaa97cb983d9f2ff48cadddc3e1fb09f24aa558abeb4dc9a0dbacd12cbb4"}, {file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c5f8a5364fc37b2f172c26a038bc7ec4885f429de4a05fc10fdcb53fb5834c5c"}, {file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4e09534037933bf6eb31d804e72c52ec23219b32c1730f9152feabbd7499463"}, {file = "coverage-7.7.0-cp313-cp313t-win32.whl", hash = "sha256:1b336d06af14f8da5b1f391e8dec03634daf54dfcb4d1c4fb6d04c09d83cef90"}, {file = "coverage-7.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b54a1ee4c6f1905a436cbaa04b26626d27925a41cbc3a337e2d3ff7038187f07"}, {file = "coverage-7.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c8fbce80b2b8bf135d105aa8f5b36eae0c57d702a1cc3ebdea2a6f03f6cdde5"}, {file = "coverage-7.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9710521f07f526de30ccdead67e6b236fe996d214e1a7fba8b36e2ba2cd8261"}, {file = "coverage-7.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7789e700f33f2b133adae582c9f437523cd5db8de845774988a58c360fc88253"}, {file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c36093aca722db73633cf2359026ed7782a239eb1c6db2abcff876012dc4cf"}, {file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c075d167a6ec99b798c1fdf6e391a1d5a2d054caffe9593ba0f97e3df2c04f0e"}, {file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d013c07061751ae81861cae6ec3a4fe04e84781b11fd4b6b4201590234b25c7b"}, {file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:104bf640f408f4e115b85110047c7f27377e1a8b7ba86f7db4fa47aa49dc9a8e"}, {file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:39abcacd1ed54e2c33c54bdc488b310e8ef6705833f7148b6eb9a547199d375d"}, {file = "coverage-7.7.0-cp39-cp39-win32.whl", hash = "sha256:8e336b56301774ace6be0017ff85c3566c556d938359b61b840796a0202f805c"}, {file = "coverage-7.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:8c938c6ae59be67ac19a7204e079efc94b38222cd7d0269f96e45e18cddeaa59"}, {file = "coverage-7.7.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:3b0e6e54591ae0d7427def8a4d40fca99df6b899d10354bab73cd5609807261c"}, {file = "coverage-7.7.0-py3-none-any.whl", hash = "sha256:708f0a1105ef2b11c79ed54ed31f17e6325ac936501fc373f24be3e6a578146a"}, {file = "coverage-7.7.0.tar.gz", hash = "sha256:cd879d4646055a573775a1cec863d00c9ff8c55860f8b17f6d8eee9140c06166"}, ] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "cython" version = "3.0.12" description = "The Cython compiler for writing C extensions in the Python language." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" groups = ["dev"] files = [ {file = "Cython-3.0.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba67eee9413b66dd9fbacd33f0bc2e028a2a120991d77b5fd4b19d0b1e4039b9"}, {file = "Cython-3.0.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee2717e5b5f7d966d0c6e27d2efe3698c357aa4d61bb3201997c7a4f9fe485a"}, {file = "Cython-3.0.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cffc3464f641c8d0dda942c7c53015291beea11ec4d32421bed2f13b386b819"}, {file = "Cython-3.0.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d3a8f81980ffbd74e52f9186d8f1654e347d0c44bfea6b5997028977f481a179"}, {file = "Cython-3.0.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8d32856716c369d01f2385ad9177cdd1a11079ac89ea0932dc4882de1aa19174"}, {file = "Cython-3.0.12-cp310-cp310-win32.whl", hash = "sha256:712c3f31adec140dc60d064a7f84741f50e2c25a8edd7ae746d5eb4d3ef7072a"}, {file = "Cython-3.0.12-cp310-cp310-win_amd64.whl", hash = "sha256:d6945694c5b9170cfbd5f2c0d00ef7487a2de7aba83713a64ee4ebce7fad9e05"}, {file = "Cython-3.0.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:feb86122a823937cc06e4c029d80ff69f082ebb0b959ab52a5af6cdd271c5dc3"}, {file = "Cython-3.0.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfdbea486e702c328338314adb8e80f5f9741f06a0ae83aaec7463bc166d12e8"}, {file = "Cython-3.0.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563de1728c8e48869d2380a1b76bbc1b1b1d01aba948480d68c1d05e52d20c92"}, {file = "Cython-3.0.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398d4576c1e1f6316282aa0b4a55139254fbed965cba7813e6d9900d3092b128"}, {file = "Cython-3.0.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1e5eadef80143026944ea8f9904715a008f5108d1d644a89f63094cc37351e73"}, {file = "Cython-3.0.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5a93cbda00a5451175b97dea5a9440a3fcee9e54b4cba7a7dbcba9a764b22aec"}, {file = "Cython-3.0.12-cp311-cp311-win32.whl", hash = "sha256:3109e1d44425a2639e9a677b66cd7711721a5b606b65867cb2d8ef7a97e2237b"}, {file = "Cython-3.0.12-cp311-cp311-win_amd64.whl", hash = "sha256:d4b70fc339adba1e2111b074ee6119fe9fd6072c957d8597bce9a0dd1c3c6784"}, {file = "Cython-3.0.12-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fe030d4a00afb2844f5f70896b7f2a1a0d7da09bf3aa3d884cbe5f73fff5d310"}, {file = "Cython-3.0.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7fec4f052b8fe173fe70eae75091389955b9a23d5cec3d576d21c5913b49d47"}, {file = "Cython-3.0.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0faa5e39e5c8cdf6f9c3b1c3f24972826e45911e7f5b99cf99453fca5432f45e"}, {file = "Cython-3.0.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d53de996ed340e9ab0fc85a88aaa8932f2591a2746e1ab1c06e262bd4ec4be7"}, {file = "Cython-3.0.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea3a0e19ab77266c738aa110684a753a04da4e709472cadeff487133354d6ab8"}, {file = "Cython-3.0.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c151082884be468f2f405645858a857298ac7f7592729e5b54788b5c572717ba"}, {file = "Cython-3.0.12-cp312-cp312-win32.whl", hash = "sha256:3083465749911ac3b2ce001b6bf17f404ac9dd35d8b08469d19dc7e717f5877a"}, {file = "Cython-3.0.12-cp312-cp312-win_amd64.whl", hash = "sha256:c0b91c7ebace030dd558ea28730de8c580680b50768e5af66db2904a3716c3e3"}, {file = "Cython-3.0.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4ee6f1ea1bead8e6cbc4e64571505b5d8dbdb3b58e679d31f3a84160cebf1a1a"}, {file = "Cython-3.0.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57aefa6d3341109e46ec1a13e3a763aaa2cbeb14e82af2485b318194be1d9170"}, {file = "Cython-3.0.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:879ae9023958d63c0675015369384642d0afb9c9d1f3473df9186c42f7a9d265"}, {file = "Cython-3.0.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36fcd584dae547de6f095500a380f4a0cce72b7a7e409e9ff03cb9beed6ac7a1"}, {file = "Cython-3.0.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62b79dcc0de49efe9e84b9d0e2ae0a6fc9b14691a65565da727aa2e2e63c6a28"}, {file = "Cython-3.0.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4aa255781b093a8401109d8f2104bbb2e52de7639d5896aefafddc85c30e0894"}, {file = "Cython-3.0.12-cp313-cp313-win32.whl", hash = "sha256:77d48f2d4bab9fe1236eb753d18f03e8b2619af5b6f05d51df0532a92dfb38ab"}, {file = "Cython-3.0.12-cp313-cp313-win_amd64.whl", hash = "sha256:86c304b20bd57c727c7357e90d5ba1a2b6f1c45492de2373814d7745ef2e63b4"}, {file = "Cython-3.0.12-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ff5c0b6a65b08117d0534941d404833d516dac422eee88c6b4fd55feb409a5ed"}, {file = "Cython-3.0.12-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:680f1d6ed4436ae94805db264d6155ed076d2835d84f20dcb31a7a3ad7f8668c"}, {file = "Cython-3.0.12-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc24609613fa06d0d896309f7164ba168f7e8d71c1e490ed2a08d23351c3f41"}, {file = "Cython-3.0.12-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1879c073e2b34924ce9b7ca64c212705dcc416af4337c45f371242b2e5f6d32"}, {file = "Cython-3.0.12-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:bfb75123dd4ff767baa37d7036da0de2dfb6781ff256eef69b11b88b9a0691d1"}, {file = "Cython-3.0.12-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:f39640f8df0400cde6882e23c734f15bb8196de0a008ae5dc6c8d1ec5957d7c8"}, {file = "Cython-3.0.12-cp36-cp36m-win32.whl", hash = "sha256:8c9efe9a0895abee3cadfdad4130b30f7b5e57f6e6a51ef2a44f9fc66a913880"}, {file = "Cython-3.0.12-cp36-cp36m-win_amd64.whl", hash = "sha256:63d840f2975e44d74512f8f34f1f7cb8121c9428e26a3f6116ff273deb5e60a2"}, {file = "Cython-3.0.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:75c5acd40b97cff16fadcf6901a91586cbca5dcdba81f738efaf1f4c6bc8dccb"}, {file = "Cython-3.0.12-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e62564457851db1c40399bd95a5346b9bb99e17a819bf583b362f418d8f3457a"}, {file = "Cython-3.0.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ccd1228cc203b1f1b8a3d403f5a20ad1c40e5879b3fbf5851ce09d948982f2c"}, {file = "Cython-3.0.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25529ee948f44d9a165ff960c49d4903267c20b5edf2df79b45924802e4cca6e"}, {file = "Cython-3.0.12-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:90cf599372c5a22120609f7d3a963f17814799335d56dd0dcf8fe615980a8ae1"}, {file = "Cython-3.0.12-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9f8c48748a9c94ea5d59c26ab49ad0fad514d36f894985879cf3c3ca0e600bf4"}, {file = "Cython-3.0.12-cp37-cp37m-win32.whl", hash = "sha256:3e4fa855d98bc7bd6a2049e0c7dc0dcf595e2e7f571a26e808f3efd84d2db374"}, {file = "Cython-3.0.12-cp37-cp37m-win_amd64.whl", hash = "sha256:120681093772bf3600caddb296a65b352a0d3556e962b9b147efcfb8e8c9801b"}, {file = "Cython-3.0.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:731d719423e041242c9303c80cae4327467299b90ffe62d4cc407e11e9ea3160"}, {file = "Cython-3.0.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3238a29f37999e27494d120983eca90d14896b2887a0bd858a381204549137a"}, {file = "Cython-3.0.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b588c0a089a9f4dd316d2f9275230bad4a7271e5af04e1dc41d2707c816be44b"}, {file = "Cython-3.0.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ab9f5198af74eb16502cc143cdde9ca1cbbf66ea2912e67440dd18a36e3b5fa"}, {file = "Cython-3.0.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8ee841c0e114efa1e849c281ac9b8df8aa189af10b4a103b1c5fd71cbb799679"}, {file = "Cython-3.0.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:43c48b5789398b228ea97499f5b864843ba9b1ab837562a9227c6f58d16ede8b"}, {file = "Cython-3.0.12-cp38-cp38-win32.whl", hash = "sha256:5e5f17c48a4f41557fbcc7ee660ccfebe4536a34c557f553b6893c1b3c83df2d"}, {file = "Cython-3.0.12-cp38-cp38-win_amd64.whl", hash = "sha256:309c081057930bb79dc9ea3061a1af5086c679c968206e9c9c2ec90ab7cb471a"}, {file = "Cython-3.0.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54115fcc126840926ff3b53cfd2152eae17b3522ae7f74888f8a41413bd32f25"}, {file = "Cython-3.0.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:629db614b9c364596d7c975fa3fb3978e8c5349524353dbe11429896a783fc1e"}, {file = "Cython-3.0.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af081838b0f9e12a83ec4c3809a00a64c817f489f7c512b0e3ecaf5f90a2a816"}, {file = "Cython-3.0.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:34ce459808f7d8d5d4007bc5486fe50532529096b43957af6cbffcb4d9cc5c8d"}, {file = "Cython-3.0.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d6c6cd6a75c8393e6805d17f7126b96a894f310a1a9ea91c47d141fb9341bfa8"}, {file = "Cython-3.0.12-cp39-cp39-win32.whl", hash = "sha256:a4032e48d4734d2df68235d21920c715c451ac9de15fa14c71b378e8986b83be"}, {file = "Cython-3.0.12-cp39-cp39-win_amd64.whl", hash = "sha256:dcdc3e5d4ce0e7a4af6903ed580833015641e968d18d528d8371e2435a34132c"}, {file = "Cython-3.0.12-py2.py3-none-any.whl", hash = "sha256:0038c9bae46c459669390e53a1ec115f8096b2e4647ae007ff1bf4e6dee92806"}, {file = "cython-3.0.12.tar.gz", hash = "sha256:b988bb297ce76c671e28c97d017b95411010f7c77fa6623dd0bb47eed1aee1bc"}, ] [[package]] name = "docutils" version = "0.21.2" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, ] [[package]] name = "exceptiongroup" version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] test = ["pytest (>=6)"] [[package]] name = "idna" version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" groups = ["docs"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] [[package]] name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" groups = ["docs"] files = [ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] [[package]] name = "importlib-metadata" version = "8.6.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" groups = ["dev", "docs"] markers = "python_version < \"3.10\"" files = [ {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, ] [package.dependencies] zipp = ">=3.20" [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] name = "jinja2" version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" groups = ["docs"] files = [ {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] [[package]] name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" groups = ["dev", "docs"] files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] mdurl = ">=0.1,<1.0" [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] code-style = ["pre-commit (>=3.0,<4.0)"] compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] linkify = ["linkify-it-py (>=1,<3)"] plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "mdit-py-plugins" version = "0.4.2" description = "Collection of plugins for markdown-it-py" optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636"}, {file = "mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5"}, ] [package.dependencies] markdown-it-py = ">=1.0.0,<4.0.0" [package.extras] code-style = ["pre-commit"] rtd = ["myst-parser", "sphinx-book-theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" groups = ["dev", "docs"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] [[package]] name = "myst-parser" version = "3.0.1" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"}, {file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"}, ] [package.dependencies] docutils = ">=0.18,<0.22" jinja2 = "*" markdown-it-py = ">=3.0,<4.0" mdit-py-plugins = ">=0.4,<1.0" pyyaml = "*" sphinx = ">=6,<8" [package.extras] code-style = ["pre-commit (>=3.0,<4.0)"] linkify = ["linkify-it-py (>=2.0,<3.0)"] rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"] testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"] [[package]] name = "packaging" version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["dev", "docs"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "pycairo" version = "1.27.0" description = "Python interface for cairo" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "pycairo-1.27.0-cp310-cp310-win32.whl", hash = "sha256:e20f431244634cf244ab6b4c3a2e540e65746eed1324573cf291981c3e65fc05"}, {file = "pycairo-1.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:03bf570e3919901572987bc69237b648fe0de242439980be3e606b396e3318c9"}, {file = "pycairo-1.27.0-cp311-cp311-win32.whl", hash = "sha256:9a9b79f92a434dae65c34c830bb9abdbd92654195e73d52663cbe45af1ad14b2"}, {file = "pycairo-1.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:d40a6d80b15dacb3672dc454df4bc4ab3988c6b3f36353b24a255dc59a1c8aea"}, {file = "pycairo-1.27.0-cp312-cp312-win32.whl", hash = "sha256:e2239b9bb6c05edae5f3be97128e85147a155465e644f4d98ea0ceac7afc04ee"}, {file = "pycairo-1.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:27cb4d3a80e3b9990af552818515a8e466e0317063a6e61585533f1a86f1b7d5"}, {file = "pycairo-1.27.0-cp313-cp313-win32.whl", hash = "sha256:01505c138a313df2469f812405963532fc2511fb9bca9bdc8e0ab94c55d1ced8"}, {file = "pycairo-1.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:b0349d744c068b6644ae23da6ada111c8a8a7e323b56cbce3707cba5bdb474cc"}, {file = "pycairo-1.27.0-cp39-cp39-win32.whl", hash = "sha256:f9ca8430751f1fdcd3f072377560c9e15608b9a42d61375469db853566993c9b"}, {file = "pycairo-1.27.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b1321652a6e27c4de3069709b1cae22aed2707fd8c5e889c04a95669228af2a"}, {file = "pycairo-1.27.0.tar.gz", hash = "sha256:5cb21e7a00a2afcafea7f14390235be33497a2cce53a98a19389492a60628430"}, ] [[package]] name = "pycparser" version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] [[package]] name = "pygments" version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" groups = ["dev", "docs"] files = [ {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, ] [package.extras] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pygobject" version = "3.50.0" description = "Python bindings for GObject Introspection" optional = false python-versions = "<4.0,>=3.9" groups = ["dev"] markers = "python_version < \"4\"" files = [ {file = "pygobject-3.50.0.tar.gz", hash = "sha256:4500ad3dbf331773d8dedf7212544c999a76fc96b63a91b3dcac1e5925a1d103"}, ] [package.dependencies] pycairo = ">=1.16" [[package]] name = "pytest" version = "8.3.5" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" version = "0.26.0" description = "Pytest support for asyncio" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0"}, {file = "pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f"}, ] [package.dependencies] pytest = ">=8.2,<9" typing-extensions = {version = ">=4.12", markers = "python_version < \"3.10\""} [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"] testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-codspeed" version = "3.2.0" description = "Pytest plugin to create CodSpeed benchmarks" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5165774424c7ab8db7e7acdb539763a0e5657996effefdf0664d7fd95158d34"}, {file = "pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bd55f92d772592c04a55209950c50880413ae46876e66bd349ef157075ca26c"}, {file = "pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf6f56067538f4892baa8d7ab5ef4e45bb59033be1ef18759a2c7fc55b32035"}, {file = "pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39a687b05c3d145642061b45ea78e47e12f13ce510104d1a2cda00eee0e36f58"}, {file = "pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46a1afaaa1ac4c2ca5b0700d31ac46d80a27612961d031067d73c6ccbd8d3c2b"}, {file = "pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c48ce3af3dfa78413ed3d69d1924043aa1519048dbff46edccf8f35a25dab3c2"}, {file = "pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66692506d33453df48b36a84703448cb8b22953eea51f03fbb2eb758dc2bdc4f"}, {file = "pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:479774f80d0bdfafa16112700df4dbd31bf2a6757fac74795fd79c0a7b3c389b"}, {file = "pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:109f9f4dd1088019c3b3f887d003b7d65f98a7736ca1d457884f5aa293e8e81c"}, {file = "pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2f69a03b52c9bb041aec1b8ee54b7b6c37a6d0a948786effa4c71157765b6da"}, {file = "pytest_codspeed-3.2.0-py3-none-any.whl", hash = "sha256:54b5c2e986d6a28e7b0af11d610ea57bd5531cec8326abe486f1b55b09d91c39"}, {file = "pytest_codspeed-3.2.0.tar.gz", hash = "sha256:f9d1b1a3b2c69cdc0490a1e8b1ced44bffbd0e8e21d81a7160cfdd923f6e8155"}, ] [package.dependencies] cffi = ">=1.17.1" importlib-metadata = {version = ">=8.5.0", markers = "python_version < \"3.10\""} pytest = ">=3.8" rich = ">=13.8.1" [package.extras] compat = ["pytest-benchmark (>=5.0.0,<5.1.0)", "pytest-xdist (>=3.6.1,<3.7.0)"] lint = ["mypy (>=1.11.2,<1.12.0)", "ruff (>=0.6.5,<0.7.0)"] test = ["pytest (>=7.0,<8.0)", "pytest-cov (>=4.0.0,<4.1.0)"] [[package]] name = "pytest-cov" version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, ] [package.dependencies] coverage = {version = ">=7.5", extras = ["toml"]} pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-timeout" version = "2.3.1" description = "pytest plugin to abort hanging tests" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ {file = "pytest-timeout-2.3.1.tar.gz", hash = "sha256:12397729125c6ecbdaca01035b9e5239d4db97352320af155b3f5de1ba5165d9"}, {file = "pytest_timeout-2.3.1-py3-none-any.whl", hash = "sha256:68188cb703edfc6a18fad98dc25a3c61e9f24d644b0b70f33af545219fc7813e"}, ] [package.dependencies] pytest = ">=7.0.0" [[package]] name = "pyyaml" version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] name = "requests" version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" groups = ["dev"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, ] [package.dependencies] markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" version = "78.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8"}, {file = "setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] [[package]] name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." optional = false python-versions = "*" groups = ["docs"] files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] [[package]] name = "sphinx" version = "7.4.7" description = "Python documentation generator" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, {file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"}, ] [package.dependencies] alabaster = ">=0.7.14,<0.8.0" babel = ">=2.13" colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} docutils = ">=0.20,<0.22" imagesize = ">=1.3" importlib-metadata = {version = ">=6.0", markers = "python_version < \"3.10\""} Jinja2 = ">=3.1" packaging = ">=23.0" Pygments = ">=2.17" requests = ">=2.30.0" snowballstemmer = ">=2.2" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" sphinxcontrib-serializinghtml = ">=1.1.9" tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"] test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] [[package]] name = "sphinx-rtd-theme" version = "3.0.2" description = "Read the Docs theme for Sphinx" optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "sphinx_rtd_theme-3.0.2-py2.py3-none-any.whl", hash = "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13"}, {file = "sphinx_rtd_theme-3.0.2.tar.gz", hash = "sha256:b7457bc25dda723b20b086a670b9953c859eab60a2a03ee8eb2bb23e176e5f85"}, ] [package.dependencies] docutils = ">0.18,<0.22" sphinx = ">=6,<9" sphinxcontrib-jquery = ">=4,<5" [package.extras] dev = ["bump2version", "transifex-client", "twine", "wheel"] [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-asyncio" version = "0.3.0" description = "sphinx extension to support coroutines in markup" optional = false python-versions = "*" groups = ["docs"] files = [ {file = "sphinxcontrib-asyncio-0.3.0.tar.gz", hash = "sha256:99fd26e0fe7edf87244a71a99c316fd0c9b50856c2519acca927ebe74100722e"}, {file = "sphinxcontrib_asyncio-0.3.0-py2.py3-none-any.whl", hash = "sha256:c18d1f07a55b27e21c15d0f8cf2b940173f1b4566374d248bc4a8d256ee3ff24"}, ] [package.dependencies] sphinx = ">=3.0" [[package]] name = "sphinxcontrib-devhelp" version = "2.0.0" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-fulltoc" version = "1.2.0" description = "Include a full table of contents in your Sphinx HTML sidebar" optional = false python-versions = "*" groups = ["docs"] files = [ {file = "sphinxcontrib-fulltoc-1.2.0.tar.gz", hash = "sha256:c845d62fc467f3135d4543e9f10e13ef91852683bd1c90fd19d07f9d36757cd9"}, ] [[package]] name = "sphinxcontrib-htmlhelp" version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] name = "sphinxcontrib-jquery" version = "4.1" description = "Extension to include jQuery on newer Sphinx releases" optional = false python-versions = ">=2.7" groups = ["docs"] files = [ {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, ] [package.dependencies] Sphinx = ">=1.8" [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" optional = false python-versions = ">=3.5" groups = ["docs"] files = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, ] [package.extras] test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" version = "2.0.0" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["defusedxml (>=0.7.1)", "pytest"] [[package]] name = "sphinxcontrib-serializinghtml" version = "2.0.0" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "tomli" version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" groups = ["dev", "docs"] files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] markers = {dev = "python_full_version <= \"3.11.0a6\"", docs = "python_version < \"3.11\""} [[package]] name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "urllib3" version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "zipp" version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["dev", "docs"] markers = "python_version < \"3.10\"" files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9" content-hash = "0dda1b11d3ce779aee26661b76b4ff6986b88b6483c37ab596c45165d0addcdd" dbus-fast-2.44.1/pyproject.toml000066400000000000000000000160771477355613200164360ustar00rootroot00000000000000[tool.poetry] name = "dbus-fast" version = "2.44.1" description = "A faster version of dbus-next" authors = ["Bluetooth Devices Authors "] license = "MIT" readme = "README.md" repository = "https://github.com/bluetooth-devices/dbus-fast" documentation = "https://dbus-fast.readthedocs.io" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Natural Language :: English", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", ] packages = [ { include = "dbus_fast", from = "src" }, ] # Make sure we don't package temporary C files generated by the build process exclude = [ "**/*.c" ] [tool.poetry.build] generate-setup-file = true script = "build_ext.py" [tool.poetry.urls] "Bug Tracker" = "https://github.com/bluetooth-devices/dbus-fast/issues" "Changelog" = "https://github.com/bluetooth-devices/dbus-fast/blob/main/CHANGELOG.md" [tool.poetry.dependencies] python = ">=3.9" # duplicated in docs/requirements.txt for readthedocs compatibility [tool.poetry.group.docs.dependencies] myst-parser = ">=0.18,<3.1" sphinx = ">=5.1.1,<8.0.0" sphinx-rtd-theme = ">=1,<4" sphinxcontrib-asyncio = "^0.3.0" sphinxcontrib-fulltoc = "^1.2.0" [tool.poetry.group.dev.dependencies] pytest = ">=7,<9" pytest-cov = ">=3,<7" pytest-asyncio = ">=0.19,<0.27" pycairo = "^1.21.0" PyGObject = {version = ">=3.50,<3.51", python = "<4"} Cython = ">=3,<3.1.0" setuptools = ">=65.4.1,<79.0.0" pytest-timeout = "^2.1.0" pytest-codspeed = "^3.1.1" covdefaults = "^2.3.0" [tool.semantic_release] branch = "main" version_toml = ["pyproject.toml:tool.poetry.version"] version_variables = ["src/dbus_fast/__version__.py:__version__"] build_command = "pip install poetry && poetry build" [tool.pytest.ini_options] addopts = "-v -Wdefault --cov=dbus_fast --cov-report=term-missing:skip-covered" pythonpath = ["src"] [tool.coverage.run] branch = true plugins = ["covdefaults"] [tool.coverage.report] fail_under = 30 # cython version will have low cover because we do not have Cython tracing exclude_also = [ "if cython.compiled:", ] [tool.isort] profile = "black" known_first_party = ["dbus_fast", "tests"] [tool.mypy] check_untyped_defs = true disallow_any_generics = false # turn this on when we drop 3.7/3.8 support disallow_incomplete_defs = true disallow_untyped_defs = true mypy_path = "src/" no_implicit_optional = true show_error_codes = true warn_unreachable = true warn_unused_ignores = true exclude = [ 'docs/.*', 'setup.py', ] [[tool.mypy.overrides]] module = "tests.*" allow_untyped_defs = true [[tool.mypy.overrides]] module = "docs.*" ignore_errors = true [build-system] requires = ['setuptools>=65.4.1', 'wheel', 'Cython>=3,<3.1.0', "poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.ruff] target-version = "py39" line-length = 88 [tool.ruff.lint] ignore = [ "F821", # undefined names are used for decorators "S101", # use of assert detected "S105", # too many false positives "SLF001", # intended "SIM109", # intended for cython "SIM102", # intended for cython "E501", # too many to fix, "TID252", # intended "PLC0414", # intended "TRY003", # too many to fix "PLR2004", # way too many to fix right now "PLR0911", # api is public "PYI036", # too many to fix "PYI034", # too many to fix "E721", # many are as intended ## should fix these sooner "B007", # too many to fix -- should fix sooner "SIM103", # too many to fix -- should fix sooner "SIM110", # too many to fix -- should fix sooner "RUF012", # too many to fix -- should fix sooner "TRY002", # too many to fix -- should fix sooner "B904", # too many to fix -- should fix sooner "PERF401", # too many to fix -- should fix sooner "B904", # too many to fix -- should fix sooner "B006", # too many to fix -- should fix sooner "G004", # too many to fix -- should fix sooner "PT015", # too many to fix -- should fix sooner "B011", # too many to fix -- should fix sooner "PLR1714", # too many to fix -- should fix sooner "PLR0915", # too many to fix -- should fix sooner "PERF102", # too many to fix -- should fix sooner "TRY401", # too many to fix -- should fix sooner "PLR0913", # too many to fix -- should fix sooner "PLR0912", # too many to fix -- should fix sooner "PERF203", # too many to fix -- should fix sooner "G201", # too many to fix -- should fix sooner "TRY301", # too many to fix -- should fix sooner "B020", # too many to fix -- should fix sooner "S314", # too many to fix -- should fix sooner "RET504", # too many to fix -- should fix sooner "SIM105", # too many to fix -- should fix sooner "TRY300", # too many to fix -- should fix sooner "PLW2901", # too many to fix -- should fix sooner "PERF402", # too many to fix -- should fix sooner ] select = [ "ASYNC", # async rules "B", # flake8-bugbear "C4", # flake8-comprehensions "S", # flake8-bandit "F", # pyflake "E", # pycodestyle "W", # pycodestyle "UP", # pyupgrade "I", # isort "LOG", # log "RUF", # ruff specific "FLY", # flynt "FURB", # refurb "G", # flake8-logging-format , "PERF", # Perflint "PGH", # pygrep-hooks "PIE", # flake8-pie "PL", # pylint "PT", # flake8-pytest-style "PYI", # flake8-pyi "RET", # flake8-return "RSE", # flake8-raise , "SIM", # flake8-simplify "SLF", # flake8-self "SLOT", # flake8-slots "T100", # Trace found: {name} used "T20", # flake8-print "TID", # Tidy imports "TRY", # tryceratops ] [tool.ruff.lint.per-file-ignores] "tests/**/*" = [ "D100", "D101", "D102", "D103", "D104", "S101", "S108", "SLF001", "PLW", # too many to fix "TRY",# too many to fix right now "PT",# too many to fix right now "B",# too many to fix right now "RET",# too many to fix right now "PLR2004", # too many to fix right now "PT011", # too many to fix right now "PT006", # too many to fix right now "PGH003", # too many to fix right now "PT007", # too many to fix right now "PT027", # too many to fix right now "PLW0603" , # too many to fix right now "PLR0915", # too many to fix right now "FLY002", # too many to fix right now "PT018", # too many to fix right now "PLR0124", # too many to fix right now "SIM202" , # too many to fix right now "PT012" , # too many to fix right now "TID252", # too many to fix right now "PLR0913", # skip this one "SIM102" , # too many to fix right now "SIM108", # too many to fix right now "T201", # too many to fix right now ] "bench/**/*" = [ "T201", # intended ] "examples/**/*" = [ "T201", # intended "RSE102", # too many to fix "C408", # too many to fix "E402", # as intended ] "docs/**/*" = [ "E402", # as intended ] dbus-fast-2.44.1/renovate.json000066400000000000000000000001011477355613200162150ustar00rootroot00000000000000{ "extends": ["github>browniebroke/renovate-configs:python"] } dbus-fast-2.44.1/src/000077500000000000000000000000001477355613200142765ustar00rootroot00000000000000dbus-fast-2.44.1/src/dbus_fast/000077500000000000000000000000001477355613200162505ustar00rootroot00000000000000dbus-fast-2.44.1/src/dbus_fast/__init__.py000066400000000000000000000036341477355613200203670ustar00rootroot00000000000000from . import introspection, message_bus, proxy_object, service from .constants import ( ArgDirection, BusType, ErrorType, MessageFlag, MessageType, NameFlag, PropertyAccess, ReleaseNameReply, RequestNameReply, ) from .errors import ( AuthError, DBusError, InterfaceNotFoundError, InvalidAddressError, InvalidBusNameError, InvalidInterfaceNameError, InvalidIntrospectionError, InvalidMemberNameError, InvalidMessageError, InvalidObjectPathError, InvalidSignatureError, SignalDisabledError, SignatureBodyMismatchError, ) from .message import Message from .signature import SignatureTree, SignatureType, Variant from .unpack import unpack_variants from .validators import ( assert_bus_name_valid, assert_interface_name_valid, assert_member_name_valid, assert_object_path_valid, is_bus_name_valid, is_interface_name_valid, is_member_name_valid, is_object_path_valid, ) __all__ = [ "ArgDirection", "AuthError", "BusType", "DBusError", "ErrorType", "InterfaceNotFoundError", "InvalidAddressError", "InvalidBusNameError", "InvalidInterfaceNameError", "InvalidIntrospectionError", "InvalidMemberNameError", "InvalidMessageError", "InvalidObjectPathError", "InvalidSignatureError", "Message", "MessageFlag", "MessageType", "NameFlag", "PropertyAccess", "ReleaseNameReply", "RequestNameReply", "SignalDisabledError", "SignatureBodyMismatchError", "SignatureTree", "SignatureType", "Variant", "assert_bus_name_valid", "assert_interface_name_valid", "assert_member_name_valid", "assert_object_path_valid", "introspection", "is_bus_name_valid", "is_interface_name_valid", "is_member_name_valid", "is_object_path_valid", "message_bus", "proxy_object", "service", "unpack_variants", ] dbus-fast-2.44.1/src/dbus_fast/__version__.py000066400000000000000000000006211477355613200211020ustar00rootroot00000000000000__title__ = "dbus_fast" __description__ = ( "A performant zero-dependency DBus library for Python with asyncio support" ) __url__ = "https://github.com/bluetooth-devices/dbus-fast" __version__ = "2.44.1" __author__ = "Bluetooth Devices authors, Tony Crisci" __author_email__ = "bluetooth@koston.org" __license__ = "MIT" __copyright__ = "Copyright 2022 Bluetooth Devices authors, 2019 Tony Crisci" dbus-fast-2.44.1/src/dbus_fast/_private/000077500000000000000000000000001477355613200200615ustar00rootroot00000000000000dbus-fast-2.44.1/src/dbus_fast/_private/__init__.py000066400000000000000000000000431477355613200221670ustar00rootroot00000000000000from __future__ import annotations dbus-fast-2.44.1/src/dbus_fast/_private/_cython_compat.py000066400000000000000000000003671477355613200234470ustar00rootroot00000000000000"""Stub for when Cython is not available.""" from __future__ import annotations class FakeCython: """Stub for when Cython is not available.""" @property def compiled(self) -> bool: return False FAKE_CYTHON = FakeCython() dbus-fast-2.44.1/src/dbus_fast/_private/address.pxd000066400000000000000000000004371477355613200222270ustar00rootroot00000000000000"""cdefs for address.py""" import cython cdef object unquote @cython.locals(kv=cython.str, opt_string=cython.str, address=cython.str) cpdef parse_address(cython.str address_str) cpdef get_bus_address(object bus_type) cpdef get_session_bus_address() cpdef get_system_bus_address() dbus-fast-2.44.1/src/dbus_fast/_private/address.py000066400000000000000000000077061477355613200220720ustar00rootroot00000000000000from __future__ import annotations import os import re from urllib.parse import unquote from ..constants import BusType from ..errors import InvalidAddressError invalid_address_chars_re = re.compile(r"[^-0-9A-Za-z_/.%]") str_ = str def parse_address(address_str: str_) -> list[tuple[str, dict[str, str]]]: """Parse a dbus address string into a list of addresses.""" addresses: list[tuple[str, dict[str, str]]] = [] for address in address_str.split(";"): if not address: continue if address.find(":") == -1: raise InvalidAddressError("address did not contain a transport") transport, opt_string = address.split(":", 1) options: dict[str, str] = {} for kv in opt_string.split(","): if not kv: continue if kv.find("=") == -1: raise InvalidAddressError("address option did not contain a value") k, v = kv.split("=", 1) if invalid_address_chars_re.search(v): raise InvalidAddressError("address contains invalid characters") # XXX the actual unquote rules are simpler than this options[k] = unquote(v) addresses.append((transport, options)) if not addresses: raise InvalidAddressError( f'address string contained no addresses: "{address_str}"' ) return addresses def get_system_bus_address() -> str: """Get the system bus address from the environment or return the default.""" return ( os.environ.get("DBUS_SYSTEM_BUS_ADDRESS") or "unix:path=/var/run/dbus/system_bus_socket" ) display_re = re.compile(r".*:([0-9]+)\.?.*") remove_quotes_re = re.compile(r"""^['"]?(.*?)['"]?$""") def get_session_bus_address() -> str: """Get the session bus address from the environment or return the default.""" dbus_session_bus_address = os.environ.get("DBUS_SESSION_BUS_ADDRESS") if dbus_session_bus_address: return dbus_session_bus_address home = os.environ["HOME"] if "DISPLAY" not in os.environ: raise InvalidAddressError( "DBUS_SESSION_BUS_ADDRESS not set and could not get DISPLAY environment variable to get bus address" ) display = os.environ["DISPLAY"] try: display = display_re.search(display).group(1) except Exception as ex: raise InvalidAddressError( f"DBUS_SESSION_BUS_ADDRESS not set and could not parse DISPLAY environment variable to get bus address: {display}" ) from ex # XXX: this will block but they're very small files and fs operations # should be fairly reliable. fix this by passing in an async func to read # the file for each io backend. machine_id = None with open("/var/lib/dbus/machine-id") as f: machine_id = f.read().rstrip() dbus_info_file_name = f"{home}/.dbus/session-bus/{machine_id}-{display}" dbus_info: str | None = None try: with open(dbus_info_file_name) as f: dbus_info = f.read().rstrip() except Exception as ex: raise InvalidAddressError( f"could not open dbus info file: {dbus_info_file_name}" ) from ex for line in dbus_info.split("\n"): if line.strip().startswith("DBUS_SESSION_BUS_ADDRESS="): _, addr = line.split("=", 1) if not addr: raise InvalidAddressError( f"DBUS_SESSION_BUS_ADDRESS variable not set correctly in dbus info file: {dbus_info_file_name}" ) addr = remove_quotes_re.search(addr).group(1) return addr raise InvalidAddressError("could not find dbus session bus address") def get_bus_address(bus_type: BusType) -> str: """Get the address of the bus specified by the bus type.""" if bus_type == BusType.SESSION: return get_session_bus_address() if bus_type == BusType.SYSTEM: return get_system_bus_address() raise Exception(f"got unknown bus type: {bus_type}") dbus-fast-2.44.1/src/dbus_fast/_private/constants.py000066400000000000000000000004671477355613200224560ustar00rootroot00000000000000from __future__ import annotations from enum import Enum PROTOCOL_VERSION = 1 LITTLE_ENDIAN = ord("l") BIG_ENDIAN = ord("B") class HeaderField(Enum): PATH = 1 INTERFACE = 2 MEMBER = 3 ERROR_NAME = 4 REPLY_SERIAL = 5 DESTINATION = 6 SENDER = 7 SIGNATURE = 8 UNIX_FDS = 9 dbus-fast-2.44.1/src/dbus_fast/_private/marshaller.pxd000066400000000000000000000051551477355613200227360ustar00rootroot00000000000000"""cdefs for marshaller.py""" import cython from ..signature cimport SignatureTree, SignatureType, Variant cdef object PACK_UINT32 cdef bytes PACKED_UINT32_ZERO cdef bytes PACKED_BOOL_TRUE cdef bytes PACKED_BOOL_FALSE cdef get_signature_tree cdef class Marshaller: cdef SignatureTree signature_tree cdef bytearray _buf cdef cython.list body cdef _buffer(self) cpdef align(self, unsigned int n) @cython.locals( offset=cython.ulong, ) cdef unsigned int _align(self, unsigned int n) cpdef write_boolean(self, object boolean, SignatureType type_) @cython.locals( written=cython.uint, ) cdef unsigned int _write_boolean(self, object boolean) cpdef write_string(self, object value, SignatureType type_) @cython.locals( buf=cython.bytearray, value_len=cython.uint, signature_len=cython.uint, written=cython.uint, ) cdef unsigned int _write_string(self, object value) @cython.locals( signature_len=cython.uint, ) cdef unsigned int _write_signature(self, bytes signature_bytes) cpdef write_array(self, object array, SignatureType type_) @cython.locals( array_len=cython.uint, buf=cython.bytearray, written=cython.uint, token=cython.str, child_type=SignatureType, array_len_packed=cython.bytes, size=cython.uint, writer=cython.object, packer=cython.object, i=cython.uint, ) cdef unsigned int _write_array(self, object array, SignatureType type_) cpdef write_struct(self, object array, SignatureType type_) @cython.locals( written=cython.uint, i=cython.uint, ) cdef unsigned int _write_struct(self, object array, SignatureType type_) cpdef write_variant(self, Variant variant, SignatureType type_) @cython.locals( written=cython.uint, signature=cython.str, signature_bytes=cython.bytes, ) cdef unsigned int _write_variant(self, Variant variant, SignatureType type_) @cython.locals( written=cython.uint, size=cython.uint, ) cdef unsigned int _write_single(self, SignatureType type_, object body) @cython.locals( written=cython.uint, t=cython.str, ) cpdef write_dict_entry(self, cython.list dict_entry, SignatureType type_) cpdef marshall(self) cdef _marshall(self) @cython.locals( offset=cython.ulong, t=cython.str, size=cython.uint, writer=cython.object, packer=cython.object, type_=SignatureType, ) cdef _construct_buffer(self) dbus-fast-2.44.1/src/dbus_fast/_private/marshaller.py000066400000000000000000000171641477355613200225760ustar00rootroot00000000000000from __future__ import annotations from struct import Struct, error from typing import Any, Callable from ..signature import SignatureType, Variant, get_signature_tree PACK_LITTLE_ENDIAN = "<" PACK_UINT32 = Struct(f"{PACK_LITTLE_ENDIAN}I").pack PACKED_UINT32_ZERO = PACK_UINT32(0) PACKED_BOOL_FALSE = PACK_UINT32(0) PACKED_BOOL_TRUE = PACK_UINT32(1) _int = int _bytes = bytes _str = str class Marshaller: """Marshall data for Dbus.""" __slots__ = ("_buf", "body", "signature_tree") def __init__(self, signature: str, body: list[Any]) -> None: """Marshaller constructor.""" self.signature_tree = get_signature_tree(signature) self._buf = bytearray() self.body = body @property def buffer(self) -> bytearray: return self._buf def _buffer(self) -> bytearray: return self._buf def align(self, n: _int) -> int: return self._align(n) def _align(self, n: _int) -> _int: offset = n - len(self._buf) % n if offset == 0 or offset == n: return 0 for _ in range(offset): self._buf.append(0) return offset def write_boolean(self, boolean: bool, type_: SignatureType) -> int: return self._write_boolean(boolean) def _write_boolean(self, boolean: bool) -> int: written = self._align(4) self._buf += PACKED_BOOL_TRUE if boolean else PACKED_BOOL_FALSE return written + 4 def write_signature(self, signature: str, type_: SignatureType) -> int: return self._write_signature(signature.encode()) def _write_signature(self, signature_bytes: _bytes) -> int: signature_len = len(signature_bytes) buf = self._buf buf.append(signature_len) buf += signature_bytes buf.append(0) return signature_len + 2 def write_string(self, value: _str, type_: SignatureType) -> int: return self._write_string(value) def _write_string(self, value: _str) -> int: value_bytes = value.encode() value_len = len(value_bytes) written = self._align(4) + 4 buf = self._buf buf += PACK_UINT32(value_len) buf += value_bytes written += value_len buf.append(0) written += 1 return written def write_variant(self, variant: Variant, type_: SignatureType) -> int: return self._write_variant(variant, type_) def _write_variant(self, variant: Variant, type_: SignatureType) -> int: signature = variant.signature signature_bytes = signature.encode() written = self._write_signature(signature_bytes) written += self._write_single(variant.type, variant.value) return written def write_array( self, array: bytes | list[Any] | dict[Any, Any], type_: SignatureType ) -> int: return self._write_array(array, type_) def _write_array( self, array: bytes | list[Any] | dict[Any, Any], type_: SignatureType ) -> int: # TODO max array size is 64MiB (67108864 bytes) written = self._align(4) # length placeholder buf: bytearray = self._buf offset = len(buf) written += self._align(4) + 4 buf += PACKED_UINT32_ZERO child_type = type_.children[0] token = child_type.token if token in "xtd{(": # the first alignment is not included in array size written += self._align(8) array_len = 0 if token == "{": for key, value in array.items(): # type: ignore[union-attr] array_len += self.write_dict_entry([key, value], child_type) elif token == "y": array_len = len(array) buf += array # type: ignore[arg-type] elif token == "(": for value in array: array_len += self._write_struct(value, child_type) else: writer, packer, size = self._writers[token] if not writer: for value in array: array_len += self._align(size) + size buf += packer(value) # type: ignore[misc] else: for value in array: array_len += writer(self, value, child_type) array_len_packed = PACK_UINT32(array_len) for i in range(offset, offset + 4): buf[i] = array_len_packed[i - offset] return written + array_len def write_struct(self, array: tuple[Any] | list[Any], type_: SignatureType) -> int: return self._write_struct(array, type_) def _write_struct(self, array: tuple[Any] | list[Any], type_: SignatureType) -> int: written = self._align(8) for i, value in enumerate(array): written += self._write_single(type_.children[i], value) return written def write_dict_entry(self, dict_entry: list[Any], type_: SignatureType) -> int: written = self._align(8) written += self._write_single(type_.children[0], dict_entry[0]) written += self._write_single(type_.children[1], dict_entry[1]) return written def _write_single(self, type_: SignatureType, body: Any) -> int: t = type_.token if t == "y": self._buf.append(body) return 1 if t == "u": written = self._align(4) self._buf += PACK_UINT32(body) return written + 4 if t == "a": return self._write_array(body, type_) if t == "s" or t == "o": return self._write_string(body) if t == "v": return self._write_variant(body, type_) if t == "b": return self._write_boolean(body) writer, packer, size = self._writers[t] if not writer: written = self._align(size) self._buf += packer(body) # type: ignore[misc] return written + size return writer(self, body, type_) def marshall(self) -> bytearray: """Marshalls the body into a byte array""" return self._marshall() def _marshall(self) -> bytearray: """Marshalls the body into a byte array""" try: return self._construct_buffer() except KeyError as ex: raise NotImplementedError( f'type is not implemented yet: "{ex.args}"' ) from ex except error: self.signature_tree.verify(self.body) raise RuntimeError("should not reach here") def _construct_buffer(self) -> bytearray: self._buf.clear() body = self.body for i, type_ in enumerate(self.signature_tree.types): self._write_single(type_, body[i]) return self._buf _writers: dict[ str, tuple[ Callable[[Any, Any, SignatureType], int] | None, Callable[[Any], bytes] | None, int, ], ] = { "y": (None, Struct(f"{PACK_LITTLE_ENDIAN}B").pack, 1), "b": (write_boolean, None, 0), "n": (None, Struct(f"{PACK_LITTLE_ENDIAN}h").pack, 2), "q": (None, Struct(f"{PACK_LITTLE_ENDIAN}H").pack, 2), "i": (None, Struct(f"{PACK_LITTLE_ENDIAN}i").pack, 4), "u": (None, PACK_UINT32, 4), "x": (None, Struct(f"{PACK_LITTLE_ENDIAN}q").pack, 8), "t": (None, Struct(f"{PACK_LITTLE_ENDIAN}Q").pack, 8), "d": (None, Struct(f"{PACK_LITTLE_ENDIAN}d").pack, 8), "h": (None, Struct(f"{PACK_LITTLE_ENDIAN}I").pack, 4), "o": (write_string, None, 0), "s": (write_string, None, 0), "g": (write_signature, None, 0), "a": (write_array, None, 0), "(": (write_struct, None, 0), "{": (write_dict_entry, None, 0), "v": (write_variant, None, 0), } dbus-fast-2.44.1/src/dbus_fast/_private/unmarshaller.pxd000066400000000000000000000156641477355613200233070ustar00rootroot00000000000000"""cdefs for unmarshaller.py""" import cython from ..message cimport Message from ..signature cimport SignatureTree, SignatureType, Variant cdef bint TYPE_CHECKING cdef object MAX_UNIX_FDS_SIZE cdef object ARRAY cdef object UNIX_FDS_CMSG_LENGTH cdef object SOL_SOCKET cdef object SCM_RIGHTS cdef object MESSAGE_FLAG_INTENUM cdef unsigned int UINT32_SIZE cdef unsigned int INT16_SIZE cdef unsigned int UINT16_SIZE cdef unsigned int HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION cdef unsigned int HEADER_SIGNATURE_SIZE cdef unsigned int LITTLE_ENDIAN cdef unsigned int BIG_ENDIAN cdef unsigned int PROTOCOL_VERSION cdef unsigned int HEADER_PATH_IDX cdef unsigned int HEADER_INTERFACE_IDX cdef unsigned int HEADER_MEMBER_IDX cdef unsigned int HEADER_ERROR_NAME_IDX cdef unsigned int HEADER_REPLY_SERIAL_IDX cdef unsigned int HEADER_DESTINATION_IDX cdef unsigned int HEADER_SENDER_IDX cdef unsigned int HEADER_SIGNATURE_IDX cdef unsigned int HEADER_UNIX_FDS_IDX cdef cython.list HEADER_IDX_TO_ARG_NAME cdef str UINT32_CAST cdef str INT16_CAST cdef str UINT16_CAST cdef bint SYS_IS_LITTLE_ENDIAN cdef bint SYS_IS_BIG_ENDIAN cdef object UNPACK_HEADER_LITTLE_ENDIAN cdef object UNPACK_HEADER_BIG_ENDIAN cdef object UINT32_UNPACK_LITTLE_ENDIAN cdef object UINT32_UNPACK_BIG_ENDIAN cdef object INT16_UNPACK_LITTLE_ENDIAN cdef object INT16_UNPACK_BIG_ENDIAN cdef object UINT16_UNPACK_LITTLE_ENDIAN cdef object UINT16_UNPACK_BIG_ENDIAN cdef cython.dict MESSAGE_TYPE_MAP cdef cython.dict MESSAGE_FLAG_MAP cdef dict HEADER_MESSAGE_ARG_NAME cdef SignatureTree SIGNATURE_TREE_EMPTY cdef SignatureTree SIGNATURE_TREE_B cdef SignatureTree SIGNATURE_TREE_N cdef SignatureTree SIGNATURE_TREE_O cdef SignatureTree SIGNATURE_TREE_S cdef SignatureTree SIGNATURE_TREE_U cdef SignatureTree SIGNATURE_TREE_Y cdef SignatureTree SIGNATURE_TREE_AS cdef SignatureType SIGNATURE_TREE_AS_TYPES_0 cdef SignatureTree SIGNATURE_TREE_AO cdef SignatureType SIGNATURE_TREE_AO_TYPES_0 cdef SignatureTree SIGNATURE_TREE_A_SV cdef SignatureType SIGNATURE_TREE_A_SV_TYPES_0 cdef SignatureTree SIGNATURE_TREE_SA_SV_AS cdef SignatureType SIGNATURE_TREE_SA_SV_AS_TYPES_1 cdef SignatureType SIGNATURE_TREE_SA_SV_AS_TYPES_2 cdef SignatureTree SIGNATURE_TREE_OAS cdef SignatureType SIGNATURE_TREE_OAS_TYPES_1 cdef SignatureTree SIGNATURE_TREE_OA_SA_SV cdef SignatureType SIGNATURE_TREE_OA_SA_SV_TYPES_1 cdef SignatureTree SIGNATURE_TREE_AY cdef SignatureType SIGNATURE_TREE_AY_TYPES_0 cdef SignatureTree SIGNATURE_TREE_A_QV cdef SignatureType SIGNATURE_TREE_A_QV_TYPES_0 cdef SignatureTree SIGNATURE_TREE_A_OA_SA_SV cdef SignatureType SIGNATURE_TREE_A_OA_SA_SV_TYPES_0 cdef unsigned int TOKEN_B_AS_INT cdef unsigned int TOKEN_U_AS_INT cdef unsigned int TOKEN_Y_AS_INT cdef unsigned int TOKEN_A_AS_INT cdef unsigned int TOKEN_O_AS_INT cdef unsigned int TOKEN_S_AS_INT cdef unsigned int TOKEN_G_AS_INT cdef unsigned int TOKEN_N_AS_INT cdef unsigned int TOKEN_X_AS_INT cdef unsigned int TOKEN_T_AS_INT cdef unsigned int TOKEN_D_AS_INT cdef unsigned int TOKEN_Q_AS_INT cdef unsigned int TOKEN_V_AS_INT cdef unsigned int TOKEN_LEFT_CURLY_AS_INT cdef unsigned int TOKEN_LEFT_PAREN_AS_INT cdef object MARSHALL_STREAM_END_ERROR cdef object DEFAULT_BUFFER_SIZE cdef Variant VARIANT_BOOL_TRUE cdef Variant VARIANT_BOOL_FALSE cdef list _EMPTY_HEADERS cdef cython.uint EAGAIN cdef cython.uint EWOULDBLOCK cdef get_signature_tree cdef unsigned int _ustr_uint32(const unsigned char * buf, unsigned int offset, unsigned int endian) noexcept cdef short _ustr_int16(const unsigned char * buf, unsigned int offset, unsigned int endian) noexcept cdef unsigned short _ustr_uint16(const unsigned char * buf, unsigned int offset, unsigned int endian) noexcept cdef class Unmarshaller: cdef list _unix_fds cdef bytearray _buf cdef Py_ssize_t _buf_len cdef const unsigned char * _buf_ustr cdef unsigned int _pos cdef object _stream cdef object _sock cdef Message _message cdef object _readers cdef unsigned int _body_len cdef unsigned int _serial cdef unsigned int _header_len cdef object _message_type cdef object _flag cdef unsigned int _msg_len cdef object _uint32_unpack cdef object _int16_unpack cdef object _uint16_unpack cdef object _stream_reader cdef object _sock_with_fds_reader cdef object _sock_without_fds_reader cdef bint _negotiate_unix_fd cdef bint _read_complete cdef unsigned int _endian @cython.locals(to_clear=Py_ssize_t) cdef _next_message(self) cdef bint _has_another_message_in_buffer(self) @cython.locals( msg=cython.bytes, recv=cython.tuple, errno=cython.uint ) cdef void _read_sock_with_fds(self, unsigned int pos, unsigned int missing_bytes) except * @cython.locals( data=cython.bytes, errno=cython.uint ) cdef void _read_sock_without_fds(self, unsigned int pos) except * @cython.locals( data=cython.bytes ) cdef void _read_stream(self, unsigned int pos, unsigned int missing_bytes) except * cdef void _read_to_pos(self, unsigned int pos) except * cpdef read_boolean(self, SignatureType type_) cdef bint _read_boolean(self) cpdef read_uint32_unpack(self, SignatureType type_) cdef unsigned int _read_uint32_unpack(self) cpdef read_int16_unpack(self, SignatureType type_) cdef int _read_int16_unpack(self) cpdef read_uint16_unpack(self, SignatureType type_) cdef unsigned int _read_uint16_unpack(self) cpdef read_string_unpack(self, SignatureType type_) @cython.locals( str_start=cython.uint, ) cdef str _read_string_unpack(self) @cython.locals( tree=SignatureTree, token_as_int=cython.uint, var=Variant, ) cdef Variant _read_variant(self) @cython.locals( beginning_pos=cython.ulong, array_length=cython.uint, children=cython.list, child_type=SignatureType, child_0=SignatureType, child_1=SignatureType, token_as_int=cython.uint, ) cpdef object read_array(self, SignatureType type_) cpdef read_signature(self, SignatureType type_) @cython.locals( o=cython.ulong, signature_len=cython.uint, ) cdef str _read_signature(self) @cython.locals( endian=cython.uint, buffer=cython.bytearray, protocol_version=cython.uint, key=cython.str, ustring="const unsigned char *", ) cdef void _read_header(self) except * @cython.locals( body=list, header_fields=list, token_as_int="unsigned int", signature=str, tree=SignatureTree, message=Message ) cdef void _read_body(self) except * cdef Message _unmarshall(self) cpdef unmarshall(self) @cython.locals( beginning_pos=cython.ulong, o=cython.ulong, token_as_int=cython.uint, signature_len=cython.uint, headers=cython.list ) cdef cython.list _header_fields(self, unsigned int header_length) dbus-fast-2.44.1/src/dbus_fast/_private/unmarshaller.py000066400000000000000000001026741477355613200231420ustar00rootroot00000000000000from __future__ import annotations import array import errno import io import socket import sys from collections.abc import Iterable from struct import Struct from typing import TYPE_CHECKING, Any, Callable from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP, MessageFlag from ..errors import InvalidMessageError from ..message import Message from ..signature import SignatureType, Variant, get_signature_tree from .constants import BIG_ENDIAN, LITTLE_ENDIAN, PROTOCOL_VERSION MESSAGE_FLAG_INTENUM = MessageFlag MAX_UNIX_FDS = 16 MAX_UNIX_FDS_SIZE = array.array("i").itemsize UNIX_FDS_CMSG_LENGTH = socket.CMSG_LEN(MAX_UNIX_FDS_SIZE) UNPACK_SYMBOL = {LITTLE_ENDIAN: "<", BIG_ENDIAN: ">"} UINT32_CAST = "I" UINT32_SIZE = 4 UINT32_DBUS_TYPE = "u" INT16_CAST = "h" INT16_SIZE = 2 INT16_DBUS_TYPE = "n" UINT16_CAST = "H" UINT16_SIZE = 2 UINT16_DBUS_TYPE = "q" SYS_IS_LITTLE_ENDIAN = sys.byteorder == "little" SYS_IS_BIG_ENDIAN = sys.byteorder == "big" DBUS_TO_CTYPE = { "y": ("B", 1), # byte INT16_DBUS_TYPE: (INT16_CAST, INT16_SIZE), # int16 UINT16_DBUS_TYPE: (UINT16_CAST, UINT16_SIZE), # uint16 "i": ("i", 4), # int32 UINT32_DBUS_TYPE: (UINT32_CAST, UINT32_SIZE), # uint32 "x": ("q", 8), # int64 "t": ("Q", 8), # uint64 "d": ("d", 8), # double "h": (UINT32_CAST, UINT32_SIZE), # uint32 } UNPACK_HEADER_LITTLE_ENDIAN = Struct("III").unpack_from UINT32_UNPACK_LITTLE_ENDIAN = Struct(f"<{UINT32_CAST}").unpack_from UINT32_UNPACK_BIG_ENDIAN = Struct(f">{UINT32_CAST}").unpack_from INT16_UNPACK_LITTLE_ENDIAN = Struct(f"<{INT16_CAST}").unpack_from INT16_UNPACK_BIG_ENDIAN = Struct(f">{INT16_CAST}").unpack_from UINT16_UNPACK_LITTLE_ENDIAN = Struct(f"<{UINT16_CAST}").unpack_from UINT16_UNPACK_BIG_ENDIAN = Struct(f">{UINT16_CAST}").unpack_from HEADER_SIGNATURE_SIZE = 16 HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION = 12 # Most common signatures SIGNATURE_TREE_EMPTY = get_signature_tree("") SIGNATURE_TREE_B = get_signature_tree("b") SIGNATURE_TREE_N = get_signature_tree("n") SIGNATURE_TREE_S = get_signature_tree("s") SIGNATURE_TREE_O = get_signature_tree("o") SIGNATURE_TREE_U = get_signature_tree("u") SIGNATURE_TREE_Y = get_signature_tree("y") SIGNATURE_TREE_AY = get_signature_tree("ay") SIGNATURE_TREE_AS = get_signature_tree("as") SIGNATURE_TREE_AS_TYPES_0 = SIGNATURE_TREE_AS.root_type SIGNATURE_TREE_A_SV = get_signature_tree("a{sv}") SIGNATURE_TREE_A_SV_TYPES_0 = SIGNATURE_TREE_A_SV.root_type SIGNATURE_TREE_AO = get_signature_tree("ao") SIGNATURE_TREE_AO_TYPES_0 = SIGNATURE_TREE_AO.root_type SIGNATURE_TREE_OAS = get_signature_tree("oas") SIGNATURE_TREE_OAS_TYPES_1 = SIGNATURE_TREE_OAS.types[1] SIGNATURE_TREE_AY_TYPES_0 = SIGNATURE_TREE_AY.root_type SIGNATURE_TREE_A_QV = get_signature_tree("a{qv}") SIGNATURE_TREE_A_QV_TYPES_0 = SIGNATURE_TREE_A_QV.root_type SIGNATURE_TREE_SA_SV_AS = get_signature_tree("sa{sv}as") SIGNATURE_TREE_SA_SV_AS_TYPES_1 = SIGNATURE_TREE_SA_SV_AS.types[1] SIGNATURE_TREE_SA_SV_AS_TYPES_2 = SIGNATURE_TREE_SA_SV_AS.types[2] SIGNATURE_TREE_OA_SA_SV = get_signature_tree("oa{sa{sv}}") SIGNATURE_TREE_OA_SA_SV_TYPES_1 = SIGNATURE_TREE_OA_SA_SV.types[1] SIGNATURE_TREE_A_OA_SA_SV = get_signature_tree("a{oa{sa{sv}}}") SIGNATURE_TREE_A_OA_SA_SV_TYPES_0 = SIGNATURE_TREE_A_OA_SA_SV.root_type TOKEN_B_AS_INT = ord("b") TOKEN_U_AS_INT = ord("u") TOKEN_Y_AS_INT = ord("y") TOKEN_A_AS_INT = ord("a") TOKEN_O_AS_INT = ord("o") TOKEN_S_AS_INT = ord("s") TOKEN_G_AS_INT = ord("g") TOKEN_N_AS_INT = ord("n") TOKEN_X_AS_INT = ord("x") TOKEN_T_AS_INT = ord("t") TOKEN_D_AS_INT = ord("d") TOKEN_Q_AS_INT = ord("q") TOKEN_V_AS_INT = ord("v") TOKEN_LEFT_CURLY_AS_INT = ord("{") TOKEN_LEFT_PAREN_AS_INT = ord("(") VARIANT_BOOL_TRUE = Variant._factory(SIGNATURE_TREE_B, True) VARIANT_BOOL_FALSE = Variant._factory(SIGNATURE_TREE_B, False) ARRAY = array.array SOL_SOCKET = socket.SOL_SOCKET SCM_RIGHTS = socket.SCM_RIGHTS EAGAIN = errno.EAGAIN EWOULDBLOCK = errno.EWOULDBLOCK HEADER_IDX_TO_ARG_NAME = [ "", "path", "interface", "member", "error_name", "reply_serial", "destination", "sender", "signature", "unix_fds", ] HEADER_PATH_IDX = HEADER_IDX_TO_ARG_NAME.index("path") HEADER_INTERFACE_IDX = HEADER_IDX_TO_ARG_NAME.index("interface") HEADER_MEMBER_IDX = HEADER_IDX_TO_ARG_NAME.index("member") HEADER_ERROR_NAME_IDX = HEADER_IDX_TO_ARG_NAME.index("error_name") HEADER_REPLY_SERIAL_IDX = HEADER_IDX_TO_ARG_NAME.index("reply_serial") HEADER_DESTINATION_IDX = HEADER_IDX_TO_ARG_NAME.index("destination") HEADER_SENDER_IDX = HEADER_IDX_TO_ARG_NAME.index("sender") HEADER_SIGNATURE_IDX = HEADER_IDX_TO_ARG_NAME.index("signature") HEADER_UNIX_FDS_IDX = HEADER_IDX_TO_ARG_NAME.index("unix_fds") _EMPTY_HEADERS: list[Any | None] = [None] * len(HEADER_IDX_TO_ARG_NAME) _SignatureType = SignatureType _int = int READER_TYPE = Callable[["Unmarshaller", SignatureType], Any] MARSHALL_STREAM_END_ERROR = BlockingIOError DEFAULT_BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE def unpack_parser_factory(unpack_from: Callable, size: int) -> READER_TYPE: """Build a parser that unpacks the bytes using the given unpack_from function.""" def _unpack_from_parser(self: Unmarshaller, signature: SignatureType) -> Any: self._pos += size + (-self._pos & (size - 1)) # align return unpack_from(self._buf, self._pos - size)[0] return _unpack_from_parser def build_simple_parsers( endian: int, ) -> dict[str, Callable[[Unmarshaller, SignatureType], Any]]: """Build a dict of parsers for simple types.""" parsers: dict[str, READER_TYPE] = {} for dbus_type, ctype_size in DBUS_TO_CTYPE.items(): ctype, size = ctype_size size = ctype_size[1] parsers[dbus_type] = unpack_parser_factory( Struct(f"{UNPACK_SYMBOL[endian]}{ctype}").unpack_from, size ) return parsers try: import cython except ImportError: from ._cython_compat import FAKE_CYTHON as cython int_ = int bytearray_ = bytearray def is_compiled() -> bool: return cython.compiled def _ustr_uint32(buf: bytearray_, pos: int_, endian: int_) -> int_: if endian == LITTLE_ENDIAN: return ( buf[pos] | (buf[pos + 1] << 8) | (buf[pos + 2] << 16) | (buf[pos + 3] << 24) ) return buf[pos + 3] | (buf[pos + 2] << 8) | (buf[pos + 1] << 16) | (buf[pos] << 24) def buffer_to_uint32(buf: bytearray, pos: int, endian: int) -> int: return _ustr_uint32(buf, pos, endian) def _ustr_int16(buf: bytearray_, pos: int_, endian: int_) -> int_: # Caution: this function will only work with Cython # because it relies on casting the result to a signed int # and will return an unsigned int if not compiled. if endian == LITTLE_ENDIAN: return buf[pos] | (buf[pos + 1] << 8) # pragma: no cover return buf[pos + 1] | (buf[pos] << 8) # pragma: no cover def buffer_to_int16(buf: bytearray | bytes, pos: int, endian: int) -> int: # Caution: this function will only work with Cython # because it relies on casting the result to a signed int # and will return an unsigned int if not compiled. return _ustr_int16(buf, pos, endian) def _ustr_uint16(buf: bytearray_, pos: int_, endian: int_) -> int_: if endian == LITTLE_ENDIAN: return buf[pos] | (buf[pos + 1] << 8) return buf[pos + 1] | (buf[pos] << 8) def buffer_to_uint16(buf: bytearray, pos: int, endian: int) -> int: return _ustr_uint16(buf, pos, endian) # Alignment padding is handled with the following formula below # # For any align value, the correct padding formula is: # # (align - (pos % align)) % align # # However, if align is a power of 2 (always the case here), the slow MOD # operator can be replaced by a bitwise AND: # # (align - (pos & (align - 1))) & (align - 1) # # Which can be simplified to: # # (-pos) & (align - 1) # # class Unmarshaller: """Unmarshall messages from a stream. When calling with sock and _negotiate_unix_fd False, the unmashaller must be called continuously for each new message as it will buffer the data until a complete message is available. """ __slots__ = ( "_body_len", "_buf", "_buf_len", "_buf_ustr", "_endian", "_flag", "_header_len", "_int16_unpack", "_message", "_message_type", "_msg_len", "_negotiate_unix_fd", "_pos", "_read_complete", "_readers", "_serial", "_sock", "_sock_with_fds_reader", "_sock_without_fds_reader", "_stream", "_stream_reader", "_uint16_unpack", "_uint32_unpack", "_unix_fds", ) _stream_reader: Callable[[int], bytes] def __init__( self, stream: io.BufferedRWPair | None = None, sock: socket.socket | None = None, negotiate_unix_fd: bool = True, ) -> None: self._unix_fds: list[int] = [] self._buf: bytearray = bytearray.__new__(bytearray) # Actual buffer self._buf_ustr = self._buf # Used to avoid type checks self._buf_len = 0 self._stream = stream self._sock = sock self._message: Message | None = None self._readers: dict[str, READER_TYPE] = {} self._pos = 0 self._body_len = 0 self._serial = 0 self._header_len = 0 self._message_type = 0 self._flag = 0 self._msg_len = 0 self._uint32_unpack: Callable[[bytearray, int], tuple[int]] | None = None self._int16_unpack: Callable[[bytearray, int], tuple[int]] | None = None self._uint16_unpack: Callable[[bytearray, int], tuple[int]] | None = None self._negotiate_unix_fd = negotiate_unix_fd self._read_complete = False if stream: if isinstance(stream, io.BufferedRWPair) and hasattr(stream, "reader"): self._stream_reader = stream.reader.read else: self._stream_reader = stream.read elif self._negotiate_unix_fd: if TYPE_CHECKING: assert self._sock is not None self._sock_with_fds_reader = self._sock.recvmsg else: if TYPE_CHECKING: assert self._sock is not None self._sock_without_fds_reader = self._sock.recv self._endian = 0 def _next_message(self) -> None: """Reset the unmarshaller to its initial state. Call this before processing a new message. """ if self._unix_fds: self._unix_fds = [] to_clear = HEADER_SIGNATURE_SIZE + self._msg_len if self._buf_len == to_clear: self._buf = bytearray.__new__(bytearray) self._buf_len = 0 else: del self._buf[:to_clear] self._buf_len -= to_clear self._buf_ustr = self._buf self._msg_len = 0 # used to check if we have ready the header self._read_complete = False # used to check if we have ready the message # No need to reset the unpack functions, they are set in _read_header # every time a new message is processed. @property def message(self) -> Message | None: """Return the message that has been unmarshalled.""" if self._read_complete: return self._message return None def _has_another_message_in_buffer(self) -> bool: """Check if there is another message in the buffer.""" return self._buf_len > HEADER_SIGNATURE_SIZE + self._msg_len def _read_sock_with_fds(self, pos: _int, missing_bytes: _int) -> None: """reads from the socket, storing any fds sent and handling errors from the read itself. This function is greedy and will read as much data as possible from the underlying socket. """ # This will raise BlockingIOError if there is no data to read # which we store in the MARSHALL_STREAM_END_ERROR object try: recv = self._sock_with_fds_reader(missing_bytes, UNIX_FDS_CMSG_LENGTH) except OSError as e: errno = e.errno if errno == EAGAIN or errno == EWOULDBLOCK: raise MARSHALL_STREAM_END_ERROR raise msg = recv[0] ancdata = recv[1] if ancdata: for level, type_, data in ancdata: if not (level == SOL_SOCKET and type_ == SCM_RIGHTS): continue self._unix_fds.extend( ARRAY("i", data[: len(data) - (len(data) % MAX_UNIX_FDS_SIZE)]) ) if not msg: raise EOFError self._buf += msg self._buf_len = len(self._buf) if self._buf_len < pos: raise MARSHALL_STREAM_END_ERROR def _read_sock_without_fds(self, pos: _int) -> None: """reads from the socket and handling errors from the read itself. This function is greedy and will read as much data as possible from the underlying socket. """ # This will raise BlockingIOError if there is no data to read # which we store in the MARSHALL_STREAM_END_ERROR object while True: try: data = self._sock_without_fds_reader(DEFAULT_BUFFER_SIZE) except OSError as e: errno = e.errno if errno == EAGAIN or errno == EWOULDBLOCK: raise MARSHALL_STREAM_END_ERROR raise if not data: raise EOFError self._buf += data self._buf_len = len(self._buf) if self._buf_len >= pos: return def _read_stream(self, pos: _int, missing_bytes: _int) -> None: """Read from the stream.""" data = self._stream_reader(missing_bytes) if data is None: raise MARSHALL_STREAM_END_ERROR if not data: raise EOFError self._buf += data self._buf_len = len(self._buf) if self._buf_len < pos: raise MARSHALL_STREAM_END_ERROR def _read_to_pos(self, pos: _int) -> None: """ Read from underlying socket into buffer. Raises BlockingIOError if there is not enough data to be read. :arg pos: The pos to read to. If not enough bytes are available in the buffer, read more from it. :returns: None """ missing_bytes = pos - self._buf_len if missing_bytes <= 0: return if self._sock is None: self._read_stream(pos, missing_bytes) elif self._negotiate_unix_fd: self._read_sock_with_fds(pos, missing_bytes) else: self._read_sock_without_fds(pos) self._buf_ustr = self._buf def read_uint32_unpack(self, type_: _SignatureType) -> int: return self._read_uint32_unpack() def _read_uint32_unpack(self) -> int: self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read uint32") return _ustr_uint32(self._buf_ustr, self._pos - UINT32_SIZE, self._endian) return self._uint32_unpack(self._buf, self._pos - UINT32_SIZE)[0] def read_uint16_unpack(self, type_: _SignatureType) -> int: return self._read_uint16_unpack() def _read_uint16_unpack(self) -> int: self._pos += UINT16_SIZE + (-self._pos & (UINT16_SIZE - 1)) # align if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read uint16") return _ustr_uint16(self._buf_ustr, self._pos - UINT16_SIZE, self._endian) return self._uint16_unpack(self._buf, self._pos - UINT16_SIZE)[0] def read_int16_unpack(self, type_: _SignatureType) -> int: return self._read_int16_unpack() def _read_int16_unpack(self) -> int: self._pos += INT16_SIZE + (-self._pos & (INT16_SIZE - 1)) # align if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read int16") return _ustr_int16(self._buf_ustr, self._pos - INT16_SIZE, self._endian) return self._int16_unpack(self._buf, self._pos - INT16_SIZE)[0] def read_boolean(self, type_: _SignatureType) -> bool: return self._read_boolean() def _read_boolean(self) -> bool: return bool(self._read_uint32_unpack()) def read_string_unpack(self, type_: _SignatureType) -> str: return self._read_string_unpack() def _read_string_unpack(self) -> str: """Read a string using unpack.""" self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align str_start = self._pos # read terminating '\0' byte as well (str_length + 1) if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read uint32") self._pos += ( _ustr_uint32(self._buf_ustr, str_start - UINT32_SIZE, self._endian) + 1 ) if self._buf_len < self._pos: raise IndexError("Not enough data to read string") else: self._pos += self._uint32_unpack(self._buf, str_start - UINT32_SIZE)[0] + 1 return self._buf_ustr[str_start : self._pos - 1].decode() def read_signature(self, type_: _SignatureType) -> str: return self._read_signature() def _read_signature(self) -> str: if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read signature") signature_len = self._buf_ustr[self._pos] # byte o = self._pos + 1 # read terminating '\0' byte as well (str_length + 1) self._pos = o + signature_len + 1 if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read signature") return self._buf_ustr[o : o + signature_len].decode() def read_variant(self, type_: _SignatureType) -> Variant: return self._read_variant() def _read_variant(self) -> Variant: signature = self._read_signature() token_as_int = ord(signature[0]) # verify in Variant is only useful on construction not unmarshalling if len(signature) == 1: if token_as_int == TOKEN_N_AS_INT: return Variant._factory(SIGNATURE_TREE_N, self._read_int16_unpack()) if token_as_int == TOKEN_S_AS_INT: return Variant._factory(SIGNATURE_TREE_S, self._read_string_unpack()) if token_as_int == TOKEN_B_AS_INT: return VARIANT_BOOL_TRUE if self._read_boolean() else VARIANT_BOOL_FALSE if token_as_int == TOKEN_O_AS_INT: return Variant._factory(SIGNATURE_TREE_O, self._read_string_unpack()) if token_as_int == TOKEN_U_AS_INT: return Variant._factory(SIGNATURE_TREE_U, self._read_uint32_unpack()) if token_as_int == TOKEN_Y_AS_INT: if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read byte") self._pos += 1 return Variant._factory(SIGNATURE_TREE_Y, self._buf_ustr[self._pos - 1]) elif token_as_int == TOKEN_A_AS_INT: if signature == "ay": return Variant._factory( SIGNATURE_TREE_AY, self.read_array(SIGNATURE_TREE_AY_TYPES_0) ) if signature == "a{qv}": return Variant._factory( SIGNATURE_TREE_A_QV, self.read_array(SIGNATURE_TREE_A_QV_TYPES_0) ) if signature == "as": return Variant._factory( SIGNATURE_TREE_AS, self.read_array(SIGNATURE_TREE_AS_TYPES_0) ) if signature == "a{sv}": return Variant._factory( SIGNATURE_TREE_A_SV, self.read_array(SIGNATURE_TREE_A_SV_TYPES_0) ) if signature == "ao": return Variant._factory( SIGNATURE_TREE_AO, self.read_array(SIGNATURE_TREE_AO_TYPES_0) ) tree = get_signature_tree(signature) signature_type = tree.root_type return Variant._factory( tree, self._readers[signature_type.token](self, signature_type) ) def read_struct(self, type_: _SignatureType) -> list[Any]: self._pos += -self._pos & 7 # align 8 readers = self._readers return [ readers[child_type.token](self, child_type) for child_type in type_.children ] def read_dict_entry(self, type_: _SignatureType) -> tuple[Any, Any]: self._pos += -self._pos & 7 # align 8 return self._readers[type_.children[0].token]( self, type_.children[0] ), self._readers[type_.children[1].token](self, type_.children[1]) def read_array(self, type_: _SignatureType) -> Iterable[Any]: self._pos += -self._pos & 3 # align 4 for the array self._pos += ( -self._pos & (UINT32_SIZE - 1) ) + UINT32_SIZE # align for the uint32 if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read uint32") array_length = _ustr_uint32( self._buf_ustr, self._pos - UINT32_SIZE, self._endian ) else: array_length = self._uint32_unpack(self._buf, self._pos - UINT32_SIZE)[0] child_type = type_._child_0 token_as_int = child_type.token_as_int if token_as_int in { TOKEN_X_AS_INT, TOKEN_T_AS_INT, TOKEN_D_AS_INT, TOKEN_LEFT_CURLY_AS_INT, TOKEN_LEFT_PAREN_AS_INT, }: # the first alignment is not included in the array size self._pos += -self._pos & 7 # align 8 if token_as_int == TOKEN_Y_AS_INT: self._pos += array_length if cython.compiled: if self._buf_len < self._pos: raise IndexError("Not enough data to read byte") return self._buf_ustr[self._pos - array_length : self._pos] if token_as_int == TOKEN_LEFT_CURLY_AS_INT: result_dict: dict[Any, Any] = {} key: str | int beginning_pos = self._pos child_0 = child_type._child_0 child_1 = child_type._child_1 child_0_token_as_int = child_0.token_as_int child_1_token_as_int = child_1.token_as_int # Strings with variant values are the most common case # so we optimize for that by inlining the string reading # and the variant reading here if ( child_0_token_as_int in {TOKEN_O_AS_INT, TOKEN_S_AS_INT} and child_1_token_as_int == TOKEN_V_AS_INT ): while self._pos - beginning_pos < array_length: self._pos += -self._pos & 7 # align 8 key = self._read_string_unpack() result_dict[key] = self._read_variant() elif ( child_0_token_as_int == TOKEN_Q_AS_INT and child_1_token_as_int == TOKEN_V_AS_INT ): while self._pos - beginning_pos < array_length: self._pos += -self._pos & 7 # align 8 key = self._read_uint16_unpack() result_dict[key] = self._read_variant() elif ( child_0_token_as_int in {TOKEN_O_AS_INT, TOKEN_S_AS_INT} and child_1_token_as_int == TOKEN_A_AS_INT ): while self._pos - beginning_pos < array_length: self._pos += -self._pos & 7 # align 8 key = self._read_string_unpack() result_dict[key] = self.read_array(child_1) else: reader_1 = self._readers[child_1.token] reader_0 = self._readers[child_0.token] while self._pos - beginning_pos < array_length: self._pos += -self._pos & 7 # align 8 key = reader_0(self, child_0) result_dict[key] = reader_1(self, child_1) return result_dict if array_length == 0: return [] result_list = [] beginning_pos = self._pos if token_as_int == TOKEN_O_AS_INT or token_as_int == TOKEN_S_AS_INT: while self._pos - beginning_pos < array_length: result_list.append(self._read_string_unpack()) return result_list reader = self._readers[child_type.token] while self._pos - beginning_pos < array_length: result_list.append(reader(self, child_type)) return result_list def _header_fields(self, header_length: _int) -> list[Any]: """Header fields are always a(yv).""" beginning_pos = self._pos headers = _EMPTY_HEADERS.copy() if cython.compiled: if self._buf_len < self._pos + header_length: raise IndexError("Not enough data to read header") while self._pos - beginning_pos < header_length: # Now read the y (byte) of struct (yv) self._pos += (-self._pos & 7) + 1 # align 8 + 1 for 'y' byte field_0 = self._buf_ustr[self._pos - 1] # Now read the v (variant) of struct (yv) # first we read the signature signature_len = self._buf_ustr[self._pos] # byte o = self._pos + 1 if cython.compiled: if self._buf_len < o + signature_len: raise IndexError("Not enough data to read signature") self._pos += signature_len + 2 # one for the byte, one for the '\0' if field_0 == HEADER_UNIX_FDS_IDX: # defined by self._unix_fds continue token_as_int = self._buf_ustr[o] # Now that we have the token we can read the variant value # Strings and signatures are the most common types # so we inline them for performance if token_as_int == TOKEN_O_AS_INT or token_as_int == TOKEN_S_AS_INT: headers[field_0] = self._read_string_unpack() elif token_as_int == TOKEN_G_AS_INT: headers[field_0] = self._read_signature() else: token = self._buf_ustr[o : o + signature_len].decode() # There shouldn't be any other types in the header # but just in case, we'll read it using the slow path headers[field_0] = self._readers[token]( self, get_signature_tree(token).root_type ) return headers def _read_header(self) -> None: """Read the header of the message.""" # Signature is of the header is # BYTE, BYTE, BYTE, BYTE, UINT32, UINT32, ARRAY of STRUCT of (BYTE,VARIANT) self._read_to_pos(HEADER_SIGNATURE_SIZE) endian = self._buf_ustr[0] self._message_type = self._buf_ustr[1] self._flag = self._buf_ustr[2] protocol_version = self._buf_ustr[3] if protocol_version != PROTOCOL_VERSION: raise InvalidMessageError( f"got unknown protocol version: {protocol_version}" ) if endian != LITTLE_ENDIAN and endian != BIG_ENDIAN: raise InvalidMessageError( f"Expecting endianness as the first byte, got {endian} from {self._buf}" ) if cython.compiled: self._body_len = _ustr_uint32(self._buf_ustr, 4, endian) self._serial = _ustr_uint32(self._buf_ustr, 8, endian) self._header_len = _ustr_uint32(self._buf_ustr, 12, endian) elif endian == LITTLE_ENDIAN: ( self._body_len, self._serial, self._header_len, ) = UNPACK_HEADER_LITTLE_ENDIAN(self._buf, 4) self._uint32_unpack = UINT32_UNPACK_LITTLE_ENDIAN self._int16_unpack = INT16_UNPACK_LITTLE_ENDIAN self._uint16_unpack = UINT16_UNPACK_LITTLE_ENDIAN else: # BIG_ENDIAN self._body_len, self._serial, self._header_len = UNPACK_HEADER_BIG_ENDIAN( self._buf, 4 ) self._uint32_unpack = UINT32_UNPACK_BIG_ENDIAN self._int16_unpack = INT16_UNPACK_BIG_ENDIAN self._uint16_unpack = UINT16_UNPACK_BIG_ENDIAN # align 8 self._msg_len = self._header_len + (-self._header_len & 7) + self._body_len if self._endian != endian: self._readers = self._readers_by_type[endian] self._endian = endian def _read_body(self) -> None: """Read the body of the message.""" self._read_to_pos(HEADER_SIGNATURE_SIZE + self._msg_len) self._pos = HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION header_fields = self._header_fields(self._header_len) self._pos += -self._pos & 7 # align 8 signature: str = header_fields[HEADER_SIGNATURE_IDX] if not self._body_len: tree = SIGNATURE_TREE_EMPTY body: list[Any] = [] else: token_as_int = ord(signature[0]) if len(signature) == 1: if token_as_int == TOKEN_O_AS_INT: tree = SIGNATURE_TREE_O body = [self._read_string_unpack()] elif token_as_int == TOKEN_S_AS_INT: tree = SIGNATURE_TREE_S body = [self._read_string_unpack()] else: tree = get_signature_tree(signature) body = [self._readers[t.token](self, t) for t in tree.types] elif token_as_int == TOKEN_S_AS_INT and signature == "sa{sv}as": tree = SIGNATURE_TREE_SA_SV_AS body = [ self._read_string_unpack(), self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_1), self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_2), ] elif token_as_int == TOKEN_O_AS_INT and signature == "oa{sa{sv}}": tree = SIGNATURE_TREE_OA_SA_SV body = [ self._read_string_unpack(), self.read_array(SIGNATURE_TREE_OA_SA_SV_TYPES_1), ] elif token_as_int == TOKEN_O_AS_INT and signature == "oas": tree = SIGNATURE_TREE_OAS body = [ self._read_string_unpack(), self.read_array(SIGNATURE_TREE_OAS_TYPES_1), ] elif token_as_int == TOKEN_A_AS_INT and signature == "a{oa{sa{sv}}}": tree = SIGNATURE_TREE_A_OA_SA_SV body = [self.read_array(SIGNATURE_TREE_A_OA_SA_SV_TYPES_0)] else: tree = get_signature_tree(signature) body = [self._readers[t.token](self, t) for t in tree.types] flags = MESSAGE_FLAG_MAP.get(self._flag) if flags is None: flags = MESSAGE_FLAG_INTENUM(self._flag) message = Message.__new__(Message) message._fast_init( header_fields[HEADER_DESTINATION_IDX], header_fields[HEADER_PATH_IDX], header_fields[HEADER_INTERFACE_IDX], header_fields[HEADER_MEMBER_IDX], MESSAGE_TYPE_MAP[self._message_type], flags, header_fields[HEADER_ERROR_NAME_IDX], header_fields[HEADER_REPLY_SERIAL_IDX] or 0, header_fields[HEADER_SENDER_IDX], self._unix_fds, tree, body, self._serial, # The D-Bus implementation already validates the message, # so we don't need to do it again. False, ) self._message = message self._read_complete = True def unmarshall(self) -> Message | None: """Unmarshall the message. The underlying read function will raise BlockingIOError if the if there are not enough bytes in the buffer. This allows unmarshall to be resumed when more data comes in over the wire. """ return self._unmarshall() def _unmarshall(self) -> Message | None: """Unmarshall the message. The underlying read function will raise BlockingIOError if the if there are not enough bytes in the buffer. This allows unmarshall to be resumed when more data comes in over the wire. """ if self._read_complete: self._next_message() try: if not self._msg_len: self._read_header() self._read_body() except MARSHALL_STREAM_END_ERROR: return None return self._message _complex_parsers_unpack: dict[str, Callable[[Unmarshaller, SignatureType], Any]] = { "b": read_boolean, "o": read_string_unpack, "s": read_string_unpack, "g": read_signature, "a": read_array, "(": read_struct, "{": read_dict_entry, "v": read_variant, "h": read_uint32_unpack, UINT32_DBUS_TYPE: read_uint32_unpack, INT16_DBUS_TYPE: read_int16_unpack, UINT16_DBUS_TYPE: read_uint16_unpack, } _ctype_by_endian: dict[int, dict[str, READER_TYPE]] = { endian: build_simple_parsers(endian) for endian in (LITTLE_ENDIAN, BIG_ENDIAN) } _readers_by_type: dict[int, dict[str, READER_TYPE]] = { LITTLE_ENDIAN: { **_ctype_by_endian[LITTLE_ENDIAN], **_complex_parsers_unpack, }, BIG_ENDIAN: { **_ctype_by_endian[BIG_ENDIAN], **_complex_parsers_unpack, }, } dbus-fast-2.44.1/src/dbus_fast/_private/util.py000066400000000000000000000135221477355613200214130ustar00rootroot00000000000000from __future__ import annotations import ast import inspect from typing import Any, Callable from ..signature import SignatureTree, SignatureType, Variant, get_signature_tree def signature_contains_type( signature: str | SignatureTree, body: list[Any], token: str ) -> bool: """For a given signature and body, check to see if it contains any members with the given token""" if type(signature) is str: signature = get_signature_tree(signature) queue = list(signature.types) # type: ignore[union-attr] contains_variants = False while True: if not queue: break st = queue.pop() if st.token == token: return True if st.token == "v": contains_variants = True queue.extend(st.children) if not contains_variants: return False for member in body: queue.append(member) while True: if not queue: return False member = queue.pop() if type(member) is Variant and signature_contains_type( member.signature, [member.value], token ): return True if type(member) is list: queue.extend(member) elif type(member) is dict: queue.extend(member.values()) def replace_fds_with_idx( signature: str | SignatureTree, body: list[Any] ) -> tuple[list[Any], list[int]]: """Take the high level body format and convert it into the low level body format. Type 'h' refers directly to the fd in the body. Replace that with an index and return the corresponding list of unix fds that can be set on the Message""" if type(signature) is str: signature = get_signature_tree(signature) if not signature_contains_type(signature, body, "h"): return body, [] unix_fds: list[Any] = [] def _replace(fd: Any) -> int: try: return unix_fds.index(fd) except ValueError: unix_fds.append(fd) return len(unix_fds) - 1 _replace_fds(body, signature.types, _replace) # type: ignore[union-attr] return body, unix_fds def replace_idx_with_fds( signature: str | SignatureTree, body: list[Any], unix_fds: list[Any] ) -> list[Any]: """Take the low level body format and return the high level body format. Type 'h' refers to an index in the unix_fds array. Replace those with the actual file descriptor or `None` if one does not exist.""" if type(signature) is str: signature = get_signature_tree(signature) if not signature_contains_type(signature, body, "h"): return body def _replace(idx: int) -> Any: try: return unix_fds[idx] except IndexError: return None _replace_fds(body, signature.types, _replace) # type: ignore[union-attr] return body def parse_annotation(annotation: str) -> str: """ Because of PEP 563, if `from __future__ import annotations` is used in code or on Python version >=3.10 where this is the default, return annotations from the `inspect` module will return annotations as "forward definitions". In this case, we must eval the result which we do only when given a string constant. """ def raise_value_error() -> None: raise ValueError( f"service annotations must be a string constant (got {annotation})" ) if not annotation or annotation is inspect.Signature.empty: return "" if type(annotation) is not str: raise_value_error() try: body = ast.parse(annotation).body if len(body) == 1 and type(body[0].value) is ast.Constant: # type: ignore[attr-defined] if type(body[0].value.value) is not str: # type: ignore[attr-defined] raise_value_error() return body[0].value.value # type: ignore[attr-defined] except SyntaxError: pass return annotation def _replace_fds( body_obj: dict[Any, Any] | list[Any], children: list[SignatureType], replace_fn: Callable[[Any], Any], ) -> None: """Replace any type 'h' with the value returned by replace_fn() given the value of the fd field. This is used by the high level interfaces which allow type 'h' to be the fd directly instead of an index in an external array such as in the spec.""" for index, st in enumerate(children): if not any(sig in st.signature for sig in "hv"): continue if st.signature == "h": body_obj[index] = replace_fn(body_obj[index]) elif st.token == "a": if st.children[0].token == "{": _replace_fds(body_obj[index], st.children, replace_fn) else: for i, child in enumerate(body_obj[index]): if st.signature == "ah": body_obj[index][i] = replace_fn(child) else: _replace_fds([child], st.children, replace_fn) elif st.token in "(": _replace_fds(body_obj[index], st.children, replace_fn) elif st.token in "{": for key, value in list(body_obj.items()): # type: ignore[union-attr] body_obj.pop(key) if st.children[0].signature == "h": key = replace_fn(key) if st.children[1].signature == "h": value = replace_fn(value) else: _replace_fds([value], [st.children[1]], replace_fn) body_obj[key] = value elif st.signature == "v": if body_obj[index].signature == "h": body_obj[index].value = replace_fn(body_obj[index].value) else: _replace_fds( [body_obj[index].value], [body_obj[index].type], replace_fn ) elif st.children: _replace_fds(body_obj[index], st.children, replace_fn) dbus-fast-2.44.1/src/dbus_fast/aio/000077500000000000000000000000001477355613200170205ustar00rootroot00000000000000dbus-fast-2.44.1/src/dbus_fast/aio/__init__.py000066400000000000000000000003061477355613200211300ustar00rootroot00000000000000from __future__ import annotations from .message_bus import MessageBus as MessageBus from .proxy_object import ProxyInterface as ProxyInterface from .proxy_object import ProxyObject as ProxyObject dbus-fast-2.44.1/src/dbus_fast/aio/message_bus.py000066400000000000000000000510041477355613200216670ustar00rootroot00000000000000from __future__ import annotations import array import asyncio import contextlib import logging import socket from collections import deque from copy import copy from functools import partial from typing import Any, Callable from .. import introspection as intr from ..auth import Authenticator, AuthExternal from ..constants import ( BusType, MessageFlag, MessageType, NameFlag, ReleaseNameReply, RequestNameReply, ) from ..errors import AuthError from ..message import Message from ..message_bus import BaseMessageBus, _block_unexpected_reply from ..service import ServiceInterface, _Method from .message_reader import build_message_reader from .proxy_object import ProxyObject NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value _LOGGER = logging.getLogger(__name__) def _generate_hello_serialized(next_serial: int) -> bytes: return bytes( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="Hello", serial=next_serial, )._marshall(False) ) HELLO_1_SERIALIZED = _generate_hello_serialized(1) def _future_set_exception(fut: asyncio.Future, exc: Exception) -> None: if fut is not None and not fut.done(): fut.set_exception(exc) def _future_set_result(fut: asyncio.Future, result: Any) -> None: if fut is not None and not fut.done(): fut.set_result(result) class _MessageWriter: """A class to handle writing messages to the message bus.""" def __init__(self, bus: MessageBus) -> None: """A class to handle writing messages to the message bus.""" self.messages: deque[ tuple[bytearray, list[int] | None, asyncio.Future | None] ] = deque() self.negotiate_unix_fd = bus._negotiate_unix_fd self.bus = bus self.sock = bus._sock self.loop = bus._loop self.buf: memoryview | None = None self.fd = bus._fd self.offset = 0 self.unix_fds: list[int] | None = None self.fut: asyncio.Future | None = None def write_callback(self, remove_writer: bool = True) -> None: """The callback to write messages to the message bus.""" sock = self.sock try: while True: if self.buf is None: # If there is no buffer, get the next message if not self.messages: # nothing more to write if remove_writer: self.loop.remove_writer(self.fd) return # Get the next message buf, unix_fds, fut = self.messages.popleft() self.unix_fds = unix_fds self.buf = memoryview(buf) self.offset = 0 self.fut = fut if self.unix_fds and self.negotiate_unix_fd: ancdata = [ ( socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", self.unix_fds), ) ] self.offset += sock.sendmsg([self.buf[self.offset :]], ancdata) self.unix_fds = None else: self.offset += sock.send(self.buf[self.offset :]) if self.offset < len(self.buf): # wait for writable return # finished writing self.buf = None _future_set_result(self.fut, None) except Exception as e: if self.bus._user_disconnect: _future_set_result(self.fut, None) else: _future_set_exception(self.fut, e) self.bus._finalize(e) def buffer_message( self, msg: Message, future: asyncio.Future | None = None ) -> None: """Buffer a message to be sent later.""" unix_fds = msg.unix_fds self.messages.append( ( msg._marshall(self.negotiate_unix_fd), copy(unix_fds) if unix_fds else None, future, ) ) def _write_without_remove_writer(self) -> None: """Call the write callback without removing the writer.""" self.write_callback(remove_writer=False) def schedule_write( self, msg: Message | None = None, future: asyncio.Future | None = None ) -> None: """Schedule a message to be written.""" queue_is_empty = not self.messages if msg is not None: self.buffer_message(msg, future) if self.bus.unique_name: # Optimization: try to send now if the queue # is empty. With bleak this usually means we # can send right away 99% of the time which # is a huge improvement in latency. if queue_is_empty: self._write_without_remove_writer() if ( self.buf is not None or self.messages or not self.fut or not self.fut.done() ): self.loop.add_writer(self.fd, self.write_callback) class MessageBus(BaseMessageBus): """The message bus implementation for use with asyncio. The message bus class is the entry point into all the features of the library. It sets up a connection to the DBus daemon and exposes an interface to send and receive messages and expose services. You must call :func:`connect() ` before using this message bus. :param bus_type: The type of bus to connect to. Affects the search path for the bus address. :type bus_type: :class:`BusType ` :param bus_address: A specific bus address to connect to. Should not be used under normal circumstances. :param auth: The authenticator to use, defaults to an instance of :class:`AuthExternal `. :type auth: :class:`Authenticator ` :param negotiate_unix_fd: Allow the bus to send and receive Unix file descriptors (DBus type 'h'). This must be supported by the transport. :type negotiate_unix_fd: bool :ivar unique_name: The unique name of the message bus connection. It will be :class:`None` until the message bus connects. :vartype unique_name: str :ivar connected: True if this message bus is expected to be able to send and receive messages. :vartype connected: bool """ __slots__ = ("_auth", "_disconnect_future", "_loop", "_pending_futures", "_writer") def __init__( self, bus_address: str | None = None, bus_type: BusType = BusType.SESSION, auth: Authenticator | None = None, negotiate_unix_fd: bool = False, ) -> None: super().__init__(bus_address, bus_type, ProxyObject, negotiate_unix_fd) self._loop = asyncio.get_running_loop() self._writer = _MessageWriter(self) if auth is None: self._auth = AuthExternal() else: self._auth = auth self._disconnect_future = self._loop.create_future() self._pending_futures: set[asyncio.Future] = set() async def connect(self) -> MessageBus: """Connect this message bus to the DBus daemon. This method must be called before the message bus can be used. :returns: This message bus for convenience. :rtype: :class:`MessageBus ` :raises: - :class:`AuthError ` - If authorization to \ the DBus daemon failed. - :class:`Exception` - If there was a connection error. """ await self._authenticate() future = self._loop.create_future() self._loop.add_reader( self._fd, build_message_reader( self._sock, self._process_message, self._finalize, self._negotiate_unix_fd, ), ) def on_hello(reply, err): try: if err: raise err self.unique_name = reply.body[0] self._writer.schedule_write() _future_set_result(future, self) except Exception as e: _future_set_exception(future, e) self.disconnect() self._finalize(err) next_serial = self.next_serial() self._method_return_handlers[next_serial] = on_hello if next_serial == 1: serialized = HELLO_1_SERIALIZED else: serialized = _generate_hello_serialized(next_serial) self._stream.write(serialized) self._stream.flush() return await future async def introspect( self, bus_name: str, path: str, timeout: float = 30.0, validate_property_names: bool = True, ) -> intr.Node: """Get introspection data for the node at the given path from the given bus name. Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect`` on the bus for the path. :param bus_name: The name to introspect. :type bus_name: str :param path: The path to introspect. :type path: str :param timeout: The timeout to introspect. :type timeout: float :param validate_property_names: Whether to validate property names or not. :type validate_property_names: bool :returns: The introspection data for the name at the path. :rtype: :class:`Node ` :raises: - :class:`InvalidObjectPathError ` \ - If the given object path is not valid. - :class:`InvalidBusNameError ` - If \ the given bus name is not valid. - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. - :class:`asyncio.TimeoutError` - Waited for future but time run out. """ future = self._loop.create_future() super().introspect( bus_name, path, partial(self._reply_handler, future), check_callback_type=False, validate_property_names=validate_property_names, ) timer_handle = self._loop.call_later( timeout, _future_set_exception, future, asyncio.TimeoutError ) try: return await future finally: timer_handle.cancel() async def request_name( self, name: str, flags: NameFlag = NameFlag.NONE ) -> RequestNameReply: """Request that this message bus owns the given name. :param name: The name to request. :type name: str :param flags: Name flags that affect the behavior of the name request. :type flags: :class:`NameFlag ` :returns: The reply to the name request. :rtype: :class:`RequestNameReply ` :raises: - :class:`InvalidBusNameError ` - If \ the given bus name is not valid. - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. """ future = self._loop.create_future() super().request_name( name, flags, partial(self._reply_handler, future), check_callback_type=False ) return await future async def release_name(self, name: str) -> ReleaseNameReply: """Request that this message bus release the given name. :param name: The name to release. :type name: str :returns: The reply to the release request. :rtype: :class:`ReleaseNameReply ` :raises: - :class:`InvalidBusNameError ` - If \ the given bus name is not valid. - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. """ future = self._loop.create_future() super().release_name( name, partial(self._reply_handler, future), check_callback_type=False ) return await future async def call(self, msg: Message) -> Message | None: """Send a method call and wait for a reply from the DBus daemon. :param msg: The method call message to send. :type msg: :class:`Message ` :returns: A message in reply to the message sent. If the message does not expect a reply based on the message flags or type, returns ``None`` after the message is sent. :rtype: :class:`Message ` or :class:`None` if no reply is expected. :raises: - :class:`Exception` - If a connection error occurred. """ if ( msg.flags.value & NO_REPLY_EXPECTED_VALUE or msg.message_type is not MessageType.METHOD_CALL ): await self.send(msg) return None future = self._loop.create_future() self._call(msg, partial(self._reply_handler, future)) await future return future.result() def send(self, msg: Message) -> asyncio.Future: """Asynchronously send a message on the message bus. .. note:: This method may change to a couroutine function in the 1.0 release of the library. :param msg: The message to send. :type msg: :class:`Message ` :returns: A future that resolves when the message is sent or a connection error occurs. :rtype: :class:`Future ` """ if not msg.serial: msg.serial = self.next_serial() future = self._loop.create_future() self._writer.schedule_write(msg, future) return future def get_proxy_object( self, bus_name: str, path: str, introspection: intr.Node ) -> ProxyObject: return super().get_proxy_object(bus_name, path, introspection) async def wait_for_disconnect(self): """Wait for the message bus to disconnect. :returns: :class:`None` when the message bus has disconnected. :rtype: :class:`None` :raises: - :class:`Exception` - If connection was terminated unexpectedly or \ an internal error occurred in the library. """ return await self._disconnect_future def _future_exception_no_reply(self, fut: asyncio.Future) -> None: """Log an exception from a future that was not expected.""" self._pending_futures.discard(fut) try: fut.result() except asyncio.CancelledError: pass except Exception as e: _LOGGER.exception("unexpected exception in future", exc_info=e) def _make_method_handler( self, interface: ServiceInterface, method: _Method ) -> Callable[[Message, Callable[[Message], None]], None]: if not asyncio.iscoroutinefunction(method.fn): return super()._make_method_handler(interface, method) negotiate_unix_fd = self._negotiate_unix_fd msg_body_to_args = ServiceInterface._msg_body_to_args fn_result_to_body = ServiceInterface._fn_result_to_body def _coroutine_method_handler( msg: Message, send_reply: Callable[[Message], None] ) -> None: """A coroutine method handler.""" args = msg_body_to_args(msg) if msg.unix_fds else msg.body fut: asyncio.Future = asyncio.ensure_future(method.fn(interface, *args)) # Hold a strong reference to the future to ensure # it is not garbage collected before it is done. self._pending_futures.add(fut) if ( send_reply is _block_unexpected_reply or msg.flags.value & NO_REPLY_EXPECTED_VALUE ): fut.add_done_callback(self._future_exception_no_reply) return # We only create the closure function if we are actually going to reply def _done(fut: asyncio.Future) -> None: """The callback for when the method is done.""" with send_reply: result = fut.result() body, unix_fds = fn_result_to_body( result, method.out_signature_tree, replace_fds=negotiate_unix_fd ) send_reply( Message.new_method_return( msg, method.out_signature, body, unix_fds ) ) fut.add_done_callback(_done) # Discard the future only after running the done callback fut.add_done_callback(self._pending_futures.discard) return _coroutine_method_handler async def _auth_readline(self) -> str: buf = b"" while buf[-2:] != b"\r\n": # The auth protocol is line based, so we can read until we get a # newline. buf += await self._loop.sock_recv(self._sock, 1024) return buf[:-2].decode() async def _authenticate(self) -> None: await self._loop.sock_sendall(self._sock, b"\0") first_line = self._auth._authentication_start( negotiate_unix_fd=self._negotiate_unix_fd ) if first_line is not None: if type(first_line) is not str: raise AuthError("authenticator gave response not type str") await self._loop.sock_sendall( self._sock, Authenticator._format_line(first_line) ) while True: response = self._auth._receive_line(await self._auth_readline()) if response is not None: await self._loop.sock_sendall( self._sock, Authenticator._format_line(response) ) self._stream.flush() if response == "BEGIN": # The first octet received by the server after the \r\n of the BEGIN command # from the client must be the first octet of the authenticated/encrypted stream # of D-Bus messages. break def disconnect(self) -> None: """Disconnect the message bus by closing the underlying connection asynchronously. All pending and future calls will error with a connection error. """ super().disconnect() try: self._sock.close() except Exception: _LOGGER.warning("could not close socket", exc_info=True) def _finalize(self, err: Exception | None = None) -> None: try: self._loop.remove_reader(self._fd) except Exception: _LOGGER.warning("could not remove message reader", exc_info=True) try: self._loop.remove_writer(self._fd) except Exception: _LOGGER.warning("could not remove message writer", exc_info=True) had_handlers = bool(self._method_return_handlers or self._user_message_handlers) super()._finalize(err) if self._disconnect_future.done(): return if err and not self._user_disconnect: _future_set_exception(self._disconnect_future, err) # If this happens during a reply, the message handlers # will have the exception set and wait_for_disconnect will # never be called so we need to manually set the exception # as retrieved to avoid asyncio warnings when the future # is garbage collected. if had_handlers: with contextlib.suppress(Exception): self._disconnect_future.exception() else: _future_set_result(self._disconnect_future, None) def _reply_handler( self, future: asyncio.Future, reply: Any | None, err: Exception | None ) -> None: """The reply handler for method calls.""" if err: _future_set_exception(future, err) else: _future_set_result(future, reply) dbus-fast-2.44.1/src/dbus_fast/aio/message_reader.pxd000066400000000000000000000003421477355613200225020ustar00rootroot00000000000000"""cdefs for message_reader.py""" import cython from .._private.unmarshaller cimport Unmarshaller cpdef _message_reader( Unmarshaller unmarshaller, object process, object finalize, bint negotiate_unix_fd ) dbus-fast-2.44.1/src/dbus_fast/aio/message_reader.py000066400000000000000000000032051477355613200223400ustar00rootroot00000000000000from __future__ import annotations import logging import socket from functools import partial from typing import Callable from .._private.unmarshaller import Unmarshaller from ..message import Message _LOGGER = logging.getLogger(__name__) def _message_reader( unmarshaller: Unmarshaller, process: Callable[[Message], None], finalize: Callable[[Exception | None], None], negotiate_unix_fd: bool, ) -> None: """Reads messages from the unmarshaller and passes them to the process function.""" try: while True: message = unmarshaller._unmarshall() if message is None: return try: process(message) except Exception: _LOGGER.error("Unexpected error processing message: %s", exc_info=True) # If we are not negotiating unix fds, we can stop reading as soon as we have # the buffer is empty as asyncio will call us again when there is more data. if ( not negotiate_unix_fd and not unmarshaller._has_another_message_in_buffer() ): return except Exception as e: finalize(e) def build_message_reader( sock: socket.socket | None, process: Callable[[Message], None], finalize: Callable[[Exception | None], None], negotiate_unix_fd: bool, ) -> Callable[[], None]: """Build a callable that reads messages from the unmarshaller and passes them to the process function.""" unmarshaller = Unmarshaller(None, sock, negotiate_unix_fd) return partial(_message_reader, unmarshaller, process, finalize, negotiate_unix_fd) dbus-fast-2.44.1/src/dbus_fast/aio/proxy_object.py000066400000000000000000000156231477355613200221100ustar00rootroot00000000000000from __future__ import annotations import xml.etree.ElementTree as ET from typing import TYPE_CHECKING, Any from .. import introspection as intr from .._private.util import replace_fds_with_idx, replace_idx_with_fds from ..constants import ErrorType, MessageFlag from ..errors import DBusError from ..message import Message from ..message_bus import BaseMessageBus from ..proxy_object import BaseProxyInterface, BaseProxyObject from ..signature import Variant from ..unpack import unpack_variants as unpack if TYPE_CHECKING: from .message_bus import MessageBus as AioMessageBus NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value class ProxyInterface(BaseProxyInterface): """A class representing a proxy to an interface exported on the bus by another client for the asyncio :class:`MessageBus ` implementation. This class is not meant to be constructed directly by the user. Use :func:`ProxyObject.get_interface() ` on a asyncio proxy object to get a proxy interface. This class exposes methods to call DBus methods, listen to signals, and get and set properties on the interface that are created dynamically based on the introspection data passed to the proxy object that made this proxy interface. A *method call* takes this form: .. code-block:: python3 result = await interface.call_[METHOD](*args) Where ``METHOD`` is the name of the method converted to snake case. DBus methods are exposed as coroutines that take arguments that correpond to the *in args* of the interface method definition and return a ``result`` that corresponds to the *out arg*. If the method has more than one out arg, they are returned within a :class:`list`. To *listen to a signal* use this form: .. code-block:: python3 interface.on_[SIGNAL](callback) To *stop listening to a signal* use this form: .. code-block:: python3 interface.off_[SIGNAL](callback) Where ``SIGNAL`` is the name of the signal converted to snake case. DBus signals are exposed with an event-callback interface. The provided ``callback`` will be called when the signal is emitted with arguments that correspond to the *out args* of the interface signal definition. To *get or set a property* use this form: .. code-block:: python3 value = await interface.get_[PROPERTY]() await interface.set_[PROPERTY](value) Where ``PROPERTY`` is the name of the property converted to snake case. DBus property getters and setters are exposed as coroutines. The ``value`` must correspond to the type of the property in the interface definition. If the service returns an error for a DBus call, a :class:`DBusError ` will be raised with information about the error. """ bus: AioMessageBus def _add_method(self, intr_method: intr.Method) -> None: async def method_fn( *args, flags=MessageFlag.NONE, unpack_variants: bool = False ): input_body, unix_fds = replace_fds_with_idx( intr_method.in_signature, list(args) ) msg = await self.bus.call( Message( destination=self.bus_name, path=self.path, interface=self.introspection.name, member=intr_method.name, signature=intr_method.in_signature, body=input_body, flags=flags, unix_fds=unix_fds, ) ) if flags is not None and flags.value & NO_REPLY_EXPECTED_VALUE: return None BaseProxyInterface._check_method_return(msg, intr_method.out_signature) out_len = len(intr_method.out_args) body = replace_idx_with_fds(msg.signature_tree, msg.body, msg.unix_fds) if not out_len: return None if unpack_variants: body = unpack(body) if out_len == 1: return body[0] return body method_name = f"call_{BaseProxyInterface._to_snake_case(intr_method.name)}" setattr(self, method_name, method_fn) def _add_property( self, intr_property: intr.Property, ) -> None: async def property_getter( *, flags=MessageFlag.NONE, unpack_variants: bool = False ): msg = await self.bus.call( Message( destination=self.bus_name, path=self.path, interface="org.freedesktop.DBus.Properties", member="Get", signature="ss", body=[self.introspection.name, intr_property.name], ) ) BaseProxyInterface._check_method_return(msg, "v") variant = msg.body[0] if variant.signature != intr_property.signature: raise DBusError( ErrorType.CLIENT_ERROR, f'property returned unexpected signature "{variant.signature}"', msg, ) body = replace_idx_with_fds("v", msg.body, msg.unix_fds)[0].value if unpack_variants: return unpack(body) return body async def property_setter(val: Any) -> None: variant = Variant(intr_property.signature, val) body, unix_fds = replace_fds_with_idx( "ssv", [self.introspection.name, intr_property.name, variant] ) msg = await self.bus.call( Message( destination=self.bus_name, path=self.path, interface="org.freedesktop.DBus.Properties", member="Set", signature="ssv", body=body, unix_fds=unix_fds, ) ) BaseProxyInterface._check_method_return(msg) snake_case = BaseProxyInterface._to_snake_case(intr_property.name) setattr(self, f"get_{snake_case}", property_getter) setattr(self, f"set_{snake_case}", property_setter) class ProxyObject(BaseProxyObject): """The proxy object implementation for the GLib :class:`MessageBus `. For more information, see the :class:`BaseProxyObject `. """ def __init__( self, bus_name: str, path: str, introspection: intr.Node | str | ET.Element, bus: BaseMessageBus, ) -> None: super().__init__(bus_name, path, introspection, bus, ProxyInterface) def get_interface(self, name: str) -> ProxyInterface: return super().get_interface(name) def get_children(self) -> list[ProxyObject]: return super().get_children() dbus-fast-2.44.1/src/dbus_fast/auth.py000066400000000000000000000104251477355613200175650ustar00rootroot00000000000000import enum import os from typing import Optional from .errors import AuthError UID_NOT_SPECIFIED = -1 # The auth interface here is unstable. I would like to eventually open this up # for people to define their own custom authentication protocols, but I'm not # familiar with what's needed for that exactly. To work with any message bus # implementation would require abstracting out all the IO. Async operations # might be challenging because different IO backends have different ways of # doing that. I might just end up giving the raw socket and leaving it all up # to the user, but it would be nice to have a little guidance in the interface # since a lot of it is strongly specified. If you have a need for this, contact # the project maintainer to help stabilize this interface. class _AuthResponse(enum.Enum): OK = "OK" REJECTED = "REJECTED" DATA = "DATA" ERROR = "ERROR" AGREE_UNIX_FD = "AGREE_UNIX_FD" @classmethod def parse(klass, line: str) -> tuple["_AuthResponse", list[str]]: args = line.split(" ") response = klass(args[0]) return response, args[1:] # UNSTABLE class Authenticator: """The base class for authenticators for :class:`MessageBus ` authentication. In the future, the library may allow extending this class for custom authentication protocols. :seealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol """ def _authentication_start(self, negotiate_unix_fd: bool = False) -> str: raise NotImplementedError( "authentication_start() must be implemented in the inheriting class" ) def _receive_line(self, line: str) -> str: raise NotImplementedError( "receive_line() must be implemented in the inheriting class" ) @staticmethod def _format_line(line: str) -> bytes: return f"{line}\r\n".encode() class AuthExternal(Authenticator): """An authenticator class for the external auth protocol for use with the :class:`MessageBus `. :param uid: The uid to use when connecting to the message bus. Use UID_NOT_SPECIFIED to use the uid known to the kernel. :vartype uid: int :sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol """ def __init__(self, uid: Optional[int] = None) -> None: self.negotiate_unix_fd: bool = False self.negotiating_fds: bool = False self.uid: Optional[int] = uid def _authentication_start(self, negotiate_unix_fd: bool = False) -> str: self.negotiate_unix_fd = negotiate_unix_fd uid = self.uid if uid == UID_NOT_SPECIFIED: return "AUTH EXTERNAL" if uid is None: uid = os.getuid() hex_uid = str(uid).encode().hex() return f"AUTH EXTERNAL {hex_uid}" def _receive_line(self, line: str) -> str: response, args = _AuthResponse.parse(line) if response is _AuthResponse.OK: if self.negotiate_unix_fd: self.negotiating_fds = True return "NEGOTIATE_UNIX_FD" return "BEGIN" if response is _AuthResponse.AGREE_UNIX_FD: return "BEGIN" if response is _AuthResponse.DATA and self.uid == UID_NOT_SPECIFIED: return "DATA" raise AuthError(f"authentication failed: {response.value}: {args}") class AuthAnonymous(Authenticator): """An authenticator class for the anonymous auth protocol for use with the :class:`MessageBus `. :sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol """ def _authentication_start(self, negotiate_unix_fd: bool = False) -> str: if negotiate_unix_fd: raise AuthError( "anonymous authentication does not support negotiating unix fds right now" ) return "AUTH ANONYMOUS" def _receive_line(self, line: str) -> str: response, args = _AuthResponse.parse(line) if response != _AuthResponse.OK: raise AuthError(f"authentication failed: {response.value}: {args}") return "BEGIN" # The following line provides backwards compatibility, remove at some point? --jrd AuthAnnonymous = AuthAnonymous dbus-fast-2.44.1/src/dbus_fast/constants.py000066400000000000000000000136621477355613200206460ustar00rootroot00000000000000from enum import Enum, IntFlag from functools import cached_property class BusType(Enum): """An enum that indicates a type of bus. On most systems, there are normally two different kinds of buses running. """ SESSION = 1 #: A bus for the current graphical user session. SYSTEM = 2 #: A persistent bus for the whole machine. class MessageType(Enum): """An enum that indicates a type of message.""" METHOD_CALL = 1 #: An outgoing method call. METHOD_RETURN = 2 #: A return to a previously sent method call ERROR = 3 #: A return to a method call that has failed SIGNAL = 4 #: A broadcast signal to subscribed connections @cached_property def value(self) -> int: """Return the value.""" return self._value_ MESSAGE_TYPE_MAP = {field.value: field for field in MessageType} class MessageFlag(IntFlag): """Flags that affect the behavior of sent and received messages""" NONE = 0 NO_REPLY_EXPECTED = 1 #: The method call does not expect a method return. NO_AUTOSTART = 2 ALLOW_INTERACTIVE_AUTHORIZATION = 4 @cached_property def value(self) -> int: """Return the value.""" return self._value_ # This is written out because of https://github.com/python/cpython/issues/98976 MESSAGE_FLAG_MAP = { 0: MessageFlag.NONE, 1: MessageFlag.NO_REPLY_EXPECTED, 2: MessageFlag.NO_AUTOSTART, 4: MessageFlag.ALLOW_INTERACTIVE_AUTHORIZATION, } class NameFlag(IntFlag): """A flag that affects the behavior of a name request.""" NONE = 0 ALLOW_REPLACEMENT = 1 #: If another client requests this name, let them have it. REPLACE_EXISTING = 2 #: If another client owns this name, try to take it. DO_NOT_QUEUE = 4 #: Name requests normally queue and wait for the owner to release the name. Do not enter this queue. class RequestNameReply(Enum): """An enum that describes the result of a name request.""" PRIMARY_OWNER = 1 #: The bus owns the name. IN_QUEUE = 2 #: The bus is in a queue and may receive the name after it is relased by the primary owner. EXISTS = 3 #: The name has an owner and NameFlag.DO_NOT_QUEUE was given. ALREADY_OWNER = 4 #: The bus already owns the name. class ReleaseNameReply(Enum): """An enum that describes the result of a name release request""" RELEASED = 1 NON_EXISTENT = 2 NOT_OWNER = 3 class PropertyAccess(Enum): """An enum that describes whether a DBus property can be gotten or set with the ``org.freedesktop.DBus.Properties`` interface. """ READ = "read" #: The property is readonly. WRITE = "write" #: The property is writeonly. READWRITE = "readwrite" #: The property can be read or written to. def readable(self) -> bool: """Get whether the property can be read.""" return self == PropertyAccess.READ or self == PropertyAccess.READWRITE def writable(self) -> bool: """Get whether the property can be written to.""" return self == PropertyAccess.WRITE or self == PropertyAccess.READWRITE class ArgDirection(Enum): """For an introspected argument, indicates whether it is an input parameter or a return value.""" IN = "in" OUT = "out" class ErrorType(str, Enum): """An enum for the type of an error for a message reply. :seealso: http://man7.org/linux/man-pages/man3/sd-bus-errors.3.html """ SERVICE_ERROR = "com.dubstepdish.dbus.next.ServiceError" #: A custom error to indicate an exported service threw an exception. INTERNAL_ERROR = "com.dubstepdish.dbus.next.InternalError" #: A custom error to indicate something went wrong with the library. CLIENT_ERROR = "com.dubstepdish.dbus.next.ClientError" #: A custom error to indicate something went wrong with the client. FAILED = "org.freedesktop.DBus.Error.Failed" NO_MEMORY = "org.freedesktop.DBus.Error.NoMemory" SERVICE_UNKNOWN = "org.freedesktop.DBus.Error.ServiceUnknown" NAME_HAS_NO_OWNER = "org.freedesktop.DBus.Error.NameHasNoOwner" NO_REPLY = "org.freedesktop.DBus.Error.NoReply" IO_ERROR = "org.freedesktop.DBus.Error.IOError" BAD_ADDRESS = "org.freedesktop.DBus.Error.BadAddress" NOT_SUPPORTED = "org.freedesktop.DBus.Error.NotSupported" LIMITS_EXCEEDED = "org.freedesktop.DBus.Error.LimitsExceeded" ACCESS_DENIED = "org.freedesktop.DBus.Error.AccessDenied" AUTH_FAILED = "org.freedesktop.DBus.Error.AuthFailed" NO_SERVER = "org.freedesktop.DBus.Error.NoServer" TIMEOUT = "org.freedesktop.DBus.Error.Timeout" NO_NETWORK = "org.freedesktop.DBus.Error.NoNetwork" ADDRESS_IN_USE = "org.freedesktop.DBus.Error.AddressInUse" DISCONNECTED = "org.freedesktop.DBus.Error.Disconnected" INVALID_ARGS = "org.freedesktop.DBus.Error.InvalidArgs" FILE_NOT_FOUND = "org.freedesktop.DBus.Error.FileNotFound" FILE_EXISTS = "org.freedesktop.DBus.Error.FileExists" UNKNOWN_METHOD = "org.freedesktop.DBus.Error.UnknownMethod" UNKNOWN_OBJECT = "org.freedesktop.DBus.Error.UnknownObject" UNKNOWN_INTERFACE = "org.freedesktop.DBus.Error.UnknownInterface" UNKNOWN_PROPERTY = "org.freedesktop.DBus.Error.UnknownProperty" PROPERTY_READ_ONLY = "org.freedesktop.DBus.Error.PropertyReadOnly" UNIX_PROCESS_ID_UNKNOWN = "org.freedesktop.DBus.Error.UnixProcessIdUnknown" INVALID_SIGNATURE = "org.freedesktop.DBus.Error.InvalidSignature" INCONSISTENT_MESSAGE = "org.freedesktop.DBus.Error.InconsistentMessage" TIMED_OUT = "org.freedesktop.DBus.Error.TimedOut" MATCH_RULE_NOT_FOUND = "org.freedesktop.DBus.Error.MatchRuleNotFound" MATCH_RULE_INVALID = "org.freedesktop.DBus.Error.MatchRuleInvalid" INTERACTIVE_AUTHORIZATION_REQUIRED = ( "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired" ) INVALID_FILE_CONTENT = "org.freedesktop.DBus.Error.InvalidFileContent" SELINUX_SECURITY_CONTEXT_UNKNOWN = ( "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" ) OBJECT_PATH_IN_USE = "org.freedesktop.DBus.Error.ObjectPathInUse" dbus-fast-2.44.1/src/dbus_fast/errors.py000066400000000000000000000037501477355613200201430ustar00rootroot00000000000000from typing import Optional, Union class SignatureBodyMismatchError(ValueError): pass class InvalidSignatureError(ValueError): pass class InvalidAddressError(ValueError): pass class AuthError(Exception): pass class InvalidMessageError(ValueError): pass class InvalidIntrospectionError(ValueError): pass class InterfaceNotFoundError(Exception): pass class SignalDisabledError(Exception): pass class InvalidBusNameError(TypeError): def __init__(self, name: str) -> None: super().__init__(f"invalid bus name: {name}") class InvalidObjectPathError(TypeError): def __init__(self, path: str) -> None: super().__init__(f"invalid object path: {path}") class InvalidInterfaceNameError(TypeError): def __init__(self, name: str) -> None: super().__init__(f"invalid interface name: {name}") class InvalidMemberNameError(TypeError): def __init__(self, member: str) -> None: super().__init__(f"invalid member name: {member}") from .constants import ErrorType, MessageType # noqa: E402 from .message import Message # noqa: E402 from .validators import assert_interface_name_valid # noqa: E402 class DBusError(Exception): def __init__( self, type_: Union[ErrorType, str], text: str, reply: Optional[Message] = None ) -> None: super().__init__(text) if type(type_) is ErrorType: type_ = type_.value assert_interface_name_valid(type_) # type: ignore[arg-type] if reply is not None and type(reply) is not Message: raise TypeError("reply must be of type Message") self.type = type_ self.text = text self.reply = reply @staticmethod def _from_message(msg: Message) -> "DBusError": assert msg.message_type == MessageType.ERROR return DBusError(msg.error_name or "unknown", msg.body[0], reply=msg) def _as_message(self, msg: Message) -> Message: return Message.new_error(msg, self.type, self.text) dbus-fast-2.44.1/src/dbus_fast/glib/000077500000000000000000000000001477355613200171655ustar00rootroot00000000000000dbus-fast-2.44.1/src/dbus_fast/glib/__init__.py000066400000000000000000000002421477355613200212740ustar00rootroot00000000000000from .message_bus import MessageBus as MessageBus from .proxy_object import ProxyInterface as ProxyInterface from .proxy_object import ProxyObject as ProxyObject dbus-fast-2.44.1/src/dbus_fast/glib/message_bus.py000066400000000000000000000401251477355613200220360ustar00rootroot00000000000000import io import logging import traceback from typing import Callable, Optional from .. import introspection as intr from .._private.unmarshaller import Unmarshaller from ..auth import Authenticator, AuthExternal from ..constants import ( BusType, MessageFlag, MessageType, NameFlag, ReleaseNameReply, RequestNameReply, ) from ..errors import AuthError from ..message import Message from ..message_bus import BaseMessageBus from .proxy_object import ProxyObject _LOGGER = logging.getLogger(__name__) # glib is optional _import_error = None try: from gi.repository import GLib _GLibSource = GLib.Source except ImportError as e: _import_error = e class _GLibSource: pass class _MessageSource(_GLibSource): def __init__(self, bus): self.unmarshaller = None self.bus = bus def prepare(self): return (False, -1) def check(self): return False def dispatch(self, callback, user_data): try: while self.bus._stream.readable(): if not self.unmarshaller: self.unmarshaller = Unmarshaller(self.bus._stream) message = self.unmarshaller.unmarshall() if message: callback(message) self.unmarshaller = None else: break except Exception as e: self.bus.disconnect() self.bus._finalize(e) return GLib.SOURCE_REMOVE return GLib.SOURCE_CONTINUE class _MessageWritableSource(_GLibSource): def __init__(self, bus): self.bus = bus self.buf = b"" self.message_stream = None self.chunk_size = 128 def prepare(self): return (False, -1) def check(self): return False def dispatch(self, callback, user_data): try: if self.buf: self.bus._stream.write(self.buf) self.buf = b"" if self.message_stream: while True: self.buf = self.message_stream.read(self.chunk_size) if self.buf == b"": break self.bus._stream.write(self.buf) if len(self.buf) < self.chunk_size: self.buf = b"" break self.buf = b"" self.bus._stream.flush() if not self.bus._buffered_messages: return GLib.SOURCE_REMOVE message = self.bus._buffered_messages.pop(0) self.message_stream = io.BytesIO(message._marshall(False)) return GLib.SOURCE_CONTINUE except BlockingIOError: return GLib.SOURCE_CONTINUE except Exception as e: self.bus._finalize(e) return GLib.SOURCE_REMOVE class _AuthLineSource(_GLibSource): def __init__(self, stream): self.stream = stream self.buf = b"" def prepare(self): return (False, -1) def check(self): return False def dispatch(self, callback, user_data): self.buf += self.stream.read() if self.buf[-2:] == b"\r\n": resp = callback(self.buf.decode()[:-2]) if resp: return GLib.SOURCE_REMOVE return GLib.SOURCE_CONTINUE class MessageBus(BaseMessageBus): """The message bus implementation for use with the GLib main loop. The message bus class is the entry point into all the features of the library. It sets up a connection to the DBus daemon and exposes an interface to send and receive messages and expose services. You must call :func:`connect() ` or :func:`connect_sync() ` before using this message bus. :param bus_type: The type of bus to connect to. Affects the search path for the bus address. :type bus_type: :class:`BusType ` :param bus_address: A specific bus address to connect to. Should not be used under normal circumstances. :param auth: The authenticator to use, defaults to an instance of :class:`AuthExternal `. :type auth: :class:`Authenticator ` :ivar connected: True if this message bus is expected to be able to send and receive messages. :vartype connected: bool :ivar unique_name: The unique name of the message bus connection. It will be :class:`None` until the message bus connects. :vartype unique_name: str """ def __init__( self, bus_address: Optional[str] = None, bus_type: BusType = BusType.SESSION, auth: Optional[Authenticator] = None, ): if _import_error: raise _import_error super().__init__(bus_address, bus_type, ProxyObject) self._main_context = GLib.main_context_default() # buffer messages until connect self._buffered_messages = [] if auth is None: self._auth = AuthExternal() else: self._auth = auth def _on_message(self, msg: Message) -> None: try: self._process_message(msg) except Exception as e: _LOGGER.exception( f"got unexpected error processing a message: {e}.\n{traceback.format_exc()}" ) def connect( self, connect_notify: Optional[ Callable[["MessageBus", Optional[Exception]], None] ] = None, ): """Connect this message bus to the DBus daemon. This method or the synchronous version must be called before the message bus can be used. :param connect_notify: A callback that will be called with this message bus. May return an :class:`Exception` on connection errors or :class:`AuthError ` on authorization errors. :type callback: :class:`Callable` """ def authenticate_notify(exc): if exc is not None: if connect_notify is not None: connect_notify(None, exc) return self.message_source = _MessageSource(self) self.message_source.set_callback(self._on_message) self.message_source.attach(self._main_context) self.writable_source = None self.message_source.add_unix_fd(self._fd, GLib.IO_IN) def on_hello(reply, err): if err: if connect_notify: connect_notify(reply, err) return self.unique_name = reply.body[0] for m in self._buffered_messages: self.send(m) if connect_notify: connect_notify(self, err) hello_msg = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="Hello", serial=self.next_serial(), ) self._method_return_handlers[hello_msg.serial] = on_hello self._stream.write(hello_msg._marshall(False)) self._stream.flush() self._authenticate(authenticate_notify) def connect_sync(self) -> "MessageBus": """Connect this message bus to the DBus daemon. This method or the asynchronous version must be called before the message bus can be used. :returns: This message bus for convenience. :rtype: :class:`MessageBus ` :raises: - :class:`AuthError ` - If authorization to \ the DBus daemon failed. - :class:`Exception` - If there was a connection error. """ main = GLib.MainLoop() connection_error = None def connect_notify(bus, err): nonlocal connection_error connection_error = err main.quit() self.connect(connect_notify) main.run() if connection_error: raise connection_error return self def call( self, msg: Message, reply_notify: Optional[ Callable[[Optional[Message], Optional[Exception]], None] ] = None, ): """Send a method call and asynchronously wait for a reply from the DBus daemon. :param msg: The method call message to send. :type msg: :class:`Message ` :param reply_notify: A callback that will be called with the reply to this message. May return an :class:`Exception` on connection errors. :type reply_notify: Callable """ BaseMessageBus._check_callback_type(reply_notify) self._call(msg, reply_notify) def call_sync(self, msg: Message) -> Optional[Message]: """Send a method call and synchronously wait for a reply from the DBus daemon. :param msg: The method call message to send. :type msg: :class:`Message ` :returns: A message in reply to the message sent. If the message does not expect a reply based on the message flags or type, returns ``None`` immediately. :rtype: :class:`Message ` :raises: - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. """ if ( msg.flags & MessageFlag.NO_REPLY_EXPECTED or msg.message_type is not MessageType.METHOD_CALL ): self.send(msg) return None if not msg.serial: msg.serial = self.next_serial() main = GLib.MainLoop() handler_reply = None connection_error = None def reply_handler(reply, err): nonlocal handler_reply nonlocal connection_error handler_reply = reply connection_error = err main.quit() self._method_return_handlers[msg.serial] = reply_handler self.send(msg) main.run() if connection_error: raise connection_error return handler_reply def introspect_sync(self, bus_name: str, path: str) -> intr.Node: """Get introspection data for the node at the given path from the given bus name. Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect`` on the bus for the path. :param bus_name: The name to introspect. :type bus_name: str :param path: The path to introspect. :type path: str :returns: The introspection data for the name at the path. :rtype: :class:`Node ` :raises: - :class:`InvalidObjectPathError ` \ - If the given object path is not valid. - :class:`InvalidBusNameError ` - If \ the given bus name is not valid. - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. """ main = GLib.MainLoop() request_result = None request_error = None def reply_notify(result, err): nonlocal request_result nonlocal request_error request_result = result request_error = err main.quit() super().introspect(bus_name, path, reply_notify) main.run() if request_error: raise request_error return request_result def request_name_sync( self, name: str, flags: NameFlag = NameFlag.NONE ) -> RequestNameReply: """Request that this message bus owns the given name. :param name: The name to request. :type name: str :param flags: Name flags that affect the behavior of the name request. :type flags: :class:`NameFlag ` :returns: The reply to the name request. :rtype: :class:`RequestNameReply ` :raises: - :class:`InvalidBusNameError ` - If \ the given bus name is not valid. - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. """ main = GLib.MainLoop() request_result = None request_error = None def reply_notify(result, err): nonlocal request_result nonlocal request_error request_result = result request_error = err main.quit() super().request_name(name, flags, reply_notify) main.run() if request_error: raise request_error return request_result def release_name_sync(self, name: str) -> ReleaseNameReply: """Request that this message bus release the given name. :param name: The name to release. :type name: str :returns: The reply to the release request. :rtype: :class:`ReleaseNameReply ` :raises: - :class:`InvalidBusNameError ` - If \ the given bus name is not valid. - :class:`DBusError ` - If the service threw \ an error for the method call or returned an invalid result. - :class:`Exception` - If a connection error occurred. """ main = GLib.MainLoop() release_result = None release_error = None def reply_notify(result, err): nonlocal release_result nonlocal release_error release_result = result release_error = err main.quit() super().release_name(name, reply_notify) main.run() if release_error: raise release_error return release_result def send(self, msg: Message): if not msg.serial: msg.serial = self.next_serial() self._buffered_messages.append(msg) if self.unique_name: self._schedule_write() def get_proxy_object( self, bus_name: str, path: str, introspection: intr.Node ) -> ProxyObject: return super().get_proxy_object(bus_name, path, introspection) def _schedule_write(self): if self.writable_source is None or self.writable_source.is_destroyed(): self.writable_source = _MessageWritableSource(self) self.writable_source.attach(self._main_context) self.writable_source.add_unix_fd(self._fd, GLib.IO_OUT) def _authenticate(self, authenticate_notify): self._stream.write(b"\0") first_line = self._auth._authentication_start() if first_line is not None: if type(first_line) is not str: raise AuthError("authenticator gave response not type str") self._stream.write(f"{first_line}\r\n".encode()) self._stream.flush() def line_notify(line): try: resp = self._auth._receive_line(line) self._stream.write(Authenticator._format_line(resp)) self._stream.flush() if resp == "BEGIN": self._readline_source = None authenticate_notify(None) return True except Exception as e: authenticate_notify(e) return True readline_source = _AuthLineSource(self._stream) readline_source.set_callback(line_notify) readline_source.add_unix_fd(self._fd, GLib.IO_IN) readline_source.attach(self._main_context) # make sure it doesnt get cleaned up self._readline_source = readline_source dbus-fast-2.44.1/src/dbus_fast/glib/proxy_object.py000066400000000000000000000247201477355613200222530ustar00rootroot00000000000000import xml.etree.ElementTree as ET from typing import Union from .. import introspection as intr from ..constants import ErrorType from ..errors import DBusError from ..message import Message from ..message_bus import BaseMessageBus from ..proxy_object import BaseProxyInterface, BaseProxyObject from ..signature import Variant from ..unpack import unpack_variants as unpack # glib is optional try: from gi.repository import GLib except ImportError: pass class ProxyInterface(BaseProxyInterface): """A class representing a proxy to an interface exported on the bus by another client for the GLib :class:`MessageBus ` implementation. This class is not meant to be constructed directly by the user. Use :func:`ProxyObject.get_interface() ` on a GLib proxy object to get a proxy interface. This class exposes methods to call DBus methods, listen to signals, and get and set properties on the interface that are created dynamically based on the introspection data passed to the proxy object that made this proxy interface. A *method call* takes this form: .. code-block:: python3 def callback(error: Exception, result: list(Any)): pass interface.call_[METHOD](*args, callback) result = interface.call_[METHOD]_sync(*args) Where ``METHOD`` is the name of the method converted to snake case. To call a method, provide ``*args`` that correspond to the *in args* of the introspection method definition. To *asynchronously* call a method, provide a callback that takes an error as the first argument and a list as the second argument. If the call completed successfully, ``error`` will be :class:`None`. If the service returns an error, it will be a :class:`DBusError ` with information about the error returned from the bus. The result will be a list of values that correspond to the *out args* of the introspection method definition. To *synchronously* call a method, use the ``call_[METHOD]_sync()`` form. The ``result`` corresponds to the *out arg* of the introspection method definition. If the method has more than one otu arg, they are returned within a :class:`list`. To *listen to a signal* use this form: .. code-block:: python3 interface.on_[SIGNAL](callback) To *stop listening to a signal* use this form: .. code-block:: python3 interface.off_[SIGNAL](callback) Where ``SIGNAL`` is the name of the signal converted to snake case. DBus signals are exposed with an event-callback interface. The provided ``callback`` will be called when the signal is emitted with arguments that correspond to the *out args* of the interface signal definition. To *get or set a property* use this form: .. code-block:: python3 def get_callback(error: Exception, value: Any): pass def set_callback(error: Exception) pass interface.get_[PROPERTY](get_callback) value: Any = interface.get_[PROPERTY]_sync() interface.set_[PROPERTY](set_callback) interface.set_[PROPERTY]_sync(value) Where ``PROPERTY`` is the name of the property converted to snake case. The ``value`` must correspond to the type of the property in the interface definition. To asynchronously get or set a property, provide a callback that takes an :class:`Exception` as the first argument. If the call completed successfully, ``error`` will be :class:`None`. If the service returns an error, it will be a :class:`DBusError ` with information about the error returned from the bus. If the service returns an error for a synchronous DBus call, a :class:`DBusError ` will be raised with information about the error. """ def _add_method(self, intr_method): in_len = len(intr_method.in_args) out_len = len(intr_method.out_args) def method_fn(*args, unpack_variants: bool = False): if len(args) != in_len + 1: raise TypeError( f"method {intr_method.name} expects {in_len} arguments and a callback (got {len(args)} args)" ) args = list(args) # TODO type check: this callback takes two parameters # (MessageBus.check_callback(cb)) callback = args.pop() def call_notify(msg, err): if err: callback([], err) return try: BaseProxyInterface._check_method_return( msg, intr_method.out_signature ) except DBusError as e: err = e if unpack_variants: callback(unpack(msg.body), err) else: callback(msg.body, err) self.bus.call( Message( destination=self.bus_name, path=self.path, interface=self.introspection.name, member=intr_method.name, signature=intr_method.in_signature, body=list(args), ), call_notify, ) def method_fn_sync(*args, unpack_variants: bool = False): main = GLib.MainLoop() call_error = None call_body = None def callback(body, err): nonlocal call_error nonlocal call_body call_error = err call_body = body main.quit() method_fn(*args, callback) main.run() if call_error: raise call_error if not out_len: return None if unpack_variants: call_body = unpack(call_body) if out_len == 1: return call_body[0] return call_body method_name = f"call_{BaseProxyInterface._to_snake_case(intr_method.name)}" method_name_sync = f"{method_name}_sync" setattr(self, method_name, method_fn) setattr(self, method_name_sync, method_fn_sync) def _add_property(self, intr_property): def property_getter(callback, *, unpack_variants: bool = False): def call_notify(msg, err): if err: callback(None, err) return try: BaseProxyInterface._check_method_return(msg) except Exception as e: callback(None, e) return variant = msg.body[0] if variant.signature != intr_property.signature: err = DBusError( ErrorType.CLIENT_ERROR, 'property returned unexpected signature "{variant.signature}"', msg, ) callback(None, err) return if unpack_variants: callback(unpack(variant.value), None) else: callback(variant.value, None) self.bus.call( Message( destination=self.bus_name, path=self.path, interface="org.freedesktop.DBus.Properties", member="Get", signature="ss", body=[self.introspection.name, intr_property.name], ), call_notify, ) def property_getter_sync(*, unpack_variants: bool = False): property_value = None reply_error = None main = GLib.MainLoop() def callback(value, err): nonlocal property_value nonlocal reply_error property_value = value reply_error = err main.quit() property_getter(callback) main.run() if reply_error: raise reply_error if unpack_variants: return unpack(property_value) return property_value def property_setter(value, callback): def call_notify(msg, err): if err: callback(None, err) return None try: BaseProxyInterface._check_method_return(msg) except Exception as e: callback(None, e) return None return callback(None, None) variant = Variant(intr_property.signature, value) self.bus.call( Message( destination=self.bus_name, path=self.path, interface="org.freedesktop.DBus.Properties", member="Set", signature="ssv", body=[self.introspection.name, intr_property.name, variant], ), call_notify, ) def property_setter_sync(val): reply_error = None main = GLib.MainLoop() def callback(value, err): nonlocal reply_error reply_error = err main.quit() property_setter(val, callback) main.run() if reply_error: raise reply_error snake_case = super()._to_snake_case(intr_property.name) setattr(self, f"get_{snake_case}", property_getter) setattr(self, f"get_{snake_case}_sync", property_getter_sync) setattr(self, f"set_{snake_case}", property_setter) setattr(self, f"set_{snake_case}_sync", property_setter_sync) class ProxyObject(BaseProxyObject): """The proxy object implementation for the asyncio :class:`MessageBus `. For more information, see the :class:`BaseProxyObject `. """ def __init__( self, bus_name: str, path: str, introspection: Union[intr.Node, str, ET.Element], bus: BaseMessageBus, ): super().__init__(bus_name, path, introspection, bus, ProxyInterface) def get_interface(self, name: str) -> ProxyInterface: return super().get_interface(name) def get_children(self) -> list["ProxyObject"]: return super().get_children() dbus-fast-2.44.1/src/dbus_fast/introspection.py000066400000000000000000000621051477355613200215260ustar00rootroot00000000000000import xml.etree.ElementTree as ET from typing import Optional, Union from .constants import ArgDirection, PropertyAccess from .errors import InvalidIntrospectionError from .signature import SignatureType, get_signature_tree from .validators import assert_interface_name_valid, assert_member_name_valid # https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format def _fetch_annotations(element: ET.Element) -> dict[str, str]: annotations: dict[str, str] = {} for child in element: if child.tag != "annotation": continue annotation_name = child.attrib["name"] annotation_value = child.attrib["value"] annotations[annotation_name] = annotation_value return annotations def _extract_annotations(element: ET.Element, annotations: dict[str, str]) -> None: for key, value in annotations.items(): annotation = ET.Element("annotation", {"name": key, "value": value}) element.append(annotation) class Arg: """A class that represents an input or output argument to a signal or a method. :ivar name: The name of this arg. :vartype name: str :ivar direction: Whether this is an input or an output argument. :vartype direction: :class:`ArgDirection ` :ivar type: The parsed signature type of this argument. :vartype type: :class:`SignatureType ` :ivar signature: The signature string of this argument. :vartype signature: str :ivar annotations: The annotations of this arg. :vartype annotations: dict[str, str] :raises: - :class:`InvalidMemberNameError ` - If the name of the arg is not valid. - :class:`InvalidSignatureError ` - If the signature is not valid. - :class:`InvalidIntrospectionError ` - If the signature is not a single complete type. """ def __init__( self, signature: Union[SignatureType, str], direction: Optional[ArgDirection] = None, name: Optional[str] = None, annotations: Optional[dict[str, str]] = None, ): type_ = None if type(signature) is SignatureType: type_ = signature signature = signature.signature else: tree = get_signature_tree(signature) if len(tree.types) != 1: raise InvalidIntrospectionError( f"an argument must have a single complete type. (has {len(tree.types)} types)" ) type_ = tree.types[0] self.type = type_ self.signature = signature self.name = name self.direction = direction self.annotations = annotations or {} def from_xml(element: ET.Element, direction: ArgDirection) -> "Arg": """Convert a :class:`xml.etree.ElementTree.Element` into a :class:`Arg`. The element must be valid DBus introspection XML for an ``arg``. :param element: The parsed XML element. :type element: :class:`xml.etree.ElementTree.Element` :param direction: The direction of this arg. Must be specified because it can default to different values depending on if it's in a method or signal. :type direction: :class:`ArgDirection ` :raises: - :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data. """ name = element.attrib.get("name") signature = element.attrib.get("type") if not signature: raise InvalidIntrospectionError( 'a method argument must have a "type" attribute' ) annotations = _fetch_annotations(element) return Arg(signature, direction, name, annotations) def to_xml(self) -> ET.Element: """Convert this :class:`Arg` into an :class:`xml.etree.ElementTree.Element`.""" element = ET.Element("arg") if self.name: element.set("name", self.name) if self.direction: element.set("direction", self.direction.value) element.set("type", self.signature) _extract_annotations(element, self.annotations) return element class Signal: """A class that represents a signal exposed on an interface. :ivar name: The name of this signal :vartype name: str :ivar args: A list of output arguments for this signal. :vartype args: list(Arg) :ivar signature: The collected signature of the output arguments. :vartype signature: str :ivar annotations: The annotations of this signal. :vartype annotations: dict[str, str] :raises: - :class:`InvalidMemberNameError ` - If the name of the signal is not a valid member name. """ def __init__( self, name: Optional[str], args: Optional[list[Arg]] = None, annotations: Optional[dict[str, str]] = None, ): if name is not None: assert_member_name_valid(name) self.name = name self.args = args or [] self.signature = "".join(arg.signature for arg in self.args) self.annotations = annotations or {} def from_xml(element): """Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Signal`. The element must be valid DBus introspection XML for a ``signal``. :param element: The parsed XML element. :type element: :class:`xml.etree.ElementTree.Element` :param is_root: Whether this is the root node :type is_root: bool :raises: - :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data. """ name = element.attrib.get("name") if not name: raise InvalidIntrospectionError('signals must have a "name" attribute') args = [] for child in element: if child.tag == "arg": args.append(Arg.from_xml(child, ArgDirection.OUT)) annotations = _fetch_annotations(element) signal = Signal(name, args, annotations) return signal def to_xml(self) -> ET.Element: """Convert this :class:`Signal` into an :class:`xml.etree.ElementTree.Element`.""" element = ET.Element("signal") element.set("name", self.name) for arg in self.args: element.append(arg.to_xml()) _extract_annotations(element, self.annotations) return element class Method: """A class that represents a method exposed on an :class:`Interface`. :ivar name: The name of this method. :vartype name: str :ivar in_args: A list of input arguments to this method. :vartype in_args: list(Arg) :ivar out_args: A list of output arguments to this method. :vartype out_args: list(Arg) :ivar in_signature: The collected signature string of the input arguments. :vartype in_signature: str :ivar out_signature: The collected signature string of the output arguments. :vartype out_signature: str :ivar annotations: The annotations of this method. :vartype annotations: dict[str, str] :raises: - :class:`InvalidMemberNameError ` - If the name of this method is not valid. """ def __init__( self, name: str, in_args: list[Arg] = [], out_args: list[Arg] = [], annotations: Optional[dict[str, str]] = None, ): assert_member_name_valid(name) self.name = name self.in_args = in_args self.out_args = out_args self.in_signature = "".join(arg.signature for arg in in_args) self.out_signature = "".join(arg.signature for arg in out_args) self.annotations = annotations or {} def from_xml(element: ET.Element) -> "Method": """Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Method`. The element must be valid DBus introspection XML for a ``method``. :param element: The parsed XML element. :type element: :class:`xml.etree.ElementTree.Element` :param is_root: Whether this is the root node :type is_root: bool :raises: - :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data. """ name = element.attrib.get("name") if not name: raise InvalidIntrospectionError('interfaces must have a "name" attribute') in_args = [] out_args = [] for child in element: if child.tag == "arg": direction = ArgDirection(child.attrib.get("direction", "in")) arg = Arg.from_xml(child, direction) if direction == ArgDirection.IN: in_args.append(arg) elif direction == ArgDirection.OUT: out_args.append(arg) annotations = _fetch_annotations(element) return Method(name, in_args, out_args, annotations) def to_xml(self) -> ET.Element: """Convert this :class:`Method` into an :class:`xml.etree.ElementTree.Element`.""" element = ET.Element("method") element.set("name", self.name) for arg in self.in_args: element.append(arg.to_xml()) for arg in self.out_args: element.append(arg.to_xml()) _extract_annotations(element, self.annotations) return element class Property: """A class that represents a DBus property exposed on an :class:`Interface`. :ivar name: The name of this property. :vartype name: str :ivar signature: The signature string for this property. Must be a single complete type. :vartype signature: str :ivar access: Whether this property is readable and writable. :vartype access: :class:`PropertyAccess ` :ivar type: The parsed type of this property. :vartype type: :class:`SignatureType ` :ivar annotations: The annotations of this property. :vartype annotations: dict[str, str] :raises: - :class:`InvalidIntrospectionError ` - If the property is not a single complete type. - :class `InvalidSignatureError ` - If the given signature is not valid. - :class: `InvalidMemberNameError ` - If the member name is not valid. """ def __init__( self, name: str, signature: str, access: PropertyAccess = PropertyAccess.READWRITE, annotations: Optional[dict[str, str]] = None, validate: bool = True, ): if validate: assert_member_name_valid(name) tree = get_signature_tree(signature) if len(tree.types) != 1: raise InvalidIntrospectionError( f"properties must have a single complete type. (has {len(tree.types)} types)" ) self.name = name self.signature = signature self.access = access self.type = tree.types[0] self.annotations = annotations or {} def from_xml(element, validate: bool = True): """Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Property`. The element must be valid DBus introspection XML for a ``property``. :param element: The parsed XML element. :type element: :class:`xml.etree.ElementTree.Element` :raises: - :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data. """ name = element.attrib.get("name") signature = element.attrib.get("type") access = PropertyAccess(element.attrib.get("access", "readwrite")) if not name: raise InvalidIntrospectionError('properties must have a "name" attribute') if not signature: raise InvalidIntrospectionError('properties must have a "type" attribute') annotations = _fetch_annotations(element) return Property( name, signature, access, annotations=annotations, validate=validate ) def to_xml(self) -> ET.Element: """Convert this :class:`Property` into an :class:`xml.etree.ElementTree.Element`.""" element = ET.Element("property") element.set("name", self.name) element.set("type", self.signature) element.set("access", self.access.value) _extract_annotations(element, self.annotations) return element class Interface: """A class that represents a DBus interface exported on on object path. Contains information about the methods, signals, and properties exposed on this interface. :ivar name: The name of this interface. :vartype name: str :ivar methods: A list of methods exposed on this interface. :vartype methods: list(:class:`Method`) :ivar signals: A list of signals exposed on this interface. :vartype signals: list(:class:`Signal`) :ivar properties: A list of properties exposed on this interface. :vartype properties: list(:class:`Property`) :ivar annotations: The annotations of this interface. :vartype annotations: dict[str, str] :raises: - :class:`InvalidInterfaceNameError ` - If the name is not a valid interface name. """ def __init__( self, name: str, methods: Optional[list[Method]] = None, signals: Optional[list[Signal]] = None, properties: Optional[list[Property]] = None, annotations: Optional[dict[str, str]] = None, ): assert_interface_name_valid(name) self.name = name self.methods = methods if methods is not None else [] self.signals = signals if signals is not None else [] self.properties = properties if properties is not None else [] self.annotations = annotations or {} @staticmethod def from_xml( element: ET.Element, validate_property_names: bool = True ) -> "Interface": """Convert a :class:`xml.etree.ElementTree.Element` into a :class:`Interface`. The element must be valid DBus introspection XML for an ``interface``. :param element: The parsed XML element. :type element: :class:`xml.etree.ElementTree.Element` :raises: - :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data. """ name = element.attrib.get("name") if not name: raise InvalidIntrospectionError('interfaces must have a "name" attribute') interface = Interface(name) for child in element: if child.tag == "method": interface.methods.append(Method.from_xml(child)) elif child.tag == "signal": interface.signals.append(Signal.from_xml(child)) elif child.tag == "property": interface.properties.append( Property.from_xml(child, validate=validate_property_names) ) interface.annotations = _fetch_annotations(element) return interface def to_xml(self) -> ET.Element: """Convert this :class:`Interface` into an :class:`xml.etree.ElementTree.Element`.""" element = ET.Element("interface") element.set("name", self.name) for method in self.methods: element.append(method.to_xml()) for signal in self.signals: element.append(signal.to_xml()) for prop in self.properties: element.append(prop.to_xml()) _extract_annotations(element, self.annotations) return element class Node: """A class that represents a node in an object path in introspection data. A node contains information about interfaces exported on this path and child nodes. A node can be converted to and from introspection XML exposed through the ``org.freedesktop.DBus.Introspectable`` standard DBus interface. This class is an essential building block for a high-level DBus interface. This is the underlying data structure for the :class:`ProxyObject `. A :class:`ServiceInterface ` definition is converted to this class to expose XML on the introspectable interface. :ivar interfaces: A list of interfaces exposed on this node. :vartype interfaces: list(:class:`Interface `) :ivar nodes: A list of child nodes. :vartype nodes: list(:class:`Node`) :ivar name: The object path of this node. :vartype name: str :ivar is_root: Whether this is the root node. False if it is a child node. :vartype is_root: bool :raises: - :class:`InvalidIntrospectionError ` - If the name is not a valid node name. """ def __init__( self, name: Optional[str] = None, interfaces: Optional[list[Interface]] = None, is_root: bool = True, ): if not is_root and not name: raise InvalidIntrospectionError('child nodes must have a "name" attribute') self.interfaces = interfaces if interfaces is not None else [] self.nodes = [] self.name = name self.is_root = is_root @staticmethod def from_xml( element: ET.Element, is_root: bool = False, validate_property_names: bool = True ) -> "Node": """Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Node`. The element must be valid DBus introspection XML for a ``node``. :param element: The parsed XML element. :type element: :class:`xml.etree.ElementTree.Element` :param is_root: Whether this is the root node :type is_root: bool :param validate_property_names: Whether to validate property names or not :type validate_property_names: bool :raises: - :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data. """ node = Node(element.attrib.get("name"), is_root=is_root) for child in element: if child.tag == "interface": node.interfaces.append( Interface.from_xml( child, validate_property_names=validate_property_names ) ) elif child.tag == "node": node.nodes.append( Node.from_xml( child, validate_property_names=validate_property_names ) ) return node @staticmethod def parse(data: str, validate_property_names: bool = True) -> "Node": """Parse XML data as a string into a :class:`Node`. The string must be valid DBus introspection XML. :param data: The XMl string. :type data: str :param validate_property_names: Whether to validate property names or not :type validate_property_names: bool :raises: - :class:`InvalidIntrospectionError ` - If the string is not valid introspection data. """ element = ET.fromstring(data) if element.tag != "node": raise InvalidIntrospectionError( 'introspection data must have a "node" for the root element' ) return Node.from_xml( element, is_root=True, validate_property_names=validate_property_names ) def to_xml(self) -> ET.Element: """Convert this :class:`Node` into an :class:`xml.etree.ElementTree.Element`.""" element = ET.Element("node") if self.name: element.set("name", self.name) for interface in self.interfaces: element.append(interface.to_xml()) for node in self.nodes: element.append(node.to_xml()) return element def tostring(self) -> str: """Convert this :class:`Node` into a DBus introspection XML string.""" header = '\n' def indent(elem, level=0): i = "\n" + level * " " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem_ in elem: indent(elem_, level + 1) if not elem.tail or not elem.tail.strip(): elem.tail = i elif level and (not elem.tail or not elem.tail.strip()): elem.tail = i xml = self.to_xml() indent(xml) return header + ET.tostring(xml, encoding="unicode").rstrip() @staticmethod def default(name: Optional[str] = None) -> "Node": """Create a :class:`Node` with the default interfaces supported by this library. The default interfaces include: * ``org.freedesktop.DBus.Introspectable`` * ``org.freedesktop.DBus.Peer`` * ``org.freedesktop.DBus.Properties`` * ``org.freedesktop.DBus.ObjectManager`` """ return Node( name, is_root=True, interfaces=[ Interface( "org.freedesktop.DBus.Introspectable", methods=[ Method( "Introspect", out_args=[Arg("s", ArgDirection.OUT, "data")] ) ], ), Interface( "org.freedesktop.DBus.Peer", methods=[ Method( "GetMachineId", out_args=[Arg("s", ArgDirection.OUT, "machine_uuid")], ), Method("Ping"), ], ), Interface( "org.freedesktop.DBus.Properties", methods=[ Method( "Get", in_args=[ Arg("s", ArgDirection.IN, "interface_name"), Arg("s", ArgDirection.IN, "property_name"), ], out_args=[Arg("v", ArgDirection.OUT, "value")], ), Method( "Set", in_args=[ Arg("s", ArgDirection.IN, "interface_name"), Arg("s", ArgDirection.IN, "property_name"), Arg("v", ArgDirection.IN, "value"), ], ), Method( "GetAll", in_args=[Arg("s", ArgDirection.IN, "interface_name")], out_args=[Arg("a{sv}", ArgDirection.OUT, "props")], ), ], signals=[ Signal( "PropertiesChanged", args=[ Arg("s", ArgDirection.OUT, "interface_name"), Arg("a{sv}", ArgDirection.OUT, "changed_properties"), Arg("as", ArgDirection.OUT, "invalidated_properties"), ], ) ], ), Interface( "org.freedesktop.DBus.ObjectManager", methods=[ Method( "GetManagedObjects", out_args=[ Arg( "a{oa{sa{sv}}}", ArgDirection.OUT, "objpath_interfaces_and_properties", ) ], ), ], signals=[ Signal( "InterfacesAdded", args=[ Arg("o", ArgDirection.OUT, "object_path"), Arg( "a{sa{sv}}", ArgDirection.OUT, "interfaces_and_properties", ), ], ), Signal( "InterfacesRemoved", args=[ Arg("o", ArgDirection.OUT, "object_path"), Arg("as", ArgDirection.OUT, "interfaces"), ], ), ], ), ], ) dbus-fast-2.44.1/src/dbus_fast/message.pxd000066400000000000000000000034511477355613200204140ustar00rootroot00000000000000"""cdefs for message.py""" import cython from ._private.marshaller cimport Marshaller from .signature cimport Variant, SignatureTree, SignatureType cdef object ErrorType cdef object MessageType cdef object HEADER_PATH cdef object HEADER_INTERFACE cdef object HEADER_MEMBER cdef object HEADER_ERROR_NAME cdef object HEADER_REPLY_SERIAL cdef object HEADER_DESTINATION cdef object HEADER_SENDER cdef object HEADER_SIGNATURE cdef object HEADER_UNIX_FDS cdef object LITTLE_ENDIAN cdef object PROTOCOL_VERSION cdef object MESSAGE_FLAG cdef object MESSAGE_FLAG_NONE cdef object MESSAGE_TYPE_METHOD_CALL cdef SignatureTree SIGNATURE_TREE_G cdef SignatureTree SIGNATURE_TREE_O cdef SignatureTree SIGNATURE_TREE_S cdef SignatureTree SIGNATURE_TREE_U cdef get_signature_tree cdef class Message: cdef public object destination cdef public object path cdef public object interface cdef public object member cdef public object message_type cdef public object flags cdef public object error_name cdef public unsigned int reply_serial cdef public object sender cdef public list unix_fds cdef public str signature cdef public SignatureTree signature_tree cdef public object body cdef public unsigned int serial @cython.locals( body_buffer=bytearray, header_buffer=bytearray, var=Variant ) cpdef _marshall(self, object negotiate_unix_fd) cdef _fast_init( self, object destination, object path, object interface, object member, object message_type, object flags, object error_name, unsigned int reply_serial, object sender, list unix_fds, SignatureTree signature_tree, object body, unsigned int serial, bint validate ) dbus-fast-2.44.1/src/dbus_fast/message.py000066400000000000000000000332451477355613200202550ustar00rootroot00000000000000from typing import Any, Optional, Union from ._private.constants import LITTLE_ENDIAN, PROTOCOL_VERSION, HeaderField from ._private.marshaller import Marshaller from .constants import ErrorType, MessageFlag, MessageType from .errors import InvalidMessageError from .signature import SignatureTree, Variant, get_signature_tree from .validators import ( assert_bus_name_valid, assert_interface_name_valid, assert_member_name_valid, assert_object_path_valid, ) REQUIRED_FIELDS = { MessageType.METHOD_CALL.value: ("path", "member"), MessageType.SIGNAL.value: ("path", "member", "interface"), MessageType.ERROR.value: ("error_name", "reply_serial"), MessageType.METHOD_RETURN.value: ("reply_serial",), } HEADER_PATH = HeaderField.PATH.value HEADER_INTERFACE = HeaderField.INTERFACE.value HEADER_MEMBER = HeaderField.MEMBER.value HEADER_ERROR_NAME = HeaderField.ERROR_NAME.value HEADER_REPLY_SERIAL = HeaderField.REPLY_SERIAL.value HEADER_DESTINATION = HeaderField.DESTINATION.value HEADER_SIGNATURE = HeaderField.SIGNATURE.value HEADER_UNIX_FDS = HeaderField.UNIX_FDS.value MESSAGE_FLAG = MessageFlag MESSAGE_FLAG_NONE = MessageFlag.NONE MESSAGE_TYPE_METHOD_CALL = MessageType.METHOD_CALL SIGNATURE_TREE_G = get_signature_tree("g") SIGNATURE_TREE_O = get_signature_tree("o") SIGNATURE_TREE_S = get_signature_tree("s") SIGNATURE_TREE_U = get_signature_tree("u") _int = int _str = str _bool = bool _MessageType = MessageType _MessageFlag = MessageFlag _list = list class Message: """A class for sending and receiving messages through the :class:`MessageBus ` with the low-level api. A ``Message`` can be constructed by the user to send over the message bus. When messages are received, such as from method calls or signal emissions, they will use this class as well. :ivar destination: The address of the client for which this message is intended. :vartype destination: str :ivar path: The intended object path exported on the destination bus. :vartype path: str :ivar interface: The intended interface on the object path. :vartype interface: str :ivar member: The intended member on the interface. :vartype member: str :ivar message_type: The type of this message. A method call, signal, method return, or error. :vartype message_type: :class:`MessageType` :ivar flags: Flags that affect the behavior of this message. :vartype flags: :class:`MessageFlag` :ivar error_name: If this message is an error, the name of this error. Must be a valid interface name. :vartype error_name: str :ivar reply_serial: If this is a return type, the serial this message is in reply to. :vartype reply_serial: int :ivar sender: The address of the sender of this message. Will be a unique name. :vartype sender: str :ivar unix_fds: A list of unix fds that were sent in the header of this message. :vartype unix_fds: list(int) :ivar signature: The signature of the body of this message. :vartype signature: str :ivar signature_tree: The signature parsed as a signature tree. :vartype signature_tree: :class:`SignatureTree` :ivar body: The body of this message. Must match the signature. :vartype body: list(Any) :ivar serial: The serial of the message. Will be automatically set during message sending if not present. Use the ``new_serial()`` method of the bus to generate a serial. :vartype serial: int :raises: - :class:`InvalidMessageError` - If the message is malformed or missing fields for the message type. - :class:`InvalidSignatureError` - If the given signature is not valid. - :class:`InvalidObjectPathError` - If ``path`` is not a valid object path. - :class:`InvalidBusNameError` - If ``destination`` is not a valid bus name. - :class:`InvalidMemberNameError` - If ``member`` is not a valid member name. - :class:`InvalidInterfaceNameError` - If ``error_name`` or ``interface`` is not a valid interface name. """ __slots__ = ( "body", "destination", "error_name", "flags", "interface", "member", "message_type", "path", "reply_serial", "sender", "serial", "signature", "signature_tree", "unix_fds", ) def __init__( self, destination: Optional[str] = None, path: Optional[str] = None, interface: Optional[str] = None, member: Optional[str] = None, message_type: MessageType = MESSAGE_TYPE_METHOD_CALL, flags: Union[MessageFlag, int] = MESSAGE_FLAG_NONE, error_name: Optional[Union[str, ErrorType]] = None, reply_serial: Optional[int] = None, sender: Optional[str] = None, unix_fds: list[int] = [], signature: Optional[Union[SignatureTree, str]] = None, body: list[Any] = [], serial: Optional[int] = None, validate: bool = True, ) -> None: self._fast_init( destination, path, interface, member, message_type, flags if type(flags) is MESSAGE_FLAG else MESSAGE_FLAG(flags), str(error_name.value) if type(error_name) is ErrorType else error_name, reply_serial or 0, sender, unix_fds, signature if type(signature) is SignatureTree else get_signature_tree(signature or ""), body, serial or 0, validate, ) def _fast_init( self, destination: Optional[_str], path: Optional[_str], interface: Optional[_str], member: Optional[_str], message_type: _MessageType, flags: _MessageFlag, error_name: Optional[_str], reply_serial: _int, sender: _str, unix_fds: _list[int], signature_tree: SignatureTree, body: _list[Any], serial: _int, validate: _bool, ) -> None: self.destination = destination self.path = path self.interface = interface self.member = member self.message_type = message_type self.flags = flags self.error_name = error_name self.reply_serial = reply_serial self.sender = sender self.unix_fds = unix_fds self.signature = signature_tree.signature self.signature_tree = signature_tree self.body = body self.serial = serial if not validate: return if self.destination is not None: assert_bus_name_valid(self.destination) if self.interface is not None: assert_interface_name_valid(self.interface) if self.path is not None: assert_object_path_valid(self.path) if self.member is not None: assert_member_name_valid(self.member) if self.error_name is not None: assert_interface_name_valid(self.error_name) # type: ignore[arg-type] required_fields = REQUIRED_FIELDS.get(self.message_type.value) if not required_fields: raise InvalidMessageError(f"got unknown message type: {self.message_type}") for field in required_fields: if not getattr(self, field): raise InvalidMessageError(f"missing required field: {field}") def __repr__(self) -> str: """Return a string representation of this message.""" return ( f"" ) @staticmethod def new_error( msg: "Message", error_name: Union[str, ErrorType], error_text: str ) -> "Message": """A convenience constructor to create an error message in reply to the given message. :param msg: The message this error is in reply to. :type msg: :class:`Message` :param error_name: The name of this error. Must be a valid interface name. :type error_name: str :param error_text: Human-readable text for the error. :returns: The error message. :rtype: :class:`Message` :raises: - :class:`InvalidInterfaceNameError` - If the error_name is not a valid interface name. """ return Message( message_type=MessageType.ERROR, reply_serial=msg.serial, destination=msg.sender, error_name=error_name, signature="s", body=[error_text], ) @staticmethod def new_method_return( msg: "Message", signature: str = "", body: list[Any] = [], unix_fds: list[int] = [], ) -> "Message": """A convenience constructor to create a method return to the given method call message. :param msg: The method call message this is a reply to. :type msg: :class:`Message` :param signature: The signature for the message body. :type signature: str :param body: The body of this message. Must match the signature. :type body: list(Any) :param unix_fds: List integer file descriptors to send with this message. :type body: list(int) :returns: The method return message :rtype: :class:`Message` :raises: - :class:`InvalidSignatureError` - If the signature is not a valid signature. """ return Message( message_type=MessageType.METHOD_RETURN, reply_serial=msg.serial, destination=msg.sender, signature=signature, body=body, unix_fds=unix_fds, ) @staticmethod def new_signal( path: str, interface: str, member: str, signature: str = "", body: Optional[list[Any]] = None, unix_fds: Optional[list[int]] = None, ) -> "Message": """A convenience constructor to create a new signal message. :param path: The path of this signal. :type path: str :param interface: The interface of this signal. :type interface: str :param member: The member name of this signal. :type member: str :param signature: The signature of the signal body. :type signature: str :param body: The body of this signal message. :type body: list(Any) :param unix_fds: List integer file descriptors to send with this message. :type body: list(int) :returns: The signal message. :rtype: :class:`Message` :raises: - :class:`InvalidSignatureError` - If the signature is not a valid signature. - :class:`InvalidObjectPathError` - If ``path`` is not a valid object path. - :class:`InvalidInterfaceNameError` - If ``interface`` is not a valid interface name. - :class:`InvalidMemberNameError` - If ``member`` is not a valid member name. """ return Message( message_type=MessageType.SIGNAL, interface=interface, path=path, member=member, signature=signature, body=body or [], unix_fds=unix_fds or [], ) def _marshall(self, negotiate_unix_fd: bool) -> bytearray: """Marshall this message into a byte array.""" # TODO maximum message size is 134217728 (128 MiB) body_block = Marshaller(self.signature, self.body) body_buffer = body_block._marshall() fields = [] # No verify here since the marshaller will raise an exception if the # Variant is invalid. if self.path: fields.append((HEADER_PATH, Variant._factory(SIGNATURE_TREE_O, self.path))) if self.interface: fields.append( (HEADER_INTERFACE, Variant._factory(SIGNATURE_TREE_S, self.interface)) ) if self.member: fields.append( (HEADER_MEMBER, Variant._factory(SIGNATURE_TREE_S, self.member)) ) if self.error_name: fields.append( ( HEADER_ERROR_NAME, Variant._factory(SIGNATURE_TREE_S, self.error_name), ) ) if self.reply_serial: fields.append( ( HEADER_REPLY_SERIAL, Variant._factory(SIGNATURE_TREE_U, self.reply_serial), ) ) if self.destination: fields.append( ( HEADER_DESTINATION, Variant._factory(SIGNATURE_TREE_S, self.destination), ) ) if self.signature: fields.append( (HEADER_SIGNATURE, Variant._factory(SIGNATURE_TREE_G, self.signature)) ) if self.unix_fds and negotiate_unix_fd: fields.append( ( HEADER_UNIX_FDS, Variant._factory(SIGNATURE_TREE_U, len(self.unix_fds)), ) ) header_body = [ LITTLE_ENDIAN, self.message_type.value, self.flags.value, PROTOCOL_VERSION, len(body_buffer), self.serial, fields, ] header_block = Marshaller("yyyyuua(yv)", header_body) header_block._marshall() header_block._align(8) header_buffer = header_block._buffer() return header_buffer + body_buffer dbus-fast-2.44.1/src/dbus_fast/message_bus.pxd000066400000000000000000000040361477355613200212650ustar00rootroot00000000000000import cython from ._private.address cimport get_bus_address, parse_address from .message cimport Message from .service cimport ServiceInterface, _Method cdef bint TYPE_CHECKING cdef object MessageType cdef object DBusError cdef object MessageFlag cdef object MESSAGE_TYPE_CALL cdef object MESSAGE_TYPE_SIGNAL cdef cython.uint NO_REPLY_EXPECTED_VALUE cdef object NONE cdef object NO_REPLY_EXPECTED cdef object BLOCK_UNEXPECTED_REPLY cdef object assert_object_path_valid cdef object assert_bus_name_valid @cython.locals(flag_value=cython.uint) cdef bint _expects_reply(Message msg) cdef class BaseMessageBus: cdef public object unique_name cdef public bint _disconnected cdef public object _user_disconnect cdef public cython.dict _method_return_handlers cdef public object _serial cdef public cython.dict _path_exports cdef public cython.list _user_message_handlers cdef public cython.dict _name_owners cdef public object _bus_address cdef public object _name_owner_match_rule cdef public cython.dict _match_rules cdef public object _high_level_client_initialized cdef public object _ProxyObject cdef public object _machine_id cdef public bint _negotiate_unix_fd cdef public object _sock cdef public object _stream cdef public object _fd cpdef void _process_message(self, Message msg) except * @cython.locals(exported_service_interface=ServiceInterface) cpdef export(self, str path, ServiceInterface interface) @cython.locals( methods=cython.list, method=_Method, interface=ServiceInterface, interfaces=dict, ) cdef _find_message_handler(self, Message msg) cdef _find_any_message_handler_matching_signature(self, dict interfaces, Message msg) cdef _setup_socket(self) cpdef _call(self, Message msg, object callback) cpdef next_serial(self) cpdef void _callback_method_handler( self, ServiceInterface interface, _Method method, Message msg, object send_reply ) except * dbus-fast-2.44.1/src/dbus_fast/message_bus.py000066400000000000000000001363751477355613200211360ustar00rootroot00000000000000from __future__ import annotations import inspect import logging import socket import traceback import xml.etree.ElementTree as ET from functools import partial from typing import TYPE_CHECKING, Any, Callable from . import introspection as intr from ._private.address import get_bus_address, parse_address from ._private.util import replace_fds_with_idx, replace_idx_with_fds from .constants import ( BusType, ErrorType, MessageFlag, MessageType, NameFlag, ReleaseNameReply, RequestNameReply, ) from .errors import DBusError, InvalidAddressError from .message import Message from .proxy_object import BaseProxyObject from .send_reply import SendReply from .service import HandlerType, ServiceInterface, _Method, _Property from .signature import Variant from .validators import assert_bus_name_valid, assert_object_path_valid MESSAGE_TYPE_CALL = MessageType.METHOD_CALL MESSAGE_TYPE_SIGNAL = MessageType.SIGNAL NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value NO_REPLY_EXPECTED = MessageFlag.NO_REPLY_EXPECTED NONE = MessageFlag.NONE _LOGGER = logging.getLogger(__name__) _Message = Message def _expects_reply(msg: _Message) -> bool: """Whether a message expects a reply.""" if msg.flags is NO_REPLY_EXPECTED: return False if msg.flags is NONE: return True # Slow check for NO_REPLY_EXPECTED flag_value = msg.flags.value return not (flag_value & NO_REPLY_EXPECTED_VALUE) def _block_unexpected_reply(reply: _Message) -> None: """Block a reply if it's not expected. Previously we silently ignored replies that were not expected, but this lead to implementation errors that were hard to debug. Now we log a debug message instead. """ _LOGGER.debug( "Blocked attempt to send a reply from handler " "that received a message with flag " "MessageFlag.NO_REPLY_EXPECTED: %s", reply, ) BLOCK_UNEXPECTED_REPLY = _block_unexpected_reply class BaseMessageBus: """An abstract class to manage a connection to a DBus message bus. The message bus class is the entry point into all the features of the library. It sets up a connection to the DBus daemon and exposes an interface to send and receive messages and expose services. This class is not meant to be used directly by users. For more information, see the documentation for the implementation of the message bus you plan to use. :param bus_type: The type of bus to connect to. Affects the search path for the bus address. :type bus_type: :class:`BusType ` :param bus_address: A specific bus address to connect to. Should not be used under normal circumstances. :type bus_address: str :param ProxyObject: The proxy object implementation for this message bus. Must be passed in by an implementation that supports the high-level client. :type ProxyObject: Type[:class:`BaseProxyObject `] :ivar unique_name: The unique name of the message bus connection. It will be :class:`None` until the message bus connects. :vartype unique_name: str :ivar connected: True if this message bus is expected to be able to send and receive messages. :vartype connected: bool """ __slots__ = ( "_ProxyObject", "_bus_address", "_disconnected", "_fd", "_high_level_client_initialized", "_machine_id", "_match_rules", "_method_return_handlers", "_name_owner_match_rule", "_name_owners", "_negotiate_unix_fd", "_path_exports", "_serial", "_sock", "_stream", "_user_disconnect", "_user_message_handlers", "unique_name", ) def __init__( self, bus_address: str | None = None, bus_type: BusType = BusType.SESSION, ProxyObject: type[BaseProxyObject] | None = None, negotiate_unix_fd: bool = False, ) -> None: self.unique_name: str | None = None self._disconnected = False self._negotiate_unix_fd = negotiate_unix_fd # True if the user disconnected himself, so don't throw errors out of # the main loop. self._user_disconnect = False self._method_return_handlers: dict[ int, Callable[[Message | None, Exception | None], None] ] = {} self._serial = 0 self._user_message_handlers: list[ Callable[[Message], Message | bool | None] ] = [] # the key is the name and the value is the unique name of the owner. # This cache is kept up to date by the NameOwnerChanged signal and is # used to route messages to the correct proxy object. (used for the # high level client only) self._name_owners: dict[str, str] = {} # used for the high level service self._path_exports: dict[str, dict[str, ServiceInterface]] = {} self._bus_address = ( parse_address(bus_address) if bus_address else parse_address(get_bus_address(bus_type)) ) # the bus implementations need this rule for the high level client to # work correctly. self._name_owner_match_rule = "sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',path='/org/freedesktop/DBus',member='NameOwnerChanged'" # _match_rules: the keys are match rules and the values are ref counts # (used for the high level client only) self._match_rules: dict[str, int] = {} self._high_level_client_initialized = False self._ProxyObject = ProxyObject # machine id is lazy loaded self._machine_id: int | None = None self._sock: socket.socket | None = None self._fd: int | None = None self._stream: Any | None = None self._setup_socket() @property def connected(self) -> bool: if self.unique_name is None or self._disconnected or self._user_disconnect: return False return True def export(self, path: str, interface: ServiceInterface) -> None: """Export the service interface on this message bus to make it available to other clients. :param path: The object path to export this interface on. :type path: str :param interface: The service interface to export. :type interface: :class:`ServiceInterface ` :raises: - :class:`InvalidObjectPathError ` - If the given object path is not valid. - :class:`ValueError` - If an interface with this name is already exported on the message bus at this path """ assert_object_path_valid(path) if not isinstance(interface, ServiceInterface): raise TypeError("interface must be a ServiceInterface") if path not in self._path_exports: self._path_exports[path] = {} elif interface.name in self._path_exports[path]: raise ValueError( f'An interface with this name is already exported on this bus at path "{path}": "{interface.name}"' ) self._path_exports[path][interface.name] = interface ServiceInterface._add_bus(interface, self, self._make_method_handler) self._emit_interface_added(path, interface) def unexport( self, path: str, interface: ServiceInterface | str | None = None ) -> None: """Unexport the path or service interface to make it no longer available to clients. :param path: The object path to unexport. :type path: str :param interface: The interface instance or the name of the interface to unexport. If ``None``, unexport every interface on the path. :type interface: :class:`ServiceInterface ` or str or None :raises: - :class:`InvalidObjectPathError ` - If the given object path is not valid. """ assert_object_path_valid(path) interface_name: str | None if interface is None: interface_name = None elif type(interface) is str: interface_name = interface elif isinstance(interface, ServiceInterface): interface_name = interface.name else: raise TypeError( f"interface must be a ServiceInterface or interface name not {type(interface)}" ) if (interfaces := self._path_exports.get(path)) is None: return removed_interface_names: list[str] = [] if interface_name is not None: if (removed_interface := interfaces.pop(interface_name, None)) is None: return removed_interface_names.append(interface_name) if not interfaces: del self._path_exports[path] ServiceInterface._remove_bus(removed_interface, self) else: del self._path_exports[path] for removed_interface in interfaces.values(): removed_interface_names.append(removed_interface.name) ServiceInterface._remove_bus(removed_interface, self) self._emit_interface_removed(path, removed_interface_names) def introspect( self, bus_name: str, path: str, callback: Callable[[intr.Node | None, Exception | None], None], check_callback_type: bool = True, validate_property_names: bool = True, ) -> None: """Get introspection data for the node at the given path from the given bus name. Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect`` on the bus for the path. :param bus_name: The name to introspect. :type bus_name: str :param path: The path to introspect. :type path: str :param callback: A callback that will be called with the introspection data as a :class:`Node `. :type callback: :class:`Callable` :param check_callback_type: Whether to check callback type or not. :type check_callback_type: bool :param validate_property_names: Whether to validate property names or not. :type validate_property_names: bool :raises: - :class:`InvalidObjectPathError ` - If the given object path is not valid. - :class:`InvalidBusNameError ` - If the given bus name is not valid. """ if check_callback_type: BaseMessageBus._check_callback_type(callback) def reply_notify(reply: Message | None, err: Exception | None) -> None: try: BaseMessageBus._check_method_return(reply, err, "s") result = intr.Node.parse( reply.body[0], # type: ignore[union-attr] validate_property_names=validate_property_names, ) except Exception as e: callback(None, e) return callback(result, None) self._call( Message( destination=bus_name, path=path, interface="org.freedesktop.DBus.Introspectable", member="Introspect", ), reply_notify, ) def _emit_interface_added(self, path: str, interface: ServiceInterface) -> None: """Emit the ``org.freedesktop.DBus.ObjectManager.InterfacesAdded`` signal. This signal is intended to be used to alert clients when a new interface has been added. :param path: Path of exported object. :type path: str :param interface: Exported service interface. :type interface: :class:`ServiceInterface ` """ if self._disconnected: return def get_properties_callback( interface: ServiceInterface, result: Any, user_data: Any, e: Exception | None, ) -> None: if e is not None: try: raise e except Exception: _LOGGER.error( "An exception ocurred when emitting ObjectManager.InterfacesAdded for %s. " "Some properties will not be included in the signal.", interface.name, exc_info=True, ) body = {interface.name: result} self.send( Message.new_signal( path=path, interface="org.freedesktop.DBus.ObjectManager", member="InterfacesAdded", signature="oa{sa{sv}}", body=[path, body], ) ) ServiceInterface._get_all_property_values(interface, get_properties_callback) def _emit_interface_removed(self, path: str, removed_interfaces: list[str]) -> None: """Emit the ``org.freedesktop.DBus.ObjectManager.InterfacesRemoved` signal. This signal is intended to be used to alert clients when a interface has been removed. :param path: Path of removed (unexported) object. :type path: str :param removed_interfaces: List of unexported service interfaces. :type removed_interfaces: list[str] """ if self._disconnected: return self.send( Message.new_signal( path=path, interface="org.freedesktop.DBus.ObjectManager", member="InterfacesRemoved", signature="oas", body=[path, removed_interfaces], ) ) def request_name( self, name: str, flags: NameFlag = NameFlag.NONE, callback: None | (Callable[[RequestNameReply | None, Exception | None], None]) = None, check_callback_type: bool = True, ) -> None: """Request that this message bus owns the given name. :param name: The name to request. :type name: str :param flags: Name flags that affect the behavior of the name request. :type flags: :class:`NameFlag ` :param callback: A callback that will be called with the reply of the request as a :class:`RequestNameReply `. :type callback: :class:`Callable` :raises: - :class:`InvalidBusNameError ` - If the given bus name is not valid. """ assert_bus_name_valid(name) if callback is not None and check_callback_type: BaseMessageBus._check_callback_type(callback) if type(flags) is not NameFlag: flags = NameFlag(flags) message = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="RequestName", signature="su", body=[name, flags], ) if callback is None: self._call(message, None) return def reply_notify(reply: Message | None, err: Exception | None) -> None: try: BaseMessageBus._check_method_return(reply, err, "u") result = RequestNameReply(reply.body[0]) # type: ignore[union-attr] except Exception as e: callback(None, e) return callback(result, None) self._call(message, reply_notify) def release_name( self, name: str, callback: None | (Callable[[ReleaseNameReply | None, Exception | None], None]) = None, check_callback_type: bool = True, ) -> None: """Request that this message bus release the given name. :param name: The name to release. :type name: str :param callback: A callback that will be called with the reply of the release request as a :class:`ReleaseNameReply `. :type callback: :class:`Callable` :raises: - :class:`InvalidBusNameError ` - If the given bus name is not valid. """ assert_bus_name_valid(name) if callback is not None and check_callback_type: BaseMessageBus._check_callback_type(callback) message = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="ReleaseName", signature="s", body=[name], ) if callback is None: self._call(message, None) return def reply_notify(reply: Message | None, err: Exception | None) -> None: try: BaseMessageBus._check_method_return(reply, err, "u") result = ReleaseNameReply(reply.body[0]) # type: ignore[union-attr] except Exception as e: callback(None, e) return callback(result, None) self._call(message, reply_notify) def get_proxy_object( self, bus_name: str, path: str, introspection: intr.Node | str | ET.Element ) -> BaseProxyObject: """Get a proxy object for the path exported on the bus that owns the name. The object is expected to export the interfaces and nodes specified in the introspection data. This is the entry point into the high-level client. :param bus_name: The name on the bus to get the proxy object for. :type bus_name: str :param path: The path on the client for the proxy object. :type path: str :param introspection: XML introspection data used to build the interfaces on the proxy object. :type introspection: :class:`Node ` or str or :class:`ElementTree` :returns: A proxy object for the given path on the given name. :rtype: :class:`BaseProxyObject ` :raises: - :class:`InvalidBusNameError ` - If the given bus name is not valid. - :class:`InvalidObjectPathError ` - If the given object path is not valid. - :class:`InvalidIntrospectionError ` - If the introspection data for the node is not valid. """ if self._ProxyObject is None: raise Exception( "the message bus implementation did not provide a proxy object class" ) self._init_high_level_client() return self._ProxyObject(bus_name, path, introspection, self) def disconnect(self) -> None: """Disconnect the message bus by closing the underlying connection asynchronously. All pending and future calls will error with a connection error. """ self._user_disconnect = True if self._sock: try: self._sock.shutdown(socket.SHUT_RDWR) except Exception: _LOGGER.warning("could not shut down socket", exc_info=True) def next_serial(self) -> int: """Get the next serial for this bus. This can be used as the ``serial`` attribute of a :class:`Message ` to manually handle the serial of messages. :returns: The next serial for the bus. :rtype: int """ self._serial += 1 return self._serial def add_message_handler( self, handler: Callable[[Message], Message | bool | None] ) -> None: """Add a custom message handler for incoming messages. The handler should be a callable that takes a :class:`Message `. If the message is a method call, you may return another Message as a reply and it will be marked as handled. You may also return ``True`` to mark the message as handled without sending a reply. :param handler: A handler that will be run for every message the bus connection received. :type handler: :class:`Callable` or None """ error_text = "a message handler must be callable with a single parameter" if not callable(handler): raise TypeError(error_text) handler_signature = inspect.signature(handler) if len(handler_signature.parameters) != 1: raise TypeError(error_text) self._user_message_handlers.append(handler) def remove_message_handler( self, handler: Callable[[Message], Message | bool | None] ) -> None: """Remove a message handler that was previously added by :func:`add_message_handler() `. :param handler: A message handler. :type handler: :class:`Callable` """ for i, h in enumerate(self._user_message_handlers): if h == handler: del self._user_message_handlers[i] return def send(self, msg: Message) -> None: """Asynchronously send a message on the message bus. :param msg: The message to send. :type msg: :class:`Message ` """ raise NotImplementedError( 'the "send" method must be implemented in the inheriting class' ) def _finalize(self, err: Exception | None) -> None: """should be called after the socket disconnects with the disconnection error to clean up resources and put the bus in a disconnected state""" if self._disconnected: return self._disconnected = True for handler in self._method_return_handlers.values(): try: handler(None, err) except Exception: _LOGGER.warning( "a message handler threw an exception on shutdown", exc_info=True ) self._method_return_handlers.clear() for path in list(self._path_exports): self.unexport(path) self._user_message_handlers.clear() def _interface_signal_notify( self, interface: ServiceInterface, interface_name: str, member: str, signature: str, body: list[Any], unix_fds: list[int] = [], ) -> None: path: str | None = None for p, ifaces in self._path_exports.items(): for i in ifaces.values(): if i is interface: path = p if path is None: raise Exception( "Could not find interface on bus (this is a bug in dbus-fast)" ) self.send( Message.new_signal( path=path, interface=interface_name, member=member, signature=signature, body=body, unix_fds=unix_fds, ) ) def _introspect_export_path(self, path: str) -> intr.Node: assert_object_path_valid(path) if (interfaces := self._path_exports.get(path)) is not None: node = intr.Node.default(path) for interface in interfaces.values(): node.interfaces.append(interface.introspect()) else: node = intr.Node(path) children = set() for export_path in self._path_exports: if not export_path.startswith(path): continue child_path = export_path.split(path, maxsplit=1)[1] if path != "/" and child_path and child_path[0] != "/": continue child_path = child_path.lstrip("/") child_name = child_path.split("/", maxsplit=1)[0] children.add(child_name) node.nodes = [intr.Node(name) for name in children if name] return node def _setup_socket(self) -> None: err = None for transport, options in self._bus_address: filename: bytes | str | None = None ip_addr = "" ip_port = 0 if transport == "unix": self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self._stream = self._sock.makefile("rwb") self._fd = self._sock.fileno() if "path" in options: filename = options["path"] elif "abstract" in options: filename = b"\0" + options["abstract"].encode() else: raise InvalidAddressError( "got unix transport with unknown path specifier" ) try: self._sock.connect(filename) self._sock.setblocking(False) break except Exception as e: err = e elif transport == "tcp": self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._stream = self._sock.makefile("rwb") self._fd = self._sock.fileno() if "host" in options: ip_addr = options["host"] if "port" in options: ip_port = int(options["port"]) try: self._sock.connect((ip_addr, ip_port)) self._sock.setblocking(False) break except Exception as e: err = e else: raise InvalidAddressError(f"got unknown address transport: {transport}") if err: raise err def _reply_notify( self, msg: Message, callback: Callable[[Message | None, Exception | None], None], reply: Message | None, err: Exception | None, ) -> None: """Callback on reply.""" if reply and msg.destination and reply.sender: self._name_owners[msg.destination] = reply.sender callback(reply, err) def _call( self, msg: Message, callback: Callable[[Message | None, Exception | None], None] | None, ) -> None: if not msg.serial: msg.serial = self.next_serial() # Make sure the return reply handler is installed # before sending the message to avoid a race condition # where the reply is lost in case the backend can # send it right away. if (reply_expected := _expects_reply(msg)) and callback is not None: self._method_return_handlers[msg.serial] = partial( self._reply_notify, msg, callback ) self.send(msg) if not reply_expected and callback is not None: callback(None, None) @staticmethod def _check_callback_type(callback: Callable) -> None: """Raise a TypeError if the user gives an invalid callback as a parameter""" text = "a callback must be callable with two parameters" if not callable(callback): raise TypeError(text) fn_signature = inspect.signature(callback) if len(fn_signature.parameters) != 2: raise TypeError(text) @staticmethod def _check_method_return( msg: Message | None, err: Exception | None, signature: str ) -> None: if err: raise err if msg is None: raise DBusError( ErrorType.INTERNAL_ERROR, "invalid message type for method call", msg ) if msg.message_type == MessageType.METHOD_RETURN and msg.signature == signature: return if msg.message_type == MessageType.ERROR: raise DBusError._from_message(msg) raise DBusError( ErrorType.INTERNAL_ERROR, "invalid message type for method call", msg ) def _process_message(self, msg: _Message) -> None: """Process a message received from the message bus.""" handled = False for user_handler in self._user_message_handlers: try: if result := user_handler(msg): if type(result) is Message: self.send(result) handled = True break except DBusError as e: if msg.message_type is MESSAGE_TYPE_CALL: self.send(e._as_message(msg)) handled = True break _LOGGER.exception("A message handler raised an exception: %s", e) except Exception as e: _LOGGER.exception("A message handler raised an exception: %s", e) if msg.message_type is MESSAGE_TYPE_CALL: self.send( Message.new_error( msg, ErrorType.INTERNAL_ERROR, f"An internal error occurred: {e}.\n{traceback.format_exc()}", ) ) handled = True break if msg.message_type is MESSAGE_TYPE_SIGNAL: if ( msg.member == "NameOwnerChanged" and msg.sender == "org.freedesktop.DBus" and msg.path == "/org/freedesktop/DBus" and msg.interface == "org.freedesktop.DBus" ): name = msg.body[0] if new_owner := msg.body[2]: self._name_owners[name] = new_owner elif name in self._name_owners: del self._name_owners[name] return if msg.message_type is MESSAGE_TYPE_CALL: if not handled: handler = self._find_message_handler(msg) if not _expects_reply(msg): if handler: handler(msg, BLOCK_UNEXPECTED_REPLY) # type: ignore[arg-type] else: _LOGGER.error( '"%s.%s" with signature "%s" could not be found', msg.interface, msg.member, msg.signature, ) return send_reply = SendReply(self, msg) with send_reply: if handler: handler(msg, send_reply) else: send_reply( Message.new_error( msg, ErrorType.UNKNOWN_METHOD, f"{msg.interface}.{msg.member} with signature " f'"{msg.signature}" could not be found', ) ) return # An ERROR or a METHOD_RETURN return_handler = self._method_return_handlers.get(msg.reply_serial) if return_handler is not None: if not handled: return_handler(msg, None) del self._method_return_handlers[msg.reply_serial] def _callback_method_handler( self, interface: ServiceInterface, method: _Method, msg: Message, send_reply: SendReply, ) -> None: """This is the callback that will be called when a method call is.""" args = ServiceInterface._c_msg_body_to_args(msg) if msg.unix_fds else msg.body result = method.fn(interface, *args) if send_reply is BLOCK_UNEXPECTED_REPLY or _expects_reply(msg) is False: return body_fds = ServiceInterface._c_fn_result_to_body( result, method.out_signature_tree, self._negotiate_unix_fd, ) send_reply( Message( message_type=MessageType.METHOD_RETURN, reply_serial=msg.serial, destination=msg.sender, signature=method.out_signature, body=body_fds[0], unix_fds=body_fds[1], ) ) def _make_method_handler( self, interface: ServiceInterface, method: _Method ) -> HandlerType: return partial(self._callback_method_handler, interface, method) def _find_message_handler(self, msg: _Message) -> HandlerType | None: """Find the message handler for for METHOD_CALL messages.""" if TYPE_CHECKING: assert msg.member is not None assert msg.path is not None if msg.interface is not None and "org.freedesktop.DBus." in msg.interface: if ( msg.interface == "org.freedesktop.DBus.Introspectable" and msg.member == "Introspect" and msg.signature == "" ): return self._default_introspect_handler if msg.interface == "org.freedesktop.DBus.Properties": return self._default_properties_handler if msg.interface == "org.freedesktop.DBus.Peer": if msg.member == "Ping" and msg.signature == "": return self._default_ping_handler if msg.member == "GetMachineId" and msg.signature == "": return self._default_get_machine_id_handler if ( msg.interface == "org.freedesktop.DBus.ObjectManager" and msg.member == "GetManagedObjects" ): return self._default_get_managed_objects_handler if (interfaces := self._path_exports.get(msg.path)) is None: return None if msg.interface is None: return self._find_any_message_handler_matching_signature(interfaces, msg) if (interface := interfaces.get(msg.interface)) is not None and ( handler := ServiceInterface._get_enabled_handler_by_name_signature( interface, self, msg.member, msg.signature ) ) is not None: return handler return None def _find_any_message_handler_matching_signature( self, interfaces: dict[str, ServiceInterface], msg: _Message ) -> HandlerType | None: # No interface, so we need to search all interfaces for the method # with a matching signature for interface in interfaces.values(): if ( handler := ServiceInterface._get_enabled_handler_by_name_signature( interface, self, msg.member, msg.signature ) ) is not None: return handler return None def _default_introspect_handler(self, msg: Message, send_reply: SendReply) -> None: if TYPE_CHECKING: assert msg.path is not None introspection = self._introspect_export_path(msg.path).tostring() send_reply(Message.new_method_return(msg, "s", [introspection])) def _default_ping_handler(self, msg: Message, send_reply: SendReply) -> None: send_reply(Message.new_method_return(msg)) def _send_machine_id_reply(self, msg: Message, send_reply: SendReply) -> None: send_reply(Message.new_method_return(msg, "s", [self._machine_id])) def _default_get_machine_id_handler( self, msg: Message, send_reply: SendReply ) -> None: if self._machine_id: self._send_machine_id_reply(msg, send_reply) return def reply_handler(reply: Message | None, err: Exception | None) -> None: if err or reply is None: # the bus has been disconnected, cannot send a reply return if reply.message_type == MessageType.METHOD_RETURN: self._machine_id = reply.body[0] self._send_machine_id_reply(msg, send_reply) elif ( reply.message_type == MessageType.ERROR and reply.error_name is not None ): send_reply(Message.new_error(msg, reply.error_name, str(reply.body))) else: send_reply( Message.new_error(msg, ErrorType.FAILED, "could not get machine_id") ) self._call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus.Peer", member="GetMachineId", ), reply_handler, ) def _default_get_managed_objects_handler( self, msg: Message, send_reply: SendReply ) -> None: result_signature = "a{oa{sa{sv}}}" error_handled = False def is_result_complete() -> bool: if not result: return True for n, interfaces in result.items(): for value in interfaces.values(): if value is None: return False return True if TYPE_CHECKING: assert msg.path is not None nodes = [ node for node in self._path_exports if msg.path == "/" or node.startswith(msg.path + "/") ] # first build up the result object to know when it's complete result: dict[str, dict[str, Any]] = { node: dict.fromkeys(self._path_exports[node]) for node in nodes } if is_result_complete(): send_reply(Message.new_method_return(msg, result_signature, [result])) return def get_all_properties_callback( interface: ServiceInterface, values: Any, node: str, err: Exception | None ) -> None: nonlocal error_handled if err is not None: if not error_handled: error_handled = True send_reply.send_error(err) return result[node][interface.name] = values if is_result_complete(): send_reply(Message.new_method_return(msg, result_signature, [result])) for node in nodes: for interface in self._path_exports[node].values(): ServiceInterface._get_all_property_values( interface, get_all_properties_callback, node ) def _default_properties_handler(self, msg: Message, send_reply: SendReply) -> None: methods = {"Get": "ss", "Set": "ssv", "GetAll": "s"} if msg.member not in methods or methods[msg.member] != msg.signature: raise DBusError( ErrorType.UNKNOWN_METHOD, f'properties interface doesn\'t have method "{msg.member}" with signature "{msg.signature}"', ) interface_name = msg.body[0] if interface_name == "": raise DBusError( ErrorType.NOT_SUPPORTED, "getting and setting properties with an empty interface string is not supported yet", ) if msg.path not in self._path_exports: raise DBusError( ErrorType.UNKNOWN_OBJECT, f'no interfaces at path: "{msg.path}"' ) if (interface := self._path_exports[msg.path].get(interface_name)) is None: if interface_name in [ "org.freedesktop.DBus.Properties", "org.freedesktop.DBus.Introspectable", "org.freedesktop.DBus.Peer", "org.freedesktop.DBus.ObjectManager", ]: # the standard interfaces do not have properties if msg.member == "Get" or msg.member == "Set": prop_name = msg.body[1] raise DBusError( ErrorType.UNKNOWN_PROPERTY, f'interface "{interface_name}" does not have property "{prop_name}"', ) if msg.member == "GetAll": send_reply(Message.new_method_return(msg, "a{sv}", [{}])) return assert False raise DBusError( ErrorType.UNKNOWN_INTERFACE, f'could not find an interface "{interface_name}" at path: "{msg.path}"', ) properties = ServiceInterface._get_properties(interface) if msg.member == "Get" or msg.member == "Set": prop_name = msg.body[1] match = [ prop for prop in properties if prop.name == prop_name and not prop.disabled ] if not match: raise DBusError( ErrorType.UNKNOWN_PROPERTY, f'interface "{interface_name}" does not have property "{prop_name}"', ) prop = match[0] if msg.member == "Get": if not prop.access.readable(): raise DBusError( ErrorType.UNKNOWN_PROPERTY, "the property does not have read access", ) def get_property_callback( interface: ServiceInterface, prop: _Property, prop_value: Any, err: Exception | None, ) -> None: try: if err is not None: send_reply.send_error(err) return body, unix_fds = replace_fds_with_idx( prop.signature, [prop_value] ) send_reply( Message.new_method_return( msg, "v", [Variant(prop.signature, body[0])], unix_fds=unix_fds, ) ) except Exception as e: send_reply.send_error(e) ServiceInterface._get_property_value( interface, prop, get_property_callback ) elif msg.member == "Set": if not prop.access.writable(): raise DBusError( ErrorType.PROPERTY_READ_ONLY, "the property is readonly" ) value = msg.body[2] if value.signature != prop.signature: raise DBusError( ErrorType.INVALID_SIGNATURE, f'wrong signature for property. expected "{prop.signature}"', ) assert prop.prop_setter def set_property_callback( interface: ServiceInterface, prop: _Property, err: Exception | None ) -> None: if err is not None: send_reply.send_error(err) return send_reply(Message.new_method_return(msg)) body = replace_idx_with_fds( value.signature, [value.value], msg.unix_fds ) ServiceInterface._set_property_value( interface, prop, body[0], set_property_callback ) elif msg.member == "GetAll": def get_all_properties_callback( interface: ServiceInterface, values: Any, user_data: Any, err: Exception | None, ) -> None: if err is not None: send_reply.send_error(err) return body, unix_fds = replace_fds_with_idx("a{sv}", [values]) send_reply( Message.new_method_return(msg, "a{sv}", body, unix_fds=unix_fds) ) ServiceInterface._get_all_property_values( interface, get_all_properties_callback ) else: assert False def _init_high_level_client(self) -> None: """The high level client is initialized when the first proxy object is gotten. Currently just sets up the match rules for the name owner cache so signals can be routed to the right objects.""" if self._high_level_client_initialized: return self._high_level_client_initialized = True def add_match_notify(msg: Message | None, err: Exception | None) -> None: if err: _LOGGER.error( f'add match request failed. match="{self._name_owner_match_rule}", {err}' ) elif msg is not None and msg.message_type == MessageType.ERROR: _LOGGER.error( f'add match request failed. match="{self._name_owner_match_rule}", {msg.body[0]}' ) self._call( Message( destination="org.freedesktop.DBus", interface="org.freedesktop.DBus", path="/org/freedesktop/DBus", member="AddMatch", signature="s", body=[self._name_owner_match_rule], ), add_match_notify, ) def _add_match_rule(self, match_rule: str) -> None: """Add a match rule. Match rules added by this function are refcounted and must be removed by _remove_match_rule(). This is for use in the high level client only.""" if match_rule == self._name_owner_match_rule: return if match_rule in self._match_rules: self._match_rules[match_rule] += 1 return self._match_rules[match_rule] = 1 def add_match_notify(msg: Message | None, err: Exception | None) -> None: if err: _LOGGER.error(f'add match request failed. match="{match_rule}", {err}') elif msg is not None and msg.message_type == MessageType.ERROR: _LOGGER.error( f'add match request failed. match="{match_rule}", {msg.body[0]}' ) self._call( Message( destination="org.freedesktop.DBus", interface="org.freedesktop.DBus", path="/org/freedesktop/DBus", member="AddMatch", signature="s", body=[match_rule], ), add_match_notify, ) def _remove_match_rule(self, match_rule: str) -> None: """Remove a match rule added with _add_match_rule(). This is for use in the high level client only.""" if match_rule == self._name_owner_match_rule: return if match_rule in self._match_rules: self._match_rules[match_rule] -= 1 if self._match_rules[match_rule] > 0: return del self._match_rules[match_rule] def remove_match_notify(msg: Message | None, err: Exception | None) -> None: if self._disconnected: return if err: _LOGGER.error( f'remove match request failed. match="{match_rule}", {err}' ) elif msg is not None and msg.message_type == MessageType.ERROR: _LOGGER.error( f'remove match request failed. match="{match_rule}", {msg.body[0]}' ) self._call( Message( destination="org.freedesktop.DBus", interface="org.freedesktop.DBus", path="/org/freedesktop/DBus", member="RemoveMatch", signature="s", body=[match_rule], ), remove_match_notify, ) dbus-fast-2.44.1/src/dbus_fast/proxy_object.py000066400000000000000000000344521477355613200213410ustar00rootroot00000000000000from __future__ import annotations import asyncio import inspect import logging import re import xml.etree.ElementTree as ET from collections.abc import Coroutine from dataclasses import dataclass from functools import lru_cache from typing import Callable from . import introspection as intr from . import message_bus from ._private.util import replace_idx_with_fds from .constants import ErrorType, MessageType from .errors import DBusError, InterfaceNotFoundError from .message import Message from .unpack import unpack_variants as unpack from .validators import assert_bus_name_valid, assert_object_path_valid _LOGGER = logging.getLogger(__name__) @dataclass class SignalHandler: """Signal handler.""" fn: Callable | Coroutine unpack_variants: bool class BaseProxyInterface: """An abstract class representing a proxy to an interface exported on the bus by another client. Implementations of this class are not meant to be constructed directly by users. Use :func:`BaseProxyObject.get_interface` to get a proxy interface. Each message bus implementation provides its own proxy interface implementation that will be returned by that method. Proxy interfaces can be used to call methods, get properties, and listen to signals on the interface. Proxy interfaces are created dynamically with a family of methods for each of these operations based on what members the interface exposes. Each proxy interface implementation exposes these members in a different way depending on the features of the backend. See the documentation of the proxy interface implementation you use for more details. :ivar bus_name: The name of the bus this interface is exported on. :vartype bus_name: str :ivar path: The object path exported on the client that owns the bus name. :vartype path: str :ivar introspection: Parsed introspection data for the proxy interface. :vartype introspection: :class:`Node ` :ivar bus: The message bus this proxy interface is connected to. :vartype bus: :class:`BaseMessageBus ` """ def __init__( self, bus_name: str, path: str, introspection: intr.Interface, bus: message_bus.BaseMessageBus, ) -> None: self.bus_name = bus_name self.path = path self.introspection = introspection self.bus = bus self._signal_handlers: dict[str, list[SignalHandler]] = {} self._signal_match_rule = f"type='signal',sender={bus_name},interface={introspection.name},path={path}" self._background_tasks: set[asyncio.Task] = set() _underscorer1 = re.compile(r"(.)([A-Z][a-z]+)") _underscorer2 = re.compile(r"([a-z0-9])([A-Z])") @staticmethod @lru_cache(maxsize=128) def _to_snake_case(member: str) -> str: subbed = BaseProxyInterface._underscorer1.sub(r"\1_\2", member) return BaseProxyInterface._underscorer2.sub(r"\1_\2", subbed).lower() @staticmethod def _check_method_return(msg: Message, signature: str | None = None): if msg.message_type == MessageType.ERROR: raise DBusError._from_message(msg) if msg.message_type != MessageType.METHOD_RETURN: raise DBusError( ErrorType.CLIENT_ERROR, "method call didnt return a method return", msg ) if signature is not None and msg.signature != signature: raise DBusError( ErrorType.CLIENT_ERROR, f'method call returned unexpected signature: "{msg.signature}"', msg, ) def _add_method(self, intr_method: intr.Method) -> None: raise NotImplementedError("this must be implemented in the inheriting class") def _add_property(self, intr_property: intr.Property) -> None: raise NotImplementedError("this must be implemented in the inheriting class") def _message_handler(self, msg: Message) -> None: if ( msg.message_type != MessageType.SIGNAL or msg.interface != self.introspection.name or msg.path != self.path or msg.member not in self._signal_handlers ): return if ( msg.sender != self.bus_name and self.bus._name_owners.get(self.bus_name, "") != msg.sender ): # The sender is always a unique name, but the bus name given might # be a well known name. If the sender isn't an exact match, check # to see if it owns the bus_name we were given from the cache kept # on the bus for this purpose. return match = [s for s in self.introspection.signals if s.name == msg.member] if not match: return intr_signal = match[0] if intr_signal.signature != msg.signature: _LOGGER.warning( f'got signal "{self.introspection.name}.{msg.member}" with unexpected signature "{msg.signature}"' ) return body = replace_idx_with_fds(msg.signature, msg.body, msg.unix_fds) no_sig = None for handler in self._signal_handlers[msg.member]: if handler.unpack_variants: if not no_sig: no_sig = unpack(body) data = no_sig else: data = body cb_result = handler.fn(*data) if isinstance(cb_result, Coroutine): # Save a strong reference to the task so it doesn't get garbage # collected before it finishes. task = asyncio.create_task(cb_result) self._background_tasks.add(task) task.add_done_callback(self._background_tasks.remove) def _add_signal(self, intr_signal: intr.Signal, interface: intr.Interface) -> None: def on_signal_fn(fn: Callable | Coroutine, *, unpack_variants: bool = False): fn_signature = inspect.signature(fn) if ( len( [ par for par in fn_signature.parameters.values() if par.kind == inspect.Parameter.KEYWORD_ONLY and par.default == inspect.Parameter.empty ] ) > 0 ): raise TypeError( "reply_notify cannot have required keyword only parameters" ) positional_params = [ par.kind for par in fn_signature.parameters.values() if par.kind not in [inspect.Parameter.KEYWORD_ONLY, inspect.Parameter.VAR_KEYWORD] ] if len(positional_params) != len(intr_signal.args) and ( inspect.Parameter.VAR_POSITIONAL not in positional_params or len(positional_params) - 1 > len(intr_signal.args) ): raise TypeError( f"reply_notify must be a function with {len(intr_signal.args)} positional parameters" ) if not self._signal_handlers: self.bus._add_match_rule(self._signal_match_rule) self.bus.add_message_handler(self._message_handler) if intr_signal.name not in self._signal_handlers: self._signal_handlers[intr_signal.name] = [] self._signal_handlers[intr_signal.name].append( SignalHandler(fn, unpack_variants) ) def off_signal_fn( fn: Callable | Coroutine, *, unpack_variants: bool = False ) -> None: try: i = self._signal_handlers[intr_signal.name].index( SignalHandler(fn, unpack_variants) ) del self._signal_handlers[intr_signal.name][i] if not self._signal_handlers[intr_signal.name]: del self._signal_handlers[intr_signal.name] except (KeyError, ValueError): return if not self._signal_handlers: self.bus._remove_match_rule(self._signal_match_rule) self.bus.remove_message_handler(self._message_handler) snake_case = BaseProxyInterface._to_snake_case(intr_signal.name) setattr(interface, f"on_{snake_case}", on_signal_fn) setattr(interface, f"off_{snake_case}", off_signal_fn) class BaseProxyObject: """An abstract class representing a proxy to an object exported on the bus by another client. Implementations of this class are not meant to be constructed directly. Use :func:`BaseMessageBus.get_proxy_object() ` to get a proxy object. Each message bus implementation provides its own proxy object implementation that will be returned by that method. The primary use of the proxy object is to select a proxy interface to act on. Information on what interfaces are available is provided by introspection data provided to this class. This introspection data can either be included in your project as an XML file (recommended) or retrieved from the ``org.freedesktop.DBus.Introspectable`` interface at runtime. :ivar bus_name: The name of the bus this object is exported on. :vartype bus_name: str :ivar path: The object path exported on the client that owns the bus name. :vartype path: str :ivar introspection: Parsed introspection data for the proxy object. :vartype introspection: :class:`Node ` :ivar bus: The message bus this proxy object is connected to. :vartype bus: :class:`BaseMessageBus ` :ivar ~.ProxyInterface: The proxy interface class this proxy object uses. :vartype ~.ProxyInterface: Type[:class:`BaseProxyInterface `] :ivar child_paths: A list of absolute object paths of the children of this object. :vartype child_paths: list(str) :raises: - :class:`InvalidBusNameError ` - If the given bus name is not valid. - :class:`InvalidObjectPathError ` - If the given object path is not valid. - :class:`InvalidIntrospectionError ` - If the introspection data for the node is not valid. """ def __init__( self, bus_name: str, path: str, introspection: intr.Node | str | ET.Element, bus: message_bus.BaseMessageBus, ProxyInterface: type[BaseProxyInterface], ) -> None: assert_object_path_valid(path) assert_bus_name_valid(bus_name) if not isinstance(bus, message_bus.BaseMessageBus): raise TypeError("bus must be an instance of BaseMessageBus") if not issubclass(ProxyInterface, BaseProxyInterface): raise TypeError("ProxyInterface must be an instance of BaseProxyInterface") if type(introspection) is intr.Node: self.introspection = introspection elif type(introspection) is str: self.introspection = intr.Node.parse(introspection) elif type(introspection) is ET.Element: self.introspection = intr.Node.from_xml(introspection) else: raise TypeError( "introspection must be xml node introspection or introspection.Node class" ) self.bus_name = bus_name self.path = path self.bus = bus self.ProxyInterface = ProxyInterface self.child_paths = [f"{path}/{n.name}" for n in self.introspection.nodes] self._interfaces = {} # lazy loaded by get_children() self._children = None def get_interface(self, name: str) -> BaseProxyInterface: """Get an interface exported on this proxy object and connect it to the bus. :param name: The name of the interface to retrieve. :type name: str :raises: - :class:`InterfaceNotFoundError ` - If there is no interface by this name exported on the bus. """ if name in self._interfaces: return self._interfaces[name] try: intr_interface = next( i for i in self.introspection.interfaces if i.name == name ) except StopIteration as ex: raise InterfaceNotFoundError( f"interface not found on this object: {name}" ) from ex interface = self.ProxyInterface( self.bus_name, self.path, intr_interface, self.bus ) for intr_method in intr_interface.methods: interface._add_method(intr_method) for intr_property in intr_interface.properties: interface._add_property(intr_property) for intr_signal in intr_interface.signals: interface._add_signal(intr_signal, interface) def get_owner_notify(msg: Message, err: Exception | None) -> None: if err: _LOGGER.error(f'getting name owner for "{name}" failed, {err}') return if msg.message_type == MessageType.ERROR: if msg.error_name != ErrorType.NAME_HAS_NO_OWNER.value: _LOGGER.error( f'getting name owner for "{name}" failed, {msg.body[0]}' ) return self.bus._name_owners[self.bus_name] = msg.body[0] if self.bus_name[0] != ":" and not self.bus._name_owners.get(self.bus_name, ""): self.bus._call( Message( destination="org.freedesktop.DBus", interface="org.freedesktop.DBus", path="/org/freedesktop/DBus", member="GetNameOwner", signature="s", body=[self.bus_name], ), get_owner_notify, ) self._interfaces[name] = interface return interface def get_children(self) -> list[BaseProxyObject]: """Get the child nodes of this proxy object according to the introspection data.""" if self._children is None: self._children = [ self.__class__(self.bus_name, self.path, child, self.bus) for child in self.introspection.nodes ] return self._children dbus-fast-2.44.1/src/dbus_fast/py.typed000066400000000000000000000000001477355613200177350ustar00rootroot00000000000000dbus-fast-2.44.1/src/dbus_fast/send_reply.py000066400000000000000000000031621477355613200207700ustar00rootroot00000000000000from __future__ import annotations import traceback from types import TracebackType from typing import TYPE_CHECKING from .constants import ErrorType from .errors import DBusError from .message import Message if TYPE_CHECKING: from .message_bus import BaseMessageBus class SendReply: """A context manager to send a reply to a message.""" __slots__ = ("_bus", "_msg") def __init__(self, bus: BaseMessageBus, msg: Message) -> None: """Create a new reply context manager.""" self._bus = bus self._msg = msg def __enter__(self) -> SendReply: return self def __call__(self, reply: Message) -> None: self._bus.send(reply) def _exit( self, exc_type: type[Exception] | None, exc_value: Exception | None, tb: TracebackType | None, ) -> bool: if exc_value: if isinstance(exc_value, DBusError): self(exc_value._as_message(self._msg)) else: self( Message.new_error( self._msg, ErrorType.SERVICE_ERROR, f"The service interface raised an error: {exc_value}.\n{traceback.format_tb(tb)}", ) ) return True return False def __exit__( self, exc_type: type[Exception] | None, exc_value: Exception | None, tb: TracebackType | None, ) -> bool: return self._exit(exc_type, exc_value, tb) def send_error(self, exc: Exception) -> None: self._exit(exc.__class__, exc, exc.__traceback__) dbus-fast-2.44.1/src/dbus_fast/service.pxd000066400000000000000000000022411477355613200204240ustar00rootroot00000000000000"""cdefs for service.py""" import cython from .message cimport Message from .signature cimport SignatureTree cdef class _Method: cdef public str name cdef public object fn cdef public bint disabled cdef public object introspection cdef public str in_signature cdef public str out_signature cdef public SignatureTree in_signature_tree cdef public SignatureTree out_signature_tree cdef tuple _real_fn_result_to_body( object result, SignatureTree signature_tree, bint replace_fds ) cdef class ServiceInterface: cdef public str name cdef list __methods cdef list __properties cdef list __signals cdef set __buses cdef dict __handlers cdef dict __enabled_handlers_by_name_signature @cython.locals(handlers=dict,in_signature=str,method=_Method) @staticmethod cdef object _get_enabled_handler_by_name_signature(ServiceInterface interface, object bus, object name, object signature) @staticmethod cdef list _c_msg_body_to_args(Message msg) @staticmethod cdef tuple _c_fn_result_to_body( object result, SignatureTree signature_tree, bint replace_fds, ) dbus-fast-2.44.1/src/dbus_fast/service.py000066400000000000000000000576041477355613200202760ustar00rootroot00000000000000from __future__ import annotations import asyncio import copy import inspect from functools import wraps from typing import TYPE_CHECKING, Any, Callable, Protocol from . import introspection as intr from ._private.util import ( parse_annotation, replace_fds_with_idx, replace_idx_with_fds, signature_contains_type, ) from .constants import PropertyAccess from .errors import SignalDisabledError from .message import Message from .send_reply import SendReply from .signature import ( SignatureBodyMismatchError, SignatureTree, Variant, get_signature_tree, ) if TYPE_CHECKING: from .message_bus import BaseMessageBus str_ = str HandlerType = Callable[[Message, SendReply], None] class _MethodCallbackProtocol(Protocol): def __call__(self, interface: ServiceInterface, *args: Any) -> Any: ... class _Method: def __init__( self, fn: _MethodCallbackProtocol, name: str, disabled: bool = False ) -> None: in_signature = "" out_signature = "" inspection = inspect.signature(fn) in_args: list[intr.Arg] = [] for i, param in enumerate(inspection.parameters.values()): if i == 0: # first is self continue annotation = parse_annotation(param.annotation) if not annotation: raise ValueError( "method parameters must specify the dbus type string as an annotation" ) in_args.append(intr.Arg(annotation, intr.ArgDirection.IN, param.name)) in_signature += annotation out_args: list[intr.Arg] = [] out_signature = parse_annotation(inspection.return_annotation) if out_signature: for type_ in get_signature_tree(out_signature).types: out_args.append(intr.Arg(type_, intr.ArgDirection.OUT)) self.name = name self.fn = fn self.disabled = disabled self.introspection = intr.Method(name, in_args, out_args) self.in_signature = in_signature self.out_signature = out_signature self.in_signature_tree = get_signature_tree(in_signature) self.out_signature_tree = get_signature_tree(out_signature) def method(name: str | None = None, disabled: bool = False) -> Callable: """A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus service method. The parameters and return value must each be annotated with a signature string of a single complete DBus type. This class method will be called when a client calls the method on the DBus interface. The parameters given to the function come from the calling client and will conform to the dbus-fast type system. The parameters returned will be returned to the calling client and must conform to the dbus-fast type system. If multiple parameters are returned, they must be contained within a :class:`list`. The decorated method may raise a :class:`DBusError ` to return an error to the client. :param name: The member name that DBus clients will use to call this method. Defaults to the name of the class method. :type name: str :param disabled: If set to true, the method will not be visible to clients. :type disabled: bool :example: :: @method() def echo(self, val: 's') -> 's': return val @method() def echo_two(self, val1: 's', val2: 'u') -> 'su': return [val1, val2] """ if name is not None and type(name) is not str: raise TypeError("name must be a string") if type(disabled) is not bool: raise TypeError("disabled must be a bool") def decorator(fn: Callable) -> Callable: @wraps(fn) def wrapped(*args: Any, **kwargs: Any) -> None: fn(*args, **kwargs) fn_name = name if name else fn.__name__ wrapped.__dict__["__DBUS_METHOD"] = _Method(fn, fn_name, disabled=disabled) return wrapped return decorator class _Signal: def __init__(self, fn: Callable, name: str, disabled: bool = False) -> None: inspection = inspect.signature(fn) args = [] signature = "" signature_tree = None return_annotation = parse_annotation(inspection.return_annotation) if return_annotation: signature = return_annotation signature_tree = get_signature_tree(signature) for type_ in signature_tree.types: args.append(intr.Arg(type_, intr.ArgDirection.OUT)) else: signature = "" signature_tree = get_signature_tree("") self.signature = signature self.signature_tree = signature_tree self.name = name self.disabled = disabled self.introspection = intr.Signal(self.name, args) def signal(name: str | None = None, disabled: bool = False) -> Callable: """A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus signal. The signal is broadcast on the bus when the decorated class method is called by the user. If the signal has an out argument, the class method must have a return type annotation with a signature string of a single complete DBus type and the return value of the class method must conform to the dbus-fast type system. If the signal has multiple out arguments, they must be returned within a ``list``. :param name: The member name that will be used for this signal. Defaults to the name of the class method. :type name: str :param disabled: If set to true, the signal will not be visible to clients. :type disabled: bool :example: :: @signal() def string_signal(self, val) -> 's': return val @signal() def two_strings_signal(self, val1, val2) -> 'ss': return [val1, val2] """ if name is not None and type(name) is not str: raise TypeError("name must be a string") if type(disabled) is not bool: raise TypeError("disabled must be a bool") def decorator(fn: Callable) -> Callable: fn_name = name if name else fn.__name__ signal = _Signal(fn, fn_name, disabled) @wraps(fn) def wrapped(self, *args: Any, **kwargs: Any) -> Any: if signal.disabled: raise SignalDisabledError("Tried to call a disabled signal") result = fn(self, *args, **kwargs) ServiceInterface._handle_signal(self, signal, result) return result wrapped.__dict__["__DBUS_SIGNAL"] = signal return wrapped return decorator class _Property(property): def set_options(self, options: dict[str, Any]) -> None: self.options = getattr(self, "options", {}) for k, v in options.items(): self.options[k] = v if "name" in options and options["name"] is not None: self.name = options["name"] else: self.name = self.prop_getter.__name__ if "access" in options: self.access = PropertyAccess(options["access"]) else: self.access = PropertyAccess.READWRITE self.disabled = options.get("disabled", False) self.introspection = intr.Property(self.name, self.signature, self.access) self.__dict__["__DBUS_PROPERTY"] = True def __init__(self, fn, *args, **kwargs): self.prop_getter = fn self.prop_setter = None inspection = inspect.signature(fn) if len(inspection.parameters) != 1: raise ValueError('the property must only have the "self" input parameter') return_annotation = parse_annotation(inspection.return_annotation) if not return_annotation: raise ValueError( "the property must specify the dbus type string as a return annotation string" ) self.signature = return_annotation tree = get_signature_tree(return_annotation) if len(tree.types) != 1: raise ValueError("the property signature must be a single complete type") self.type = tree.types[0] if "options" in kwargs: options = kwargs["options"] self.set_options(options) del kwargs["options"] super().__init__(fn, *args, **kwargs) def setter(self, fn, **kwargs): # XXX The setter decorator seems to be recreating the class in the list # of class members and clobbering the options so we need to reset them. # Why does it do that? result = super().setter(fn, **kwargs) result.prop_setter = fn result.set_options(self.options) return result def dbus_property( access: PropertyAccess = PropertyAccess.READWRITE, name: str | None = None, disabled: bool = False, ) -> Callable: """A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus property. The class method must be a Python getter method with a return annotation that is a signature string of a single complete DBus type. When a client gets the property through the ``org.freedesktop.DBus.Properties`` interface, the getter will be called and the resulting value will be returned to the client. If the property is writable, it must have a setter method that takes a single parameter that is annotated with the same signature. When a client sets the property through the ``org.freedesktop.DBus.Properties`` interface, the setter will be called with the value from the calling client. The parameters of the getter and the setter must conform to the dbus-fast type system. The getter or the setter may raise a :class:`DBusError ` to return an error to the client. :param name: The name that DBus clients will use to interact with this property on the bus. :type name: str :param disabled: If set to true, the property will not be visible to clients. :type disabled: bool :example: :: @dbus_property() def string_prop(self) -> 's': return self._string_prop @string_prop.setter def string_prop(self, val: 's'): self._string_prop = val """ if type(access) is not PropertyAccess: raise TypeError("access must be a PropertyAccess class") if name is not None and type(name) is not str: raise TypeError("name must be a string") if type(disabled) is not bool: raise TypeError("disabled must be a bool") def decorator(fn: Callable) -> _Property: options = {"name": name, "access": access, "disabled": disabled} return _Property(fn, options=options) return decorator def _real_fn_result_to_body( result: Any | None, signature_tree: SignatureTree, replace_fds: bool, ) -> tuple[list[Any], list[int]]: out_len = len(signature_tree.types) if result is None: final_result = [] elif out_len == 1: final_result = [result] else: result_type = type(result) if result_type is not list and result_type is not tuple: raise SignatureBodyMismatchError( "Expected signal to return a list or tuple of arguments" ) final_result = result if out_len != len(final_result): raise SignatureBodyMismatchError( f"Signature and function return mismatch, expected " f"{len(signature_tree.types)} arguments but got {len(result)}" # type: ignore[arg-type] ) if not replace_fds: return final_result, [] return replace_fds_with_idx(signature_tree, final_result) class ServiceInterface: """An abstract class that can be extended by the user to define DBus services. Instances of :class:`ServiceInterface` can be exported on a path of the bus with the :class:`export ` method of a :class:`MessageBus `. Use the :func:`@method `, :func:`@dbus_property `, and :func:`@signal ` decorators to mark class methods as DBus methods, properties, and signals respectively. :ivar name: The name of this interface as it appears to clients. Must be a valid interface name. :vartype name: str """ def __init__(self, name: str) -> None: # TODO cannot be overridden by a dbus member self.name = name self.__methods: list[_Method] = [] self.__properties: list[_Property] = [] self.__signals: list[_Signal] = [] self.__buses: set[BaseMessageBus] = set() self.__handlers: dict[BaseMessageBus, dict[_Method, HandlerType]] = {} # Map of methods by bus of name -> method, handler self.__handlers_by_name_signature: dict[ BaseMessageBus, dict[str, tuple[_Method, HandlerType]] ] = {} for _, member in inspect.getmembers(type(self)): member_dict = getattr(member, "__dict__", {}) if type(member) is _Property: # XXX The getter and the setter may show up as different # members if they have different names. But if they have the # same name, they will be the same member. So we try to merge # them together here. I wish we could make this cleaner. found = False for prop in self.__properties: if prop.prop_getter is member.prop_getter: found = True if member.prop_setter is not None: prop.prop_setter = member.prop_setter if not found: self.__properties.append(member) elif "__DBUS_METHOD" in member_dict: method = member_dict["__DBUS_METHOD"] assert type(method) is _Method self.__methods.append(method) elif "__DBUS_SIGNAL" in member_dict: signal = member_dict["__DBUS_SIGNAL"] assert type(signal) is _Signal self.__signals.append(signal) # validate that writable properties have a setter for prop in self.__properties: if prop.access.writable() and prop.prop_setter is None: raise ValueError( f'property "{prop.name}" is writable but does not have a setter' ) def emit_properties_changed( self, changed_properties: dict[str, Any], invalidated_properties: list[str] = [] ) -> None: """Emit the ``org.freedesktop.DBus.Properties.PropertiesChanged`` signal. This signal is intended to be used to alert clients when a property of the interface has changed. :param changed_properties: The keys must be the names of properties exposed by this bus. The values must be valid for the signature of those properties. :type changed_properties: dict(str, Any) :param invalidated_properties: A list of names of properties that are now invalid (presumably for clients who cache the value). :type invalidated_properties: list(str) """ # TODO cannot be overridden by a dbus member variant_dict = {} for prop in ServiceInterface._get_properties(self): if prop.name in changed_properties: variant_dict[prop.name] = Variant( prop.signature, changed_properties[prop.name] ) body = [self.name, variant_dict, invalidated_properties] for bus in ServiceInterface._get_buses(self): bus._interface_signal_notify( self, "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", body, ) def introspect(self) -> intr.Interface: """Get introspection information for this interface. This might be useful for creating clients for the interface or examining the introspection output of an interface. :returns: The introspection data for the interface. :rtype: :class:`dbus_fast.introspection.Interface` """ # TODO cannot be overridden by a dbus member return intr.Interface( self.name, methods=[ method.introspection for method in ServiceInterface._get_methods(self) if not method.disabled ], signals=[ signal.introspection for signal in ServiceInterface._get_signals(self) if not signal.disabled ], properties=[ prop.introspection for prop in ServiceInterface._get_properties(self) if not prop.disabled ], ) @staticmethod def _get_properties(interface: ServiceInterface) -> list[_Property]: return interface.__properties @staticmethod def _get_methods(interface: ServiceInterface) -> list[_Method]: return interface.__methods @staticmethod def _get_signals(interface: ServiceInterface) -> list[_Signal]: return interface.__signals @staticmethod def _get_buses(interface: ServiceInterface) -> set[BaseMessageBus]: return interface.__buses @staticmethod def _get_handler( interface: ServiceInterface, method: _Method, bus: BaseMessageBus ) -> HandlerType: return interface.__handlers[bus][method] @staticmethod def _get_enabled_handler_by_name_signature( interface: ServiceInterface, bus: BaseMessageBus, name: str_, signature: str_, ) -> HandlerType | None: handlers = interface.__handlers_by_name_signature[bus] if (method_handler := handlers.get(name)) is None: return None method = method_handler[0] if method.disabled: return None return method_handler[1] if method.in_signature == signature else None @staticmethod def _add_bus( interface: ServiceInterface, bus: BaseMessageBus, maker: Callable[[ServiceInterface, _Method], HandlerType], ) -> None: interface.__buses.add(bus) interface.__handlers[bus] = { method: maker(interface, method) for method in interface.__methods } interface.__handlers_by_name_signature[bus] = { method.name: (method, handler) for method, handler in interface.__handlers[bus].items() } @staticmethod def _remove_bus(interface: ServiceInterface, bus: BaseMessageBus) -> None: interface.__buses.remove(bus) del interface.__handlers[bus] @staticmethod def _msg_body_to_args(msg: Message) -> list[Any]: return ServiceInterface._c_msg_body_to_args(msg) @staticmethod def _c_msg_body_to_args(msg: Message) -> list[Any]: # https://github.com/cython/cython/issues/3327 if not signature_contains_type(msg.signature_tree, msg.body, "h"): return msg.body # XXX: This deep copy could be expensive if messages are very # large. We could optimize this by only copying what we change # here. return replace_idx_with_fds( msg.signature_tree, copy.deepcopy(msg.body), msg.unix_fds ) @staticmethod def _fn_result_to_body( result: Any | None, signature_tree: SignatureTree, replace_fds: bool = True, ) -> tuple[list[Any], list[int]]: return _real_fn_result_to_body(result, signature_tree, replace_fds) @staticmethod def _c_fn_result_to_body( result: Any | None, signature_tree: SignatureTree, replace_fds: bool, ) -> tuple[list[Any], list[int]]: """The high level interfaces may return single values which may be wrapped in a list to be a message body. Also they may return fds directly for type 'h' which need to be put into an external list.""" # https://github.com/cython/cython/issues/3327 return _real_fn_result_to_body(result, signature_tree, replace_fds) @staticmethod def _handle_signal( interface: ServiceInterface, signal: _Signal, result: Any | None ) -> None: body, fds = ServiceInterface._fn_result_to_body(result, signal.signature_tree) for bus in ServiceInterface._get_buses(interface): bus._interface_signal_notify( interface, interface.name, signal.name, signal.signature, body, fds ) @staticmethod def _get_property_value( interface: ServiceInterface, prop: _Property, callback: Callable[[ServiceInterface, _Property, Any, Exception | None], None], ) -> None: # XXX MUST CHECK TYPE RETURNED BY GETTER try: if asyncio.iscoroutinefunction(prop.prop_getter): task: asyncio.Task = asyncio.ensure_future(prop.prop_getter(interface)) def get_property_callback(task_: asyncio.Task) -> None: try: result = task_.result() except Exception as e: callback(interface, prop, None, e) return callback(interface, prop, result, None) task.add_done_callback(get_property_callback) return callback( interface, prop, getattr(interface, prop.prop_getter.__name__), None ) except Exception as e: callback(interface, prop, None, e) @staticmethod def _set_property_value( interface: ServiceInterface, prop: _Property, value: Any, callback: Callable[[ServiceInterface, _Property, Exception | None], None], ) -> None: # XXX MUST CHECK TYPE TO SET try: if asyncio.iscoroutinefunction(prop.prop_setter): task: asyncio.Task = asyncio.ensure_future( prop.prop_setter(interface, value) ) def set_property_callback(task_: asyncio.Task) -> None: try: task_.result() except Exception as e: callback(interface, prop, e) return callback(interface, prop, None) task.add_done_callback(set_property_callback) return setattr(interface, prop.prop_setter.__name__, value) callback(interface, prop, None) except Exception as e: callback(interface, prop, e) @staticmethod def _get_all_property_values( interface: ServiceInterface, callback: Callable[[ServiceInterface, Any, Any, Exception | None], None], user_data: Any | None = None, ) -> None: result: dict[str, Variant | None] = {} result_error = None for prop in ServiceInterface._get_properties(interface): if prop.disabled or not prop.access.readable(): continue result[prop.name] = None if not result: callback(interface, result, user_data, None) return def get_property_callback( interface: ServiceInterface, prop: _Property, value: Any, e: Exception | None, ) -> None: nonlocal result_error if e is not None: result_error = e del result[prop.name] else: try: result[prop.name] = Variant(prop.signature, value) except SignatureBodyMismatchError as exc: result_error = exc del result[prop.name] if any(v is None for v in result.values()): return callback(interface, result, user_data, result_error) for prop in ServiceInterface._get_properties(interface): if prop.disabled or not prop.access.readable(): continue ServiceInterface._get_property_value(interface, prop, get_property_callback) dbus-fast-2.44.1/src/dbus_fast/signature.pxd000066400000000000000000000011761477355613200207730ustar00rootroot00000000000000"""cdefs for signature.py""" import cython cdef class SignatureType: cdef public str token cdef public unsigned int token_as_int cdef public list children cdef str _signature cdef public SignatureType _child_0 cdef public SignatureType _child_1 cdef class SignatureTree: cdef public str signature cdef public list types cdef public SignatureType root_type cdef class Variant: cdef public SignatureType type cdef public str signature cdef public object value @cython.locals(self=Variant) @staticmethod cdef Variant _factory(SignatureTree signature_tree, object value) dbus-fast-2.44.1/src/dbus_fast/signature.py000066400000000000000000000424211477355613200206260ustar00rootroot00000000000000from functools import lru_cache from typing import Any, Callable, Optional, Union from .errors import InvalidSignatureError, SignatureBodyMismatchError from .validators import is_object_path_valid class SignatureType: """A class that represents a single complete type within a signature. This class is not meant to be constructed directly. Use the :class:`SignatureTree` class to parse signatures. :ivar ~.signature: The signature of this complete type. :vartype ~.signature: str :ivar children: A list of child types if this is a container type. Arrays \ have one child type, dict entries have two child types (key and value), and \ structs have child types equal to the number of struct members. :vartype children: list(:class:`SignatureType`) """ _tokens = "ybnqiuxtdsogavh({" __slots__ = ( "_child_0", "_child_1", "_signature", "children", "token", "token_as_int", ) def __init__(self, token: str) -> None: """Init a new SignatureType.""" self.token: str = token self.token_as_int = ord(token) self.children: list[SignatureType] = [] self._child_0: Optional[SignatureType] = None self._child_1: Optional[SignatureType] = None self._signature: Optional[str] = None def __eq__(self, other: object) -> bool: """Compare this type to another type or signature string.""" if type(other) is SignatureType: return self.signature == other.signature return super().__eq__(other) def _collapse(self) -> str: """Collapse this type into a signature string.""" if self.token not in "a({": return self.token signature = [self.token] for child in self.children: signature.append(child._collapse()) if self.token == "(": signature.append(")") elif self.token == "{": signature.append("}") return "".join(signature) @property def signature(self) -> str: if self._signature is not None: return self._signature self._signature = self._collapse() return self._signature def _add_child(self, child: "SignatureType") -> None: """Add a child type to this type. :param child: The child type to add. :type child: :class:`SignatureType` """ if self._child_0 is None: self._child_0 = child elif self._child_1 is None: self._child_1 = child self.children.append(child) @staticmethod def _parse_next(signature: str) -> tuple["SignatureType", str]: if not signature: raise InvalidSignatureError("Cannot parse an empty signature") token = signature[0] if token not in SignatureType._tokens: raise InvalidSignatureError(f'got unexpected token: "{token}"') # container types if token == "a": self = SignatureType("a") (child, signature) = SignatureType._parse_next(signature[1:]) if not child: raise InvalidSignatureError("missing type for array") self._add_child(child) return (self, signature) if token == "(": self = SignatureType("(") signature = signature[1:] while True: (child, signature) = SignatureType._parse_next(signature) if not signature: raise InvalidSignatureError('missing closing ")" for struct') self._add_child(child) if signature[0] == ")": return (self, signature[1:]) elif token == "{": self = SignatureType("{") signature = signature[1:] (key_child, signature) = SignatureType._parse_next(signature) if not key_child or len(key_child.children): raise InvalidSignatureError("expected a simple type for dict entry key") self._add_child(key_child) (value_child, signature) = SignatureType._parse_next(signature) if not value_child: raise InvalidSignatureError("expected a value for dict entry") if not signature or signature[0] != "}": raise InvalidSignatureError('missing closing "}" for dict entry') self._add_child(value_child) return (self, signature[1:]) # basic type return (SignatureType(token), signature[1:]) def _verify_byte(self, body: Any) -> None: BYTE_MIN = 0x00 BYTE_MAX = 0xFF if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus BYTE type "y" must be Python type "int", got {type(body)}' ) if body < BYTE_MIN or body > BYTE_MAX: raise SignatureBodyMismatchError( f"DBus BYTE type must be between {BYTE_MIN} and {BYTE_MAX}" ) def _verify_boolean(self, body: Any) -> None: if not isinstance(body, bool): raise SignatureBodyMismatchError( f'DBus BOOLEAN type "b" must be Python type "bool", got {type(body)}' ) def _verify_int16(self, body: Any) -> None: INT16_MIN = -0x7FFF - 1 INT16_MAX = 0x7FFF if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus INT16 type "n" must be Python type "int", got {type(body)}' ) if body > INT16_MAX or body < INT16_MIN: raise SignatureBodyMismatchError( f'DBus INT16 type "n" must be between {INT16_MIN} and {INT16_MAX}' ) def _verify_uint16(self, body: Any) -> None: UINT16_MIN = 0 UINT16_MAX = 0xFFFF if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus UINT16 type "q" must be Python type "int", got {type(body)}' ) if body > UINT16_MAX or body < UINT16_MIN: raise SignatureBodyMismatchError( f'DBus UINT16 type "q" must be between {UINT16_MIN} and {UINT16_MAX}' ) def _verify_int32(self, body: int) -> None: INT32_MIN = -0x7FFFFFFF - 1 INT32_MAX = 0x7FFFFFFF if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus INT32 type "i" must be Python type "int", got {type(body)}' ) if body > INT32_MAX or body < INT32_MIN: raise SignatureBodyMismatchError( f'DBus INT32 type "i" must be between {INT32_MIN} and {INT32_MAX}' ) def _verify_uint32(self, body: Any) -> None: UINT32_MIN = 0 UINT32_MAX = 0xFFFFFFFF if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus UINT32 type "u" must be Python type "int", got {type(body)}' ) if body > UINT32_MAX or body < UINT32_MIN: raise SignatureBodyMismatchError( f'DBus UINT32 type "u" must be between {UINT32_MIN} and {UINT32_MAX}' ) def _verify_int64(self, body: Any) -> None: INT64_MAX = 9223372036854775807 INT64_MIN = -INT64_MAX - 1 if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus INT64 type "x" must be Python type "int", got {type(body)}' ) if body > INT64_MAX or body < INT64_MIN: raise SignatureBodyMismatchError( f'DBus INT64 type "x" must be between {INT64_MIN} and {INT64_MAX}' ) def _verify_uint64(self, body: Any) -> None: UINT64_MIN = 0 UINT64_MAX = 18446744073709551615 if not isinstance(body, int): raise SignatureBodyMismatchError( f'DBus UINT64 type "t" must be Python type "int", got {type(body)}' ) if body > UINT64_MAX or body < UINT64_MIN: raise SignatureBodyMismatchError( f'DBus UINT64 type "t" must be between {UINT64_MIN} and {UINT64_MAX}' ) def _verify_double(self, body: Any) -> None: if not isinstance(body, (float, int)): raise SignatureBodyMismatchError( f'DBus DOUBLE type "d" must be Python type "float" or "int", got {type(body)}' ) def _verify_unix_fd(self, body: Any) -> None: try: self._verify_uint32(body) except SignatureBodyMismatchError as ex: raise SignatureBodyMismatchError( 'DBus UNIX_FD type "h" must be a valid UINT32' ) from ex def _verify_object_path(self, body: Any) -> None: if not is_object_path_valid(body): raise SignatureBodyMismatchError( 'DBus OBJECT_PATH type "o" must be a valid object path' ) def _verify_string(self, body: Any) -> None: if not isinstance(body, str): raise SignatureBodyMismatchError( f'DBus STRING type "s" must be Python type "str", got {type(body)}' ) def _verify_signature(self, body: Any) -> None: # I guess we could run it through the SignatureTree parser instead if not isinstance(body, str): raise SignatureBodyMismatchError( f'DBus SIGNATURE type "g" must be Python type "str", got {type(body)}' ) if len(body.encode()) > 0xFF: raise SignatureBodyMismatchError( 'DBus SIGNATURE type "g" must be less than 256 bytes' ) def _verify_array(self, body: Any) -> None: child_type = self.children[0] if child_type.token == "{": if not isinstance(body, dict): raise SignatureBodyMismatchError( f'DBus ARRAY type "a" with DICT_ENTRY child must be Python type "dict", got {type(body)}' ) for key, value in body.items(): child_type.children[0].verify(key) child_type.children[1].verify(value) elif child_type.token == "y": if not isinstance(body, (bytearray, bytes)): raise SignatureBodyMismatchError( f'DBus ARRAY type "a" with BYTE child must be Python type "bytes", got {type(body)}' ) # no need to verify children else: if not isinstance(body, list): raise SignatureBodyMismatchError( f'DBus ARRAY type "a" must be Python type "list", got {type(body)}' ) for member in body: child_type.verify(member) def _verify_struct(self, body: Any) -> None: if not isinstance(body, (list, tuple)): raise SignatureBodyMismatchError( f'DBus STRUCT type "(" must be Python type "list" or "tuple", got {type(body)}' ) if len(body) != len(self.children): raise SignatureBodyMismatchError( 'DBus STRUCT type "(" must have Python list members equal to the number of struct type members' ) for i, member in enumerate(body): self.children[i].verify(member) def _verify_variant(self, body: Any) -> None: # a variant signature and value is valid by construction if not isinstance(body, Variant): raise SignatureBodyMismatchError( f'DBus VARIANT type "v" must be Python type "Variant", got {type(body)}' ) def verify(self, body: Any) -> bool: """Verify that the body matches this type. :returns: True if the body matches this type. :raises: :class:`SignatureBodyMismatchError` if the body does not match this type. """ if body is None: raise SignatureBodyMismatchError('Cannot serialize Python type "None"') validator = self.validators.get(self.token) if validator: validator(self, body) else: raise Exception(f"cannot verify type with token {self.token}") return True validators: dict[str, Callable[["SignatureType", Any], None]] = { "y": _verify_byte, "b": _verify_boolean, "n": _verify_int16, "q": _verify_uint16, "i": _verify_int32, "u": _verify_uint32, "x": _verify_int64, "t": _verify_uint64, "d": _verify_double, "h": _verify_uint32, "o": _verify_string, "s": _verify_string, "g": _verify_signature, "a": _verify_array, "(": _verify_struct, "v": _verify_variant, } class SignatureTree: """A class that represents a signature as a tree structure for conveniently working with DBus signatures. This class will not normally be used directly by the user. :ivar types: A list of parsed complete types. :vartype types: list(:class:`SignatureType`) :ivar ~.signature: The signature of this signature tree. :vartype ~.signature: str :ivar root_type: The root type of this signature tree. :vartype root_type: :class:`SignatureType :raises: :class:`InvalidSignatureError` if the given signature is not valid. """ __slots__ = ("root_type", "signature", "types") def __init__(self, signature: str = "") -> None: self.signature = signature self.types: list[SignatureType] = [] if len(signature) > 0xFF: raise InvalidSignatureError("A signature must be less than 256 characters") while signature: (type_, signature) = SignatureType._parse_next(signature) self.types.append(type_) self.root_type = self.types[0] if self.types else None def __eq__(self, other: object) -> bool: if type(other) is SignatureTree: return self.signature == other.signature return super().__eq__(other) def verify(self, body: list[Any]) -> bool: """Verifies that the give body matches this signature tree :param body: the body to verify for this tree :type body: list(Any) :returns: True if the signature matches the body or an exception if not. :raises: :class:`SignatureBodyMismatchError` if the signature does not match the body. """ if not isinstance(body, list): raise SignatureBodyMismatchError( f"The body must be a list (got {type(body)})" ) if len(body) != len(self.types): raise SignatureBodyMismatchError( f"The body has the wrong number of types (got {len(body)}, expected {len(self.types)})" ) for i, type_ in enumerate(self.types): type_.verify(body[i]) return True class Variant: """A class to represent a DBus variant (type "v"). This class is used in message bodies to represent variants. The user can expect a value in the body with type "v" to use this class and can construct this class directly for use in message bodies sent over the bus. :ivar signature: The signature for this variant. Must be a single complete type. :vartype signature: str or SignatureTree or SignatureType :ivar value: The value of this variant. Must correspond to the signature. :vartype value: Any :raises: :class:`InvalidSignatureError` if the signature is not valid. :class:`SignatureBodyMismatchError` if the signature does not match the body. """ __slots__ = ("signature", "type", "value") def __init__( self, signature: Union[str, SignatureTree, SignatureType], value: Any, verify: bool = True, ) -> None: """Init a new Variant.""" if type(signature) is SignatureTree: signature_tree = signature self.signature = signature_tree.signature self.type = signature_tree.types[0] elif type(signature) is SignatureType: signature_tree = None self.signature = signature.signature self.type = signature elif type(signature) is str: signature_tree = get_signature_tree(signature) self.signature = signature self.type = signature_tree.types[0] else: raise TypeError( "signature must be a SignatureTree, SignatureType, or a string" ) self.value = value if verify: if signature_tree and len(signature_tree.types) != 1: raise ValueError( "variants must have a signature for a single complete type" ) self.type.verify(value) @staticmethod def _factory(signature_tree: SignatureTree, value: Any) -> "Variant": self = Variant.__new__(Variant) self.signature = signature_tree.signature self.type = signature_tree.root_type self.value = value return self def __eq__(self, other: object) -> bool: if type(other) is Variant: return self.signature == other.signature and self.value == other.value return super().__eq__(other) def __repr__(self) -> str: return f"" get_signature_tree = lru_cache(maxsize=None)(SignatureTree) """Get a signature tree for the given signature. :param signature: The signature to get a tree for. :type signature: str :returns: The signature tree for the given signature. :rtype: :class:`SignatureTree` """ dbus-fast-2.44.1/src/dbus_fast/unpack.pxd000066400000000000000000000002651477355613200202510ustar00rootroot00000000000000"""cdefs for unpack.py""" import cython from .signature cimport Variant cpdef unpack_variants(object data) @cython.locals( var=Variant ) cdef _unpack_variants(object data) dbus-fast-2.44.1/src/dbus_fast/unpack.py000066400000000000000000000011561477355613200201060ustar00rootroot00000000000000from typing import Any from .signature import Variant def unpack_variants(data: Any) -> Any: """Unpack variants and remove signature info. This function should only be used to unpack unmarshalled data as the checks are not idiomatic. """ return _unpack_variants(data) def _unpack_variants(data: Any) -> Any: if type(data) is dict: return {k: _unpack_variants(v) for k, v in data.items()} if type(data) is list: return [_unpack_variants(item) for item in data] if type(data) is Variant: var = data return _unpack_variants(var.value) return data dbus-fast-2.44.1/src/dbus_fast/validators.py000066400000000000000000000121671477355613200210010ustar00rootroot00000000000000import re from functools import lru_cache from .errors import ( InvalidBusNameError, InvalidInterfaceNameError, InvalidMemberNameError, InvalidObjectPathError, ) _bus_name_re = re.compile(r"^[A-Za-z_-][A-Za-z0-9_-]*$") _path_re = re.compile(r"^[A-Za-z0-9_]+$") _element_re = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$") _member_re = re.compile(r"^[A-Za-z_][A-Za-z0-9_-]*$") @lru_cache(maxsize=32) def is_bus_name_valid(name: str) -> bool: """Whether this is a valid bus name. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus :param name: The bus name to validate. :type name: str :returns: Whether the name is a valid bus name. :rtype: bool """ if not isinstance(name, str): return False # type: ignore[unreachable] if not name or len(name) > 255: return False if name.startswith(":"): # a unique bus name return True if name.startswith("."): return False if name.find(".") == -1: return False for element in name.split("."): if _bus_name_re.search(element) is None: return False return True @lru_cache(maxsize=1024) def is_object_path_valid(path: str) -> bool: """Whether this is a valid object path. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path :param path: The object path to validate. :type path: str :returns: Whether the object path is valid. :rtype: bool """ if not isinstance(path, str): return False # type: ignore[unreachable] if not path: return False if not path.startswith("/"): return False if len(path) == 1: return True for element in path[1:].split("/"): if _path_re.search(element) is None: return False return True @lru_cache(maxsize=32) def is_interface_name_valid(name: str) -> bool: """Whether this is a valid interface name. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface :param name: The interface name to validate. :type name: str :returns: Whether the name is a valid interface name. :rtype: bool """ if not isinstance(name, str): return False # type: ignore[unreachable] if not name or len(name) > 255: return False if name.startswith("."): return False if name.find(".") == -1: return False for element in name.split("."): if _element_re.search(element) is None: return False return True @lru_cache(maxsize=512) def is_member_name_valid(member: str) -> bool: """Whether this is a valid member name. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member :param member: The member name to validate. :type member: str :returns: Whether the name is a valid member name. :rtype: bool """ if not isinstance(member, str): return False # type: ignore[unreachable] if not member or len(member) > 255: return False if _member_re.search(member) is None: return False return True @lru_cache(maxsize=32) def assert_bus_name_valid(name: str) -> None: """Raise an error if this is not a valid bus name. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus :param name: The bus name to validate. :type name: str :raises: - :class:`InvalidBusNameError` - If this is not a valid bus name. """ if not is_bus_name_valid(name): raise InvalidBusNameError(name) @lru_cache(maxsize=1024) def assert_object_path_valid(path: str) -> None: """Raise an error if this is not a valid object path. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path :param path: The object path to validate. :type path: str :raises: - :class:`InvalidObjectPathError` - If this is not a valid object path. """ if not is_object_path_valid(path): raise InvalidObjectPathError(path) @lru_cache(maxsize=32) def assert_interface_name_valid(name: str) -> None: """Raise an error if this is not a valid interface name. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface :param name: The interface name to validate. :type name: str :raises: - :class:`InvalidInterfaceNameError` - If this is not a valid object path. """ if not is_interface_name_valid(name): raise InvalidInterfaceNameError(name) @lru_cache(maxsize=512) def assert_member_name_valid(member: str) -> None: """Raise an error if this is not a valid member name. .. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member :param member: The member name to validate. :type member: str :raises: - :class:`InvalidMemberNameError` - If this is not a valid object path. """ if not is_member_name_valid(member): raise InvalidMemberNameError(member) dbus-fast-2.44.1/tests/000077500000000000000000000000001477355613200146515ustar00rootroot00000000000000dbus-fast-2.44.1/tests/__init__.py000066400000000000000000000000001477355613200167500ustar00rootroot00000000000000dbus-fast-2.44.1/tests/benchmarks/000077500000000000000000000000001477355613200167665ustar00rootroot00000000000000dbus-fast-2.44.1/tests/benchmarks/test_marshall.py000066400000000000000000000006521477355613200222050ustar00rootroot00000000000000from pytest_codspeed import BenchmarkFixture from dbus_fast import Message message = Message( destination="org.bluez", path="/", interface="org.freedesktop.DBus.ObjectManager", member="GetManagedObjects", ) def test_marshall_bluez_get_managed_objects_message( benchmark: BenchmarkFixture, ) -> None: @benchmark def marhsall_bluez_get_managed_objects_message(): message._marshall(False) dbus-fast-2.44.1/tests/benchmarks/test_unmarshall.py000066400000000000000000000157161477355613200225570ustar00rootroot00000000000000import io import socket from pytest_codspeed import BenchmarkFixture from dbus_fast._private.unmarshaller import Unmarshaller def test_unmarshall_bluez_rssi_message(benchmark: BenchmarkFixture) -> None: bluez_rssi_message = ( "6c04010134000000e25389019500000001016f00250000002f6f72672f626c75657a2f686369302f6465" "765f30385f33415f46325f31455f32425f3631000000020173001f0000006f72672e667265656465736b" "746f702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e" "67656400000000000000080167000873617b73767d617300000007017300040000003a312e3400000000" "110000006f72672e626c75657a2e446576696365310000000e0000000000000004000000525353490001" "6e00a7ff000000000000" ) stream = io.BytesIO(bytes.fromhex(bluez_rssi_message)) unmarshaller = Unmarshaller(stream) @benchmark def unmarhsall_bluez_rssi_message(): stream.seek(0) unmarshaller.unmarshall() bluez_properties_message = ( b"l\4\1\0014\0\0\0\16Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_08_3A_F2_1E_28_89\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1" b"s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\242\377\0\0\0\0\0\0" b"l\4\1\1\220\0\0\0\17Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_A4_C1_38_6E_9F_7C\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s" b"\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0k\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\250\377\0\0\20\0\0\0" b"ManufacturerData\0\5a{qv}\0;\0\0\0\1\0\2ay\0\0\0\t\0\0\0\1\1\1\3\361\234\\\0\1\0\0\0L\0\2ay\0\0\0\27\0\0\0\2\25" b"INTELLI_ROCKS_HWPu\362\377\302\0\0\0\0\0l\4\1\0014\0\0\0\20Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_F8" b"_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0" b"\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0" b"\0\0RSSI\0\1n\0\262\377\0\0\0\0\0\0l\4\1\0014\0\0\0\21Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_54_E6_" b"1B_F0_20_97\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0" b"\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0" b"RSSI\0\1n\0\254\377\0\0\0\0\0\0l\4\1\0014\0\0\0\22Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_D8_EF_2F_41" b"_B1_34\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10" b"\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0" b"\1n\0\244\377\0\0\0\0\0\0l\4\1\0014\0\0\0\23Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_66_6D\0" b"\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10" b"sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\236" b"\377\0\0\0\0\0\0l\4\1\0014\0\0\0\24Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_08_3A_F2_1E_32_69\0\0\0\2\1s" b"\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0" b"\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\246\377\0\0\0" b"\0\0\0l\4\1\0014\0\0\0\25Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_71_D1\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4" b"\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\232\377\0\0\0\0\0\0l\4\1\001" b"4\0\0\0\26Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_F8_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.D" b"Bus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0" b"\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\306\377\0\0\0\0\0\0" ) def test_unmarshall_bluez_properties_message(benchmark: BenchmarkFixture) -> None: stream = io.BytesIO(bluez_properties_message) unmarshaller = Unmarshaller(stream) @benchmark def unmarshall_bluez_properties_message(): stream.seek(0) unmarshaller.unmarshall() def test_unmarshall_multiple_bluez_properties_message( benchmark: BenchmarkFixture, ) -> None: stream = io.BytesIO(bluez_properties_message) unmarshaller = Unmarshaller(stream) @benchmark def unmarshall_bluez_properties_message(): stream.seek(0) for _ in range(9): unmarshaller.unmarshall() def test_unmarshall_multiple_bluez_properties_message_socket( benchmark: BenchmarkFixture, ) -> None: sock1, sock2 = socket.socketpair() sock1.setblocking(False) sock2.setblocking(False) unmarshaller = Unmarshaller(None, sock1, False) @benchmark def unmarshall_bluez_properties_message(): sock2.send(bluez_properties_message) for _ in range(9): unmarshaller.unmarshall() sock1.close() sock2.close() def test_unmarshall_bluez_interfaces_added_message(benchmark: BenchmarkFixture) -> None: bluez_interfaces_added_message = ( b'l\4\1\1\240\2\0\0\227\272\23\0u\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0' b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\17\0\0\0InterfacesAdded\0\10" b"\1g\0\noa{sa{sv}}\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_2D_34" b"_60_26_36\0\0\0p\2\0\0#\0\0\0org.freedesktop.DBus.Introspectable\0\0\0\0\0\0\0\0\0" b"\21\0\0\0org.bluez.Device1\0\0\0\364\1\0\0\0\0\0\0\7\0\0\0Address\0\1s\0\0\21\0\0" b"\00058:2D:34:60:26:36\0\0\0\v\0\0\0AddressType\0\1s\0\0\6\0\0\0public\0\0\4\0\0\0" b"Name\0\1s\0\33\0\0\0Qingping Door/Window Sensor\0\0\0\0\0\5\0\0\0Alias\0\1s\0\0\0" b"\0\33\0\0\0Qingping Door/Window Sensor\0\6\0\0\0Paired\0\1b\0\0\0\0\0\0\0\0\0\0\0" b"\7\0\0\0Trusted\0\1b\0\0\0\0\0\0\0\0\0\0\7\0\0\0Blocked\0\1b\0\0\0\0\0\0\0\0\0\0\r" b"\0\0\0LegacyPairing\0\1b\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\316\377\0\0\t" b"\0\0\0Connected\0\1b\0\0\0\0\0\0\0\0\5\0\0\0UUIDs\0\2as\0\0\0\0\0\0\0\0\0\0\0\7\0" b"\0\0Adapter\0\1o\0\0\17\0\0\0/org/bluez/hci1\0\0\0\0\0\v\0\0\0ServiceData\0\5a{sv}" b"\0\0@\0\0\0\0\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\f\0" b"\0\0000X\326\3\0026&`4-X\10\20\0\0\0ServicesResolved\0\1b\0\0\0\0\0\0\0\0\0\37\0\0" b"\0org.freedesktop.DBus.Properties\0\0\0\0\0" ) stream = io.BytesIO(bluez_interfaces_added_message) unmarshaller = Unmarshaller(stream) @benchmark def unmarshall(): stream.seek(0) unmarshaller.unmarshall() dbus-fast-2.44.1/tests/client/000077500000000000000000000000001477355613200161275ustar00rootroot00000000000000dbus-fast-2.44.1/tests/client/__init__.py000066400000000000000000000000001477355613200202260ustar00rootroot00000000000000dbus-fast-2.44.1/tests/client/test_aio.py000066400000000000000000000013701477355613200203110ustar00rootroot00000000000000import pytest from dbus_fast import aio from dbus_fast.service import ServiceInterface class ExampleInterface(ServiceInterface): def __init__(self): super().__init__("test.interface") @pytest.mark.asyncio async def test_fast_disconnect(): bus_name = "aio.client.test.methods" bus = await aio.MessageBus().connect() bus2 = await aio.MessageBus().connect() await bus.request_name(bus_name) service_interface = ExampleInterface() bus.export("/test/path", service_interface) introspection = await bus2.introspect(bus_name, "/test/path") bus2.get_proxy_object(bus_name, "/test/path", introspection) bus2.disconnect() bus.disconnect() await bus.wait_for_disconnect() await bus2.wait_for_disconnect() dbus-fast-2.44.1/tests/client/test_methods.py000066400000000000000000000132251477355613200212060ustar00rootroot00000000000000import logging import sys from logging.handlers import QueueHandler from queue import SimpleQueue import pytest import dbus_fast.introspection as intr from dbus_fast import DBusError, aio, glib from dbus_fast.message import MessageFlag from dbus_fast.service import ServiceInterface, method from dbus_fast.signature import Variant from tests.util import check_gi_repository, skip_reason_no_gi has_gi = check_gi_repository() class ExampleInterface(ServiceInterface): def __init__(self): super().__init__("test.interface") @method() def Ping(self): pass @method() def EchoInt64(self, what: "x") -> "x": return what @method() def EchoString(self, what: "s") -> "s": return what @method() def ConcatStrings(self, what1: "s", what2: "s") -> "s": return what1 + what2 @method() def EchoThree(self, what1: "s", what2: "s", what3: "s") -> "sss": return [what1, what2, what3] @method() def GetComplex(self) -> "a{sv}": # noqa: F722 """Return complex output.""" return {"hello": Variant("s", "world")} @method() def ThrowsError(self): raise DBusError("test.error", "something went wrong") @pytest.mark.asyncio async def test_aio_proxy_object(): bus_name = "aio.client.test.methods" bus = await aio.MessageBus().connect() bus2 = await aio.MessageBus().connect() await bus.request_name(bus_name) service_interface = ExampleInterface() bus.export("/test/path", service_interface) # add some more to test nodes bus.export("/test/path/child1", ExampleInterface()) bus.export("/test/path/child2", ExampleInterface()) introspection = await bus2.introspect(bus_name, "/test/path") assert type(introspection) is intr.Node obj = bus2.get_proxy_object(bus_name, "/test/path", introspection) interface = obj.get_interface(service_interface.name) children = obj.get_children() assert len(children) == 2 for child in obj.get_children(): assert type(child) is aio.ProxyObject result = await interface.call_ping() assert result is None result = await interface.call_echo_string("hello") assert result == "hello" result = await interface.call_concat_strings("hello ", "world") assert result == "hello world" result = await interface.call_echo_three("hello", "there", "world") assert result == ["hello", "there", "world"] result = await interface.call_echo_int64(-10000) assert result == -10000 result = await interface.call_echo_string( "no reply", flags=MessageFlag.NO_REPLY_EXPECTED ) assert result is None result = await interface.call_get_complex() assert result == {"hello": Variant("s", "world")} result = await interface.call_get_complex(unpack_variants=True) assert result == {"hello": "world"} # In addition to the exception passing through, we need to verify that # the exception doesn't trigger logging errors. log_error_queue = SimpleQueue() log_handler = QueueHandler(log_error_queue) logger = logging.getLogger() logger.addHandler(log_handler) try: with pytest.raises(DBusError): try: await interface.call_throws_error() except DBusError as e: assert e.reply is not None assert e.type == "test.error" assert e.text == "something went wrong" raise e finally: logger.removeHandler(log_handler) assert log_error_queue.empty(), log_error_queue.get_nowait() bus.disconnect() bus2.disconnect() await bus.wait_for_disconnect() await bus2.wait_for_disconnect() @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10/py3.11" ) @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) def test_glib_proxy_object(): bus_name = "glib.client.test.methods" bus = glib.MessageBus().connect_sync() bus.request_name_sync(bus_name) service_interface = ExampleInterface() bus.export("/test/path", service_interface) bus2 = glib.MessageBus().connect_sync() introspection = bus2.introspect_sync(bus_name, "/test/path") assert type(introspection) is intr.Node obj = bus.get_proxy_object(bus_name, "/test/path", introspection) interface = obj.get_interface(service_interface.name) result = interface.call_ping_sync() assert result is None result = interface.call_echo_string_sync("hello") assert result == "hello" result = interface.call_concat_strings_sync("hello ", "world") assert result == "hello world" result = interface.call_echo_three_sync("hello", "there", "world") assert result == ["hello", "there", "world"] result = interface.call_get_complex_sync() assert result == {"hello": Variant("s", "world")} result = interface.call_get_complex_sync(unpack_variants=True) assert result == {"hello": "world"} # In addition to the exception passing through, we need to verify that # the exception doesn't trigger logging errors. log_error_queue = SimpleQueue() log_handler = QueueHandler(log_error_queue) logger = logging.getLogger() logger.addHandler(log_handler) try: with pytest.raises(DBusError): try: result = interface.call_throws_error_sync() assert False, result except DBusError as e: assert e.reply is not None assert e.type == "test.error" assert e.text == "something went wrong" raise e finally: logger.removeHandler(log_handler) assert log_error_queue.empty() bus.disconnect() bus2.disconnect() dbus-fast-2.44.1/tests/client/test_properties.py000066400000000000000000000113111477355613200217310ustar00rootroot00000000000000import sys import pytest from dbus_fast import DBusError, Message, aio, glib from dbus_fast.service import PropertyAccess, ServiceInterface, dbus_property from dbus_fast.signature import Variant from tests.util import check_gi_repository, skip_reason_no_gi has_gi = check_gi_repository() class ExampleInterface(ServiceInterface): def __init__(self): super().__init__("test.interface") self._some_property = "foo" self.error_name = "test.error" self.error_text = "i am bad" self._int64_property = -10000 @dbus_property() def SomeProperty(self) -> "s": return self._some_property @SomeProperty.setter def SomeProperty(self, val: "s"): self._some_property = val @dbus_property(access=PropertyAccess.READ) def Int64Property(self) -> "x": return self._int64_property @dbus_property(access=PropertyAccess.READ) def ComplexProperty(self) -> "a{sv}": # noqa: F722 """Return complex output.""" return {"hello": Variant("s", "world")} @dbus_property() def ErrorThrowingProperty(self) -> "s": raise DBusError(self.error_name, self.error_text) @ErrorThrowingProperty.setter def ErrorThrowingProperty(self, val: "s"): raise DBusError(self.error_name, self.error_text) @pytest.mark.asyncio async def test_aio_properties(): service_bus = await aio.MessageBus().connect() service_interface = ExampleInterface() service_bus.export("/test/path", service_interface) bus = await aio.MessageBus().connect() obj = bus.get_proxy_object( service_bus.unique_name, "/test/path", service_bus._introspect_export_path("/test/path"), ) interface = obj.get_interface(service_interface.name) prop = await interface.get_some_property() assert prop == service_interface._some_property prop = await interface.get_int64_property() assert prop == service_interface._int64_property await interface.set_some_property("different") assert service_interface._some_property == "different" prop = await interface.get_complex_property() assert prop == {"hello": Variant("s", "world")} prop = await interface.get_complex_property(unpack_variants=True) assert prop == {"hello": "world"} with pytest.raises(DBusError): try: prop = await interface.get_error_throwing_property() assert False, prop except DBusError as e: assert e.type == service_interface.error_name assert e.text == service_interface.error_text assert type(e.reply) is Message raise e with pytest.raises(DBusError): try: await interface.set_error_throwing_property("different") except DBusError as e: assert e.type == service_interface.error_name assert e.text == service_interface.error_text assert type(e.reply) is Message raise e service_bus.disconnect() bus.disconnect() @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10,py3.11,py3.12,py3.13", ) @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) def test_glib_properties(): service_bus = glib.MessageBus().connect_sync() service_interface = ExampleInterface() service_bus.export("/test/path", service_interface) bus = glib.MessageBus().connect_sync() obj = bus.get_proxy_object( service_bus.unique_name, "/test/path", service_bus._introspect_export_path("/test/path"), ) interface = obj.get_interface(service_interface.name) prop = interface.get_some_property_sync() assert prop == service_interface._some_property interface.set_some_property_sync("different") assert service_interface._some_property == "different" prop = interface.get_complex_property_sync() assert prop == {"hello": Variant("s", "world")} prop = interface.get_complex_property_sync(unpack_variants=True) assert prop == {"hello": "world"} with pytest.raises(DBusError): try: prop = interface.get_error_throwing_property_sync() assert False, prop except DBusError as e: assert e.type == service_interface.error_name assert e.text == service_interface.error_text assert type(e.reply) is Message raise e with pytest.raises(DBusError): try: interface.set_error_throwing_property_sync("different2") except DBusError as e: assert e.type == service_interface.error_name assert e.text == service_interface.error_text assert type(e.reply) is Message raise e service_bus.disconnect() bus.disconnect() dbus-fast-2.44.1/tests/client/test_signals.py000066400000000000000000000371231477355613200212060ustar00rootroot00000000000000import asyncio import pytest from dbus_fast import Message from dbus_fast.aio import MessageBus from dbus_fast.constants import RequestNameReply from dbus_fast.introspection import Node from dbus_fast.service import ServiceInterface, signal from dbus_fast.signature import Variant class ExampleInterface(ServiceInterface): def __init__(self): super().__init__("test.interface") @signal() def SomeSignal(self) -> "s": return "hello" @signal() def SignalMultiple(self) -> "ss": return ["hello", "world"] @signal() def SignalComplex(self) -> "a{sv}": # noqa: F722 """Broadcast a complex signal.""" return {"hello": Variant("s", "world")} @pytest.mark.asyncio async def test_signals(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() bus_intr = await bus1.introspect("org.freedesktop.DBus", "/org/freedesktop/DBus") bus_obj = bus1.get_proxy_object( "org.freedesktop.DBus", "/org/freedesktop/DBus", bus_intr ) stats = bus_obj.get_interface("org.freedesktop.DBus.Debug.Stats") await bus1.request_name("test.signals.name") service_interface = ExampleInterface() bus1.export("/test/path", service_interface) obj = bus2.get_proxy_object( "test.signals.name", "/test/path", bus1._introspect_export_path("/test/path") ) interface = obj.get_interface(service_interface.name) async def ping(): await bus2.call( Message( destination=bus1.unique_name, interface="org.freedesktop.DBus.Peer", path="/test/path", member="Ping", ) ) err = None single_counter = 0 def single_handler(value): try: nonlocal single_counter nonlocal err assert value == "hello" single_counter += 1 except Exception as e: err = e multiple_counter = 0 def multiple_handler(value1, value2): nonlocal multiple_counter nonlocal err try: assert value1 == "hello" assert value2 == "world" multiple_counter += 1 except Exception as e: err = e await ping() match_rules = await stats.call_get_all_match_rules() assert bus2.unique_name in match_rules bus_match_rules = match_rules[bus2.unique_name] # the bus connection itself takes a rule on NameOwnerChange after the high # level client is initialized assert len(bus_match_rules) == 1 assert len(bus2._user_message_handlers) == 0 interface.on_some_signal(single_handler) interface.on_signal_multiple(multiple_handler) # Interlude: adding a signal handler with `on_[signal]` should add a match rule and # message handler. Removing a signal handler with `off_[signal]` should # remove the match rule and message handler to avoid memory leaks. await ping() match_rules = await stats.call_get_all_match_rules() assert bus2.unique_name in match_rules bus_match_rules = match_rules[bus2.unique_name] # test the match rule and user handler has been added assert len(bus_match_rules) == 2 assert ( "type='signal',interface='test.interface',path='/test/path',sender='test.signals.name'" in bus_match_rules ) assert len(bus2._user_message_handlers) == 1 service_interface.SomeSignal() await ping() assert err is None assert single_counter == 1 service_interface.SignalMultiple() await ping() assert err is None assert multiple_counter == 1 # special case: another bus with the same path and interface but on a # different name and connection will trigger the match rule of the first # (happens with mpris) bus3 = await MessageBus().connect() await bus3.request_name("test.signals.name2") service_interface2 = ExampleInterface() bus3.export("/test/path", service_interface2) obj = bus2.get_proxy_object( "test.signals.name2", "/test/path", bus3._introspect_export_path("/test/path") ) # we have to add a dummy handler to add the match rule iface2 = obj.get_interface(service_interface2.name) def dummy_signal_handler(what): pass iface2.on_some_signal(dummy_signal_handler) await ping() service_interface2.SomeSignal() await ping() # single_counter is not incremented for signals of the second interface assert single_counter == 1 interface.off_some_signal(single_handler) interface.off_signal_multiple(multiple_handler) iface2.off_some_signal(dummy_signal_handler) # After `off_[signal]`, the match rule and user handler should be removed await ping() match_rules = await stats.call_get_all_match_rules() assert bus2.unique_name in match_rules bus_match_rules = match_rules[bus2.unique_name] assert len(bus_match_rules) == 1 assert ( "type='signal',interface='test.interface',path='/test/path',sender='test.signals.name'" not in bus_match_rules ) assert len(bus2._user_message_handlers) == 0 bus1.disconnect() bus2.disconnect() bus3.disconnect() @pytest.mark.asyncio async def test_complex_signals(): """Test complex signals with and without signature removal.""" bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus1.request_name("test.signals.name") service_interface = ExampleInterface() bus1.export("/test/path", service_interface) obj = bus2.get_proxy_object( "test.signals.name", "/test/path", bus1._introspect_export_path("/test/path") ) interface = obj.get_interface(service_interface.name) async def ping(): await bus2.call( Message( destination=bus1.unique_name, interface="org.freedesktop.DBus.Peer", path="/test/path", member="Ping", ) ) sig_handler_counter = 0 sig_handler_err = None no_sig_handler_counter = 0 no_sig_handler_err = None def complex_handler_with_sig(value): nonlocal sig_handler_counter nonlocal sig_handler_err try: assert value == {"hello": Variant("s", "world")} sig_handler_counter += 1 except AssertionError as ex: sig_handler_err = ex def complex_handler_no_sig(value): nonlocal no_sig_handler_counter nonlocal no_sig_handler_err try: assert value == {"hello": "world"} no_sig_handler_counter += 1 except AssertionError as ex: no_sig_handler_err = ex interface.on_signal_complex(complex_handler_with_sig) interface.on_signal_complex(complex_handler_no_sig, unpack_variants=True) await ping() service_interface.SignalComplex() await ping() assert sig_handler_err is None assert sig_handler_counter == 1 assert no_sig_handler_err is None assert no_sig_handler_counter == 1 bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_varargs_callback(): """Test varargs callback for signal.""" bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus1.request_name("test.signals.name") service_interface = ExampleInterface() bus1.export("/test/path", service_interface) obj = bus2.get_proxy_object( "test.signals.name", "/test/path", bus1._introspect_export_path("/test/path") ) interface = obj.get_interface(service_interface.name) async def ping(): await bus2.call( Message( destination=bus1.unique_name, interface="org.freedesktop.DBus.Peer", path="/test/path", member="Ping", ) ) varargs_handler_counter = 0 varargs_handler_err = None varargs_plus_handler_counter = 0 varargs_plus_handler_err = None def varargs_handler(*args): nonlocal varargs_handler_counter nonlocal varargs_handler_err try: assert args[0] == "hello" varargs_handler_counter += 1 except AssertionError as ex: varargs_handler_err = ex def varargs_plus_handler(value, *_): nonlocal varargs_plus_handler_counter nonlocal varargs_plus_handler_err try: assert value == "hello" varargs_plus_handler_counter += 1 except AssertionError as ex: varargs_plus_handler_err = ex interface.on_some_signal(varargs_handler) interface.on_some_signal(varargs_plus_handler) await ping() service_interface.SomeSignal() await ping() assert varargs_handler_err is None assert varargs_handler_counter == 1 assert varargs_plus_handler_err is None assert varargs_plus_handler_counter == 1 bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_kwargs_callback(): """Test callback for signal with kwargs.""" bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus1.request_name("test.signals.name") service_interface = ExampleInterface() bus1.export("/test/path", service_interface) obj = bus2.get_proxy_object( "test.signals.name", "/test/path", bus1._introspect_export_path("/test/path") ) interface = obj.get_interface(service_interface.name) async def ping(): await bus2.call( Message( destination=bus1.unique_name, interface="org.freedesktop.DBus.Peer", path="/test/path", member="Ping", ) ) kwargs_handler_counter = 0 kwargs_handler_err = None kwarg_default_handler_counter = 0 kwarg_default_handler_err = None def kwargs_handler(value, **_): nonlocal kwargs_handler_counter nonlocal kwargs_handler_err try: assert value == "hello" kwargs_handler_counter += 1 except AssertionError as ex: kwargs_handler_err = ex def kwarg_default_handler(value, *, _=True): nonlocal kwarg_default_handler_counter nonlocal kwarg_default_handler_err try: assert value == "hello" kwarg_default_handler_counter += 1 except AssertionError as ex: kwarg_default_handler_err = ex interface.on_some_signal(kwargs_handler) interface.on_some_signal(kwarg_default_handler) await ping() service_interface.SomeSignal() await ping() assert kwargs_handler_err is None assert kwargs_handler_counter == 1 assert kwarg_default_handler_err is None assert kwarg_default_handler_counter == 1 def kwarg_bad_handler(value, *, bad_kwarg): pass with pytest.raises(TypeError): interface.on_some_signal(kwarg_bad_handler) bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_coro_callback(): """Test callback for signal with a coroutine.""" bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus1.request_name("test.signals.name") service_interface = ExampleInterface() bus1.export("/test/path", service_interface) obj = bus2.get_proxy_object( "test.signals.name", "/test/path", bus1._introspect_export_path("/test/path") ) interface = obj.get_interface(service_interface.name) async def ping(): await bus2.call( Message( destination=bus1.unique_name, interface="org.freedesktop.DBus.Peer", path="/test/path", member="Ping", ) ) kwargs_handler_counter = 0 kwargs_handler_err = None kwarg_default_handler_counter = 0 kwarg_default_handler_err = None async def kwargs_handler(value, **_): nonlocal kwargs_handler_counter nonlocal kwargs_handler_err try: assert value == "hello" kwargs_handler_counter += 1 except AssertionError as ex: kwargs_handler_err = ex async def kwarg_default_handler(value, *, _=True): nonlocal kwarg_default_handler_counter nonlocal kwarg_default_handler_err try: assert value == "hello" kwarg_default_handler_counter += 1 except AssertionError as ex: kwarg_default_handler_err = ex interface.on_some_signal(kwargs_handler) interface.on_some_signal(kwarg_default_handler) await ping() service_interface.SomeSignal() await ping() await asyncio.sleep(0) assert kwargs_handler_err is None assert kwargs_handler_counter == 1 assert kwarg_default_handler_err is None assert kwarg_default_handler_counter == 1 def kwarg_bad_handler(value, *, bad_kwarg): pass with pytest.raises(TypeError): interface.on_some_signal(kwarg_bad_handler) bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_on_signal_type_error(): """Test on callback raises type errors for invalid callbacks.""" bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus1.request_name("test.signals.name") service_interface = ExampleInterface() bus1.export("/test/path", service_interface) obj = bus2.get_proxy_object( "test.signals.name", "/test/path", bus1._introspect_export_path("/test/path") ) interface = obj.get_interface(service_interface.name) with pytest.raises(TypeError): interface.on_some_signal("not_a_callable") with pytest.raises(TypeError): interface.on_some_signal(lambda a, b: "Too many parameters") with pytest.raises(TypeError): interface.on_some_signal(lambda: "Too few parameters") with pytest.raises(TypeError): interface.on_some_signal(lambda a, b, *args: "Too many before varargs") bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_signals_with_changing_owners(): well_known_name = "test.signals.changing.name" bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() bus3 = await MessageBus().connect() async def ping(): await bus1.call( Message( destination=bus1.unique_name, interface="org.freedesktop.DBus.Peer", path="/test/path", member="Ping", ) ) service_interface = ExampleInterface() introspection = Node.default() introspection.interfaces.append(service_interface.introspect()) # get the interface before export obj = bus1.get_proxy_object(well_known_name, "/test/path", introspection) iface = obj.get_interface("test.interface") counter = 0 def handler(what): nonlocal counter counter += 1 iface.on_some_signal(handler) await ping() # now export and get the name bus2.export("/test/path", service_interface) result = await bus2.request_name(well_known_name) assert result is RequestNameReply.PRIMARY_OWNER # the signal should work service_interface.SomeSignal() await ping() assert counter == 1 counter = 0 # now queue up a transfer of the name service_interface2 = ExampleInterface() bus3.export("/test/path", service_interface2) result = await bus3.request_name(well_known_name) assert result is RequestNameReply.IN_QUEUE # if it doesn't own the name, the signal shouldn't work here service_interface2.SomeSignal() await ping() assert counter == 0 # now transfer over the name and it should work bus2.disconnect() await ping() service_interface2.SomeSignal() await ping() assert counter == 1 counter = 0 bus1.disconnect() bus2.disconnect() bus3.disconnect() dbus-fast-2.44.1/tests/data/000077500000000000000000000000001477355613200155625ustar00rootroot00000000000000dbus-fast-2.44.1/tests/data/get_managed_objects.hex000066400000000000000000016356411477355613200222540ustar00rootroot000000000000006c020101809d030072056c003d00000006017300070000003a312e31373336000501750002000000080167000d617b6f617b73617b73767d7d7d00000000000007017300040000003a312e3400000000789d0300000000000a0000002f6f72672f626c75657a00007800000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000170000006f72672e626c75657a2e4167656e744d616e61676572310000000000190000006f72672e626c75657a2e50726f66696c654d616e616765723100000000000000000000000f0000002f6f72672f626c75657a2f6863693000ff040000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000120000006f72672e626c75657a2e416461707465723100006f03000000000000070000004164647265737300017300001100000030303a31413a37443a44413a37313a30340000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000d000000686f6d65617373697374616e7400000005000000416c696173000173000000000d000000686f6d65617373697374616e740000000000000005000000436c6173730001750000000000002c000000000007000000506f7765726564000162000001000000000000000c000000446973636f76657261626c65000162000000000013000000446973636f76657261626c6554696d656f75740001750000b4000000080000005061697261626c650001620000000000000000000f0000005061697261626c6554696d656f7574000175000000000000000000000b000000446973636f766572696e6700016200000100000005000000555549447300026173000000b50100002400000030303030313130652d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130612d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313230302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130622d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130382d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130632d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830612d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313131322d303030302d313030302d383030302d3030383035663962333466620000000000000000080000004d6f64616c69617300017300130000007573623a7631443642703032343664303533460005000000526f6c6573000261730000001b0000000700000063656e7472616c000a0000007065726970686572616c00001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000160000006f72672e626c75657a2e476174744d616e6167657231000000000000100000006f72672e626c75657a2e4d6564696131000000000000000000000000180000006f72672e626c75657a2e4e6574776f726b536572766572310000000000000000000000001f0000006f72672e626c75657a2e4c454164766572746973696e674d616e616765723100870000000f000000416374697665496e7374616e636573000179000012000000537570706f72746564496e7374616e6365730001790005000000000011000000537570706f72746564496e636c75646573000261730000002f0000000800000074782d706f776572000000000a000000617070656172616e636500000a0000006c6f63616c2d6e616d650000250000002f6f72672f626c75657a2f686369302f6465765f31305f31465f45465f45355f34395f324500000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000031303a31463a45463a45353a34393a32450000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000031302d31462d45462d45352d34392d324500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d002700000006000261790000001b000000010f2002abd9b0f38e8e32c134801987f78703003aee68dde57466001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43425f36415f31325f45465f37455f413900000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000043423a36413a31323a45463a37453a41390000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000043422d36412d31322d45462d37452d413900000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00adff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00270000004c000261790000001b00000012195075c129debb41163e049ade3f3f94f3498509a1bb70780045001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f34395f46465f44395f35455f38445f313200000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000034393a46463a44393a35453a38443a31320000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000034392d46462d44392d35452d38442d313200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000001006581d80929d8000000000070000005478506f77657200016e000007000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f31335f38365f41365f42355f38425f304500000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000031333a38363a41363a42353a38423a30450000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000031332d38362d41362d42352d38422d304500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00adff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000009060385c0a8d3e4000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f34325f38335f46395f44465f46425f444100000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000034323a38333a46393a44463a46423a44410000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000034322d38332d46392d44462d46422d444100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00240000004c00026179000000180000000c0e0010214ca675ab775d9132fa401510067f1db9018a18000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45315f35315f45315f37385f38365f413800000008020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000008c01000000000000070000004164647265737300017300001100000045313a35313a45313a37383a38363a41380000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000045312d35312d45312d37382d38362d413800000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00abff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00100000004c0002617900000004000000120200001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42345f45385f34325f44425f35365f354200000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000042343a45383a34323a44423a35363a35420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300140000004c45446e657457463031303039374442353635410000000005000000416c69617300017300000000140000004c45446e65745746303130303937444235363541000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0027000000015a0261790000001b0000005202b4e842db565a00970b03010203040506070809a1a2a3a4a5a6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f34335f33335f41355f33455f42425f454400000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000034333a33333a41353a33453a42423a45440000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000034332d33332d41352d33452d42422d454400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000010060619a814a35800000000070000005478506f77657200016e000002000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35315f31345f35355f44315f37365f433100000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000035313a31343a35353a44313a37363a43310000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000035312d31342d35352d44312d37362d433100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b1ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000010060619a814a35800000000070000005478506f77657200016e000002000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30445f39465f45305f36335f46305f353600000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000030443a39463a45303a36333a46303a35360000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000030442d39462d45302d36332d46302d353600000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000000906036fc0a8d326000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f46415f31375f42365f32435f39385f314600000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000046413a31373a42363a32433a39383a31460000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300080000004641313742363243000000000000000005000000416c696173000173000000000800000046413137423632430000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b3ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0025000000330102617900000019000000011902ab00ab01be00c601d500c401ca00c401cf00000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36455f38465f46305f44425f44465f413200000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000036453a38463a46303a44423a44463a41320000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000036452d38462d46302d44422d44462d413200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b5ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00170000004c000261790000000b0000000f05900032250c1002200400070000005478506f77657200016e000006000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f32415f46325f46365f35455f44415f443400000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000032413a46323a46363a35453a44413a44340000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000032412d46322d46362d35452d44412d443400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00220000004c000261790000001600000009060325c0a8d172130c0acb212e8817a3010401030c0000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f37415f38465f45305f45315f34305f433700000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000037413a38463a45303a45313a34303a43370000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300080000003966326164636632000000000000000005000000416c696173000173000000000800000039663261646366320000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c9ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000033396436623333332d616461642d343563382d623665652d65616336633463643030303000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0016000000f7030261790000000a0000001a0000000000486f6d6500001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44355f37365f39425f45425f41325f313100000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000044353a37363a39423a45423a41323a31310000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000044352d37362d39422d45422d41322d313100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00abff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00270000004c000261790000001b0000001219504890337fccd1171fe530454c57d260c7ac20f8f9478d0211001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36465f30375f39335f35455f35305f4544000000a0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000002402000000000000070000004164647265737300017300001100000036463a30373a39333a35453a35303a45440000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000036462d30372d39332d35452d35302d454400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00afff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666539662d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0012000000e000026179000000060000000145ca9ed45d0000000000000b00000053657276696365446174610005617b73767d000048000000000000002400000030303030666539662d303030302d313030302d383030302d3030383035663962333466620002617900000000140000000255795366316e5a796a347700000184435ed85c1000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30415f37445f43325f32375f37455f364600000068020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ec01000000000000070000004164647265737300017300001100000030413a37443a43323a32373a37453a36460000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000030412d37442d43322d32372d37452d364600000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666436662d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000048000000000000002400000030303030666436662d303030302d313030302d383030302d30303830356639623334666200026179000000001400000064edc902d73adc4230c61b06978426a71dd9c2c71000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36365f34365f34395f37305f44435f363000000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000036363a34363a34393a37303a44433a36300000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000036362d34362d34392d37302d44432d363000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00abff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00150000004c00026179000000090000001007361f53834a3118000000070000005478506f77657200016e000007000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45435f31325f38375f44435f32395f314200000008020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000008c01000000000000070000004164647265737300017300001100000045433a31323a38373a44433a32393a31420000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000045432d31322d38372d44432d32392d314200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00100000004c0002617900000004000000120200001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35345f36445f45335f41465f33425f324300000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000035343a36443a45333a41463a33423a32430000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000035342d36442d45332d41462d33422d324300000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c5ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00100000004c000261790000000400000010020200070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45445f45445f32355f44345f44335f463100000080020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000000402000000000000070000004164647265737300017300001100000045443a45443a32353a44343a44333a46310000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173001200000038343642323146464141443033334139453900000000000005000000416c6961730001730000000012000000383436423231464641414430333341394539000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b5ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666530372d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0019000000a7050261790000000d000000051001000000000000012200ca00000000000000070000005478506f77657200016e000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f32415f31365f31325f34415f34365f394300000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000032413a31363a31323a34413a34363a39430000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000032412d31362d31322d34412d34362d394300000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00beff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000000906030bc0a8d16f000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f31435f42335f43395f31315f31395f323200000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000031433a42333a43393a31313a31393a32320000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000031432d42332d43392d31312d31392d323200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00130000004c000261790000000700000010050e1040c47d0000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f31415f35375f373600000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000041343a43313a33383a31413a35373a37360000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730004000000543330310000000005000000416c696173000173000000000400000054333031000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00afff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001d00000055aa026179000000110000000105a4c1381a5776010707ee15184800010000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f31325f44365f464200000078020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000fc01000000000000070000004164647265737300017300001100000041343a43313a33383a31323a44363a46420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300090000004235313738443646420000000000000005000000416c696173000173000000000900000042353137384436464200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00cdff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030656338382d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b00000001000261790000000900000001010103fac24600050000004c00026179000000170000000215494e54454c4c495f524f434b535f48575075f2ffc200000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f45445f32375f363200000080020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000000402000000000000070000004164647265737300017300001100000041343a43313a33383a45443a32373a36320000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000c000000475648353037355f323736320000000005000000416c696173000173000000000c000000475648353037355f32373632000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b3ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030656338382d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b00000088ec0261790000000600000000030b185a000000000000004c00026179000000170000000215494e54454c4c495f524f434b535f48575075f2ff0c00000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f3643000000c0030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000004403000000000000070000004164647265737300017300001100000044303a37323a30453a34423a37463a36430000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000e00000057656d6f20537461676520303633000005000000416c696173000173000000000e00000057656d6f2053746167652030363300000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d4ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000890100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303063632d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303132392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303233362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313830302d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c000261790000001300000006310042154cf4b9de0f0063000102b533e54f001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303132392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303133392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c7565000261790000001c000000d5b017879b0b3af2bd6e864f4b9445b35c8547af26c3517f1711d129090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303061342f6465736330306137002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303061342f6465736330306136002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303133382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303061312f6465736330306133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396500006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c7565000261790000001a000000ad14ff1e719e773d8b9546fee0f3b2866948726ca8ec673127ba000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039652f6465736330306130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303133312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039622f6465736330303964002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393800006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303133302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000220000007ce0e39be3df9a1872be3508d6285cf9b3a89c1c944474d8574a8de5f79544212e78000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039382f6465736330303961002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039352f6465736330303937002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303233362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386500009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000090100000400000055554944000173002400000030303030303233352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c7565000261790000001e00000067ad136eceff732d130fdd259fd34caa0974749658745b2776a536ed0757000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038652f6465736330303931002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038652f6465736330303930002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386100009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000090100000400000055554944000173002400000030303030303233342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c7565000261790000001d000000847fb53cc7fe03a5fd2f6a3c1a286d07afff9f80b0deaf3d4a99b19a6d00000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038612f6465736330303864002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038612f6465736330303863002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030383700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038372f6465736330303839002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030383700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030383500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030383100006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c7565000261790000001e000000a9de36c64b727b6fe27bf95c09557de53c621a65d3c80450730cc15e762b00000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303038312f6465736330303833002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030383100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030376400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c756500026179000000180000006b4e4ec7f908a5cba38372b9dbdd5922d03f2c4e2891f25800000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037642f6465736330303830002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030376400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037642f6465736330303766002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030376400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373900008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c75650002617900000018000000536f356f279e1733fdeefec426b73cf92d99305086e9f17300000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037392f6465736330303763002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037392f6465736330303762002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030373300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c75650002617900000018000000049d0c3c192f7343003107e73be7d4f95a372af3df3d66c90000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030373300000500000056616c75650002617900000002000000640000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c7565000261790000001c0000002fd32cdcac5c1454fe1b44ef67bbcd89805b4b687e4192bceaaef783090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036662f6465736330303732002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366600000500000056616c75650002617900000002000000630000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366300008001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000fa0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c756500026179000000360000008b777440ace1de1ac5ec4cf604f13f0ed6511bf96661a20ab07fef5fae73f4d9a4c3ecb4b2482d9e0b4e2e6f9da411a5d1f47e5f31b800000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036632f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366300000500000056616c75650002617900000002000000620000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030363900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036392f6465736330303662002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030363900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030363700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030363300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c756500026179000000180000009deaedc82ab8fb127d2014e823cd93fe5c4eaaeb5f80117d0000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303036332f6465736330303635002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030363300000500000056616c75650002617900000002000000540000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c7565000261790000001c0000004bdf0b05f0d9e6127a20d743ff2bb6125fb5d7848cb8313dffbe6d2c090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035662f6465736330303632002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356600000500000056616c75650002617900000002000000530000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035662f6465736330303631002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356300008001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000fa0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c75650002617900000036000000ac47653d40f34ab0d6db002d56d92da92eb5dc2e77feecb5c2a0e30ef07d10888b7f7534751d6cdf2e2d128f455fbc92adc171534c7700000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035632f6465736330303565002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356300000500000056616c75650002617900000002000000520000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030353900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035392f6465736330303562002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030353700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030353300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c75650002617900000018000000533044670d2038a235f96446a90c1bcc4d4cc1bc2f6845770000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303035332f6465736330303535002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030353300000500000056616c75650002617900000002000000440000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000170000000d99e75cc6f9eefd3d491c603ee0b0d8921da85ac433630000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034662f6465736330303532002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346600000500000056616c75650002617900000002000000430000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034662f6465736330303531002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346300008001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000fa0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000360000000f3bb1b485243439fd1f4fa5e7d5b801b8fe61fc80baaf9f63e4f76af0f7178943282eed8aefd0a728ce0a13fea2ccd318980990bac400000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034632f6465736330303465002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346300000500000056616c75650002617900000002000000420000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030343900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034392f6465736330303462002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030343900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030343700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303063632d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063642d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000000500000056616c75650002617900000018000000156e709a979ec0d41dd55d0802864b1d1a5e9f335a1dd5060000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f63686172303034332f6465736330303435002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f63686172303034302f6465736330303432002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030336500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030336100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033612f6465736330303363002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030336100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033372f6465736330303339002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333400005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c7565000261790000000a00000002080005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033342f6465736330303336002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333400000500000056616c75650002617900000002000000230000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033312f6465736330303333002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030326600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030326200006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000000500000056616c7565000261790000001c000000547f62b362940b982c779db50ff9257f04feee0cc0adb9a18dd92df005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f63686172303032622f6465736330303264002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030326200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030323800009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000000500000056616c75650002617900000046000000dcd522b625a8c030c786c89102d997f3ebb53182d14a7b0afdcb7386a939ac51a028e2b610ad827dd6f05d805b6885327ddc2cdf4a13fe2aba80181558a4863c77b4ab55ea3a00000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f63686172303032382f6465736330303261002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030323800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030323600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030323200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303232302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303032322f6465736330303234002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030323200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000033346162383831312d616337662d343334302d626163332d66643661383566393934336200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031662f6465736330303231002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031632f6465736330303165002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313800007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e90000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031382f6465736330303162002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031382f6465736330303161002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031352f6465736330303137002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031322f6465736330303134002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303030662f6465736330303131002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303030632f6465736330303065002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030303900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303030392f6465736330303062002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030303900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030303700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43425f45375f37425f36385f45385f383000000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000043423a45373a37423a36383a45383a38300000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000f000000457665204d6f74696f6e20343141340005000000416c696173000173000000000f000000457665204d6f74696f6e2034314134000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d1ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c00026179000000130000000631006e35dc9fc1090a0019000102cbfa6fbb001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35385f32445f33345f36305f32365f3336000000b8020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000003c02000000000000070000004164647265737300017300001100000035383a32443a33343a36303a32363a33360000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173001b00000051696e6770696e6720446f6f722f57696e646f772053656e736f72000000000005000000416c696173000173000000001b00000051696e6770696e6720446f6f722f57696e646f772053656e736f720006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d9ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000085000000000000002400000030303030666539352d303030302d313030302d383030302d30303830356639623334666200026179000000000c0000003058d60302362660342d58082400000030303030666463642d303030302d313030302d383030302d3030383035663962333466620002617900000000110000000804362660342d580201140f010c0f01010000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f32455f43415f364500000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000041343a43313a33383a32453a43413a36450000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730004000000543230310000000005000000416c696173000173000000000400000054323031000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001d00000055aa026179000000110000000101a4c1382eca6e010707ec121d6200010000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44425f30325f38305f31465f41445f314400000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000044423a30323a38303a31463a41443a31440000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000d00000045766520526f6f6d203038383100000005000000416c696173000173000000000d00000045766520526f6f6d20303838310000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001b0000004c000261790000000f00000006cd00fbbef0c7cf250a000e00010200000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f31305f37365f33365f31345f39335f373600000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000031303a37363a33363a31343a39333a37360000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000c0000005450333933202839333736290000000005000000416c696173000173000000000c000000545033393320283933373629000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0020000000c2c502617900000004000000002d022cc2c402617900000004000000002d022c1000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30305f30365f38305f30385f44325f393500000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000030303a30363a38303a30383a44323a39350000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730008000000535a472034385344000000000000000005000000416c6961730001730000000008000000535a4720343853440000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bdff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000065323061333966342d373366352d346263342d613132662d31376431616430376139363100000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001200000010100261790000000600000000068008d2950000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44355f30375f38455f45455f41365f4242000000f0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000007402000000000000070000004164647265737300017300001100000044353a30373a38453a45453a41363a42420000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d650001730001000000730000000000000005000000416c69617300017300000000010000007300000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bbff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000065663039303030302d313164362d343262612d393362382d39646437656330393061613900000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00c600000062e6026179000000020000008c0500004c00026179000000170000000215ef09000011d642ba93b89dd7ec090aa900061e06c8000000000062f6026179000000020000008c0500006206026179000000020000008d0500006216026179000000020000008d0500006226026179000000020000008d0500006236026179000000020000008d0500006036026179000000020000008d0500006026026179000000020000008d0500006046026179000000020000008d0500006246026179000000020000008d0500001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44465f37395f45335f41365f31325f423300000048030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000cc02000000000000070000004164647265737300017300001100000044463a37393a45333a41363a31323a42330000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300070000004d6f61745f53320005000000416c69617300017300000000070000004d6f61745f5332000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00beff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000550000002400000030303030313030302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030323030302d303030302d313030302d383030302d3030383035663962333466620000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215f173a6a0acd811eabb370242ac130002d660407bcb00000000000b00000053657276696365446174610005617b73767d000084000000000000002400000030303030313030302d303030302d313030302d383030302d303038303566396233346662000261790000000012000000df79e3a612b3a534656318612869b90bffff00002400000030303030353030302d303030302d313030302d383030302d303038303566396233346662000261790000000008000000df79e3a612b3b90b00000000070000005478506f77657200016e000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000050040000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d403000000000000070000004164647265737300017300001100000043443a41333a46413a44313a35303a35360000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300110000004f6e7669732d534d53312d3362326431610000000000000005000000416c69617300017300000000110000004f6e7669732d534d53312d33623264316100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d5ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000d0200002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000034616161663936312d306465632d313165352d623933392d303830303230306339613636000000002400000034616161663964352d306465632d313165352d623933392d3038303032303063396136360000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c00026179000000130000000631008209820e65e00a001a1201021277e7d2001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000034616161663964352d306465632d313165352d623933392d303830303230306339613636000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030616100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663964372d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000000500000056616c7565000261790000001b0000000201f1a6233f2ba1595de529129ee68fd2fbe13e1bc6c2a20152dd0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f63686172303061612f6465736330306163002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030616100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030613700006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663964362d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000000500000056616c7565000261790000001b000000f773af102f37b1a155cc63eb74906ae165ab782b234fb1ec21a1c30005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f63686172303061372f6465736330306139002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030613700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030613500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030613100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030313533312d313231322d656664652d313532332d37383566656162636431323300000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f63686172303061312f6465736330306133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030613100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030396500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f63686172303039652f6465736330306130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030396500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030396300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393700008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303038662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c7565000261790000001c000000fc25cd1a8ae8fdddd474a96e689b1f22a31ff5b3dfa41828314512c2090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039372f6465736330303961002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039372f6465736330303939002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393400007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c756500026179000000260000001fa358c95f8d6f16f4f90b49f7277384df1b4aa5dba19925145e397fea9c1241197efe0979a500000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039342f6465736330303936002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393000008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c7565000261790000001c0000000a3a210659ac6698a9cb257e0f9534b4c32e4e78437697185af386b2090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039302f6465736330303933002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039302f6465736330303932002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c7565000261790000001c000000fb84802fc059c3587335ef0b7d80b6119bf2c20ea0df8f0710fe39eb090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303038632f6465736330303866002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303038632f6465736330303865002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000034616161663936312d306465632d313165352d623933392d303830303230306339613636000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383600006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663936332d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000000500000056616c7565000261790000001b00000051e4a221c6455f0339f4a5acb7fa6e6ea3308b2469d6a343df91b70005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f63686172303038362f6465736330303838002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663936322d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000000500000056616c7565000261790000001b000000ee92725b7589873b89ae596e1c9c6c0fbc6e24512f77e814ae074c0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f63686172303038332f6465736330303835002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663962392d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c75650002617900000017000000f6bf4bec08843fa3f17f498f7f9375c738c2f3a3cf3cf1000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037642f6465736330303766002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000034616161663962382d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c75650002617900000029000000f02cf675ea88f17fde55b3cac216130de4c23485bbfaca3ebd9438d9c301856dcd3c72c3e80087ac3200000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037612f6465736330303763002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c7565000261790000001c000000804b21b7b0a9d3a849c7365e17c43426cb6ba6664e77f3af0c5762e8090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037362f6465736330303739002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037362f6465736330303738002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373300007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c7565000261790000002c00000099b82c95686e511795250db93f64b598e87f4c89d76388a3bf697a5aaa226d60dcd10c4eeecbdf431604f1f405000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663962642d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c75650002617900000017000000d142febcf9065dff3079911ce72392e7afa630d3b29748000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036642f6465736330303666002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000034616161663962632d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c756500026179000000290000001dabc2325704e8de64768f396e917e71a5c5724af6b4140d58893ab4297876c46fb86650b5d10f639f00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036612f6465736330303663002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c7565000261790000001c0000003e59fd2dbcc2dc8dc58a593c4ed839a29fdef1944b406914006ab015090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036362f6465736330303639002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036362f6465736330303638002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363300007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c7565000261790000002f000000f3d36e0845882eba309a12bd2b31b9132a8af9c92cf29183109ee2db858117ba32ba9fc2654b624d78b7c1187381b4000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036332f6465736330303635002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663939662d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000001b000000dff36beb6be2224e4c9e1fc89767693e8723fb2c2bec32a54fa6390005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035642f6465736330303566002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663938392d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000190000003182232bc64172b4989010980aa2e048502b9cee1e9c85f71e00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035612f6465736330303563002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353700006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000034616161663938382d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000001d000000d8d0d32123bc3b0c93ede75c39d953731e1c14823dac11e2cc04d727e60000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035372f6465736330303539002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663935652d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c75650002617900000019000000b839722e7d846c51d270116f51a81e22c26bbf0f8783ef09ff00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035342f6465736330303536002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663935642d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c75650002617900000019000000a46761f05a3cf9ae1c59dcbd009fae264aad7dda39efa0ec0e00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035312f6465736330303533002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346500006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663935632d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000190000008e29a95862714e8c3198b33579e33a68a6b55893ccebf5e88a00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034652f6465736330303530002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346100008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303032322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000001c000000646058aa8f4221083dc72066d86011ba371f83a81358742ad691e47f090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034612f6465736330303464002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034612f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343700007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000002a000000803ee8d1eaa2394ac69a3097a62cea51635faa64b2c702bc35134f61f173f11c1bda4aaf3ff01e5b47b5000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034372f6465736330303439002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034342f6465736330303436002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343200003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033652f6465736330303430002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033622f6465736330303364002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333800005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c7565000261790000000a000000025b0005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033382f6465736330303361002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333800000500000056616c756500026179000000020000000b0000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033352f6465736330303337002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326600006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000000500000056616c7565000261790000001c00000015ba6229c69f6dfc36fc2408e4f9040a054ca23becceb601e658088e05000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f63686172303032662f6465736330303331002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326300009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000000500000056616c75650002617900000046000000b7b13b6b03c7d87dbc812023ecfaffa7944535b6eaf95832ffd3ecbdd0e8e247fe90551d6ad39fd9c7db8b419adad5037ae4b58eee609be557607cf03d533782a62a160869a900000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f63686172303032632f6465736330303265002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303232302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303032362f6465736330303238002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000033346162383831312d616337662d343334302d626163332d66643661383566393934336200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303032332f6465736330303235002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303032302f6465736330303232002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031642f6465736330303166002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031612f6465736330303163002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031372f6465736330303139002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031342f6465736330303136002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031312f6465736330303133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030306500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303030652f6465736330303130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030306500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030306300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35385f44335f34395f45365f30325f364500000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000035383a44333a34393a45363a30323a36450000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000035382d44332d34392d45362d30322d364500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b9ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00130000004c000261790000000700000010050e10b8832c0000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44435f30445f31355f33365f43445f433900000038030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc02000000000000070000004164647265737300017300001100000044433a30443a31353a33363a43443a43390000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000a0000004653432d42503130354e00000000000005000000416c696173000173000000000a0000004653432d42503130354e000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00ddff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000550000002400000030303030666566352d303030302d313030302d383030302d303038303566396233346662000000002400000030303030666561612d303030302d313030302d383030302d3030383035663962333466620000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215fda50693a4e24fb1afcfc6eb07647825275165c1fd00000000000b00000053657276696365446174610005617b73767d000082000000000000002400000030303030666666302d303030302d313030302d383030302d30303830356639623334666200026179000000000b000000360216b2dc0d1536cdc964002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200026179000000000e00000020000bcd80000010e5e6117ee3030000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44445f33345f30325f30365f44455f413100000018030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009c02000000000000070000004164647265737300017300001100000044443a33343a30323a30363a44453a41310000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d650001730010000000426c7565436861726d5f313737393939000000000000000005000000416c6961730001730000000010000000426c7565436861726d5f3137373939390000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d7ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215426c7565436861726d426561636f6e730efe1355c500000000000b00000053657276696365446174610005617b73767d000082000000000000002400000030303030323038302d303030302d313030302d383030302d303038303566396233346662000261790000000006000000640c0efe13550000000000002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200026179000000000e00000020000bc61b00003db2380279a78a0000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42435f31345f45465f37425f32325f324100000058020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000dc01000000000000070000004164647265737300017300001100000042433a31343a45463a37423a32323a32410000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000c0000004e41505f4650435f323232410000000005000000416c696173000173000000000c0000004e41505f4650435f32323241000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b5ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666630302d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00160000004e410261790000000a000000505f4650435f3232324100001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42345f45385f34325f44425f41465f364200000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000042343a45383a34323a44423a41463a36420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300140000004c45446e657457463031303039374442414636410000000005000000416c69617300017300000000140000004c45446e65745746303130303937444241463641000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00acff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0027000000015a0261790000001b0000005202b4e842dbaf6a00970b03010203040506070809a1a2a3a4a5a6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45305f34355f38315f31315f31335f463700000030020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000b401000000000000070000004164647265737300017300001100000045303a34353a38313a31313a31333a46370000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000045302d34352d38312d31312d31332d463700000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000038000000000000002400000030303030666666652d303030302d313030302d383030302d3030383035663962333466620002617900000000040000000900ff001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35385f32445f33345f36305f44415f3146000000b0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000003402000000000000070000004164647265737300017300001100000035383a32443a33343a36303a44413a31460000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173001700000051696e6770696e67204d6f74696f6e2026204c696768740005000000416c696173000173000000001700000051696e6770696e67204d6f74696f6e2026204c69676874000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c9ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000088000000000000002400000030303030666539352d303030302d313030302d383030302d30303830356639623334666200026179000000000c0000003058830a021fda60342d58082400000030303030666463642d303030302d313030302d383030302d30303830356639623334666200026179000000001400000008121fda60342d580201550f01e409040a0000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44435f30445f33305f30465f41435f444100000038030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc02000000000000070000004164647265737300017300001100000044433a30443a33303a30463a41433a44410000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000a0000004653432d42503130334200000000000005000000416c696173000173000000000a0000004653432d425031303342000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00caff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000550000002400000030303030666566352d303030302d313030302d383030302d303038303566396233346662000000002400000030303030666561612d303030302d313030302d383030302d3030383035663962333466620000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215d546df97475747efbe093e2dcbdd0c777775f4a5b500000000000b00000053657276696365446174610005617b73767d000084000000000000002400000030303030666666302d303030302d313030302d383030302d30303830356639623334666200026179000000000b00000029021792dc0d300facda61002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200026179000000001000000010eb03676f6f2e676c2f50484e53646d000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44375f45415f32375f44355f46465f373500000090020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000001402000000000000070000004164647265737300017300001100000044373a45413a32373a44353a46463a37350000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000044372d45412d32372d44352d46462d373500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d3ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0012000000590002617900000006000000d7ea27d5ff750000000000000b00000053657276696365446174610005617b73767d000038000000000000002400000030303030306430302d303030302d313030302d383030302d303038303566396233346662000261790000000004000000620062001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f3133000000f8030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000007c03000000000000070000004164647265737300017300001100000044333a32433a35413a35423a35333a31330000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173001200000051696e6770696e672054656d70205248204800000000000005000000416c696173000173000000001200000051696e6770696e672054656d702052482048000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d0ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000b50100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000032323231303030302d353534612d343534362d353534322d3436353334343530343634640000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100cacc78de9d4d0a00b3020102648d8540001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030373200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303038662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c75650002617900000019000000360cd8f589cd437c8e63e0ed4026ef8e23521c438cf9603846000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303037322f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030373200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303037322f6465736330303734002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030373200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366600007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c756500026179000000260000008acacfbede51497aa8314cd7d962914118939e7de11e0a0c72f2288299134c0bc6e32fb9eb9500000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c7565000261790000001900000050f2de9cfe1dfe3a5429155f435a90ef698e2027ad8baf1b68000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036622f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036622f6465736330303664002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363700008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c75650002617900000019000000c054d735743526ea57788686e5bff568aff675f2e9a8befc1d000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036372f6465736330303661002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036372f6465736330303639002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030363000008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000000500000056616c75650002617900000019000000ce22ecd3258d6fa2c9051c49b3281fd3581ac02954f27a04f4000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f63686172303036302f6465736330303633002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030363000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f63686172303036302f6465736330303632002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030363000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030356400007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000000500000056616c756500026179000000280000004c1f1698d0d39c3321a5875685533f0e36cb215974814b62f533a39753351429ad985e524dbb71bc0000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f63686172303035642f6465736330303566002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030356200003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000000500000056616c756500026179000000190000004333a86ddd626c73ff065dc79e6bd65e403e5e6656ff37ac4a000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f63686172303035362f6465736330303539002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f63686172303035362f6465736330303538002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353300007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000000500000056616c7565000261790000002b00000084460d1eb333851e7a6c7258498116fd93cb732431dd4a6f934e5387df41ac12cf7161e86238bdc518e1180005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f63686172303035332f6465736330303535002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000032323231303030302d353534612d343534362d353534322d343635333434353034363464000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346400007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000000500000056616c75650002617900000027000000b0a8a34ea00c61b9660183c344acb37d9d23f31c1ce267783a149341ebae5d9dcd0548949ec468000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f63686172303034642f6465736330303466002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000032323231303030312d353534612d343534362d353534322d34363533343435303436346400000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000000500000056616c75650002617900000017000000bf304d57146670a9539b6b2b108f59e89100fa97308b82000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f63686172303034612f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030343800003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030313533312d313231322d656664652d313532332d37383566656162636431323300000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f63686172303034342f6465736330303436002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f63686172303034312f6465736330303433002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030336600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030336200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033622f6465736330303364002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030336200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333800004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033382f6465736330303361002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333500005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c7565000261790000000a00000002ea0005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033352f6465736330303337002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333500000500000056616c756500026179000000020000000b0000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033322f6465736330303334002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333000003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030326300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000000500000056616c7565000261790000001c0000008a5b51efc327b514b7cc70276f9e15a279d785a38c36e88959f98b3505000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f63686172303032632f6465736330303265002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030326300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030323900009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000000500000056616c75650002617900000046000000daf38c8555278d56e414620809dcf4edb6a7eabec4affc61392f26c3e5c5916a968e541d76fb18effa14ffeb35afae79307941f9a9bacf324e95013c2d41961c43c1c6b0917200000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f63686172303032392f6465736330303262002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030323900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030323700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303032332f6465736330303235002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303032302f6465736330303232002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031642f6465736330303166002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031612f6465736330303163002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031372f6465736330303139002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031342f6465736330303136002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031312f6465736330303133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030306600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030612f636861723030306200005801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000d10000000400000055554944000173002400000030303030326130352d303030302d313030302d383030302d30303830356639623334666200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030610000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000000d00000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030612f63686172303030622f6465736330303064002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030612f636861723030306200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43375f39355f35395f34385f45445f4430000000c0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000004402000000000000070000004164647265737300017300001100000043373a39353a35393a34383a45443a44300000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300080000004131333352445038000000000000000005000000416c696173000173000000000800000041313333524450380000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d1ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666462662d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100fe312467a4170600330001024e60e6a2000b00000053657276696365446174610005617b73767d000041000000000000002400000030303030666462662d303030302d313030302d383030302d30303830356639623334666200026179000000000d000000021a032db41ce3c06701009dba000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f32325f32385f37305f33395f42315f443200000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000032323a32383a37303a33393a42313a44320000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000032322d32382d37302d33392d42312d443200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000000906030dc0a8d2a3000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f37385f39435f38355f30415f39345f343000000070020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000f401000000000000070000004164647265737300017300001100000037383a39433a38353a30413a39343a34300000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300070000004c3330433457330005000000416c69617300017300000000070000004c333043345733000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666532342d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b000000d101026179000000120000000000a04284a740c04fa88ad5e4917143475100004c000261790000000f000000068d003847f4f21d200600f610010200000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45445f31415f32355f32375f36435f384600000040020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000c401000000000000070000004164647265737300017300001100000045443a31413a32353a32373a36433a38460000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300130000004e616e6f6c6561662053747269702032443253000000000005000000416c69617300017300000000130000004e616e6f6c65616620537472697020324432530006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000000b08026179000000130000004e4c353501041d01000400804b50fffe6c1238001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44385f33355f36375f41345f46355f4135000000a8020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000002c02000000000000070000004164647265737300017300001100000044383a33353a36373a41343a46353a41350000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173001500000050726f646967696f5f44383335363741344635413500000005000000416c696173000173000000001500000050726f646967696f5f4438333536374134463541350000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b4ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030366161313931302d663232612d313165332d396461612d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b0000000225026179000000060000004409800700020000000000004c0002617900000017000000021506aa1910f22a11e39daa0002a5d5c51b071b700ec40000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f43325f34455f30385f41425f353700000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000044303a43323a34453a30383a41423a35370000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000044302d43322d34452d30382d41422d353700000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bdff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0024000000750002617900000018000000420401806ed0c24e08ab57d2c24e08ab5601000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f30335f44465f42315f34325f364600000048020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000cc01000000000000070000004164647265737300017300001100000044303a30333a44463a42313a34323a36460000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300120000005b54565d204d61737465722062656420747600000000000005000000416c69617300017300000000120000005b54565d204d617374657220626564207476000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c6ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0024000000750002617900000018000000420401017ed003dfb1426fd203dfb1426e01000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30425f30325f35455f34465f35435f393400000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000030423a30323a35453a34463a35433a39340000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000030422d30322d35452d34462d35432d393400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d3ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000009060312c0a8d208000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000098030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000001c03000000000000070000004164647265737300017300001100000046463a44383a36363a35383a41353a37430000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000f00000045766520427574746f6e20464342410005000000416c696173000173000000000f00000045766520427574746f6e2046434241000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00caff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000005d0100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000065383633663030372d303739652d343866662d386632372d3963323630356132396635320000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100f445fbc5aa1b0f00f000010231164ce5001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001c0000008cf98b58fff7d782824141107fdc63b6527a8a436061bcc68f7e6b0b090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303037332f6465736330303736002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303038662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001c0000001bbbedc69f899451c85a3cb18039e7b18ae4aae5cd91ce639f3eec24090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036662f6465736330303732002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001c00000030d4c96faf74ec43c4767cabf1f33b21f1a75606d43ec61ffad112e3090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036622f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036622f6465736330303664002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030363800006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001e00000068dc9a07f960f43eb92a5ea12b3bd46ea0360a9bc4b0ef4a1064c113f58a00000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036382f6465736330303661002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030363800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000065383633663030372d303739652d343866662d386632372d396332363035613239663532000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030363500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030363200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303036322f6465736330303634002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030363200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030356600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000065383633663131642d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035662f6465736330303631002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030356600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035630000b001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000002a0100000400000055554944000173002400000065383633663133312d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000006b0000003ce7a58c4cc046586313cd5e7a9e95131ae166b4d689f6c9e98b33452ce7a4a64a12922f4e1b95f7b424101917aa58e03d0d96c383cfebed7134132fa6906be276fe4cb58acb5fdfb62334fcf284bfc4d75fd35ee558ba505d8107566a00621fc5810d9644fba101d48a8a0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035632f6465736330303565002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030356300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353900006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000065383633663131372d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000002200000082fc818fc6b07331d1395f33a8564e77cc1ff3c07aa7a5086c876860b681ab6ed45c000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035392f6465736330303562002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353600007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f20000000400000055554944000173002400000065383633663131362d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c75650002617900000034000000e8f9ff23d8034e61b3bca655238a0b31352bb2ac92a7dc917df918a504acfa7c65fdd59131eac4ea49136ff124793a3d8b84366905000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035362f6465736330303538002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000065383633663132312d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035332f6465736330303535002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000065383633663131632d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035302f6465736330303532002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000065383633663131322d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000001b000000f26d31c4b56c2e47c3906451ac615d841f1d9acba308c08f054dce0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303034642f6465736330303466002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000065383633663131652d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000290000004f59cab057e9eceac3ee2548eb47ffe7bf531f61d64d4abf56ca117af439ad2185971b89a61eafdfa400000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303034612f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030343700006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000001e0000008648819bfcf041c81fcaf693fc2c2f4e8e8a7be5e35e3b455a2ac446342400000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303034372f6465736330303439002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030343700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030343400003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030343100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303034312f6465736330303433002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030343100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c7565000261790000001c000000a1e5d72ab52fc742a78feae94ad2df30f39732bd455d2ad92fbb699f090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303033642f6465736330303430002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303033642f6465736330303366002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336100006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c75650002617900000021000000ff6fcae85d64504982b7a4752df8fb4452239352acfea5939a39e6c28c406c56a700000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303033612f6465736330303363002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303033342f6465736330303336002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303033312f6465736330303333002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326500005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c7565000261790000000a000000024f0005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303032652f6465736330303330002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326500000500000056616c756500026179000000020000000e0000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303032622f6465736330303264002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323800003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323500009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000000500000056616c756500026179000000460000004749c3506527b2a6154ef462499e14311039b0f3d228a44327ef1b62c28ae997802fb821a413211bc31145ee0c53680f3eda3bff825d0a78c67129d6851fd7098dffc6310b2200000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f63686172303032352f6465736330303237002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323200006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000000500000056616c7565000261790000001c00000006d1aeb01ac30545bac72d7233429346b8b3874c5b922b4ef677aabb05000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f63686172303032322f6465736330303234002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030316600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030316300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031632f6465736330303165002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030316300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031392f6465736330303162002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031362f6465736330303138002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031332f6465736330303135002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031302f6465736330303132002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303030642f6465736330303066002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303030612f6465736330303063002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030380000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42445f32345f36465f38355f41415f363100000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000042443a32343a36463a38353a41413a36310000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730012000000447265616d7e42443234364638354141363100000000000005000000416c6961730001730000000012000000447265616d7e424432343646383541413631000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00deff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00120000004851026179000000060000003336343635360000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43315f43375f32375f37445f35355f414200000098020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000001c02000000000000070000004164647265737300017300001100000043313a43373a32373a37443a35353a41420000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000043312d43372d32372d37442d35352d414200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00deff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0012000000590002617900000006000000c1c7277d55ab0000000000000b00000053657276696365446174610005617b73767d00003a000000000000002400000030303030306430302d303030302d313030302d383030302d30303830356639623334666200026179000000000600000063d0d26411040000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f46305f42335f45435f32305f44345f373600000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000046303a42333a45433a32303a44343a37360000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000046302d42332d45432d32302d44342d373600000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00ceff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00130000004c000261790000000700000010050714e02d0e0000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f30335f44465f39465f33305f353900000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000044303a30333a44463a39463a33303a35390000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000044302d30332d44462d39462d33302d353900000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bcff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00240000007500026179000000180000004204018060d003df9f3059d203df9f305801000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42345f45385f34325f34415f37335f384200000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000042343a45383a34323a34413a37333a38420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300140000004c45446e657457463030303031433441373338410000000005000000416c69617300017300000000140000004c45446e65745746303030303143344137333841000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00afff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0027000000005a0261790000001b0000005203b4e8424a738a001c1a03010203040506070809a1a2a3a4a5a6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f4143000000c8030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000004c03000000000000070000004164647265737300017300001100000043463a44463a41353a43343a46343a41430000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300130000004e616e6f6c6561662053747269702032443253000000000005000000416c69617300017300000000130000004e616e6f6c65616620537472697020324432530006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c4ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000890100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303034332d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303233392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303730312d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030653963633637372d613731662d386238332d623834642d353638323738373930636233000000002400000036643261653163342d396165612d313165612d626233372d30323432616331333030303200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100eab2458702490500cf0001028f7cafd6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000036643261653163342d396165612d313165612d626233372d303234326163313330303032000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030613100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000061396530613264652d396165612d313165612d626233372d30323432616331333030303200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030396500007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e90000000400000055554944000173002400000036643261646461302d396165612d313165612d626233372d30323432616331333030303200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f63686172303039652f6465736330306130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030396500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030396300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000036643261646664612d396165612d313165612d626233372d30323432616331333030303200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030653963633637372d613731662d386238332d623834642d353638323738373930636233000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039342f636861723030393900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000031333536333465362d336363312d303562382d306434392d34383432616435663933633900000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039342f636861723030393700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030393139393231632d633465372d386339342d353034622d64303461313436623831353700000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039342f636861723030393500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000061356635623538312d663638662d343363362d383866312d38343136666263376335313300000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303233392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030393000008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303234612d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c7565000261790000001b000000e460312c7bc34b123a10a49d8059b122180dbc32d76a17e0cc1ede00090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303039302f6465736330303933002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303039302f6465736330303932002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030386300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303233632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c756500026179000000170000001b19b57fe169eb38d1c9104328b0542156c964e57f508a0000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038632f6465736330303866002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038632f6465736330303865002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383800008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303233612d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c7565000261790000001b000000e635fd8679a7e6020ccba38cd8614572a15b640a511ccf3b4af9d100090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038382f6465736330303862002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038382f6465736330303861002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038352f6465736330303837002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303730312d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376600006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303730342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c7565000261790000001700000073ac012862d53de353b04377c9a2a7556206ff9b1aa111000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037662f6465736330303831002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303232622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c756500026179000000180000009ab83ec21e47d91d097e1fabcdbf7ca46509dfa93abc88fb00000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037622f6465736330303765002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037622f6465736330303764002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373700008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303730332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c7565000261790000001900000081edc5e8a83b73820820794a72c67338209b0bfa6d661492db000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037372f6465736330303761002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037372f6465736330303739002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303730322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c75650002617900000019000000813bc232fdc177d62806e74416de6807f5526c98cfe98f3b38000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037332f6465736330303736002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036660000d801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000510100000400000055554944000173002400000030303030303730362d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c7565000261790000006800000081faf9feacc0e99c6447c9683b1faba564bf8cebb718a354d85c0bf1747296776b7be7ceee8e204c255e2d4971060b73da317ac7c38c1ddbdc593cb35c4e13e22e890b98c952e0ae21c22a42f6817ede89a2980f8301af0e2ca6f66110b8c352df3290d3ce132afb00000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036662f6465736330303732002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036632f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303034332d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363500008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303234622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000018000000e5fd94280f3d0a882d8f31986eebb2a63c63d61ae01b147c00000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036352f6465736330303638002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036352f6465736330303637002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036310000a001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000190100000400000055554944000173002400000030303030303134342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000002f00000017c9379c7143b5a575b2dbf7c51531707018af85f2927959baa1d0d39c4a9566c4ef8286a5d3aadc225a80791ed0ff0000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036312f6465736330303634002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036312f6465736330303633002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030356400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303134332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000017000000f877f6e2d3f1253e82d145058a26f97683e8c598bef3200000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035642f6465736330303630002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035642f6465736330303566002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353900008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000061323865313930322d636661312d346433372d613130662d30303731636565656565626400000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000017000000a8dec0db0cbafe9640bb2ed847eab37f535038c39a79800000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035392f6465736330303563002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035392f6465736330303562002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353500008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303032662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b00000093b47702465a8d4b59c0e7454e7e5a24a132c6f21b7395c2486f8a00090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035352f6465736330303538002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035352f6465736330303537002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353100008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b00000055883ec1c266bf491feef70d66085b4d2bedcaa82de0c18b19920f00090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035312f6465736330303534002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035312f6465736330303533002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030346400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303063652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b000000e5c8a04859451dd18a277908d63d85f762e3592889721e564d8d2800090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034642f6465736330303530002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034642f6465736330303466002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343900008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303030382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b000000bea7cb3df9bae95486a0659d83edd4aa224a0116a3e12161a0f3f100090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034392f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034392f6465736330303462002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343600007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000002b0000009cf36d0b77ef915335391c1e9f3db4bf8b2f3adc329adbecf9b4a7d4a4394e359d7d62cd8559cd397202bf0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034362f6465736330303438002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303032352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000018000000a18583ad4550c9909bb270a2f72af115b05031c193681e3700000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034322f6465736330303435002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034322f6465736330303434002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030336600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303033662f6465736330303431002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030336600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030336400003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333900006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000000500000056616c7565000261790000001c000000a20c37be2e21ddd9ff4ac736ce277e8e62d65a7f14a1172a4eb8084805000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f63686172303033392f6465736330303362002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333600009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000000500000056616c75650002617900000046000000c74543f0f66c46def821a8929b07577f168e831270b53e876ca7c9ff17750470cbfaf3ca75251064ae9bbe58b8df51f927088d688c563df5905461b6c8cf9c633eb5e5990dd100000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f63686172303033362f6465736330303338002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333400003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030333000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303033302f6465736330303332002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030333000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303032642f6465736330303266002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c75650002617900000029000000023b00240001220601020001060e08043b253a0ba2f9c105106f6214a6270b6a78349b3f6626b9a97a00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303032612f6465736330303263002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326100000500000056616c75650002617900000002000000230000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030323700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303032372f6465736330303239002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030323700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030323500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030323100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303232302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303032312f6465736330303233002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030323100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000033346162383831312d616337662d343334302d626163332d66643661383566393934336200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031652f6465736330303230002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031622f6465736330303164002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313800004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031382f6465736330303161002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031352f6465736330303137002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031322f6465736330303134002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303030662f6465736330303131002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303030632f6465736330303065002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030303900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303030392f6465736330303062002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030303900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030303700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f433200000000030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000008402000000000000070000004164647265737300017300001100000036303a35353a46393a32423a33363a43320000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730007000000576f53747269700005000000416c6961730001730000000007000000576f5374726970000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d6ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000810000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001c0000006909026179000000100000006055f92b36c24d6422dc000000000000000000000b00000053657276696365446174610005617b73767d000037000000000000002400000030303030666433642d303030302d313030302d383030302d303038303566396233346662000261790000000003000000720064001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032380000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000063626132306430302d323234642d313165362d396662382d303030326135643563353162000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f433200000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f636861723030326300007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f40000000400000055554944000173002400000063626132303030322d323234642d313165362d396662382d30303032613564356335316200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032380000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000260000001600000077726974652d776974686f75742d726573706f6e73650000050000007772697465000000000000000d000000577269746541637175697265640001620000000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f636861723030323900007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f40000000400000055554944000173002400000063626132303030332d323234642d313165362d396662382d30303032613564356335316200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032380000000500000056616c7565000261790000000b000000010064ff60d7000000ff0200090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000000b000000060000006e6f7469667900000e0000004e6f74696679416371756972656400016200000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f63686172303032392f6465736330303262002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f636861723030323900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030310000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f433200000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030312f636861723030303200005801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000d10000000400000055554944000173002400000030303030326130352d303030302d313030302d383030302d30303830356639623334666200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030310000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000000d00000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030312f63686172303030322f6465736330303034002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030312f636861723030303200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f33435f33345f4441000000f8020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000007c02000000000000070000004164647265737300017300001100000036303a35353a46393a33433a33343a44410000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730006000000576f506c7567000005000000416c6961730001730000000006000000576f506c756700000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00dcff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000810000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001800000069090261790000000c0000006055f93c34daea00103400000b00000053657276696365446174610005617b73767d000037000000000000002400000030303030666433642d303030302d313030302d383030302d303038303566396233346662000261790000000003000000670064001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000 dbus-fast-2.44.1/tests/data/messages.json000066400000000000000000000263561477355613200203000ustar00rootroot00000000000000[ { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "" }, "data": "6c01000100000000010000006d00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e4442757300000000" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "as", "body": [["hello", "world"]] }, "data": "6c0100011a000000010000007800000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670002617300160000000500000068656c6c6f00000005000000776f726c6400" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "a(uu)", "body": [ [ [1, 1], [2, 2] ] ] }, "data": "6c01000118000000010000007b00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700056128757529000000000000100000000000000001000000010000000200000002000000" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "a{ss}", "body": [ { "foo": "bar", "bat": "baz" } ] }, "data": "6c01000128000000010000007b00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670005617b73737d000000000000200000000000000003000000666f6f00030000006261720003000000626174000300000062617a00" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "a(as(uu(a{ss})))", "body": [ [ [ ["hello", "there"], [ 5, 6, [ { "five": "six", "seven": "eight" } ] ] ], [ ["to", "the", "world"], [ 7, 8, [ { "seven": "eight", "nine": "ten" } ] ] ] ] ] }, "data": "6c010001c4000000010000008600000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700106128617328757528617b73737d292929000000bc00000000000000160000000500000068656c6c6f0000000500000074686572650000000000000005000000060000002e0000000000000004000000666976650000000003000000736978000000000005000000736576656e0000000500000065696768740000001a00000002000000746f0000030000007468650005000000776f726c6400000007000000080000002c0000000000000005000000736576656e000000050000006569676874000000040000006e696e65000000000300000074656e00" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "t", "body": [9007199254740988] }, "data": "6c01000108000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001740000fcffffffffff1f00" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "x", "body": [-9007199254740988] }, "data": "6c01000108000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001780000040000000000e0ff" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "bnqiud", "body": [true, -200, 150, -20000, 20000, 9083492084.4444] }, "data": "6c01000118000000010000007c00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670006626e7169756400000000000100000038ff9600e0b1ffff204e0000228ea3b758eb0042" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "v", "body": [ { "signature": "s", "value": "hello world" } ] }, "data": "6c01000114000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001760000017300000b00000068656c6c6f20776f726c6400" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "v", "body": [ { "signature": "v", "value": { "signature": "s", "value": "hello" } } ] }, "data": "6c01000112000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e4442757300000000080167000176000001760001730000000500000068656c6c6f00" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "a{sv}", "body": [ { "variant_key_1": { "signature": "s", "value": "variant_val_1" }, "variant_key_2": { "signature": "s", "value": "variant_val_2" } } ] }, "data": "6c01000162000000010000007b00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670005617b73767d0000000000005a000000000000000d00000076617269616e745f6b65795f31000173000000000d00000076617269616e745f76616c5f31000000000000000d00000076617269616e745f6b65795f32000173000000000d00000076617269616e745f76616c5f3200" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "v", "body": [ { "signature": "as", "value": ["foo", "bar"] } ] }, "data": "6c01000118000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001760000026173001000000003000000666f6f000300000062617200" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "vas", "body": [ { "signature": "v", "value": { "signature": "s", "value": "world" } }, ["bar"] ] }, "data": "6c01000120000000010000007900000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700037661730000000000000000017600017300000005000000776f726c64000000080000000300000062617200" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "asbbasbb", "body": [["hello", "worl"], true, false, ["hello", "worl"], true, false] }, "data": "6c01000148000000010000007e00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700086173626261736262000000150000000500000068656c6c6f00000004000000776f726c000000000100000000000000150000000500000068656c6c6f00000004000000776f726c000000000100000000000000" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "as", "body": [["//doesntmatter/über"]] }, "data": "6c0100011d000000010000007800000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e4442757300000000080167000261730019000000140000002f2f646f65736e746d61747465722fc3bc62657200" }, { "message": { "destination": "org.freedesktop.DBus", "path": "/org/freedesktop/DBus", "interface": "org.freedesktop.DBus", "member": "Hello", "serial": 1, "signature": "an", "body": [[-1024]] }, "data": "6c01000106000000010000007800000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670002616e000200000000fc" } ] dbus-fast-2.44.1/tests/data/sloppy-introspection.xml000066400000000000000000000006651477355613200225370ustar00rootroot00000000000000 dbus-fast-2.44.1/tests/data/strict-introspection.xml000066400000000000000000000023141477355613200225120ustar00rootroot00000000000000 dbus-fast-2.44.1/tests/service/000077500000000000000000000000001477355613200163115ustar00rootroot00000000000000dbus-fast-2.44.1/tests/service/__init__.py000066400000000000000000000000001477355613200204100ustar00rootroot00000000000000dbus-fast-2.44.1/tests/service/test_decorators.py000066400000000000000000000111501477355613200220650ustar00rootroot00000000000000from dbus_fast import PropertyAccess from dbus_fast import introspection as intr from dbus_fast.service import ServiceInterface, dbus_property, method, signal class ExampleInterface(ServiceInterface): def __init__(self): super().__init__("test.interface") self._some_prop = 55 self._another_prop = 101 self._weird_prop = 500 @method() def some_method(self, one: "s", two: "s") -> "s": return "hello" @method(name="renamed_method", disabled=True) def another_method(self, eight: "o", six: "t"): pass @signal() def some_signal(self) -> "as": # noqa: F722 return ["result"] @signal(name="renamed_signal", disabled=True) def another_signal(self) -> "(dodo)": return [1, "/", 1, "/"] @dbus_property( name="renamed_readonly_property", access=PropertyAccess.READ, disabled=True ) def another_prop(self) -> "t": return self._another_prop @dbus_property() def some_prop(self) -> "u": return self._some_prop @some_prop.setter def some_prop(self, val: "u"): self._some_prop = val + 1 # for this one, the setter has a different name than the getter which is a # special case in the code @dbus_property() def weird_prop(self) -> "t": return self._weird_prop @weird_prop.setter def setter_for_weird_prop(self, val: "t"): self._weird_prop = val def test_method_decorator(): interface = ExampleInterface() assert interface.name == "test.interface" properties = ServiceInterface._get_properties(interface) methods = ServiceInterface._get_methods(interface) signals = ServiceInterface._get_signals(interface) assert len(methods) == 2 method = methods[0] assert method.name == "renamed_method" assert method.in_signature == "ot" assert method.out_signature == "" assert method.disabled assert type(method.introspection) is intr.Method method = methods[1] assert method.name == "some_method" assert method.in_signature == "ss" assert method.out_signature == "s" assert not method.disabled assert type(method.introspection) is intr.Method assert len(signals) == 2 signal = signals[0] assert signal.name == "renamed_signal" assert signal.signature == "(dodo)" assert signal.disabled assert type(signal.introspection) is intr.Signal signal = signals[1] assert signal.name == "some_signal" assert signal.signature == "as" assert not signal.disabled assert type(signal.introspection) is intr.Signal assert len(properties) == 3 renamed_readonly_prop = properties[0] assert renamed_readonly_prop.name == "renamed_readonly_property" assert renamed_readonly_prop.signature == "t" assert renamed_readonly_prop.access == PropertyAccess.READ assert renamed_readonly_prop.disabled assert type(renamed_readonly_prop.introspection) is intr.Property weird_prop = properties[1] assert weird_prop.name == "weird_prop" assert weird_prop.access == PropertyAccess.READWRITE assert weird_prop.signature == "t" assert not weird_prop.disabled assert weird_prop.prop_getter is not None assert weird_prop.prop_getter.__name__ == "weird_prop" assert weird_prop.prop_setter is not None assert weird_prop.prop_setter.__name__ == "setter_for_weird_prop" assert type(weird_prop.introspection) is intr.Property prop = properties[2] assert prop.name == "some_prop" assert prop.access == PropertyAccess.READWRITE assert prop.signature == "u" assert not prop.disabled assert prop.prop_getter is not None assert prop.prop_setter is not None assert type(prop.introspection) is intr.Property # make sure the getter and setter actually work assert interface._some_prop == 55 interface._some_prop = 555 assert interface.some_prop == 555 assert interface._weird_prop == 500 assert weird_prop.prop_getter(interface) == 500 interface._weird_prop = 1001 assert interface._weird_prop == 1001 weird_prop.prop_setter(interface, 600) assert interface._weird_prop == 600 def test_interface_introspection(): interface = ExampleInterface() intr_interface = interface.introspect() assert type(intr_interface) is intr.Interface xml = intr_interface.to_xml() assert xml.tag == "interface" assert xml.attrib.get("name", None) == "test.interface" methods = xml.findall("method") signals = xml.findall("signal") properties = xml.findall("property") assert len(xml) == 4 assert len(methods) == 1 assert len(signals) == 1 assert len(properties) == 2 dbus-fast-2.44.1/tests/service/test_export.py000066400000000000000000000076741477355613200212610ustar00rootroot00000000000000import pytest from dbus_fast import Message, MessageType from dbus_fast import introspection as intr from dbus_fast.aio import MessageBus from dbus_fast.service import ServiceInterface, method standard_interfaces_count = len(intr.Node.default().interfaces) class ExampleInterface(ServiceInterface): def __init__(self, name): self._method_called = False super().__init__(name) @method() def some_method(self): self._method_called = True @pytest.mark.asyncio async def test_export_unexport(): interface = ExampleInterface("test.interface") interface2 = ExampleInterface("test.interface2") export_path = "/test/path" export_path2 = "/test/path/child" bus = await MessageBus().connect() bus.export(export_path, interface) with pytest.raises(ValueError): # Already exported bus.export(export_path, interface) assert export_path in bus._path_exports assert len(bus._path_exports[export_path]) == 1 assert bus._path_exports[export_path][interface.name] is interface assert len(ServiceInterface._get_buses(interface)) == 1 bus.export(export_path2, interface2) node = bus._introspect_export_path(export_path) assert len(node.interfaces) == standard_interfaces_count + 1 assert len(node.nodes) == 1 # relative path assert node.nodes[0].name == "child" bus.unexport(export_path, interface) assert export_path not in bus._path_exports assert len(ServiceInterface._get_buses(interface)) == 0 bus.export(export_path2, interface) assert len(bus._path_exports[export_path2]) == 2 # test unexporting the whole path bus.unexport(export_path2) assert not bus._path_exports assert not ServiceInterface._get_buses(interface) assert not ServiceInterface._get_buses(interface2) # test unexporting by name bus.export(export_path, interface) bus.unexport(export_path, interface.name) assert not bus._path_exports assert not ServiceInterface._get_buses(interface) # test unexporting by ServiceInterface bus.export(export_path, interface) bus.unexport(export_path, interface) assert not bus._path_exports assert not ServiceInterface._get_buses(interface) with pytest.raises(TypeError): bus.unexport(export_path, object()) node = bus._introspect_export_path("/path/doesnt/exist") assert type(node) is intr.Node assert not node.interfaces assert not node.nodes # Should to nothing bus.unexport("/path/doesnt/exist", interface) bus.disconnect() @pytest.mark.asyncio async def test_export_alias(): bus = await MessageBus().connect() interface = ExampleInterface("test.interface") export_path = "/test/path" export_path2 = "/test/path/child" bus.export(export_path, interface) bus.export(export_path2, interface) result = await bus.call( Message( destination=bus.unique_name, path=export_path, interface="test.interface", member="some_method", ) ) assert result.message_type is MessageType.METHOD_RETURN, result.body[0] assert interface._method_called interface._method_called = False result = await bus.call( Message( destination=bus.unique_name, path=export_path2, interface="test.interface", member="some_method", ) ) assert result.message_type is MessageType.METHOD_RETURN, result.body[0] assert interface._method_called bus.disconnect() @pytest.mark.asyncio async def test_export_introspection(): interface = ExampleInterface("test.interface") interface2 = ExampleInterface("test.interface2") export_path = "/test/path" export_path2 = "/test/path/child" bus = await MessageBus().connect() bus.export(export_path, interface) bus.export(export_path2, interface2) root = bus._introspect_export_path("/") assert len(root.nodes) == 1 bus.disconnect() dbus-fast-2.44.1/tests/service/test_methods.py000066400000000000000000000156021477355613200213710ustar00rootroot00000000000000import pytest from dbus_fast import ( DBusError, ErrorType, Message, MessageFlag, MessageType, SignatureTree, Variant, ) from dbus_fast.aio import MessageBus from dbus_fast.service import ServiceInterface, method class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) @method() def echo(self, what: "s") -> "s": assert type(self) is ExampleInterface return what @method() def echo_multiple(self, what1: "s", what2: "s") -> "ss": assert type(self) is ExampleInterface return [what1, what2] @method() def echo_containers( self, array: "as", # noqa: F722 variant: "v", dict_entries: "a{sv}", # noqa: F722 struct: "(s(s(v)))", ) -> "asva{sv}(s(s(v)))": # noqa: F722 assert type(self) is ExampleInterface return [array, variant, dict_entries, struct] @method() def ping(self): assert type(self) is ExampleInterface @method(name="renamed") def original_name(self): assert type(self) is ExampleInterface @method(disabled=True) def not_here(self): assert type(self) is ExampleInterface @method() def throws_unexpected_error(self): assert type(self) is ExampleInterface raise Exception("oops") @method() def throws_dbus_error(self): assert type(self) is ExampleInterface raise DBusError("test.error", "an error occurred") class AsyncInterface(ServiceInterface): def __init__(self, name): super().__init__(name) @method() async def echo(self, what: "s") -> "s": assert type(self) is AsyncInterface return what @method() async def echo_multiple(self, what1: "s", what2: "s") -> "ss": assert type(self) is AsyncInterface return [what1, what2] @method() async def echo_containers( self, array: "as", # noqa: F722 variant: "v", dict_entries: "a{sv}", # noqa: F722 struct: "(s(s(v)))", ) -> "asva{sv}(s(s(v)))": # noqa: F722 assert type(self) is AsyncInterface return [array, variant, dict_entries, struct] @method() async def ping(self): assert type(self) is AsyncInterface @method(name="renamed") async def original_name(self): assert type(self) is AsyncInterface @method(disabled=True) async def not_here(self): assert type(self) is AsyncInterface @method() async def throws_unexpected_error(self): assert type(self) is AsyncInterface raise Exception("oops") @method() def throws_dbus_error(self): assert type(self) is AsyncInterface raise DBusError("test.error", "an error occurred") @pytest.mark.parametrize("interface_class", [ExampleInterface, AsyncInterface]) @pytest.mark.asyncio async def test_methods(interface_class): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = interface_class("test.interface") export_path = "/test/path" async def call( member, signature="", body=[], flags=MessageFlag.NONE, interface=interface.name ): return await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface=interface, member=member, signature=signature, body=body, flags=flags, ) ) bus1.export(export_path, interface) body = ["hello world"] reply = await call("echo", "s", body) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "s" assert reply.body == body body = ["hello", "world"] reply = await call("echo_multiple", "ss", body) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "ss" assert reply.body == body body = [ ["hello", "world"], Variant("v", Variant("(ss)", ["hello", "world"])), {"foo": Variant("t", 100)}, ["one", ["two", [Variant("s", "three")]]], ] signature = "asva{sv}(s(s(v)))" SignatureTree(signature).verify(body) reply = await call("echo_containers", signature, body) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == signature assert reply.body == body # Wrong interface should be a failure reply = await call( "echo_containers", signature, body, interface="org.abc.xyz.Props" ) assert reply.message_type == MessageType.ERROR, reply.body[0] assert reply.error_name == "org.freedesktop.DBus.Error.UnknownMethod", reply.body[0] assert reply.body == [ 'org.abc.xyz.Props.echo_containers with signature "asva{sv}(s(s(v)))" could not be found' ] # No interface should result in finding anything that matches the member name # and the signature reply = await call("echo_containers", signature, body, interface=None) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == signature assert reply.body == body # No interface should result in finding anything that matches the member name # and the signature, but in this case it will be nothing because # the signature is wrong reply = await call("echo_containers", "as", body, interface=None) assert reply.message_type == MessageType.ERROR, reply.body[0] assert reply.error_name == "org.freedesktop.DBus.Error.UnknownMethod", reply.body[0] assert reply.body == ['None.echo_containers with signature "as" could not be found'] reply = await call("ping") assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "" assert reply.body == [] reply = await call("throws_unexpected_error") assert reply.message_type == MessageType.ERROR, reply.body[0] assert reply.error_name == ErrorType.SERVICE_ERROR.value, reply.body[0] reply = await call("throws_dbus_error") assert reply.message_type == MessageType.ERROR, reply.body[0] assert reply.error_name == "test.error", reply.body[0] assert reply.body == ["an error occurred"] reply = await call("ping", flags=MessageFlag.NO_REPLY_EXPECTED) assert reply is None reply = await call("throws_unexpected_error", flags=MessageFlag.NO_REPLY_EXPECTED) assert reply is None reply = await call("throws_dbus_error", flags=MessageFlag.NO_REPLY_EXPECTED) assert reply is None reply = await call("does_not_exist") assert reply.message_type == MessageType.ERROR, reply.body[0] assert reply.error_name == "org.freedesktop.DBus.Error.UnknownMethod", reply.body[0] assert reply.body == [ 'test.interface.does_not_exist with signature "" could not be found' ] bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() dbus-fast-2.44.1/tests/service/test_properties.py000066400000000000000000000227771477355613200221350ustar00rootroot00000000000000import asyncio import pytest from dbus_fast import ( DBusError, ErrorType, Message, MessageType, PropertyAccess, Variant, ) from dbus_fast.aio import MessageBus from dbus_fast.service import ServiceInterface, dbus_property, method class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) self._string_prop = "hi" self._readonly_prop = 100 self._disabled_prop = "1234" self._container_prop = [["hello", "world"]] self._renamed_prop = "65" @dbus_property() def string_prop(self) -> "s": return self._string_prop @string_prop.setter def string_prop_setter(self, val: "s"): self._string_prop = val @dbus_property(PropertyAccess.READ) def readonly_prop(self) -> "t": return self._readonly_prop @dbus_property() def container_prop(self) -> "a(ss)": return self._container_prop @container_prop.setter def container_prop(self, val: "a(ss)"): self._container_prop = val @dbus_property(name="renamed_prop") def original_name(self) -> "s": return self._renamed_prop @original_name.setter def original_name_setter(self, val: "s"): self._renamed_prop = val @dbus_property(disabled=True) def disabled_prop(self) -> "s": return self._disabled_prop @disabled_prop.setter def disabled_prop(self, val: "s"): self._disabled_prop = val @dbus_property(disabled=True) def throws_error(self) -> "s": raise DBusError("test.error", "told you so") @throws_error.setter def throws_error(self, val: "s"): raise DBusError("test.error", "told you so") @dbus_property(PropertyAccess.READ, disabled=True) def returns_wrong_type(self) -> "s": return 5 @method() def do_emit_properties_changed(self): changed = {"string_prop": "asdf"} invalidated = ["container_prop"] self.emit_properties_changed(changed, invalidated) class AsyncInterface(ServiceInterface): def __init__(self, name): super().__init__(name) self._string_prop = "hi" self._readonly_prop = 100 self._disabled_prop = "1234" self._container_prop = [["hello", "world"]] self._renamed_prop = "65" @dbus_property() async def string_prop(self) -> "s": return self._string_prop @string_prop.setter async def string_prop_setter(self, val: "s"): self._string_prop = val @dbus_property(PropertyAccess.READ) async def readonly_prop(self) -> "t": return self._readonly_prop @dbus_property() async def container_prop(self) -> "a(ss)": return self._container_prop @container_prop.setter async def container_prop(self, val: "a(ss)"): self._container_prop = val @dbus_property(name="renamed_prop") async def original_name(self) -> "s": return self._renamed_prop @original_name.setter async def original_name_setter(self, val: "s"): self._renamed_prop = val @dbus_property(disabled=True) async def disabled_prop(self) -> "s": return self._disabled_prop @disabled_prop.setter async def disabled_prop(self, val: "s"): self._disabled_prop = val @dbus_property(disabled=True) async def throws_error(self) -> "s": raise DBusError("test.error", "told you so") @throws_error.setter async def throws_error(self, val: "s"): raise DBusError("test.error", "told you so") @dbus_property(PropertyAccess.READ, disabled=True) async def returns_wrong_type(self) -> "s": return 5 @method() def do_emit_properties_changed(self): changed = {"string_prop": "asdf"} invalidated = ["container_prop"] self.emit_properties_changed(changed, invalidated) @pytest.mark.parametrize("interface_class", [ExampleInterface, AsyncInterface]) @pytest.mark.asyncio async def test_property_methods(interface_class): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = interface_class("test.interface") export_path = "/test/path" bus1.export(export_path, interface) async def call_properties(member, signature, body): return await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface="org.freedesktop.DBus.Properties", member=member, signature=signature, body=body, ) ) result = await call_properties("GetAll", "s", [interface.name]) assert result.message_type == MessageType.METHOD_RETURN, result.body[0] assert result.signature == "a{sv}" assert result.body == [ { "string_prop": Variant("s", interface._string_prop), "readonly_prop": Variant("t", interface._readonly_prop), "container_prop": Variant("a(ss)", interface._container_prop), "renamed_prop": Variant("s", interface._renamed_prop), } ] result = await call_properties("Get", "ss", [interface.name, "string_prop"]) assert result.message_type == MessageType.METHOD_RETURN, result.body[0] assert result.signature == "v" assert result.body == [Variant("s", "hi")] result = await call_properties( "Set", "ssv", [interface.name, "string_prop", Variant("s", "ho")] ) assert result.message_type == MessageType.METHOD_RETURN, result.body[0] assert interface._string_prop == "ho" if interface_class is AsyncInterface: assert "ho", await interface.string_prop() else: assert "ho", interface.string_prop result = await call_properties( "Set", "ssv", [interface.name, "readonly_prop", Variant("t", 100)] ) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == ErrorType.PROPERTY_READ_ONLY.value, result.body[0] result = await call_properties( "Set", "ssv", [interface.name, "disabled_prop", Variant("s", "asdf")] ) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value result = await call_properties( "Set", "ssv", [interface.name, "not_a_prop", Variant("s", "asdf")] ) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value # wrong type result = await call_properties( "Set", "ssv", [interface.name, "string_prop", Variant("t", 100)] ) assert result.message_type == MessageType.ERROR assert result.error_name == ErrorType.INVALID_SIGNATURE.value # enable the erroring properties so we can test them for prop in ServiceInterface._get_properties(interface): if prop.name in ["throws_error", "returns_wrong_type"]: prop.disabled = False result = await call_properties("Get", "ss", [interface.name, "returns_wrong_type"]) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == ErrorType.SERVICE_ERROR.value result = await call_properties( "Set", "ssv", [interface.name, "throws_error", Variant("s", "ho")] ) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == "test.error" assert result.body == ["told you so"] result = await call_properties("Get", "ss", [interface.name, "throws_error"]) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == "test.error" assert result.body == ["told you so"] result = await call_properties("GetAll", "s", [interface.name]) assert result.message_type == MessageType.ERROR, result.body[0] assert result.error_name == "test.error" assert result.body == ["told you so"] bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() @pytest.mark.parametrize("interface_class", [ExampleInterface, AsyncInterface]) @pytest.mark.asyncio async def test_property_changed_signal(interface_class): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus2.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="AddMatch", signature="s", body=[f"sender={bus1.unique_name}"], ) ) interface = interface_class("test.interface") export_path = "/test/path" bus1.export(export_path, interface) async def wait_for_message(): # TODO timeout future = asyncio.get_running_loop().create_future() def message_handler(signal): if signal.interface == "org.freedesktop.DBus.Properties": bus2.remove_message_handler(message_handler) future.set_result(signal) bus2.add_message_handler(message_handler) return await future bus2.send( Message( destination=bus1.unique_name, interface=interface.name, path=export_path, member="do_emit_properties_changed", ) ) signal = await wait_for_message() assert signal.interface == "org.freedesktop.DBus.Properties" assert signal.member == "PropertiesChanged" assert signal.signature == "sa{sv}as" assert signal.body == [ interface.name, {"string_prop": Variant("s", "asdf")}, ["container_prop"], ] bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() dbus-fast-2.44.1/tests/service/test_signals.py000066400000000000000000000167031477355613200213710ustar00rootroot00000000000000import asyncio import pytest from dbus_fast import Message, MessageType from dbus_fast.aio import MessageBus from dbus_fast.constants import PropertyAccess from dbus_fast.service import ( ServiceInterface, SignalDisabledError, dbus_property, signal, ) from dbus_fast.signature import Variant class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) @signal() def signal_empty(self): assert type(self) is ExampleInterface @signal() def signal_simple(self) -> "s": assert type(self) is ExampleInterface return "hello" @signal() def signal_multiple(self) -> "ss": assert type(self) is ExampleInterface return ["hello", "world"] @signal(name="renamed") def original_name(self): assert type(self) is ExampleInterface @signal(disabled=True) def signal_disabled(self): assert type(self) is ExampleInterface @dbus_property(access=PropertyAccess.READ) def test_prop(self) -> "i": return 42 class SecondExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) @dbus_property(access=PropertyAccess.READ) def str_prop(self) -> "s": return "abc" @dbus_property(access=PropertyAccess.READ) def list_prop(self) -> "ai": return [1, 2, 3] class ExpectMessage: def __init__(self, bus1, bus2, interface_name, timeout=1): self.future = asyncio.get_running_loop().create_future() self.bus1 = bus1 self.bus2 = bus2 self.interface_name = interface_name self.timeout = timeout self.timeout_task = None def message_handler(self, msg): if msg.sender == self.bus1.unique_name and msg.interface == self.interface_name: self.timeout_task.cancel() self.future.set_result(msg) return True def timeout_cb(self): self.future.set_exception(TimeoutError) async def __aenter__(self): self.bus2.add_message_handler(self.message_handler) self.timeout_task = asyncio.get_running_loop().call_later( self.timeout, self.timeout_cb ) return self.future async def __aexit__(self, exc_type, exc_val, exc_tb): self.bus2.remove_message_handler(self.message_handler) def assert_signal_ok(signal, export_path, member, signature, body): assert signal.message_type == MessageType.SIGNAL assert signal.path == export_path assert signal.member == member assert signal.signature == signature assert signal.body == body @pytest.mark.asyncio async def test_signals(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = ExampleInterface("test.interface") export_path = "/test/path" bus1.export(export_path, interface) await bus2.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="AddMatch", signature="s", body=[f"sender={bus1.unique_name}"], ) ) async with ExpectMessage(bus1, bus2, interface.name) as expected_signal: interface.signal_empty() assert_signal_ok( signal=await expected_signal, export_path=export_path, member="signal_empty", signature="", body=[], ) async with ExpectMessage(bus1, bus2, interface.name) as expected_signal: interface.original_name() assert_signal_ok( signal=await expected_signal, export_path=export_path, member="renamed", signature="", body=[], ) async with ExpectMessage(bus1, bus2, interface.name) as expected_signal: interface.signal_simple() assert_signal_ok( signal=await expected_signal, export_path=export_path, member="signal_simple", signature="s", body=["hello"], ) async with ExpectMessage(bus1, bus2, interface.name) as expected_signal: interface.signal_multiple() assert_signal_ok( signal=await expected_signal, export_path=export_path, member="signal_multiple", signature="ss", body=["hello", "world"], ) with pytest.raises(SignalDisabledError): interface.signal_disabled() bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() @pytest.mark.asyncio async def test_interface_add_remove_signal(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() await bus2.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="AddMatch", signature="s", body=[f"sender={bus1.unique_name}"], ) ) first_interface = ExampleInterface("test.interface.first") second_interface = SecondExampleInterface("test.interface.second") export_path = "/test/path" # add first interface async with ExpectMessage( bus1, bus2, "org.freedesktop.DBus.ObjectManager" ) as expected_signal: bus1.export(export_path, first_interface) assert_signal_ok( signal=await expected_signal, export_path=export_path, member="InterfacesAdded", signature="oa{sa{sv}}", body=[ export_path, {"test.interface.first": {"test_prop": Variant("i", 42)}}, ], ) # add second interface async with ExpectMessage( bus1, bus2, "org.freedesktop.DBus.ObjectManager" ) as expected_signal: bus1.export(export_path, second_interface) assert_signal_ok( signal=await expected_signal, export_path=export_path, member="InterfacesAdded", signature="oa{sa{sv}}", body=[ export_path, { "test.interface.second": { "str_prop": Variant("s", "abc"), "list_prop": Variant("ai", [1, 2, 3]), } }, ], ) # remove single interface async with ExpectMessage( bus1, bus2, "org.freedesktop.DBus.ObjectManager" ) as expected_signal: bus1.unexport(export_path, second_interface) assert_signal_ok( signal=await expected_signal, export_path=export_path, member="InterfacesRemoved", signature="oas", body=[export_path, ["test.interface.second"]], ) # add second interface again async with ExpectMessage( bus1, bus2, "org.freedesktop.DBus.ObjectManager" ) as expected_signal: bus1.export(export_path, second_interface) await expected_signal # remove multiple interfaces async with ExpectMessage( bus1, bus2, "org.freedesktop.DBus.ObjectManager" ) as expected_signal: bus1.unexport(export_path) assert_signal_ok( signal=await expected_signal, export_path=export_path, member="InterfacesRemoved", signature="oas", body=[export_path, ["test.interface.first", "test.interface.second"]], ) bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() dbus-fast-2.44.1/tests/service/test_standard_interfaces.py000066400000000000000000000215031477355613200237260ustar00rootroot00000000000000import pytest from dbus_fast import Message, MessageType from dbus_fast import introspection as intr from dbus_fast.aio import MessageBus from dbus_fast.constants import ErrorType from dbus_fast.service import PropertyAccess, ServiceInterface, dbus_property from dbus_fast.signature import Variant standard_interfaces_count = len(intr.Node.default().interfaces) class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) class ExampleComplexInterface(ServiceInterface): def __init__(self, name): self._foo = 42 self._bar = "str" self._async_prop = "async" super().__init__(name) @dbus_property(access=PropertyAccess.READ) def Foo(self) -> "y": return self._foo @dbus_property(access=PropertyAccess.READ) def Bar(self) -> "s": return self._bar @dbus_property(access=PropertyAccess.READ) async def AsyncProp(self) -> "s": return self._async_prop @pytest.mark.asyncio async def test_introspectable_interface(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = ExampleInterface("test.interface") interface2 = ExampleInterface("test.interface2") export_path = "/test/path" bus1.export(export_path, interface) bus1.export(export_path, interface2) reply = await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface="org.freedesktop.DBus.Introspectable", member="Introspect", ) ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "s" node = intr.Node.parse(reply.body[0]) assert len(node.interfaces) == standard_interfaces_count + 2 assert node.interfaces[-1].name == "test.interface2" assert node.interfaces[-2].name == "test.interface" assert not node.nodes # introspect works on every path reply = await bus2.call( Message( destination=bus1.unique_name, path="/path/doesnt/exist", interface="org.freedesktop.DBus.Introspectable", member="Introspect", ) ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "s" node = intr.Node.parse(reply.body[0]) assert not node.interfaces assert not node.nodes bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_introspect_matching_sub_paths(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = ExampleInterface("test.interface1") bus1.export("/a/test/path1", interface) bus1.export("/a/test/path10", interface) bus1.export("/a/subpath/a/test/path2", interface) async def introspect_subpath(path, expected_subnodes): reply = await bus2.call( Message( destination=bus1.unique_name, path=path, interface="org.freedesktop.DBus.Introspectable", member="Introspect", ) ) assert reply.signature == "s" node = intr.Node.parse(reply.body[0]) assert {n.name for n in node.nodes} == expected_subnodes await introspect_subpath("/", {"a"}) await introspect_subpath("/a", {"test", "subpath"}) await introspect_subpath("/a/test", {"path1", "path10"}) await introspect_subpath("/a/test/path1", set()) await introspect_subpath("/a/test/path10", set()) await introspect_subpath("/a/subpath/a/test", {"path2"}) await introspect_subpath("/a/subpath/a/test/path2", set()) bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_peer_interface(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() reply = await bus2.call( Message( destination=bus1.unique_name, path="/path/doesnt/exist", interface="org.freedesktop.DBus.Peer", member="Ping", ) ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "" reply = await bus2.call( Message( destination=bus1.unique_name, path="/path/doesnt/exist", interface="org.freedesktop.DBus.Peer", member="GetMachineId", signature="", ) ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.signature == "s" reply2 = await bus2.call( Message( destination=bus1.unique_name, path="/path/doesnt/exist", interface="org.freedesktop.DBus.Peer", member="GetMachineId", signature="", ) ) assert reply2.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply2.signature == "s" bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_object_manager(): expected_reply = { "/test/path/deeper": { "test.interface2": { "Bar": Variant("s", "str"), "Foo": Variant("y", 42), "AsyncProp": Variant("s", "async"), } } } reply_ext = { "/test/path": { "test.interface1": {}, "test.interface2": { "Bar": Variant("s", "str"), "Foo": Variant("y", 42), "AsyncProp": Variant("s", "async"), }, } } bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = ExampleInterface("test.interface1") interface2 = ExampleComplexInterface("test.interface2") export_path = "/test/path" bus1.export(export_path, interface) bus1.export(export_path, interface2) bus1.export(export_path + "/deeper", interface2) reply_root = await bus2.call( Message( destination=bus1.unique_name, path="/", interface="org.freedesktop.DBus.ObjectManager", member="GetManagedObjects", ) ) reply_level1 = await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface="org.freedesktop.DBus.ObjectManager", member="GetManagedObjects", ) ) reply_level2 = await bus2.call( Message( destination=bus1.unique_name, path=export_path + "/deeper", interface="org.freedesktop.DBus.ObjectManager", member="GetManagedObjects", ) ) assert reply_root.signature == "a{oa{sa{sv}}}", reply_root assert reply_level1.signature == "a{oa{sa{sv}}}", reply_level1 assert reply_level2.signature == "a{oa{sa{sv}}}", reply_level2 assert reply_level2.body == [{}] assert reply_level1.body == [expected_reply] expected_reply.update(reply_ext) assert reply_root.body == [expected_reply] bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_standard_interface_properties(): # standard interfaces have no properties, but should still behave correctly # when you try to call the methods anyway (#49) bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() interface = ExampleInterface("test.interface1") export_path = "/test/path" bus1.export(export_path, interface) for iface in [ "org.freedesktop.DBus.Properties", "org.freedesktop.DBus.Introspectable", "org.freedesktop.DBus.Peer", "org.freedesktop.DBus.ObjectManager", ]: result = await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface="org.freedesktop.DBus.Properties", member="Get", signature="ss", body=[iface, "anything"], ) ) assert result.message_type is MessageType.ERROR assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value result = await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface="org.freedesktop.DBus.Properties", member="Set", signature="ssv", body=[iface, "anything", Variant("s", "new thing")], ) ) assert result.message_type is MessageType.ERROR assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value result = await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface="org.freedesktop.DBus.Properties", member="GetAll", signature="s", body=[iface], ) ) assert result.message_type is MessageType.METHOD_RETURN assert result.body == [{}] bus1.disconnect() bus2.disconnect() dbus-fast-2.44.1/tests/test_address_parser.py000066400000000000000000000047231477355613200212710ustar00rootroot00000000000000import os from unittest.mock import patch import pytest from dbus_fast._private.address import ( get_bus_address, get_session_bus_address, get_system_bus_address, parse_address, ) from dbus_fast.constants import BusType from dbus_fast.errors import InvalidAddressError def test_valid_addresses(): valid_addresses = { "unix:path=/run/user/1000/bus": [("unix", {"path": "/run/user/1000/bus"})], "unix:abstract=/tmp/dbus-ft9sODWpZk,guid=a7b1d5912379c2d471165e9b5cb74a03": [ ( "unix", { "abstract": "/tmp/dbus-ft9sODWpZk", "guid": "a7b1d5912379c2d471165e9b5cb74a03", }, ) ], "unix1:key1=val1;unix2:key2=val2": [ ("unix1", {"key1": "val1"}), ("unix2", {"key2": "val2"}), ], "unix:escaped=hello%20world": [("unix", {"escaped": "hello world"})], "tcp:host=127.0.0.1,port=55556": [ ("tcp", {"host": "127.0.0.1", "port": "55556"}) ], "unix:tmpdir=/tmp,;": [("unix", {"tmpdir": "/tmp"})], } for address, parsed in valid_addresses.items(): assert parse_address(address) == parsed def test_invalid_addresses(): with pytest.raises(InvalidAddressError): assert parse_address("") with pytest.raises(InvalidAddressError): assert parse_address("unix") with pytest.raises(InvalidAddressError): assert parse_address("unix:tmpdir") with pytest.raises(InvalidAddressError): assert parse_address("unix:tmpdir=😁") def test_get_system_bus_address(): with patch.dict(os.environ, DBUS_SYSTEM_BUS_ADDRESS="unix:path=/dog"): assert get_system_bus_address() == "unix:path=/dog" assert get_bus_address(BusType.SYSTEM) == "unix:path=/dog" with patch.dict(os.environ, DBUS_SYSTEM_BUS_ADDRESS=""): assert get_system_bus_address() == "unix:path=/var/run/dbus/system_bus_socket" def test_get_session_bus_address(): with patch.dict(os.environ, DBUS_SESSION_BUS_ADDRESS="unix:path=/dog"): assert get_session_bus_address() == "unix:path=/dog" assert get_bus_address(BusType.SESSION) == "unix:path=/dog" with ( patch.dict(os.environ, DBUS_SESSION_BUS_ADDRESS="", DISPLAY=""), pytest.raises(InvalidAddressError), ): assert get_session_bus_address() def test_invalid_bus_address(): with pytest.raises(Exception): assert get_bus_address(-1) dbus-fast-2.44.1/tests/test_aio_low_level.py000066400000000000000000000121321477355613200211010ustar00rootroot00000000000000import pytest from dbus_fast import Message, MessageFlag, MessageType from dbus_fast.aio import MessageBus @pytest.mark.asyncio async def test_standard_interfaces(): bus = await MessageBus().connect() msg = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="ListNames", serial=bus.next_serial(), ) reply = await bus.call(msg) assert reply.message_type == MessageType.METHOD_RETURN assert reply.reply_serial == msg.serial assert reply.signature == "as" assert bus.unique_name in reply.body[0] msg.interface = "org.freedesktop.DBus.Introspectable" msg.member = "Introspect" msg.serial = bus.next_serial() reply = await bus.call(msg) assert reply.message_type == MessageType.METHOD_RETURN assert reply.reply_serial == msg.serial assert reply.signature == "s" assert type(reply.body[0]) is str msg.member = "MemberDoesNotExist" msg.serial = bus.next_serial() reply = await bus.call(msg) assert reply.message_type == MessageType.ERROR assert reply.reply_serial == msg.serial assert reply.error_name assert reply.signature == "s" assert type(reply.body[0]) is str bus.disconnect() @pytest.mark.asyncio async def test_error_handling(): bus = await MessageBus().connect() msg = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="InvalidMember", serial=bus.next_serial(), ) reply = await bus.call(msg) assert reply.message_type == MessageType.ERROR assert reply.reply_serial == msg.serial assert reply.signature == "s" bus.disconnect() @pytest.mark.asyncio async def test_sending_messages_between_buses(): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() msg = Message( destination=bus1.unique_name, path="/org/test/path", interface="org.test.iface", member="SomeMember", serial=bus2.next_serial(), ) def message_handler(sent): if sent.sender == bus2.unique_name and sent.serial == msg.serial: assert sent.path == msg.path assert sent.serial == msg.serial assert sent.interface == msg.interface assert sent.member == msg.member bus1.send(Message.new_method_return(sent, "s", ["got it"])) bus1.remove_message_handler(message_handler) return True bus1.add_message_handler(message_handler) reply = await bus2.call(msg) assert reply.message_type == MessageType.METHOD_RETURN assert reply.sender == bus1.unique_name assert reply.signature == "s" assert reply.body == ["got it"] assert reply.reply_serial == msg.serial def message_handler_error(sent): if sent.sender == bus2.unique_name and sent.serial == msg.serial: assert sent.path == msg.path assert sent.serial == msg.serial assert sent.interface == msg.interface assert sent.member == msg.member bus1.send(Message.new_error(sent, "org.test.Error", "throwing an error")) bus1.remove_message_handler(message_handler_error) return True bus1.add_message_handler(message_handler_error) msg.serial = bus2.next_serial() reply = await bus2.call(msg) assert reply.message_type == MessageType.ERROR assert reply.sender == bus1.unique_name assert reply.reply_serial == msg.serial assert reply.error_name == "org.test.Error" assert reply.signature == "s" assert reply.body == ["throwing an error"] msg.serial = bus2.next_serial() msg.flags = MessageFlag.NO_REPLY_EXPECTED reply = await bus2.call(msg) assert reply is None bus1.disconnect() bus2.disconnect() @pytest.mark.asyncio async def test_sending_signals_between_buses(event_loop): bus1 = await MessageBus().connect() bus2 = await MessageBus().connect() add_match_msg = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="AddMatch", signature="s", body=[f"sender={bus2.unique_name}"], ) await bus1.call(add_match_msg) async def wait_for_message(): future = event_loop.create_future() def message_handler(signal): if signal.sender == bus2.unique_name: bus1.remove_message_handler(message_handler) future.set_result(signal) bus1.add_message_handler(message_handler) return await future bus2.send( Message.new_signal( "/org/test/path", "org.test.interface", "SomeSignal", "s", ["a signal"] ) ) signal = await wait_for_message() assert signal.message_type == MessageType.SIGNAL assert signal.path == "/org/test/path" assert signal.interface == "org.test.interface" assert signal.member == "SomeSignal" assert signal.signature == "s" assert signal.body == ["a signal"] bus1.disconnect() bus2.disconnect() dbus-fast-2.44.1/tests/test_aio_multi_flags.py000066400000000000000000000011321477355613200214150ustar00rootroot00000000000000import pytest from dbus_fast.aio import MessageBus from dbus_fast.service import ServiceInterface, method @pytest.mark.asyncio async def test_multiple_flags_in_message(): class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) @method() def Echo(self, what: "s") -> "s": return what bus = await MessageBus().connect() interface = ExampleInterface("test.interface") bus.export("/test/path", interface) await bus.request_name("test.name") bus.disconnect() await bus.wait_for_disconnect() dbus-fast-2.44.1/tests/test_auth.py000066400000000000000000000014001477355613200172160ustar00rootroot00000000000000"""This tests setting a hardcoded UID in AuthExternal""" import pytest from dbus_fast.auth import ( UID_NOT_SPECIFIED, AuthAnnonymous, AuthAnonymous, AuthExternal, ) from dbus_fast.errors import AuthError def test_annonymous_backcompat(): auth = AuthAnnonymous() assert isinstance(auth, AuthAnonymous) def test_uid_is_set(): auth = AuthExternal(uid=999) assert auth._authentication_start() == "AUTH EXTERNAL 393939" def test_auth_external_no_uid(): """Test AuthExternal with UID_NOT_SPECIFIED""" auth = AuthExternal(uid=UID_NOT_SPECIFIED) assert auth._authentication_start() == "AUTH EXTERNAL" assert auth._receive_line("DATA") == "DATA" with pytest.raises(AuthError): auth._receive_line("REJECTED") dbus-fast-2.44.1/tests/test_big_message.py000066400000000000000000000041261477355613200205320ustar00rootroot00000000000000import sys import pytest from dbus_fast import Message, MessageType, aio, glib from dbus_fast.service import ServiceInterface, method from tests.util import check_gi_repository, skip_reason_no_gi has_gi = check_gi_repository() class ExampleInterface(ServiceInterface): def __init__(self): super().__init__("example.interface") @method() def echo_bytes(self, what: "ay") -> "ay": return what @pytest.mark.asyncio async def test_aio_big_message(): "this tests that nonblocking reads and writes actually work for aio" bus1 = await aio.MessageBus().connect() bus2 = await aio.MessageBus().connect() interface = ExampleInterface() bus1.export("/test/path", interface) # two megabytes big_body = [bytes(1000000) * 2] result = await bus2.call( Message( destination=bus1.unique_name, path="/test/path", interface=interface.name, member="echo_bytes", signature="ay", body=big_body, ) ) assert result.message_type == MessageType.METHOD_RETURN, result.body[0] assert result.body[0] == big_body[0] bus1.disconnect() bus2.disconnect() @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10,py3.11,py3.12,py3.13", ) def test_glib_big_message(): "this tests that nonblocking reads and writes actually work for glib" bus1 = glib.MessageBus().connect_sync() bus2 = glib.MessageBus().connect_sync() interface = ExampleInterface() bus1.export("/test/path", interface) # two megabytes big_body = [bytes(1000000) * 2] result = bus2.call_sync( Message( destination=bus1.unique_name, path="/test/path", interface=interface.name, member="echo_bytes", signature="ay", body=big_body, ) ) assert result.message_type == MessageType.METHOD_RETURN, result.body[0] assert result.body[0] == big_body[0] bus1.disconnect() bus2.disconnect() dbus-fast-2.44.1/tests/test_constants.py000066400000000000000000000005131477355613200202750ustar00rootroot00000000000000from dbus_fast.constants import MESSAGE_FLAG_MAP, ErrorType, MessageFlag from dbus_fast.errors import DBusError def test_message_flag_map(): assert 0 in MESSAGE_FLAG_MAP assert MessageFlag.NONE in MESSAGE_FLAG_MAP def test_error_type(): err = DBusError(ErrorType.FAILED, "") assert err.type == ErrorType.FAILED dbus-fast-2.44.1/tests/test_disconnect.py000066400000000000000000000041001477355613200204060ustar00rootroot00000000000000import asyncio from unittest.mock import patch import pytest from dbus_fast import Message from dbus_fast.aio import MessageBus @pytest.mark.asyncio async def test_bus_disconnect_before_reply(event_loop): """In this test, the bus disconnects before the reply comes in. Make sure the caller receives a reply with the error instead of hanging.""" bus = MessageBus() assert not bus.connected await bus.connect() assert bus.connected with patch.object(bus._writer, "_write_without_remove_writer"): ping = bus.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="Ping", ) ) event_loop.call_soon(bus.disconnect) with pytest.raises((EOFError, BrokenPipeError)): await ping assert bus._disconnected assert not bus.connected assert (await bus.wait_for_disconnect()) is None # Let the exception propagate to the event loop # so the next test does not fail await asyncio.sleep(0) await asyncio.sleep(0) @pytest.mark.asyncio async def test_unexpected_disconnect(event_loop): bus = MessageBus() class FakeSocket: def send(self, *args, **kwargs): raise OSError assert not bus.connected await bus.connect() assert bus.connected with ( patch.object(bus._writer, "_write_without_remove_writer"), patch.object(bus._writer, "sock", FakeSocket()), ): ping = bus.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="Ping", ) ) with pytest.raises(OSError): await ping assert bus._disconnected assert not bus.connected with pytest.raises(OSError): await bus.wait_for_disconnect() bus.disconnect() with pytest.raises(OSError): await bus.wait_for_disconnect() dbus-fast-2.44.1/tests/test_fd_passing.py000066400000000000000000000256671477355613200204170ustar00rootroot00000000000000"""This tests the ability to send and receive file descriptors in dbus messages""" import os import pytest from dbus_fast import Message, MessageType from dbus_fast.aio import MessageBus from dbus_fast.service import ServiceInterface, dbus_property, method, signal from dbus_fast.signature import SignatureTree, Variant def open_file(): return os.open(os.devnull, os.O_RDONLY) class ExampleInterface(ServiceInterface): def __init__(self, name): super().__init__(name) self.fds = [] @method() def ReturnsFd(self) -> "h": fd = open_file() self.fds.append(fd) return fd @method() def AcceptsFd(self, fd: "h"): assert fd != 0 self.fds.append(fd) def get_last_fd(self): return self.fds[-1] def cleanup(self): for fd in self.fds: os.close(fd) self.fds.clear() @signal() def SignalFd(self) -> "h": fd = open_file() self.fds.append(fd) return fd @dbus_property() def PropFd(self) -> "h": if not self.fds: fd = open_file() self.fds.append(fd) return self.fds[-1] @PropFd.setter def PropFd(self, fd: "h"): assert fd self.fds.append(fd) def assert_fds_equal(fd1, fd2): assert fd1 assert fd2 stat1 = os.fstat(fd1) stat2 = os.fstat(fd2) assert stat1.st_dev == stat2.st_dev assert stat1.st_ino == stat2.st_ino assert stat1.st_rdev == stat2.st_rdev @pytest.mark.asyncio async def test_sending_file_descriptor_low_level(): bus1 = await MessageBus(negotiate_unix_fd=True).connect() bus2 = await MessageBus(negotiate_unix_fd=True).connect() fd_before = open_file() fd_after = None msg = Message( destination=bus1.unique_name, path="/org/test/path", interface="org.test.iface", member="SomeMember", body=[0], signature="h", unix_fds=[fd_before], ) def message_handler(sent): nonlocal fd_after if sent.sender == bus2.unique_name and sent.serial == msg.serial: assert sent.path == msg.path assert sent.serial == msg.serial assert sent.interface == msg.interface assert sent.member == msg.member assert sent.body == [0] assert len(sent.unix_fds) == 1 fd_after = sent.unix_fds[0] bus1.send(Message.new_method_return(sent, "s", ["got it"])) bus1.remove_message_handler(message_handler) return True bus1.add_message_handler(message_handler) reply = await bus2.call(msg) assert reply.body == ["got it"] assert fd_after is not None assert_fds_equal(fd_before, fd_after) for fd in [fd_before, fd_after]: os.close(fd) for bus in [bus1, bus2]: bus.disconnect() @pytest.mark.asyncio async def test_high_level_service_fd_passing(event_loop): bus1 = await MessageBus(negotiate_unix_fd=True).connect() bus2 = await MessageBus(negotiate_unix_fd=True).connect() interface_name = "test.interface" interface = ExampleInterface(interface_name) export_path = "/test/path" async def call(member, signature="", body=[], unix_fds=[], iface=interface.name): return await bus2.call( Message( destination=bus1.unique_name, path=export_path, interface=iface, member=member, signature=signature, body=body, unix_fds=unix_fds, ) ) bus1.export(export_path, interface) # test that an fd can be returned by the service reply = await call("ReturnsFd") assert reply.message_type == MessageType.METHOD_RETURN, reply.body assert reply.signature == "h" assert len(reply.unix_fds) == 1 assert_fds_equal(interface.get_last_fd(), reply.unix_fds[0]) interface.cleanup() os.close(reply.unix_fds[0]) # test that an fd can be sent to the service fd = open_file() reply = await call("AcceptsFd", signature="h", body=[0], unix_fds=[fd]) assert reply.message_type == MessageType.METHOD_RETURN, reply.body assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) # signals fut = event_loop.create_future() def fd_listener(msg): if msg.sender == bus1.unique_name and msg.message_type == MessageType.SIGNAL: fut.set_result(msg) reply = await bus2.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", member="AddMatch", signature="s", body=[f"sender='{bus1.unique_name}'"], ) ) assert reply.message_type == MessageType.METHOD_RETURN bus2.add_message_handler(fd_listener) interface.SignalFd() reply = await fut assert len(reply.unix_fds) == 1 assert reply.body == [0] assert_fds_equal(reply.unix_fds[0], interface.get_last_fd()) interface.cleanup() os.close(reply.unix_fds[0]) # properties reply = await call( "Get", "ss", [interface_name, "PropFd"], iface="org.freedesktop.DBus.Properties" ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body assert reply.body[0].signature == "h" assert reply.body[0].value == 0 assert len(reply.unix_fds) == 1 assert_fds_equal(interface.get_last_fd(), reply.unix_fds[0]) interface.cleanup() os.close(reply.unix_fds[0]) fd = open_file() reply = await call( "Set", "ssv", [interface_name, "PropFd", Variant("h", 0)], iface="org.freedesktop.DBus.Properties", unix_fds=[fd], ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) reply = await call( "GetAll", "s", [interface_name], iface="org.freedesktop.DBus.Properties" ) assert reply.message_type == MessageType.METHOD_RETURN, reply.body assert reply.body[0]["PropFd"].signature == "h" assert reply.body[0]["PropFd"].value == 0 assert len(reply.unix_fds) == 1 assert_fds_equal(interface.get_last_fd(), reply.unix_fds[0]) interface.cleanup() os.close(reply.unix_fds[0]) for bus in [bus1, bus2]: bus.disconnect() @pytest.mark.asyncio async def test_sending_file_descriptor_with_proxy(event_loop): name = "dbus.next.test.service" path = "/test/path" interface_name = "test.interface" bus = await MessageBus(negotiate_unix_fd=True).connect() interface = ExampleInterface(interface_name) bus.export(path, interface) await bus.request_name(name) intr = await bus.introspect(name, path) proxy = bus.get_proxy_object(name, path, intr) proxy_interface = proxy.get_interface(interface_name) # test fds are replaced correctly in all high level interfaces fd = await proxy_interface.call_returns_fd() assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) fd = open_file() await proxy_interface.call_accepts_fd(fd) assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) fd = await proxy_interface.get_prop_fd() assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) fd = open_file() await proxy_interface.set_prop_fd(fd) assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) fut = event_loop.create_future() def on_signal_fd(fd): fut.set_result(fd) proxy_interface.off_signal_fd(on_signal_fd) proxy_interface.on_signal_fd(on_signal_fd) interface.SignalFd() fd = await fut assert_fds_equal(interface.get_last_fd(), fd) interface.cleanup() os.close(fd) bus.disconnect() @pytest.mark.asyncio @pytest.mark.parametrize( "result, out_signature, expected", [ pytest.param(5, "h", ([0], [5]), id='Signature: "h"'), pytest.param([5, "foo"], "hs", ([0, "foo"], [5]), id='Signature: "hs"'), pytest.param([5, 7], "hh", ([0, 1], [5, 7]), id='Signature: "hh"'), pytest.param([5, 7], "ah", ([[0, 1]], [5, 7]), id='Signature: "ah"'), pytest.param([9], "ah", ([[0]], [9]), id='Signature: "ah"'), pytest.param([3], "(h)", ([[0]], [3]), id='Signature: "(h)"'), pytest.param([3, "foo"], "(hs)", ([[0, "foo"]], [3]), id='Signature: "(hs)"'), pytest.param( [[7, "foo"], [8, "bar"]], "a(hs)", ([[[0, "foo"], [1, "bar"]]], [7, 8]), id='Signature: "a(hs)"', ), pytest.param({"foo": 3}, "a{sh}", ([{"foo": 0}], [3]), id='Signature: "a{sh}"'), pytest.param( {"foo": 3, "bar": 6}, "a{sh}", ([{"foo": 0, "bar": 1}], [3, 6]), id='Signature: "a{sh}"', ), pytest.param( {"foo": [3, 8]}, "a{sah}", ([{"foo": [0, 1]}], [3, 8]), id='Signature: "a{sah}"', ), pytest.param( {"foo": Variant("t", 100)}, "a{sv}", ([{"foo": Variant("t", 100)}], []), id='Signature: "a{sv}"', ), pytest.param( ["one", ["two", [Variant("s", "three")]]], "(s(s(v)))", ([["one", ["two", [Variant("s", "three")]]]], []), id='Signature: "(s(s(v)))"', ), pytest.param( Variant("h", 2), "v", ([Variant("h", 0)], [2]), id='Variant with: "h"' ), pytest.param( Variant("(hh)", [2, 8]), "v", ([Variant("(hh)", [0, 1])], [2, 8]), id='Variant with: "(hh)"', ), pytest.param( Variant("ah", [2, 4]), "v", ([Variant("ah", [0, 1])], [2, 4]), id='Variant with: "ah"', ), pytest.param( Variant("(ss)", ["hello", "world"]), "v", ([Variant("(ss)", ["hello", "world"])], []), id='Variant with: "(ss)"', ), pytest.param( Variant("v", Variant("t", 100)), "v", ([Variant("v", Variant("t", 100))], []), id='Variant with: "v"', ), pytest.param( [ Variant("v", Variant("(ss)", ["hello", "world"])), {"foo": Variant("t", 100)}, ["one", ["two", [Variant("s", "three")]]], ], "va{sv}(s(s(v)))", ( [ Variant("v", Variant("(ss)", ["hello", "world"])), {"foo": Variant("t", 100)}, ["one", ["two", [Variant("s", "three")]]], ], [], ), id='Variant with: "va{sv}(s(s(v)))"', ), ], ) async def test_fn_result_to_body(result, out_signature, expected): out_signature_tree = SignatureTree(out_signature) assert ServiceInterface._fn_result_to_body(result, out_signature_tree) == expected dbus-fast-2.44.1/tests/test_glib_low_level.py000066400000000000000000000125361477355613200212560ustar00rootroot00000000000000import sys import pytest from dbus_fast import Message, MessageFlag, MessageType from dbus_fast.glib import MessageBus from tests.util import check_gi_repository, skip_reason_no_gi has_gi = check_gi_repository() if has_gi: from gi.repository import GLib @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10,py3.11,py3.12,py3.13", ) def test_standard_interfaces(): bus = MessageBus().connect_sync() msg = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="ListNames", serial=bus.next_serial(), ) reply = bus.call_sync(msg) assert reply.message_type == MessageType.METHOD_RETURN assert reply.reply_serial == msg.serial assert reply.signature == "as" assert bus.unique_name in reply.body[0] msg.interface = "org.freedesktop.DBus.Introspectable" msg.member = "Introspect" msg.serial = bus.next_serial() reply = bus.call_sync(msg) assert reply.message_type == MessageType.METHOD_RETURN assert reply.reply_serial == msg.serial assert reply.signature == "s" assert type(reply.body[0]) is str msg.member = "MemberDoesNotExist" msg.serial = bus.next_serial() reply = bus.call_sync(msg) assert reply.message_type == MessageType.ERROR assert reply.reply_serial == msg.serial assert reply.error_name assert reply.signature == "s" assert type(reply.body[0]) is str bus.disconnect() @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10,py3.11,py3.12,py3.13", ) def test_sending_messages_between_buses(): bus1 = MessageBus().connect_sync() bus2 = MessageBus().connect_sync() msg = Message( destination=bus1.unique_name, path="/org/test/path", interface="org.test.iface", member="SomeMember", serial=bus2.next_serial(), ) def message_handler(sent): if sent.sender == bus2.unique_name and sent.serial == msg.serial: assert sent.path == msg.path assert sent.serial == msg.serial assert sent.interface == msg.interface assert sent.member == msg.member bus1.send(Message.new_method_return(sent, "s", ["got it"])) bus1.remove_message_handler(message_handler) return True bus1.add_message_handler(message_handler) reply = bus2.call_sync(msg) assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0] assert reply.sender == bus1.unique_name assert reply.signature == "s" assert reply.body == ["got it"] assert reply.reply_serial == msg.serial def message_handler_error(sent): if sent.sender == bus2.unique_name and sent.serial == msg.serial: assert sent.path == msg.path assert sent.serial == msg.serial assert sent.interface == msg.interface assert sent.member == msg.member bus1.send(Message.new_error(sent, "org.test.Error", "throwing an error")) bus1.remove_message_handler(message_handler_error) return True bus1.add_message_handler(message_handler_error) msg.serial = bus2.next_serial() reply = bus2.call_sync(msg) assert reply.message_type == MessageType.ERROR assert reply.sender == bus1.unique_name assert reply.reply_serial == msg.serial assert reply.error_name == "org.test.Error" assert reply.signature == "s" assert reply.body == ["throwing an error"] msg.serial = bus2.next_serial() msg.flags = MessageFlag.NO_REPLY_EXPECTED reply = bus2.call_sync(msg) assert reply is None bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10,py3.11,py3.12,py3.13", ) def test_sending_signals_between_buses(): bus1 = MessageBus().connect_sync() bus2 = MessageBus().connect_sync() add_match_msg = Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="AddMatch", signature="s", body=[f"sender={bus2.unique_name}"], ) bus1.call_sync(add_match_msg) main = GLib.MainLoop() def wait_for_message(): ret = None def message_handler(signal): nonlocal ret if signal.sender == bus2.unique_name: ret = signal bus1.remove_message_handler(message_handler) main.quit() bus1.add_message_handler(message_handler) main.run() return ret bus2.send( Message.new_signal( "/org/test/path", "org.test.interface", "SomeSignal", "s", ["a signal"] ) ) signal = wait_for_message() assert signal.message_type == MessageType.SIGNAL assert signal.path == "/org/test/path" assert signal.interface == "org.test.interface" assert signal.member == "SomeSignal" assert signal.signature == "s" assert signal.body == ["a signal"] bus1.disconnect() bus2.disconnect() bus1._sock.close() bus2._sock.close() dbus-fast-2.44.1/tests/test_introspection.py000066400000000000000000000104421477355613200211630ustar00rootroot00000000000000import os from dbus_fast import ( ArgDirection, InvalidMemberNameError, PropertyAccess, SignatureType, ) from dbus_fast import introspection as intr with open(f"{os.path.dirname(__file__)}/data/strict-introspection.xml") as f: strict_data = f.read() with open(f"{os.path.dirname(__file__)}/data/sloppy-introspection.xml") as f: sloppy_data = f.read() def test_introspection_from_xml_sloppy(): intr.Node.parse(sloppy_data, validate_property_names=False) def test_introspection_from_xml_strict(): try: node = intr.Node.parse(sloppy_data) except InvalidMemberNameError: pass else: assert False, "Expected an AssertionError" node = intr.Node.parse(strict_data) assert len(node.interfaces) == 1 interface = node.interfaces[0] assert len(node.nodes) == 2 assert len(interface.methods) == 3 assert len(interface.signals) == 2 assert len(interface.properties) == 1 assert type(node.nodes[0]) is intr.Node assert node.nodes[0].name == "child_of_sample_object" assert type(node.nodes[1]) is intr.Node assert node.nodes[1].name == "another_child_of_sample_object" assert interface.name == "com.example.SampleInterface0" frobate = interface.methods[0] assert type(frobate) is intr.Method assert frobate.name == "Frobate" assert len(frobate.in_args) == 1 assert len(frobate.out_args) == 2 foo = frobate.in_args[0] assert type(foo) is intr.Arg assert foo.name == "foo" assert foo.direction == ArgDirection.IN assert foo.signature == "i" assert type(foo.type) is SignatureType assert foo.type.token == "i" bar = frobate.out_args[0] assert type(bar) is intr.Arg assert bar.name == "bar" assert bar.direction == ArgDirection.OUT assert bar.signature == "s" assert type(bar.type) is SignatureType assert bar.type.token == "s" prop = interface.properties[0] assert type(prop) is intr.Property assert prop.name == "Bar" assert prop.signature == "y" assert type(prop.type) is SignatureType assert prop.type.token == "y" assert prop.access == PropertyAccess.WRITE changed = interface.signals[0] assert type(changed) is intr.Signal assert changed.name == "Changed" assert len(changed.args) == 1 new_value = changed.args[0] assert type(new_value) is intr.Arg assert new_value.name == "0-new_value" assert new_value.signature == "b" def test_example_introspection_to_xml(): node = intr.Node.parse(strict_data) tree = node.to_xml() assert tree.tag == "node" assert tree.attrib.get("name") == "/com/example/sample_object0" assert len(tree) == 3 interface = tree[0] assert interface.tag == "interface" assert interface.get("name") == "com.example.SampleInterface0" assert len(interface) == 6 method = interface[0] assert method.tag == "method" assert method.get("name") == "Frobate" assert len(method) == 4 arg = method[0] assert arg.tag == "arg" assert arg.attrib.get("name") == "foo" assert arg.attrib.get("type") == "i" assert arg.attrib.get("direction") == "in" annotation = method[3] assert annotation.tag == "annotation" assert annotation.attrib.get("name") == "org.freedesktop.DBus.Deprecated" assert annotation.attrib.get("value") == "true" signal = interface[3] assert signal.tag == "signal" assert signal.attrib.get("name") == "Changed" assert len(signal) == 1 arg = signal[0] assert arg.tag == "arg" assert arg.attrib.get("name") == "0-new_value" assert arg.attrib.get("type") == "b" signal = interface[4] assert signal.tag == "signal" assert signal.attrib.get("name") == "ChangedMulti" assert len(signal) == 2 arg = signal[0] assert arg.tag == "arg" assert arg.attrib.get("name") == "new_value1" assert arg.attrib.get("type") == "b" arg = signal[1] assert arg.tag == "arg" assert arg.attrib.get("name") == "0-new_value2" assert arg.attrib.get("type") == "y" prop = interface[5] assert prop.attrib.get("name") == "Bar" assert prop.attrib.get("type") == "y" assert prop.attrib.get("access") == "write" def test_default_interfaces(): # just make sure it doesn't throw default = intr.Node.default() assert type(default) is intr.Node dbus-fast-2.44.1/tests/test_marshaller.py000066400000000000000000000747331477355613200204320ustar00rootroot00000000000000import io import json import os from enum import Enum from typing import Any import pytest from dbus_fast import Message, MessageFlag, MessageType, SignatureTree, Variant from dbus_fast._private._cython_compat import FakeCython from dbus_fast._private.constants import BIG_ENDIAN, LITTLE_ENDIAN from dbus_fast._private.unmarshaller import ( Unmarshaller, buffer_to_int16, buffer_to_uint16, buffer_to_uint32, is_compiled, ) from dbus_fast.unpack import unpack_variants def test_bytearray_to_uint32_big_end(): assert buffer_to_uint32(bytearray(b"\x01\x02\x03\x04"), 0, BIG_ENDIAN) == 16909060 assert ( buffer_to_uint32( bytearray((0xFFFFFFFF).to_bytes(4, byteorder="big", signed=False)), 0, BIG_ENDIAN, ) == 0xFFFFFFFF ) def test_bytearray_to_uint16_big_end(): assert buffer_to_uint16(bytearray(b"\x01\x02"), 0, BIG_ENDIAN) == 258 assert ( buffer_to_uint16( bytearray((0xFFFF).to_bytes(2, byteorder="big", signed=False)), 0, BIG_ENDIAN, ) == 0xFFFF ) def test_bytearray_to_int16_big_end(): assert buffer_to_int16(bytearray(b"\x01\x02"), 0, BIG_ENDIAN) == 258 assert ( buffer_to_int16( bytearray((32767).to_bytes(2, byteorder="big", signed=True)), 0, BIG_ENDIAN ) == 32767 ) @pytest.mark.skipif(not is_compiled(), reason="requires cython") def test_bytearray_to_int16_big_end_signed(): assert buffer_to_int16(bytearray(b"\xff\xff"), 0, BIG_ENDIAN) == -1 assert ( buffer_to_int16( bytearray((-32768).to_bytes(2, byteorder="big", signed=True)), 0, BIG_ENDIAN, ) == -32768 ) def test_bytearray_to_uint32_little_end(): assert ( buffer_to_uint32(bytearray(b"\x01\x02\x03\x04"), 0, LITTLE_ENDIAN) == 67305985 ) assert ( buffer_to_uint32( bytearray((0xFFFFFFFF).to_bytes(4, byteorder="little", signed=False)), 0, LITTLE_ENDIAN, ) == 0xFFFFFFFF ) def test_bytearray_to_uint16_little_end(): assert buffer_to_uint16(bytearray(b"\x01\x02"), 0, LITTLE_ENDIAN) == 513 assert ( buffer_to_uint16( bytearray((0xFFFF).to_bytes(2, byteorder="little", signed=False)), 0, LITTLE_ENDIAN, ) == 0xFFFF ) def test_bytearray_to_int16_little_end(): assert buffer_to_int16(bytearray(b"\x01\x02"), 0, LITTLE_ENDIAN) == 513 assert ( buffer_to_int16( bytearray((32767).to_bytes(2, byteorder="little", signed=True)), 0, LITTLE_ENDIAN, ) == 32767 ) @pytest.mark.skipif(not is_compiled(), reason="requires cython") def test_bytearray_to_int16_little_end_signed(): assert buffer_to_int16(bytearray(b"\xff\xff"), 0, LITTLE_ENDIAN) == -1 assert ( buffer_to_int16( bytearray((-32768).to_bytes(2, byteorder="little", signed=True)), 0, LITTLE_ENDIAN, ) == -32768 ) def print_buf(buf): i = 0 while True: p = buf[i : i + 8] if not p: break print(p) i += 8 # these messages have been verified with another library with open(os.path.dirname(__file__) + "/data/messages.json") as f: table = json.load(f) with open(os.path.dirname(__file__) + "/data/get_managed_objects.hex") as fp: get_managed_objects_msg = fp.read() def json_to_message(message: dict[str, Any]) -> Message: copy = dict(message) if "message_type" in copy: copy["message_type"] = MessageType(copy["message_type"]) if "flags" in copy: copy["flags"] = MessageFlag(copy["flags"]) return Message(**copy) # variants are an object in the json def replace_variants(type_, item): if type_.token == "v" and type(item) is not Variant: item = Variant( item["signature"], replace_variants(SignatureTree(item["signature"]).types[0], item["value"]), ) elif type_.token == "a": for i, item_child in enumerate(item): if type_.children[0].token == "{": for k, v in item.items(): item[k] = replace_variants(type_.children[0].children[1], v) else: item[i] = replace_variants(type_.children[0], item_child) elif type_.token == "(": for i, item_child in enumerate(item): if type_.children[0].token == "{": assert False else: item[i] = replace_variants(type_.children[i], item_child) return item def json_dump(what): def dumper(obj): try: return obj.toJSON() except Exception: return obj.__dict__ return json.dumps(what, default=dumper, indent=2) def test_marshalling_with_table(): for item in table: message = json_to_message(item["message"]) body = [] for i, type_ in enumerate(message.signature_tree.types): body.append(replace_variants(type_, message.body[i])) message.body = body buf = message._marshall(False) data = bytes.fromhex(item["data"]) if buf != data: print("message:") print(json_dump(item["message"])) print() print("mine:") print_buf(bytes(buf)) print() print("theirs:") print_buf(data) assert buf == data @pytest.mark.parametrize("unmarshall_table", (table,)) def test_unmarshalling_with_table(unmarshall_table): for item in unmarshall_table: stream = io.BytesIO(bytes.fromhex(item["data"])) unmarshaller = Unmarshaller(stream) try: unmarshaller.unmarshall() except Exception as e: print("message failed to unmarshall:") print(json_dump(item["message"])) raise e message = json_to_message(item["message"]) body = [] for i, type_ in enumerate(message.signature_tree.types): body.append(replace_variants(type_, message.body[i])) message.body = body for attr in [ "body", "signature", "message_type", "destination", "path", "interface", "member", "flags", "serial", ]: assert getattr(unmarshaller.message, attr) == getattr(message, attr), ( f"attr doesnt match: {attr}" ) def test_unmarshall_can_resume(): """Verify resume works.""" bluez_rssi_message = ( "6c04010134000000e25389019500000001016f00250000002f6f72672f626c75657a2f686369302f6465" "765f30385f33415f46325f31455f32425f3631000000020173001f0000006f72672e667265656465736b" "746f702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e" "67656400000000000000080167000873617b73767d617300000007017300040000003a312e3400000000" "110000006f72672e626c75657a2e446576696365310000000e0000000000000004000000525353490001" "6e00a7ff000000000000" ) message_bytes = bytes.fromhex(bluez_rssi_message) class SlowStream(io.IOBase): """A fake stream that will only give us one byte at a time.""" def __init__(self): self.data = message_bytes self.pos = 0 def read(self, n) -> bytes: data = self.data[self.pos : self.pos + 1] self.pos += 1 return data stream = SlowStream() unmarshaller = Unmarshaller(stream) for _ in range(len(bluez_rssi_message)): if unmarshaller.unmarshall(): break assert unmarshaller.message is not None def test_unmarshall_bluez_message(): bluez_mfr_message = ( "6c040101780000009aca0a009500000001016f00250000002f6f72672f626c75657a2f686369302f646576" "5f44305f43325f34455f30385f41425f3537000000020173001f0000006f72672e667265656465736b746f" "702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e676564" "00000000000000080167000873617b73767d617300000007017300040000003a312e340000000011000000" "6f72672e626c75657a2e446576696365310000005400000000000000040000005253534900016e00aaff00" "00100000004d616e756661637475726572446174610005617b71767d002400000075000261790000001800" "00004204010170d0c24e08ab57d2c24e08ab5601000000000000000000006c040101340000009bca0a0095" "00000001016f002500" ) message_bytes = bytes.fromhex(bluez_mfr_message) stream = io.BytesIO(message_bytes) unmarshaller = Unmarshaller(stream) assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None assert message.body == [ "org.bluez.Device1", { "ManufacturerData": Variant( "a{qv}", { 117: Variant( "ay", bytearray( b"B\x04\x01\x01p\xd0\xc2N\x08\xabW\xd2\xc2N\x08\xabV\x01\x00\x00\x00\x00\x00\x00" ), ) }, ), "RSSI": Variant("n", -86), }, [], ] assert message.sender == ":1.4" assert message.path == "/org/bluez/hci0/dev_D0_C2_4E_08_AB_57" assert message.interface == "org.freedesktop.DBus.Properties" assert message.member == "PropertiesChanged" assert message.signature == "sa{sv}as" assert message.message_type == MessageType.SIGNAL assert message.flags == MessageFlag.NO_REPLY_EXPECTED assert message.serial == 707226 assert message.destination is None unpacked = unpack_variants(message.body) assert unpacked == [ "org.bluez.Device1", { "ManufacturerData": { 117: bytearray( b"B\x04\x01\x01p\xd0\xc2N\x08\xabW\xd2" b"\xc2N\x08\xabV\x01\x00\x00" b"\x00\x00\x00\x00" ) }, "RSSI": -86, }, [], ] def test_unmarshall_bluez_interfaces_added_message(): bluez_interfaces_added_message = ( b'l\4\1\1\240\2\0\0\227\272\23\0u\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0' b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\17\0\0\0InterfacesAdded\0\10" b"\1g\0\noa{sa{sv}}\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_2D_34" b"_60_26_36\0\0\0p\2\0\0#\0\0\0org.freedesktop.DBus.Introspectable\0\0\0\0\0\0\0\0\0" b"\21\0\0\0org.bluez.Device1\0\0\0\364\1\0\0\0\0\0\0\7\0\0\0Address\0\1s\0\0\21\0\0" b"\00058:2D:34:60:26:36\0\0\0\v\0\0\0AddressType\0\1s\0\0\6\0\0\0public\0\0\4\0\0\0" b"Name\0\1s\0\33\0\0\0Qingping Door/Window Sensor\0\0\0\0\0\5\0\0\0Alias\0\1s\0\0\0" b"\0\33\0\0\0Qingping Door/Window Sensor\0\6\0\0\0Paired\0\1b\0\0\0\0\0\0\0\0\0\0\0" b"\7\0\0\0Trusted\0\1b\0\0\0\0\0\0\0\0\0\0\7\0\0\0Blocked\0\1b\0\0\0\0\0\0\0\0\0\0\r" b"\0\0\0LegacyPairing\0\1b\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\316\377\0\0\t" b"\0\0\0Connected\0\1b\0\0\0\0\0\0\0\0\5\0\0\0UUIDs\0\2as\0\0\0\0\0\0\0\0\0\0\0\7\0" b"\0\0Adapter\0\1o\0\0\17\0\0\0/org/bluez/hci1\0\0\0\0\0\v\0\0\0ServiceData\0\5a{sv}" b"\0\0@\0\0\0\0\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\f\0" b"\0\0000X\326\3\0026&`4-X\10\20\0\0\0ServicesResolved\0\1b\0\0\0\0\0\0\0\0\0\37\0\0" b"\0org.freedesktop.DBus.Properties\0\0\0\0\0" ) stream = io.BytesIO(bluez_interfaces_added_message) unmarshaller = Unmarshaller(stream) assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None assert message.body == [ "/org/bluez/hci1/dev_58_2D_34_60_26_36", { "org.bluez.Device1": { "Adapter": Variant("o", "/org/bluez/hci1"), "Address": Variant("s", "58:2D:34:60:26:36"), "AddressType": Variant("s", "public"), "Alias": Variant("s", "Qingping Door/Window Sensor"), "Blocked": Variant("b", False), "Connected": Variant("b", False), "LegacyPairing": Variant("b", False), "Name": Variant("s", "Qingping Door/Window Sensor"), "Paired": Variant("b", False), "RSSI": Variant("n", -50), "ServiceData": Variant( "a{sv}", { "0000fe95-0000-1000-8000-00805f9b34fb": Variant( "ay", bytearray(b"0X\xd6\x03\x026&`4-X\x08") ) }, ), "ServicesResolved": Variant("b", False), "Trusted": Variant("b", False), "UUIDs": Variant("as", []), }, "org.freedesktop.DBus.Introspectable": {}, "org.freedesktop.DBus.Properties": {}, }, ] assert message.sender == ":1.4" assert message.path == "/" assert message.interface == "org.freedesktop.DBus.ObjectManager" assert message.member == "InterfacesAdded" assert message.signature == "oa{sa{sv}}" assert message.message_type == MessageType.SIGNAL assert message.flags == MessageFlag.NO_REPLY_EXPECTED assert message.serial == 1292951 assert message.destination is None unpacked = unpack_variants(message.body) assert unpacked == [ "/org/bluez/hci1/dev_58_2D_34_60_26_36", { "org.bluez.Device1": { "Adapter": "/org/bluez/hci1", "Address": "58:2D:34:60:26:36", "AddressType": "public", "Alias": "Qingping Door/Window Sensor", "Blocked": False, "Connected": False, "LegacyPairing": False, "Name": "Qingping Door/Window Sensor", "Paired": False, "RSSI": -50, "ServiceData": { "0000fe95-0000-1000-8000-00805f9b34fb": bytearray( b"0X\xd6\x03\x026&`4-X\x08" ) }, "ServicesResolved": False, "Trusted": False, "UUIDs": [], }, "org.freedesktop.DBus.Introspectable": {}, "org.freedesktop.DBus.Properties": {}, }, ] def test_unmarshall_bluez_interfaces_removed_message(): bluez_interfaces_removed_message = ( b'l\4\1\1\222\0\0\0\377@-\0~\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0' b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\21\0\0\0InterfacesRemoved" b"\0\0\0\0\0\0\0\10\1g\0\3oas\0\0\0\0\0\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0%\0\0\0" b"/org/bluez/hci0/dev_5F_13_47_38_26_55\0\0\0b\0\0\0\37\0\0\0org.freedesktop.DBus" b".Properties\0#\0\0\0org.freedesktop.DBus.Introspectable\0\21\0\0\0org.bluez.Dev" b"ice1\0" ) stream = io.BytesIO(bluez_interfaces_removed_message) unmarshaller = Unmarshaller(stream) assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None assert message.body == [ "/org/bluez/hci0/dev_5F_13_47_38_26_55", [ "org.freedesktop.DBus.Properties", "org.freedesktop.DBus.Introspectable", "org.bluez.Device1", ], ] assert message.sender == ":1.12" assert message.path == "/" assert message.interface == "org.freedesktop.DBus.ObjectManager" assert message.member == "InterfacesRemoved" assert message.signature == "oas" assert message.message_type == MessageType.SIGNAL assert message.flags == MessageFlag.NO_REPLY_EXPECTED assert message.serial == 2965759 assert message.destination is None unpacked = unpack_variants(message.body) assert unpacked == [ "/org/bluez/hci0/dev_5F_13_47_38_26_55", [ "org.freedesktop.DBus.Properties", "org.freedesktop.DBus.Introspectable", "org.bluez.Device1", ], ] def test_unmarshall_bluez_properties_changed_with_service_data(): bluez_properties_changed_message = ( b"l\4\1\1\334\0\0\0@\236.\0\226\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_58_2D_34_60_DA_1F" b"\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged" b"\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0\21\0\0\0org.bluez.Devi" b"ce1\0\0\0\270\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\301\377\0\0\v\0\0\0ServiceData\0\5a{sv}" b"\0\0\210\0\0\0\0\0\0\0$\0\0\0000000fdcd-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\24\0" b"\0\0\10\22\37\332`4-X\2\1U\17\1\315\t\4\5\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f" b"9b34fb\0\2ay\0\0\0\0\f\0\0\0000X\203\n\2\37\332`4-X\10\0\0\0\0" ) stream = io.BytesIO(bluez_properties_changed_message) unmarshaller = Unmarshaller(stream) assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None assert message.body == [ "org.bluez.Device1", { "RSSI": Variant("n", -63), "ServiceData": Variant( "a{sv}", { "0000fdcd-0000-1000-8000-00805f9b34fb": Variant( "ay", bytearray( b"\x08\x12\x1f\xda`4-X\x02\x01U\x0f\x01\xcd\t\x04\x05\x00\x00\x00" ), ), "0000fe95-0000-1000-8000-00805f9b34fb": Variant( "ay", bytearray(b"0X\x83\n\x02\x1f\xda`4-X\x08") ), }, ), }, [], ] assert message.sender == ":1.12" assert message.path == "/org/bluez/hci0/dev_58_2D_34_60_DA_1F" assert message.interface == "org.freedesktop.DBus.Properties" assert message.member == "PropertiesChanged" assert message.signature == "sa{sv}as" assert message.message_type == MessageType.SIGNAL assert message.flags == MessageFlag.NO_REPLY_EXPECTED assert message.serial == 3055168 assert message.destination is None unpacked = unpack_variants(message.body) assert unpacked == [ "org.bluez.Device1", { "RSSI": -63, "ServiceData": { "0000fdcd-0000-1000-8000-00805f9b34fb": bytearray( b"\x08\x12\x1f\xda`4-X\x02\x01U\x0f\x01\xcd\t\x04\x05\x00\x00\x00" ), "0000fe95-0000-1000-8000-00805f9b34fb": bytearray( b"0X\x83\n\x02\x1f\xda`4-X\x08" ), }, }, [], ] def test_unmarshall_multiple_messages(): """Test we can unmarshall multiple messages in a single packet.""" multiple_message_packet = ( b"l\4\1\0014\0\0\0J\27\230\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_F0_B3_EC_15_7F_8E\0\0\0\2\1s\0\37\0\0\0" b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1" b"s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\264\377\0\0\0\0\0" b"\0l\4\1\0014\0\0\0K\27\230\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_3F_70_98_0F_08_CB\0\0\0\2\1s\0\37\0\0" b"\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7" b"\1s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\260\377\0\0\0\0" b"\0\0l\4\1\0014\0\0\0L\27\230\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_D8_35_67_A4_F5_A5\0\0\0\2\1s\0\37\0" b"\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0" b"\7\1s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\242\377\0\0\0" b"\0\0\0" ) stream = io.BytesIO(multiple_message_packet) unmarshaller = Unmarshaller(stream) assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None unpacked = unpack_variants(message.body) assert unpacked == ["org.bluez.Device1", {"RSSI": -76}, []] assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None unpacked = unpack_variants(message.body) assert unpacked == ["org.bluez.Device1", {"RSSI": -80}, []] assert unmarshaller.unmarshall() message = unmarshaller.message assert message is not None unpacked = unpack_variants(message.body) assert unpacked == ["org.bluez.Device1", {"RSSI": -94}, []] with pytest.raises(EOFError): unmarshaller.unmarshall() def test_ay_buffer(): body = [bytes(10000)] msg = Message(path="/test", member="test", signature="ay", body=body) marshalled = msg._marshall(False) unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall() assert unmarshalled_msg.body[0] == body[0] def tests_fallback_no_cython(): assert FakeCython().compiled is False def test_unmarshall_large_message(): stream = io.BytesIO(bytes.fromhex(get_managed_objects_msg)) unmarshaller = Unmarshaller(stream) unmarshaller.unmarshall() message = unmarshaller.message unpacked = unpack_variants(message.body) objects = unpacked[0] assert objects["/org/bluez/hci0"] == { "org.bluez.Adapter1": { "Address": "00:1A:7D:DA:71:04", "AddressType": "public", "Alias": "homeassistant", "Class": 2883584, "Discoverable": False, "DiscoverableTimeout": 180, "Discovering": True, "Modalias": "usb:v1D6Bp0246d053F", "Name": "homeassistant", "Pairable": False, "PairableTimeout": 0, "Powered": True, "Roles": ["central", "peripheral"], "UUIDs": [ "0000110e-0000-1000-8000-00805f9b34fb", "0000110a-0000-1000-8000-00805f9b34fb", "00001200-0000-1000-8000-00805f9b34fb", "0000110b-0000-1000-8000-00805f9b34fb", "00001108-0000-1000-8000-00805f9b34fb", "0000110c-0000-1000-8000-00805f9b34fb", "00001800-0000-1000-8000-00805f9b34fb", "00001801-0000-1000-8000-00805f9b34fb", "0000180a-0000-1000-8000-00805f9b34fb", "00001112-0000-1000-8000-00805f9b34fb", ], }, "org.bluez.GattManager1": {}, "org.bluez.LEAdvertisingManager1": { "ActiveInstances": 0, "SupportedIncludes": ["tx-power", "appearance", "local-name"], "SupportedInstances": 5, }, "org.bluez.Media1": {}, "org.bluez.NetworkServer1": {}, "org.freedesktop.DBus.Introspectable": {}, "org.freedesktop.DBus.Properties": {}, } assert objects["/org/bluez/hci0/dev_CD_A3_FA_D1_50_56/service000b/char000c"] == { "org.bluez.GattCharacteristic1": { "Flags": ["read"], "Service": "/org/bluez/hci0/dev_CD_A3_FA_D1_50_56/service000b", "UUID": "e604e95d-a759-4817-87d3-aa005083a0d1", "Value": bytearray(b""), }, "org.freedesktop.DBus.Introspectable": {}, "org.freedesktop.DBus.Properties": {}, } def test_unmarshall_big_end_message(): """Test we can unmarshall a big endian message.""" msg = ( b"B\x01\x00\x01\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x82" b"\x01\x01o\x00\x00\x00\x00\x01/\x00\x00\x00\x00\x00\x00\x00" b'\x02\x01s\x00\x00\x00\x00"org.freedesktop.DBus.ObjectManag' b"er\x00\x00\x00\x00\x00\x00\x03\x01s\x00\x00\x00\x00\x11GetManagedOb" b"jects\x00\x00\x00\x00\x00\x00\x00\x06\x01s\x00\x00\x00\x00\torg." b"bluez\x00\x00\x00\x00\x00\x00\x00\x08\x01g\x00\x04ussv\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x03zip\x00" b"\x00\x00\x00\x07Trusted\x00\x01b\x00\x00\x00\x00\x00\x01" ) stream = io.BytesIO(msg) unmarshaller = Unmarshaller(stream) unmarshaller.unmarshall() message = unmarshaller.message unpacked = unpack_variants(message.body) assert unpacked == [42, "zip", "Trusted", True] class RaucState(str, Enum): """Rauc slot states.""" GOOD = "good" BAD = "bad" ACTIVE = "active" def test_marshalling_enum(): """Test marshalling an enum.""" msg = Message( path="/test", member="test", signature="s", body=[RaucState.GOOD], ) marshalled = msg._marshall(False) unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall() assert unpack_variants(unmarshalled_msg.body)[0] == RaucState.GOOD.value def test_unmarshall_bluez_passive_message(): """Test we can unmarshall a bluez passive message.""" bluez_passive_message = ( b"l\1\1\1*\0\0\0\205D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472597302272\0\0\0\6\1s\0\7\0\0" b"\0:1.1450\0\2\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10" b"\1g\0\1o\0\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci0/dev_58_D3_49_E6_02_6E\0l\1\1\1*\0\0\0" b"\206D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472593362560\0\0\0\6\1s\0\7\0\0\0:1.1450\0\2" b"\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10\1g\0\1o\0\0" b"\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_D3_49_E6_02_6E\0" ) stream = io.BytesIO(bluez_passive_message) unmarshaller = Unmarshaller(stream) unmarshaller.unmarshall() message = unmarshaller.message assert "/org/bluez/hci0/dev_58_D3_49_E6_02_6E" in str(message) unpacked = unpack_variants(message.body) assert unpacked == ["/org/bluez/hci0/dev_58_D3_49_E6_02_6E"] def test_unmarshall_mount_message(): """Test we mount message unmarshall.""" mount_message = ( b"l\1\0\1\30\1\0\0\213\1\0\0\266\0\0\0\1\1o\0\31\0\0\0/org/freedesktop/systemd1" b"\0\0\0\0\0\0\0\2\1s\0 \0\0\0org.freedesktop.systemd1.Manager\0\0\0\0\0\0\0\0" b"\3\1s\0\22\0\0\0StartTransientUnit\0\0\0\0\0\0\6\1s\0\30\0\0\0org.freedesktop" b".systemd1\0\0\0\0\0\0\0\0\10\1g\0\20ssa(sv)a(sa(sv))\0\0\0)\0\0\0mnt-data-sup" b"ervisor-mounts-test1234.mount\0\0\0\4\0\0\0fail\0\0\0\0\314\0\0\0\7\0\0\0Opti" b"ons\0\1s\0\0I\0\0\0noserverino,credentials=/mnt/data/supervisor/.mounts_crede" b"ntials/test1234\0\0\0\4\0\0\0Type\0\1s\0\4\0\0\0cifs\0\0\0\0\v\0\0\0Descripti" b"on\0\1s\0\0\37\0\0\0Supervisor cifs mount: test1234\0\4\0\0\0What\0\1s\0\v\0\0" b"\0//\303\274ber/test\0\0\0\0\0\0\0\0\0\0\0\0" ) stream = io.BytesIO(mount_message) unmarshaller = Unmarshaller(stream) unmarshaller.unmarshall() message = unmarshaller.message assert unmarshaller.message.signature == "ssa(sv)a(sa(sv))" unpacked = unpack_variants(message.body) assert unpacked == [ "mnt-data-supervisor-mounts-test1234.mount", "fail", [ [ "Options", "noserverino,credentials=/mnt/data/supervisor/.mounts_credentials/test1234", ], ["Type", "cifs"], ["Description", "Supervisor cifs mount: test1234"], ["What", "//über/tes"], ], [], ] def test_unmarshall_mount_message_2(): """Test we mount message unmarshall version 2.""" mount_message = ( b"l\1\0\1 \1\0\0+\6\0\0\266\0\0\0\1\1o\0\31\0\0\0/org/freedesktop/systemd1" b"\0\0\0\0\0\0\0\2\1s\0 \0\0\0org.freedesktop.systemd1.Manager\0\0\0\0\0\0" b"\0\0\3\1s\0\22\0\0\0StartTransientUnit\0\0\0\0\0\0\6\1s\0\30\0\0\0org.fr" b"eedesktop.systemd1\0\0\0\0\0\0\0\0\10\1g\0\20ssa(sv)a(sa(sv))\0\0\0(\0\0" b"\0mnt-data-supervisor-mounts-BadTest.mount\0\0\0\0\4\0\0\0fail\0\0\0\0\324" b"\0\0\0\7\0\0\0Options\0\1s\0\0H\0\0\0noserverino,credentials=/mnt/data/su" b"pervisor/.mounts_credentials/BadTest\0\0\0\0\4\0\0\0Type\0\1s\0\4\0\0\0cifs" b"\0\0\0\0\v\0\0\0Description\0\1s\0\0\36\0\0\0Supervisor cifs mount: BadTest" b"\0\0\4\0\0\0What\0\1s\0\23\0\0\0//doesntmatter/\303\274ber\0\0\0\0\0\0\0\0\0" b"\0\0\0" ) stream = io.BytesIO(mount_message) unmarshaller = Unmarshaller(stream) unmarshaller.unmarshall() message = unmarshaller.message assert unmarshaller.message.signature == "ssa(sv)a(sa(sv))" unpacked = unpack_variants(message.body) assert unpacked == [ "mnt-data-supervisor-mounts-BadTest.mount", "fail", [ [ "Options", "noserverino,credentials=/mnt/data/supervisor/.mounts_credentials/BadTest", ], ["Type", "cifs"], ["Description", "Supervisor cifs mount: BadTest"], ["What", "//doesntmatter/übe"], ], [], ] def test_unmarshall_multi_byte_string(): """Test unmarshall a multi-byte string.""" mount_message = ( b"l\x01\x00\x01\x1d\x00\x00\x00" b"\x01\x00\x00\x00x\x00\x00\x00" b"\x01\x01o\x00\x15\x00\x00\x00" b"/org/fre" b"edesktop" b"/DBus\x00\x00\x00" b"\x02\x01s\x00\x14\x00\x00\x00" b"org.free" b"desktop." b"DBus\x00\x00\x00\x00" b"\x03\x01s\x00\x05\x00\x00\x00" b"Hello\x00\x00\x00" b"\x06\x01s\x00\x14\x00\x00\x00" b"org.free" b"desktop." b"DBus\x00\x00\x00\x00" b"\x08\x01g\x00\x02as\x00" b"\x19\x00\x00\x00\x14\x00\x00\x00" b"//doesnt" b"matter/\xc3" b"\xbcber\x00" ) stream = io.BytesIO(mount_message) unmarshaller = Unmarshaller(stream) unmarshaller.unmarshall() message = unmarshaller.message assert unmarshaller.message.signature == "as" unpacked = unpack_variants(message.body) assert unpacked == [["//doesntmatter/über"]] def test_marshalling_struct_accepts_tuples(): """Test marshalling a struct accepts tuples.""" msg = Message( path="/test", member="test", signature="(s)", body=[(RaucState.GOOD,)], ) marshalled = msg._marshall(False) unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall() assert unpack_variants(unmarshalled_msg.body)[0] == [RaucState.GOOD.value] def test_marshalling_struct_accepts_lists(): """Test marshalling a struct accepts lists.""" msg = Message( path="/test", member="test", signature="(s)", body=[[RaucState.GOOD]], ) marshalled = msg._marshall(False) unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall() assert unpack_variants(unmarshalled_msg.body)[0] == [RaucState.GOOD.value] dbus-fast-2.44.1/tests/test_request_name.py000066400000000000000000000046031477355613200207550ustar00rootroot00000000000000import sys import pytest from dbus_fast import ( Message, MessageType, NameFlag, ReleaseNameReply, RequestNameReply, aio, glib, ) from tests.util import check_gi_repository, skip_reason_no_gi has_gi = check_gi_repository() @pytest.mark.asyncio async def test_name_requests(): test_name = "aio.test.request.name" bus1 = await aio.MessageBus().connect() bus2 = await aio.MessageBus().connect() async def get_name_owner(name): reply = await bus1.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus", member="GetNameOwner", signature="s", body=[name], ) ) assert reply.message_type == MessageType.METHOD_RETURN return reply.body[0] reply = await bus1.request_name(test_name) assert reply == RequestNameReply.PRIMARY_OWNER reply = await bus1.request_name(test_name) assert reply == RequestNameReply.ALREADY_OWNER reply = await bus2.request_name(test_name, NameFlag.ALLOW_REPLACEMENT) assert reply == RequestNameReply.IN_QUEUE reply = await bus1.release_name(test_name) assert reply == ReleaseNameReply.RELEASED reply = await bus1.release_name("name.doesnt.exist") assert reply == ReleaseNameReply.NON_EXISTENT reply = await bus1.release_name(test_name) assert reply == ReleaseNameReply.NOT_OWNER new_owner = await get_name_owner(test_name) assert new_owner == bus2.unique_name reply = await bus1.request_name(test_name, NameFlag.DO_NOT_QUEUE) assert reply == RequestNameReply.EXISTS reply = await bus1.request_name( test_name, NameFlag.DO_NOT_QUEUE | NameFlag.REPLACE_EXISTING ) assert reply == RequestNameReply.PRIMARY_OWNER bus1.disconnect() bus2.disconnect() @pytest.mark.skipif( sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10,py3.11,py3.12,py3.13", ) @pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi) def test_request_name_glib(): test_name = "glib.test.request.name" bus = glib.MessageBus().connect_sync() reply = bus.request_name_sync(test_name) assert reply == RequestNameReply.PRIMARY_OWNER reply = bus.release_name_sync(test_name) assert reply == ReleaseNameReply.RELEASED bus.disconnect() dbus-fast-2.44.1/tests/test_send_reply.py000066400000000000000000000045771477355613200204430ustar00rootroot00000000000000import os from unittest.mock import patch import pytest from dbus_fast.constants import ErrorType, MessageType from dbus_fast.errors import DBusError from dbus_fast.message import Message from dbus_fast.message_bus import BaseMessageBus from dbus_fast.send_reply import SendReply @pytest.fixture(autouse=True) def mock_address() -> None: original_address = os.environ.get("DBUS_SESSION_BUS_ADDRESS") os.environ["DBUS_SESSION_BUS_ADDRESS"] = "unix:path=/dev/null" yield if original_address is None: del os.environ["DBUS_SESSION_BUS_ADDRESS"] else: os.environ["DBUS_SESSION_BUS_ADDRESS"] = original_address def test_send_reply_exception() -> None: """Test that SendReply sends an error message when DBusError is raised.""" messages = [] class MockBus(BaseMessageBus): def send(self, msg: Message) -> None: messages.append(msg) def send_message(self, msg: Message) -> None: messages.append(msg) def _setup_socket(self) -> None: pass with patch("socket.socket.connect"): mock_message_bus = MockBus() mock_message = Message( path="/test/path", interface="test.interface", member="test_member", serial=1 ) send_reply = SendReply(mock_message_bus, mock_message) with send_reply: raise DBusError(ErrorType.DISCONNECTED, "Disconnected", None) assert len(messages) == 1 assert messages[0].message_type == MessageType.ERROR assert messages[0].error_name == "org.freedesktop.DBus.Error.Disconnected" assert messages[0].reply_serial == 1 def test_send_reply_happy_path() -> None: """Test that SendReply sends a message.""" messages = [] class MockBus(BaseMessageBus): def send(self, msg: Message) -> None: messages.append(msg) def send_message(self, msg: Message) -> None: messages.append(msg) def _setup_socket(self) -> None: pass with patch("socket.socket.connect"): mock_message_bus = MockBus() mock_message = Message( path="/test/path", interface="test.interface", member="test_member", serial=1 ) send_reply = SendReply(mock_message_bus, mock_message) with send_reply as reply: reply(mock_message) assert len(messages) == 1 assert messages[0].message_type == MessageType.METHOD_CALL assert messages[0].error_name is None dbus-fast-2.44.1/tests/test_signature.py000066400000000000000000000164141477355613200202710ustar00rootroot00000000000000import pytest from dbus_fast import SignatureBodyMismatchError, SignatureTree, Variant from dbus_fast._private.util import signature_contains_type def assert_simple_type(signature, type_): assert type_.token == signature assert type_.signature == signature assert len(type_.children) == 0 def test_simple(): tree = SignatureTree("s") assert len(tree.types) == 1 assert_simple_type("s", tree.types[0]) def test_multiple_simple(): tree = SignatureTree("sss") assert len(tree.types) == 3 for i in range(3): assert_simple_type("s", tree.types[i]) def test_children(): tree = SignatureTree("ss") assert len(tree.types) == 2 parent = tree.types[0] assert parent.token == "s" assert parent.signature == "s" assert len(parent.children) == 0 def test_array(): tree = SignatureTree("as") assert len(tree.types) == 1 child = tree.types[0] assert child.signature == "as" assert child.token == "a" assert len(child.children) == 1 assert_simple_type("s", child.children[0]) assert child.children[0].token == "s" assert child._child_0.signature == "s" assert child._child_1 is None with pytest.raises(AttributeError): _ = child._child_1.signature def test_array_multiple(): tree = SignatureTree("asasass") assert len(tree.types) == 4 assert_simple_type("s", tree.types[3]) for i in range(3): array_child = tree.types[i] assert array_child.token == "a" assert array_child.signature == "as" assert len(array_child.children) == 1 assert_simple_type("s", array_child.children[0]) def test_array_nested(): tree = SignatureTree("aas") assert len(tree.types) == 1 child = tree.types[0] assert child.token == "a" assert child.signature == "aas" assert len(child.children) == 1 nested_child = child.children[0] assert nested_child.token == "a" assert nested_child.signature == "as" assert len(nested_child.children) == 1 assert_simple_type("s", nested_child.children[0]) def test_simple_struct(): tree = SignatureTree("(sss)") assert len(tree.types) == 1 child = tree.types[0] assert child.signature == "(sss)" assert len(child.children) == 3 for i in range(3): assert_simple_type("s", child.children[i]) assert child._child_0.signature == "s" assert child._child_1.signature == "s" def test_nested_struct(): tree = SignatureTree("(s(s(s)))") assert len(tree.types) == 1 child = tree.types[0] assert child.signature == "(s(s(s)))" assert child.token == "(" assert len(child.children) == 2 assert_simple_type("s", child.children[0]) first_nested = child.children[1] assert first_nested.token == "(" assert first_nested.signature == "(s(s))" assert len(first_nested.children) == 2 assert_simple_type("s", first_nested.children[0]) second_nested = first_nested.children[1] assert second_nested.token == "(" assert second_nested.signature == "(s)" assert len(second_nested.children) == 1 assert_simple_type("s", second_nested.children[0]) def test_struct_multiple(): tree = SignatureTree("(s)(s)(s)") assert len(tree.types) == 3 for i in range(3): child = tree.types[0] assert child.token == "(" assert child.signature == "(s)" assert len(child.children) == 1 assert_simple_type("s", child.children[0]) def test_array_of_structs(): tree = SignatureTree("a(ss)") assert len(tree.types) == 1 child = tree.types[0] assert child.token == "a" assert child.signature == "a(ss)" assert len(child.children) == 1 struct_child = child.children[0] assert struct_child.token == "(" assert struct_child.signature == "(ss)" assert len(struct_child.children) == 2 for i in range(2): assert_simple_type("s", struct_child.children[i]) def test_dict_simple(): tree = SignatureTree("a{ss}") assert len(tree.types) == 1 child = tree.types[0] assert child.signature == "a{ss}" assert child.token == "a" assert len(child.children) == 1 dict_child = child.children[0] assert dict_child.token == "{" assert dict_child.signature == "{ss}" assert len(dict_child.children) == 2 assert_simple_type("s", dict_child.children[0]) assert_simple_type("s", dict_child.children[1]) def test_dict_of_structs(): tree = SignatureTree("a{s(ss)}") assert len(tree.types) == 1 child = tree.types[0] assert child.token == "a" assert child.signature == "a{s(ss)}" assert len(child.children) == 1 dict_child = child.children[0] assert dict_child.token == "{" assert dict_child.signature == "{s(ss)}" assert len(dict_child.children) == 2 assert_simple_type("s", dict_child.children[0]) struct_child = dict_child.children[1] assert struct_child.token == "(" assert struct_child.signature == "(ss)" assert len(struct_child.children) == 2 for i in range(2): assert_simple_type("s", struct_child.children[i]) def test_contains_type(): tree = SignatureTree("h") assert signature_contains_type(tree, [0], "h") assert not signature_contains_type(tree, [0], "u") tree = SignatureTree("ah") assert signature_contains_type(tree, [[0]], "h") assert signature_contains_type(tree, [[0]], "a") assert not signature_contains_type(tree, [[0]], "u") tree = SignatureTree("av") body = [ [ Variant("u", 0), Variant("i", 0), Variant("x", 0), Variant("v", Variant("s", "hi")), ] ] assert signature_contains_type(tree, body, "u") assert signature_contains_type(tree, body, "x") assert signature_contains_type(tree, body, "v") assert signature_contains_type(tree, body, "s") assert not signature_contains_type(tree, body, "o") tree = SignatureTree("a{sv}") body = { "foo": Variant("h", 0), "bar": Variant("i", 0), "bat": Variant("x", 0), "baz": Variant("v", Variant("o", "/hi")), } for expected in "hixvso": assert signature_contains_type(tree, [body], expected) assert not signature_contains_type(tree, [body], "b") def test_invalid_variants(): tree = SignatureTree("a{sa{sv}}") s_con = { "type": "802-11-wireless", "uuid": "1234", "id": "SSID", } s_wifi = { "ssid": "SSID", "mode": "infrastructure", "hidden": True, } s_wsec = { "key-mgmt": "wpa-psk", "auth-alg": "open", "psk": "PASSWORD", } s_ip4 = {"method": "auto"} s_ip6 = {"method": "auto"} con = { "connection": s_con, "802-11-wireless": s_wifi, "802-11-wireless-security": s_wsec, "ipv4": s_ip4, "ipv6": s_ip6, } with pytest.raises(SignatureBodyMismatchError): tree.verify([con]) def test_variant_signature_type(): tree = SignatureTree("as") var = Variant(tree.types[0], ["foo", "bar"]) assert var.type == tree.types[0] assert var.value == ["foo", "bar"] assert var.signature == "as" with pytest.raises(SignatureBodyMismatchError): Variant(tree.types[0], "wrong") def test_struct_accepts_tuples_or_lists(): tree = SignatureTree("(s)") tree.verify([("ok",)]) tree.verify([["ok"]]) dbus-fast-2.44.1/tests/test_tcp_address.py000066400000000000000000000045721477355613200205650ustar00rootroot00000000000000import asyncio import os from contextlib import suppress import pytest from dbus_fast import Message from dbus_fast._private.address import parse_address from dbus_fast.aio import MessageBus @pytest.mark.asyncio async def test_tcp_connection_with_forwarding(event_loop): closables = [] host = "127.0.0.1" port = "55556" addr_info = parse_address(os.environ.get("DBUS_SESSION_BUS_ADDRESS")) assert addr_info addr_zero_options = addr_info[0][1] if "abstract" in addr_zero_options: path = f"\0{addr_zero_options['abstract']}" else: path = addr_zero_options["path"] tasks: list[asyncio.Task] = [] async def handle_connection(tcp_reader, tcp_writer): unix_reader, unix_writer = await asyncio.open_unix_connection(path) closables.append(tcp_writer) closables.append(unix_writer) async def handle_read(): while True: data = await tcp_reader.read(1) if not data: break unix_writer.write(data) async def handle_write(): while True: data = await unix_reader.read(1) if not data: break tcp_writer.write(data) tasks.append(asyncio.create_task(handle_read())) tasks.append(asyncio.create_task(handle_write())) server = await asyncio.start_server(handle_connection, host, port) closables.append(server) bus = await MessageBus(bus_address=f"tcp:host={host},port={port}").connect() # basic tests to see if it works result = await bus.call( Message( destination="org.freedesktop.DBus", path="/org/freedesktop/DBus", interface="org.freedesktop.DBus.Peer", member="Ping", ) ) assert result intr = await bus.introspect("org.freedesktop.DBus", "/org/freedesktop/DBus") obj = bus.get_proxy_object("org.freedesktop.DBus", "/org/freedesktop/DBus", intr) iface = obj.get_interface("org.freedesktop.DBus.Peer") await iface.call_ping() assert bus._sock.getpeername()[0] == host assert bus._sock.getsockname()[0] == host assert bus._sock.gettimeout() == 0 assert bus._stream.closed is False for c in closables: c.close() for t in tasks: t.cancel() with suppress(asyncio.CancelledError): await t dbus-fast-2.44.1/tests/test_unpack_variants.py000066400000000000000000000032171477355613200214550ustar00rootroot00000000000000"""Test unpack variants.""" import pytest from dbus_fast.signature import Variant from dbus_fast.unpack import unpack_variants @pytest.mark.asyncio async def test_dictionary(): """Test variants unpacked from dictionary.""" assert unpack_variants( { "string": Variant("s", "test"), "boolean": Variant("b", True), "int": Variant("u", 1), "object": Variant("o", "/test/path"), "array": Variant("as", ["test", "value"]), "tuple": Variant("(su)", ["test", 1]), "bytes": Variant("ay", b"\0x62\0x75\0x66"), } ) == { "string": "test", "boolean": True, "int": 1, "object": "/test/path", "array": ["test", "value"], "tuple": ["test", 1], "bytes": b"\0x62\0x75\0x66", } @pytest.mark.asyncio async def test_output_list(): """Test variants unpacked from multiple outputs.""" assert unpack_variants( [{"hello": Variant("s", "world")}, {"boolean": Variant("b", True)}, 1] ) == [{"hello": "world"}, {"boolean": True}, 1] @pytest.mark.asyncio async def test_nested_variants(): """Test unpack variants handles nesting.""" assert unpack_variants( { "dict": Variant("a{sv}", {"hello": Variant("s", "world")}), "array": Variant( "aa{sv}", [ {"hello": Variant("s", "world")}, {"bytes": Variant("ay", b"\0x62\0x75\0x66")}, ], ), } ) == { "dict": {"hello": "world"}, "array": [{"hello": "world"}, {"bytes": b"\0x62\0x75\0x66"}], } dbus-fast-2.44.1/tests/test_validators.py000066400000000000000000000044241477355613200204360ustar00rootroot00000000000000from dbus_fast import ( is_bus_name_valid, is_interface_name_valid, is_member_name_valid, is_object_path_valid, ) def test_object_path_validator(): valid_paths = ["/", "/foo", "/foo/bar", "/foo/bar/bat"] invalid_paths = [ None, "", "foo", "foo/bar", "/foo/bar/", "/$/foo/bar", "/foo//bar", "/foo$bar/baz", ] for path in valid_paths: assert is_object_path_valid(path), f'path should be valid: "{path}"' for path in invalid_paths: assert not is_object_path_valid(path), f'path should be invalid: "{path}"' def test_bus_name_validator(): valid_names = [ "foo.bar", "foo.bar.bat", "_foo._bar", "foo.bar69", "foo.bar-69", "org.mpris.MediaPlayer2.google-play-desktop-player", ] invalid_names = [ None, "", "5foo.bar", "foo.6bar", ".foo.bar", "bar..baz", "$foo.bar", "foo$.ba$r", ] for name in valid_names: assert is_bus_name_valid(name), f'bus name should be valid: "{name}"' for name in invalid_names: assert not is_bus_name_valid(name), f'bus name should be invalid: "{name}"' def test_interface_name_validator(): valid_names = ["foo.bar", "foo.bar.bat", "_foo._bar", "foo.bar69"] invalid_names = [ None, "", "5foo.bar", "foo.6bar", ".foo.bar", "bar..baz", "$foo.bar", "foo$.ba$r", "org.mpris.MediaPlayer2.google-play-desktop-player", ] for name in valid_names: assert is_interface_name_valid(name), ( f'interface name should be valid: "{name}"' ) for name in invalid_names: assert not is_interface_name_valid(name), ( f'interface name should be invalid: "{name}"' ) def test_member_name_validator(): valid_members = ["foo", "FooBar", "Bat_Baz69", "foo-bar"] invalid_members = [None, "", "foo.bar", "5foo", "foo$bar"] for member in valid_members: assert is_member_name_valid(member), f'member name should be valid: "{member}"' for member in invalid_members: assert not is_member_name_valid(member), ( f'member name should be invalid: "{member}"' ) dbus-fast-2.44.1/tests/util.py000066400000000000000000000005321477355613200162000ustar00rootroot00000000000000_has_gi = None skip_reason_no_gi = "glib tests require python3-gi" def check_gi_repository(): global _has_gi if _has_gi is not None: return _has_gi try: from gi.repository import GLib # noqa: F401 _has_gi = True return _has_gi except ImportError: _has_gi = False return _has_gi