rigplane 2.7.2__tar.gz → 2.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rigplane-2.7.2 → rigplane-2.7.3}/PKG-INFO +1 -1
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/CHANGELOG.md +17 -1
- rigplane-2.7.3/hatch_build.py +68 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/pyproject.toml +13 -3
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/backend.py +96 -31
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_backend.py +193 -0
- rigplane-2.7.3/tests/test_audio_capture_tx_validator_seam.py +312 -0
- rigplane-2.7.3/tests/test_audio_tx_contract_consistency.py +244 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/uv.lock +1 -1
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/analyze-failure.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/audit-ui.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/decompose-issue.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/generate-tests.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/next.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/refactor.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/regression-check.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/scan-issues.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/commands/solve-issue.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.claude/skills/release/SKILL.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/ISSUE_TEMPLATE/epic.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/ISSUE_TEMPLATE/feature.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/ISSUE_TEMPLATE/radio_report.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/ISSUE_TEMPLATE/ui-component.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/pull_request_template.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/scripts/check-rebrand-allowlist.sh +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/workflows/agent-review-gate.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/workflows/docs.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/workflows/full.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/workflows/publish.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/workflows/quick.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.github/workflows/rebrand-gate.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.gitignore +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/.importlinter +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/AGENTS.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/ARCHITECTURE.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/CHANGELOG.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/CLAUDE.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/CONTRIBUTING.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/LICENSE +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/README.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/ROADMAP.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/band-plans/_config.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/band-plans/arrl-hf.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/band-plans/broadcast.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/band-plans/iaru-r1.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/band-plans/utility.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/4f4bcd28cb8d426ca58ec08b5035541e.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/AUDIO_STREAMING_PROFILE.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/CNAME +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/EXTENDED_PROTOCOL_RESEARCH.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/PERFORMANCE.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/PROJECT.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/SECURITY.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/audio.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/auth.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/backends-icom7610-drivers.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/backends-icom7610.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/backends.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/command-catalog.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/commander.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/commands.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/exceptions.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/public-api-surface.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/radio.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/radios.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/rig-loader.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/rigctld.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/scope.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/sync.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/transport.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/types.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/api/web.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/architecture/open-core-policy.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/assets/scope-example.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/capabilities-matrix.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/contracts/diagnostic-bundle-v1.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/contracts/diagnostic-bundle-v2.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/contracts/validation-matrix-v1.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/audio-recipes.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/cli.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/commands.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/configuration.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/connection.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/diagnostic-reports.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/hamlib-rigctld-provider.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/ic705-usb-setup.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/ic7300-usb-setup.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/ic7610-usb-setup.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/ic9700-usb-setup.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/installation.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/profiles.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/quickstart.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/radios.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/rig-profiles.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/troubleshooting.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/web-ui.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/guide/wsjtx-setup.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/i18n/core-string-inventory.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/i18n/locale-contract.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/i18n/translating.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/index.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/architecture.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/cli-design.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/contributing.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/github-project-workflow.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/hamlib-provider-rollout.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/protocol.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/raw-civ-transactions.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/reliability-semantics.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/internals/rfc-audio-v1-mini.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/migrate.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/operations/managed-runtime-packaging.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/opuslib-macos-fix.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/overrides/main.html +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/parity/README.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/parity/ic7610_command_matrix.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/parity/test_mapping.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-03-07-ui-architecture.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-05-desktop-companion-architecture.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-09-audio-backend-design.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-11-frontend-migration-plan.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-11-parity-matrix.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-11-presentation-architecture.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-11-rx-audio-trace.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-11-shared-frontend-runtime-contract.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-11-v2-lcd-runtime-audit.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-12-architecture-presentation.html +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-12-target-frontend-architecture.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-18-desktop-meters-panel.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-18-lcd-display-enhancements.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-18-mobile-ia.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-18-receiver-activation.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-18-spectrum-controls.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-18-ui-refinements-execution.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-19-lcd-layout-redesign-v2.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-19-lcd-layout-redesign.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-29-modularization-discovery.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-29-modularization-plan.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-29-panel-adapter-migration.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-04-29-ui-v1-deprecation-audit.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-03-diagnostic-data-collection-design.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-07-audio-route-resolver-design.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-08-audio-capability-probing.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-08-audio-codec-policy.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-08-audio-profile-policy-audit.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-08-usb-audio-negotiation.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-23-hamlib-provider-contract.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-28-real-radio-validation-matrix.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/2026-05-28-universal-validation-matrix.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/archive/2026-03-04-dx-cluster.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/archive/2026-03-m5-m6-roadmap.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/archive/2026-04-19-lcd-twin-skins.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/build_orphan_report.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/classify_cycle_edges.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/cycles-classified.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/cycles.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/discovery_graph.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/external-usage.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/file-inventory.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/file-inventory.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/import-graph.dot +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/importlinter-config-draft.ini +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/init-snapshot.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/orphan-candidates.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/tach-config-draft.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/test-inventory.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/discovery-artifacts/tooling-assessment.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/00-epic-final.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/00-epic.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/01-skeleton.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/02-core-foundationals.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/03-core-contracts.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/04-commands.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/05-profiles.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/06-scope.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/07-audio.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/08-runtime-radio.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/09-runtime-mixins.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/10-runtime-pollers.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/11-discovery-to-backends.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/12-cli.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/13-import-linter.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/14-followup-tests.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/15-followup-web-startup.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/2026-05-07-core-audio-pipeline-test-harness.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/plans/issue-drafts/2026-05-07-core-audio-route-resolver.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/radio-protocol.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/robots.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/screenshots/amber-lcd.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/screenshots/hero.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/screenshots/lcd-scope.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/validation/running-validation.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/validation/templates/ftx1.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/validation/templates/ic7300.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/validation/templates/tx500.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/validation/templates/x6200.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/docs/validation/universal-matrix.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/.gitignore +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/README.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/eslint.config.js +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/index.html +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/package-lock.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/package.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/playwright.config.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/playwright.i18n.config.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/pnpm-lock.yaml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/apple-touch-icon.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/lockup-dark.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/lockup-light.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/lockup-mono.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/mark-dark.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/mark-light.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/mark-mono.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/marketing/github-social-preview.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/marketing/readme-banner.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/wordmark-dark.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/wordmark-light.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/brand/wordmark-mono.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicon.ico +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-128.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-180.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-256.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon-64.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/ink/favicon.ico +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-128.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-180.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-256.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon-64.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/paper/favicon.ico +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-128.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-180.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-256.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/favicons/transparent/favicon-64.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/manifest.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/og-image.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/pwa-192x192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/pwa-512x512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/public/twitter-card.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/scripts/i18n-check.mjs +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/App.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/app.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/assets/svelte.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/shared/Toast.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/shared/__tests__/Toast.component.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/BandPlanOverlay.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/DxOverlay.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/EiBiBrowser.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/ScopeSettingsPopover.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/SpectrumCanvas.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/SpectrumPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/SpectrumToolbar.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/WaterfallCanvas.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/BandPlanOverlay.component.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/DxOverlay.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/EiBiBrowser.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/SpectrumPanel.component.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/SpectrumToolbar.component.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/band-plan-overlay.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/click-to-tune.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/passband-geometry.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/spectrum-panel-logic.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/spectrum-toolbar.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/__tests__/tuning-indicator.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/band-plan-logic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/passband-geometry.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/spectrum-logic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components/spectrum/spectrum-toolbar-logic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/AttenuatorControl.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/BandSelector.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/BottomSheet.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/CollapsiblePanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/ControlButtonDemo.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/InstallPrompt.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/LanguageSelector.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/PttFab.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/PullToRefresh.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/SegmentedButton.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/StatusBadge.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/ThemePicker.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/ValueControlLab.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/AttenuatorControl.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/BandSelector.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/BottomSheet.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/CollapsiblePanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/InstallPrompt.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/LanguageSelector.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/PullToRefresh.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/SegmentedButton.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/StatusBadge.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/__tests__/broadcast-presets.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/band-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/broadcast-presets.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/button-tokens.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/control-button.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/install-prompt-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/status-badge-style.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/BipolarRenderer.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/DiscreteRenderer.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/DualParamRenderer.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/HBarRenderer.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/KnobRenderer.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/ValueControl.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/__tests__/ValueControl.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/__tests__/value-control-core.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/skin.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/skins/ProfessionalKnob.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/skins/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/value-control-core.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/controls/value-control/value-control.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/dialogs/SendReportDialog.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/dialogs/__tests__/SendReportDialog.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/display/FrequencyDisplay.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/display/FrequencyDisplayInteractive.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/display/__tests__/FrequencyDisplay.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/display/__tests__/frequency-tuning.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/display/frequency-format.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/display/frequency-tuning.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/KeyboardHandler.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/LcdLayout.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/LeftSidebar.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/MobileNav.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/MobileRadioLayout.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/RadioLayout.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/RightSidebar.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/StatusBar.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/VfoHeader.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/KeyboardHandler.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/LeftSidebar.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/MobileRadioLayout.component.svelte.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/RadioLayout.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/SpectrumPanelStub.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/keyboard-map.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/mobile-layout-logic.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/mobile-nav.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/top-row-visual-regression.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/vfo-header.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/__tests__/vfo-layout-tokens.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/keyboard-map.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/layout-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/mobile-chip-bar.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/mobile-layout-logic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/mobile-nav-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/responsive.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/shortcut-hints.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/layout/vfo-layout-tokens.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/BarGauge.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/LinearSMeter.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/NeedleGauge.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/SMeterDemo.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/__tests__/BarGauge.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/__tests__/LinearSMeter.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/__tests__/NeedleGauge.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/bar-gauge-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/needle-gauge-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/meters/smeter-scale.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/AgcPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/AntennaPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/AudioRoutingControl.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/CwPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/DockMeterPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/DspPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/EssentialsPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/FilterPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/MemoryPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/MeterPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/MetersDockPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/ModePanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/RfFrontEnd.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/RitXitPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/RxAudioPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/ScanPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/TxPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/VoxPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/AgcPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/AudioRoutingControl.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/CwPanel.component.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/DspPanel.component.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/DspPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/FilterPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/MeterPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/MetersDockPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/ModePanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/RfFrontEnd.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/RitXitPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/RxAudioPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/TxPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/cw-panel-logic.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/dsp-panel-logic.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/__tests__/filter-controls.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/agc-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/audio-scope/AudioSpectrumCanvas.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/audio-scope/AudioSpectrumPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/audio-scope/__tests__/audio-spectrum-renderer.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/audio-scope/audio-spectrum-renderer.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/audio-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/cw-panel-logic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/dsp-panel-logic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/dsp-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/filter-controls.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/filter-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberAfScope.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberCockpit.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberFilterGhost.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberFrequency.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberIndStrip.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberLcdDisplay.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberMemoryStrip.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberScope.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberSmeter.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberSparkline.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/AmberTelemetryStrip.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/LcdContrastControl.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/LcdDisplayModeControl.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/VfoControlPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/__tests__/lcd-components.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/__tests__/scope-frame.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/lcd/lcd-vintage.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/meter-utils.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/meter-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/rf-frontend-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/rit-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/tx-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/vfo/DualVfoDisplay.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/panels/vfo/__tests__/DualVfoDisplay.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/fonts-digital.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/fonts.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/theme-switcher.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/amoled-black.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/ayu-dark.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/catppuccin-latte.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/catppuccin-mocha.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/crt-green.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/custom-ic7610.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/dracula.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/github-light.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/gruvbox-dark.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/gruvbox-light.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/high-contrast.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/lcd-blue.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/lcd-warm.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/nixie-tube.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/nord-light.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/nord.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/one-dark.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/solarized-dark.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/solarized-light.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/themes/tokyo-night.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/tokens.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/vfo-themes/crt-green.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/vfo-themes/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/vfo-themes/lcd-blue.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/theme/vfo-themes/nixie-tube.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/ActiveReceiverToggle.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/VfoOps.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/VfoPanel.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/__tests__/ActiveReceiverToggle.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/__tests__/VfoOps.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/__tests__/VfoPanel.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/vfo-ops-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/vfo/vfo-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/__tests__/double-click.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/__tests__/focus-mode-race.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/__tests__/keyboard-wiring.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/__tests__/state-adapter.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/__tests__/vfo-wiring.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/command-bus.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/double-click.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/components-v2/wiring/state-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/ControlButton.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/DotButton.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/FillButton.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/HardwareButton.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/HardwarePlainButton.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/StatusIndicator.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/__tests__/ControlButton.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/__tests__/ControlledHarness.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/roleMapping.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/Button/types.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/SegmentedControl/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/__tests__/drag-reorder.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/__tests__/migrate-legacy-storage.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/actions/keyboard.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/api/__tests__/diagnostics.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/api/diagnostics.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/__tests__/audio-manager.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/__tests__/constants.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/__tests__/rx-player.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/__tests__/tx-mic.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/audio-manager.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/constants.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/rx-player.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/audio/tx-mic.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/data/__tests__/arrl-band-plan.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/data/arrl-band-plan.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/drag-reorder.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/gestures/gesture-recognizer.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/gestures/use-gesture.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/CONTRIBUTING.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/index.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/locale-contract.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/plural.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/pseudo-locale.smoke.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/pseudo.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/runtime.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/__tests__/store.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/locale-contract.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/locales/en-US.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/locales/ja-JP.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/locales/ru-RU.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/plural.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/pseudo.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/runtime.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/store.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/i18n/types.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/LocalExtensionsHost.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/__tests__/dock-layout.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/__tests__/host-api.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/__tests__/manifest.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/dock-layout.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/host-api.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/keyboard-scope.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/local-extensions/manifest.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/media/__tests__/media-session.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/media/media-session.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/migrate-legacy-storage.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/radio/filter-controls.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/radio/pending-focus.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/radio/pending-focus.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/renderers/__tests__/spectrum-renderer.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/renderers/__tests__/waterfall-renderer.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/renderers/spectrum-renderer.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/renderers/waterfall-renderer.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/__tests__/frontend-runtime.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/__tests__/scope-controller.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/audio-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/capabilities-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/lcd-chrome-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/panel-adapters.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/qsy-history-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/scope-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/tx-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/adapters/vfo-adapter.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/commands/panel-commands.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/frontend-runtime.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/index.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/props/panel-props.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/scope-controller.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/runtime/system-controller.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/__tests__/audio.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/__tests__/capabilities.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/__tests__/commands.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/__tests__/connection.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/__tests__/radio.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/__tests__/ui.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/audio.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/capabilities.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/commands.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/connection.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/connection.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/layout.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/lcd-contrast.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/lcd-display-mode.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/qsy-history.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/radio.svelte.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/radio.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/tuning.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/stores/ui.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/transport/__tests__/http-client.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/transport/__tests__/ws-client.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/transport/http-client.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/transport/ws-client.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/types/capabilities.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/types/protocol.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/types/state.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/__tests__/battery.test.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/battery.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/filter-width.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/haptics.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/meter-utils.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/smoothing.svelte.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/tx-permit.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/lib/utils/uuid.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/main.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/amber-lcd/LcdSkin.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/desktop-v2/DesktopSkin.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/lcd-cockpit/LcdCockpitSkin.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/lcd-scope/LcdScopeSkin.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/mobile/MobileSkin.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/registry.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/sdr-test/SdrTestSkin.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/skins/sdr-test/SdrVfoScreen.svelte +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/styles/animations.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/styles/tokens.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/types/pwa.d.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/src/types/webcodecs.d.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/static/fonts/DSEG7Classic-Bold.woff2 +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/svelte.config.js +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/README.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/app-shell-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/app-shell-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/connection-overlay-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/connection-overlay-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/send-report-dialog-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/send-report-dialog-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/settings-modal-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/settings-modal-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/status-bar-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/status-bar-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/toast-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/en-US/toast-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/app-shell-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/app-shell-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/connection-overlay-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/connection-overlay-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/send-report-dialog-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/send-report-dialog-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/settings-modal-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/settings-modal-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/status-bar-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/status-bar-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/toast-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/ja-JP/toast-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/app-shell-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/app-shell-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/connection-overlay-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/connection-overlay-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/send-report-dialog-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/send-report-dialog-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/settings-modal-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/settings-modal-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/status-bar-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/status-bar-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/toast-desktop.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/__screenshots__/i18n/qps-ploc/toast-mobile.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/fixtures.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/i18n/i18n-visual.spec.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tests/e2e/v2-ui-interactive.impl.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tsconfig.app.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tsconfig.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/tsconfig.node.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/frontend/vite.config.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/hooks/sitemap_noindex.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/mkdocs.yml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/_keyboard-default.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/_schema.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/_schema_v2.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/examples/ftx1.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/examples/lab599_tx500.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/examples/sdrplay_rspdx.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/examples/xiegu_x6200.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/ftx1.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/ic705.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/ic7300.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/ic7610.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/ic9700.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/tx500.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/x6100.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/rigs/x6200.toml +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/icom_lan/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/icom_lan/_cli_shim.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/__main__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_audio_codecs.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_audio_recovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_audio_runtime_mixin.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_audio_transcoder.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_bounded_queue.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_bridge_metrics.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_bridge_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_civ_rx.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_connection_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_control_phase.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_dual_rx_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_optional_deps.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_platformdirs_migration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_poller_types.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_queue_pressure.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_runtime_protocols.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_scope_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_shared_state_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_state_cache.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/_state_queries.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/_bridge_metrics.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/_bridge_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/_codecs.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/_macos_uid.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/_transcoder.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/_usb_resolve.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/analyzer.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/bridge.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/bus.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/dsp.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/fft_scope.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/lan_stream.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/probe.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/probe_profile.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/probe_runner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/resample.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/route.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio/usb_driver.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio_analyzer.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio_bridge.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio_bus.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/audio_fft_scope.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/auth.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/_icom_serial_base.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/discovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/factory.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/hamlib_models.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/hamlib_probe.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic705/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic705/core.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic705/serial.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic7300/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic7300/core.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic7300/serial.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic9700/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic9700/core.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/ic9700/serial.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/drivers/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/drivers/contracts.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/drivers/serial_civ_link.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/drivers/serial_session.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/drivers/serial_stub.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/drivers/usb_audio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/lan.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/icom7610/serial.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/rigctld_client/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/rigctld_client/radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/rigctld_client/transport.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/yaesu_cat/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/yaesu_cat/parser.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/yaesu_cat/poller.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/yaesu_cat/radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/backends/yaesu_cat/transport.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/capabilities.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/civ.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/_convert.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/_diagnose.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/_discover_hamlib.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/_radio_validate.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cli/_validate.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/command_map.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/command_spec.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commander.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/_builders.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/_codec.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/_frame.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/antenna.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/command_map.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/command_spec.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/commander.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/cw.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/dsp.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/freq.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/levels.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/memory.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/meters.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/mode.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/power.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/ptt.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/scope.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/speech.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/system.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/tone.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/tx_band.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/commands/vfo.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/_bounded_queue.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/_optional_deps.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/_queue_pressure.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/_state_cache.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/auth.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/capabilities.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/civ.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/env_config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/exceptions.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/radio_protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/radio_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/transport.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/core/types.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/cw_auto_tuner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/_discovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/_error_ring.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/_errors.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/_logging.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/_manifest.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/bundle.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributor.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/audio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/dependencies.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/errors.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/invocation.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/logs.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/contributors/system.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/redaction.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/diagnostics/upload.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/discovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/exceptions.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/nodes/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/nodes/base.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/nodes/nr_scipy.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/pipeline.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/resample.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/dsp/tap_registry.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/env_config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/exceptions.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/hamlib_bridge.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/ic705.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/meter_cal.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/profiles/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/profiles/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/profiles/rig_loader.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/profiles_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/proxy.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/py.typed +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radio_initial_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radio_protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radio_reconnect.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radio_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radio_state_snapshot.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/radios.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rig_loader.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/audit.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/circuit_breaker.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/contract.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/handler.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/poller.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/routing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/server.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/state_cache.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/rigctld/utils.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_audio_recovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_audio_runtime_mixin.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_civ_rx.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_connection_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_control_phase.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_dual_rx_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_poller_types.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_runtime_protocols.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_scope_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_shared_state_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/_state_queries.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/cw_auto_tuner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/ic705.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/meter_cal.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/profiles_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/proxy.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/radio_initial_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/radio_reconnect.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/radio_state_snapshot.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/radios.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/startup_checks.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/runtime/sync.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/scope/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/scope/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/scope/render.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/scope_render.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/startup_checks.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/sync.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/transport.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/types.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/usb_audio_resolve.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/comparison.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/hardware.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/overrides.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/registry.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/runner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/validation/schema.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/LAYER.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/_delta_encoder.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/api_contract.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/band_plan.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/discovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/dx_cluster.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/eibi.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/handlers/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/handlers/audio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/handlers/control.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/handlers/diagnostics.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/handlers/scope.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/radio_poller.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/rtc.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/runtime_helpers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/server.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/apple-touch-icon.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/assets/ControlButtonDemo-CnelvEOz.js +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/assets/ControlButtonDemo-Ddi7py1_.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/assets/index-CvOPafTi.css +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/assets/index-MRf0y8eM.js +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/lockup-dark.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/lockup-light.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/lockup-mono.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/mark-dark.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/mark-light.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/mark-mono.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/marketing/github-social-preview.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/marketing/readme-banner.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/wordmark-dark.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/wordmark-light.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/brand/wordmark-mono.svg +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicon.ico +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-128.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-180.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-256.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon-64.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/ink/favicon.ico +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-128.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-180.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-256.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon-64.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/paper/favicon.ico +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-128.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-16.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-180.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-256.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-32.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-48.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/favicons/transparent/favicon-64.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/index.html +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/manifest.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/og-image.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/pwa-192x192.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/pwa-512x512.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static/twitter-card.png +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/static.old/index.html +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/tls.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/web_routing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/web_startup.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/src/rigplane/web/websocket.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_audio_pipeline_helpers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_audio_stream_fake.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_caps.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_command_test_helpers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_diagnostics_mock_server.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_helpers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/_perf_helpers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/conftest.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/contracts/__init__.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/contracts/test_lazy_imports.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/e2e/package.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/e2e/v2-ui-interactive.spec.ts +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fake_rigctld.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fixtures/civ_rx_frames.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fixtures/hamlib_dump_caps_ts480.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fixtures/hamlib_rigctl_list.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fixtures/validation_artifact_mixed.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fixtures/validation_artifact_reverse_sync_fail.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/fixtures/validation_template_ic7300.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/golden/dump_state_ic7610.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/golden/dump_state_yaesu.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/golden/fldigi_dual_rx_session.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/golden/js8call_dual_rx_session.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/golden/protocol_golden.json +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/golden/wsjtx_dual_rx_session.txt +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/hardware/test_ic7610_audio_pipeline.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/hardware/test_x6200_serial_tx_smoke.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/README.md +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/conftest.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/full_handshake.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/logging_utils.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/probe_handshake.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/probe_login.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_audio_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_audio_routing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_connect.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_controls_extended_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_dsp_levels_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_get_freq.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_media_scope_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_memory_set_only.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_negative_auth_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_operator_toggles_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_radio_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_reliability_matrix_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_rigctld_audio_pipeline.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_rigctld_golden_replay.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_rigctld_wsjtx.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_rit_tuner_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_scope_advanced_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_tone_tsql_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_vfo_dual_watch_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/integration/test_x6200_audio_scope_smoke.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/mock_server.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_analyzer.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_bridge.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_bridge_stereo.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_bus.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_codec.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_codecs.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_dsp.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_fft_scope.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_fullduplex.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_pipeline_harness.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_pipeline_os_smoke.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_probe.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_probe_profile.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_probe_runner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_recovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_resample.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_route.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_rx_tx_transition.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_scope_dispatch.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_stress.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_transcoder.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_transcoder_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audio_watchdog.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_audit.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_auth.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_authz_registry_gated.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_backend_contract_matrix.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_backend_factory.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_bounded_queue.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_bsr_band_switching.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_circuit_breaker.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ_command_profiling.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ_rx_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ_rx_dispatch_golden.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ_rx_mixin_host.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ_rx_short_frame_robustness.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_civ_transaction_ownership.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli_async.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli_diagnose.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli_diagnose_lazy_import.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli_e2e.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cli_model.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cmd29_parsing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_command_catalog_docs.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_command_map_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_command_spec.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_commander.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_commands.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_commands_extended.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_convert.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_convert_cli.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cw_auto_tune_wiring.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_cw_auto_tuner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_data_mode.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_delta_encoder.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_bundle.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_contributor.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_contributors_batch1.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_contributors_batch2.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_contributors_batch3.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_e2e.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_logging.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_privacy_invariants.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_redaction.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_diagnostics_upload.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_discovery.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_discovery_responder.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_docs_runtime_sync.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dsp_filter_family.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dsp_levels_part1.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dsp_levels_part2.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dsp_nodes.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dsp_nr_scipy.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dsp_pipeline.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_dx_cluster.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_env_config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_exports.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_fake_rigctld.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_frontend_e2e_config.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ftx1_audio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ftx1_radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_golden_protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_hamlib_bridge.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_hamlib_dump_caps.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_hamlib_external_rigctld_contract.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_hamlib_models.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_hamlib_probe.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_handlers_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_handlers_dsp_407_408.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_handlers_protocol_gap_399.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_handlers_sys_band.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ic705.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ic705_backend.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ic7300_backend.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ic7610_parity_matrix.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_ic9700_backend.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_icom7610_serial_radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_icom_lan_shim.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_icom_receiver_tier.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_issue_141_core_refactor.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_jitter_buffer.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_lifecycle_diagnostics.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_macos_audio_uid.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_main_sub_tracking.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_managed_runtime_packaging_doc.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_memory_commands.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_mock_integration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_naming_parity.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_operator_toggles.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_overrides.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_pcm_e2e.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_per_receiver_vfo_roundtrip.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_performance_regressions.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_platformdirs_migration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_poller.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_poller_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_power_unit_extension.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_profiles_routing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_profiles_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_proxy.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_proxy_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_public_api_surface.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_connect.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_extended.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_poller_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radio_validate.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_radios.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rate_limiter.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_raw_civ_pipe.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_raw_civ_transaction.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_reconnect.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rf_gain_af_level.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rig_ic7300.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rig_ic7610.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rig_loader.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rig_multi_vendor.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rig_schema.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_client_backend.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_consistency.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_dump_state_snapshot.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_handler.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_init_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_protocol.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_routable_extension.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_server.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_server_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_rigctld_utils.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_scope.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_scope_render.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_scope_render_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_scope_stress.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_security_headers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_selected_freq_mode.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_serial_backend_smoke.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_serial_backend_tx_mor242.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_serial_civ_link.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_serial_session.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_serial_stub_framing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_server_wire.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_shared_state_runtime.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_single_rx_plain_routing.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_state_cache.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_state_cache_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_state_pollable_extension.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_state_queries.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_supports_command.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_swr_calibration.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_sync.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_sync_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_tap_registry.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_tls.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_token_renewal.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_tone_tsql.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_transport.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_tx_band_edge.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_usb_audio_capable_extension.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_usb_audio_channel_clamp_mor238.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_usb_audio_resolve.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_usb_audio_stub.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_validate_hamlib_provider.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_validate_overrides.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_validation_comparison.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_validation_runner.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_validation_schema.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_validation_templates.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_vfo_dual_watch.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_vox_tone_state.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_api_contract.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_audio_streaming_profile.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_auth_compare_digest.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_capability_guards.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_command_batch_http.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_cw_http_control.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_diagnostics.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_post_body_cap.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_ptt_readonly.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_runtime_helpers.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_server.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_server_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_web_server_token_redaction.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_webrtc_signaling.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_websocket_coverage.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_x6200_rx_audio_mor236.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_yaesu_audio.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_yaesu_cat_parser.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_yaesu_cat_poller.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_yaesu_cat_transport.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/test_yaesu_cli_factory.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/validation/test_generator.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/validation/test_generator_hamlib.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/validation/test_hardware.py +0 -0
- {rigplane-2.7.2 → rigplane-2.7.3}/tests/validation/test_registry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rigplane
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.3
|
|
4
4
|
Summary: Multi-vendor radio control library and Web UI with native providers and planned Hamlib-backed CAT coverage
|
|
5
5
|
Project-URL: Homepage, https://rigplane.dev/
|
|
6
6
|
Project-URL: Documentation, https://rigplane.dev/
|
|
@@ -11,6 +11,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [2.7.3] — 2026-05-31
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Windows FT8 TX delivered no audio (Po=0 W): the callback/`blocksize=0` TX
|
|
19
|
+
capture emitted 960-byte (10 ms) frames while the PCM TX validator requires
|
|
20
|
+
1920-byte (20 ms) frames; capture now re-chunks the continuous callback stream
|
|
21
|
+
into fixed 20 ms frames (keeps the ~50 Hz comb fix; lossless) (MOR-256, #1699,
|
|
22
|
+
17492be6)
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Build (packaging): build the web UI during packaging so source/git installs
|
|
27
|
+
bundle the SPA (#1698, 55a0f81f)
|
|
28
|
+
|
|
14
29
|
## [2.7.2] — 2026-05-30
|
|
15
30
|
|
|
16
31
|
### Fixed
|
|
@@ -1543,7 +1558,8 @@ These deprecation closures were announced in v0.19 and dropped on schedule.
|
|
|
1543
1558
|
- Transport layer, authentication, CI-V commands, meters, PTT, keep-alive.
|
|
1544
1559
|
- Clean-room Icom LAN UDP protocol implementation.
|
|
1545
1560
|
|
|
1546
|
-
[Unreleased]: https://github.com/rigplane/rigplane-core/compare/v2.7.
|
|
1561
|
+
[Unreleased]: https://github.com/rigplane/rigplane-core/compare/v2.7.3...HEAD
|
|
1562
|
+
[2.7.3]: https://github.com/rigplane/rigplane-core/compare/v2.7.2...v2.7.3
|
|
1547
1563
|
[2.7.2]: https://github.com/rigplane/rigplane-core/compare/v2.7.1...v2.7.2
|
|
1548
1564
|
[2.7.1]: https://github.com/rigplane/rigplane-core/compare/v2.7.0...v2.7.1
|
|
1549
1565
|
[2.7.0]: https://github.com/rigplane/rigplane-core/compare/v2.6.0...v2.7.0
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Hatchling build hook that bundles the Svelte web UI into the package.
|
|
2
|
+
|
|
3
|
+
The frontend lives in ``frontend/`` and its build output (``frontend/dist``)
|
|
4
|
+
is gitignored. At runtime the SPA is served from ``src/rigplane/web/static``,
|
|
5
|
+
so the package must ship the built assets at that location.
|
|
6
|
+
|
|
7
|
+
This hook makes every build target (wheel *and* sdist) self-contained:
|
|
8
|
+
|
|
9
|
+
* If ``frontend/dist/index.html`` is missing and a ``frontend/`` source tree is
|
|
10
|
+
present, it builds the SPA with ``npm`` (``npm ci``/``npm install`` then
|
|
11
|
+
``npm run build``). If ``npm`` is unavailable and no prebuilt dist exists, it
|
|
12
|
+
raises a clear ``RuntimeError`` so the failure is actionable.
|
|
13
|
+
* If ``frontend/dist/index.html`` already exists, the npm build is skipped — the
|
|
14
|
+
hook is idempotent, so the PyPI publish flow (which prebuilds the frontend)
|
|
15
|
+
does not rebuild it.
|
|
16
|
+
* The built ``frontend/dist`` is force-included at ``src/rigplane/web/static``
|
|
17
|
+
for whichever target is building, centralizing the mapping in one place.
|
|
18
|
+
|
|
19
|
+
Without this, ``pip install git+https://...`` (a direct wheel build) would not
|
|
20
|
+
bundle the SPA and the desktop UI would 404.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import shutil
|
|
26
|
+
import subprocess
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import Any
|
|
29
|
+
|
|
30
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
31
|
+
|
|
32
|
+
# Runtime location the installed package serves the SPA from. Must not change.
|
|
33
|
+
_RUNTIME_STATIC = "src/rigplane/web/static"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class FrontendBuildHook(BuildHookInterface): # type: ignore[type-arg]
|
|
37
|
+
"""Build the web UI (if needed) and bundle it into the package."""
|
|
38
|
+
|
|
39
|
+
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
|
|
40
|
+
root = Path(self.root)
|
|
41
|
+
frontend_dir = root / "frontend"
|
|
42
|
+
dist_index = frontend_dir / "dist" / "index.html"
|
|
43
|
+
|
|
44
|
+
if not dist_index.exists() and frontend_dir.is_dir():
|
|
45
|
+
self._build_frontend(frontend_dir)
|
|
46
|
+
|
|
47
|
+
# Inject the force-include so the SPA lands at the runtime location for
|
|
48
|
+
# whichever target (wheel or sdist) is building.
|
|
49
|
+
force_include = build_data.setdefault("force_include", {})
|
|
50
|
+
force_include["frontend/dist"] = _RUNTIME_STATIC
|
|
51
|
+
|
|
52
|
+
def _build_frontend(self, frontend_dir: Path) -> None:
|
|
53
|
+
npm = shutil.which("npm")
|
|
54
|
+
if npm is None:
|
|
55
|
+
raise RuntimeError(
|
|
56
|
+
"Building rigplane from source requires Node.js/npm to build "
|
|
57
|
+
"the web UI (frontend/dist is not present and could not be "
|
|
58
|
+
"built). Install Node.js/npm, or build a wheel/sdist on a "
|
|
59
|
+
"machine that has them (the resulting artifact is "
|
|
60
|
+
"self-contained and needs no Node.js to install)."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
lockfile = frontend_dir / "package-lock.json"
|
|
64
|
+
install_cmd = [npm, "ci"] if lockfile.exists() else [npm, "install"]
|
|
65
|
+
|
|
66
|
+
self.app.display_info("Building rigplane web UI (npm)...")
|
|
67
|
+
subprocess.run(install_cmd, cwd=frontend_dir, check=True)
|
|
68
|
+
subprocess.run([npm, "run", "build"], cwd=frontend_dir, check=True)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rigplane"
|
|
7
|
-
version = "2.7.
|
|
7
|
+
version = "2.7.3"
|
|
8
8
|
description = "Multi-vendor radio control library and Web UI with native providers and planned Hamlib-backed CAT coverage"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -74,12 +74,22 @@ dev = [
|
|
|
74
74
|
|
|
75
75
|
[tool.hatch.build.targets.wheel]
|
|
76
76
|
packages = ["src/rigplane", "src/icom_lan"]
|
|
77
|
+
# The web UI is placed at src/rigplane/web/static exclusively via the custom
|
|
78
|
+
# build hook's force-include (see hatch_build.py). When building a wheel from an
|
|
79
|
+
# sdist (uv build's default sdist->wheel chain), the sdist has already
|
|
80
|
+
# materialized src/rigplane/web/static on disk; exclude it from normal project
|
|
81
|
+
# file selection so the force-include is the single source and the tree is not
|
|
82
|
+
# bundled twice.
|
|
83
|
+
exclude = ["src/rigplane/web/static"]
|
|
77
84
|
|
|
78
85
|
[tool.hatch.build.targets.wheel.force-include]
|
|
79
86
|
"rigs" = "rigplane/rigs"
|
|
80
87
|
|
|
81
|
-
|
|
82
|
-
|
|
88
|
+
# Builds the Svelte web UI during packaging (if not prebuilt) and force-includes
|
|
89
|
+
# the result at src/rigplane/web/static for BOTH wheel and sdist targets, so
|
|
90
|
+
# source/git installs are self-contained. See hatch_build.py.
|
|
91
|
+
[tool.hatch.build.hooks.custom]
|
|
92
|
+
path = "hatch_build.py"
|
|
83
93
|
|
|
84
94
|
[tool.pytest.ini_options]
|
|
85
95
|
asyncio_mode = "auto"
|
|
@@ -10,7 +10,6 @@ opening RX/TX audio streams, plus two concrete implementations:
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
-
import asyncio
|
|
14
13
|
import logging
|
|
15
14
|
import math
|
|
16
15
|
import threading
|
|
@@ -228,7 +227,35 @@ def _ensure_portaudio_deps() -> tuple[Any, Any]:
|
|
|
228
227
|
|
|
229
228
|
|
|
230
229
|
class _PortAudioRxStream:
|
|
231
|
-
"""RxStream backed by a sounddevice InputStream.
|
|
230
|
+
"""RxStream backed by a callback-driven sounddevice InputStream.
|
|
231
|
+
|
|
232
|
+
Capture is clocked by PortAudio's own audio thread via an ``InputStream``
|
|
233
|
+
callback, mirroring the callback design of :class:`_PortAudioTxStream`.
|
|
234
|
+
This replaces the previous fixed-``blocksize=960`` blocking-read loop
|
|
235
|
+
(``stream.read(960)`` on a worker thread), whose 20 ms read straddled the
|
|
236
|
+
WASAPI shared-mode engine period (~10 ms) and dropped/duplicated a sample
|
|
237
|
+
run once per block, producing a ~50 Hz spectral comb on captured TX audio
|
|
238
|
+
on Windows. The stream is opened with ``blocksize=0`` (engine-native
|
|
239
|
+
period), mirroring a known-clean ``sd.rec`` capture. The earlier WDM-KS
|
|
240
|
+
capture face rejected ``blocksize=0`` (PortAudioError -9999), but companion
|
|
241
|
+
device selection now forces the WASAPI host-API face, on which
|
|
242
|
+
``blocksize=0`` opens cleanly.
|
|
243
|
+
|
|
244
|
+
The PortAudio callback runs on the audio thread and must not block. It
|
|
245
|
+
copies the captured PCM (s16le) out of the engine-native, variable-size
|
|
246
|
+
block and *re-chunks* it into fixed ``frame_ms``-sized frames before
|
|
247
|
+
handing them to the consumer *callback*. The downstream PCM-TX contract
|
|
248
|
+
requires fixed-size frames (e.g. 20 ms = 960 samples = 1920 bytes s16le
|
|
249
|
+
mono @ 48 kHz); a managed core validator rejects any frame whose byte
|
|
250
|
+
length differs. Re-chunking a *continuous* callback stream is lossless and
|
|
251
|
+
introduces no scheduling seam (the ~50 Hz comb came from the old
|
|
252
|
+
blocking-read inter-read gap, not from re-chunking), so this preserves the
|
|
253
|
+
fixed-frame contract without re-introducing the comb. Sub-frame remainders
|
|
254
|
+
are buffered across callbacks; a trailing partial frame at stop is dropped.
|
|
255
|
+
The consumer contract (see :class:`RxStream`) is that the callback is cheap
|
|
256
|
+
and thread-safe to invoke from the audio thread; the companion bridge
|
|
257
|
+
marshals onto its event loop via ``call_soon_threadsafe``.
|
|
258
|
+
"""
|
|
232
259
|
|
|
233
260
|
def __init__(
|
|
234
261
|
self,
|
|
@@ -237,24 +264,40 @@ class _PortAudioRxStream:
|
|
|
237
264
|
sample_rate: int,
|
|
238
265
|
channels: int,
|
|
239
266
|
blocksize: int,
|
|
267
|
+
frame_ms: int,
|
|
240
268
|
) -> None:
|
|
241
269
|
self._sd = sd
|
|
242
270
|
self._device_index = device_index
|
|
243
271
|
self._sample_rate = sample_rate
|
|
244
272
|
self._channels = channels
|
|
273
|
+
# Capture is callback-driven with blocksize=0 (engine-native period),
|
|
274
|
+
# mirroring a clean sd.rec. blocksize=0 was previously rejected by the
|
|
275
|
+
# WDM-KS capture face (PortAudioError -9999), but companion device
|
|
276
|
+
# selection now forces the WASAPI face, on which blocksize=0 opens.
|
|
245
277
|
self._blocksize = blocksize
|
|
278
|
+
# Fixed delivered-frame size: frame_ms worth of audio frames, each
|
|
279
|
+
# ``channels`` interleaved s16le samples (2 bytes/sample). The PortAudio
|
|
280
|
+
# stream stays blocksize=0; only the size handed to ``cb`` is fixed.
|
|
281
|
+
frame_samples = (sample_rate * frame_ms) // 1000
|
|
282
|
+
self._frame_bytes = max(1, frame_samples * channels * 2)
|
|
246
283
|
self._stream: Any = None
|
|
247
|
-
self.
|
|
284
|
+
self._running = False
|
|
248
285
|
self._callback: Callable[[bytes], None] | None = None
|
|
286
|
+
# Sub-frame remainder carried between audio-thread callbacks. The audio
|
|
287
|
+
# thread is the only writer, so no lock is needed.
|
|
288
|
+
self._accumulator = bytearray()
|
|
249
289
|
|
|
250
290
|
@property
|
|
251
291
|
def running(self) -> bool:
|
|
252
|
-
return self.
|
|
292
|
+
return self._running
|
|
253
293
|
|
|
254
294
|
async def start(self, callback: Callable[[bytes], None]) -> None:
|
|
255
295
|
if self.running:
|
|
256
296
|
raise RuntimeError("RX stream already running.")
|
|
257
297
|
self._callback = callback
|
|
298
|
+
self._accumulator = bytearray()
|
|
299
|
+
# blocksize=0 (engine-native period) mirrors a clean sd.rec on the
|
|
300
|
+
# WASAPI face. latency="low" matches the (clean) output stream.
|
|
258
301
|
self._stream = self._sd.InputStream(
|
|
259
302
|
samplerate=self._sample_rate,
|
|
260
303
|
channels=self._channels,
|
|
@@ -262,17 +305,19 @@ class _PortAudioRxStream:
|
|
|
262
305
|
device=self._device_index,
|
|
263
306
|
blocksize=self._blocksize,
|
|
264
307
|
latency="low",
|
|
308
|
+
callback=self._input_callback,
|
|
265
309
|
)
|
|
266
310
|
self._stream.start()
|
|
267
|
-
self.
|
|
311
|
+
self._running = True
|
|
268
312
|
|
|
269
313
|
async def stop(self) -> None:
|
|
270
314
|
stream = self._stream
|
|
271
|
-
task = self._task
|
|
272
315
|
self._stream = None
|
|
273
|
-
self.
|
|
316
|
+
self._running = False
|
|
274
317
|
self._callback = None
|
|
275
|
-
#
|
|
318
|
+
# Drop any sub-frame remainder: an incomplete trailing frame cannot
|
|
319
|
+
# satisfy the fixed-size contract and is discarded at teardown.
|
|
320
|
+
self._accumulator = bytearray()
|
|
276
321
|
if stream is not None:
|
|
277
322
|
try:
|
|
278
323
|
stream.stop()
|
|
@@ -282,30 +327,44 @@ class _PortAudioRxStream:
|
|
|
282
327
|
stream.close()
|
|
283
328
|
except Exception:
|
|
284
329
|
logger.debug("portaudio-rx: stream close failed", exc_info=True)
|
|
285
|
-
# Now cancel the task (thread is already unblocked)
|
|
286
|
-
if task is not None and not task.done():
|
|
287
|
-
task.cancel()
|
|
288
|
-
try:
|
|
289
|
-
await task
|
|
290
|
-
except asyncio.CancelledError:
|
|
291
|
-
pass
|
|
292
330
|
|
|
293
|
-
|
|
294
|
-
|
|
331
|
+
def _input_callback(
|
|
332
|
+
self,
|
|
333
|
+
indata: Any,
|
|
334
|
+
_frames: int,
|
|
335
|
+
_time_info: Any,
|
|
336
|
+
_status: Any,
|
|
337
|
+
) -> None:
|
|
338
|
+
# Runs on PortAudio's audio thread: keep it non-blocking. Copy the
|
|
339
|
+
# captured PCM (s16le) out of the (reused, variable-size) input buffer,
|
|
340
|
+
# append it to the running accumulator, then slice off whole fixed-size
|
|
341
|
+
# frames and deliver each to the consumer. Re-chunking a continuous
|
|
342
|
+
# callback stream is lossless (every sample reaches the consumer in
|
|
343
|
+
# order) and adds no scheduling seam, so it keeps the fixed-frame
|
|
344
|
+
# contract without re-introducing the comb. The consumer is
|
|
345
|
+
# contractually cheap/thread-safe.
|
|
346
|
+
cb = self._callback
|
|
347
|
+
if cb is None:
|
|
348
|
+
return
|
|
295
349
|
try:
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
350
|
+
pcm = (
|
|
351
|
+
bytes(indata.tobytes()) if hasattr(indata, "tobytes") else bytes(indata)
|
|
352
|
+
)
|
|
353
|
+
except Exception:
|
|
354
|
+
logger.warning("portaudio-rx: capture copy failed", exc_info=True)
|
|
355
|
+
return
|
|
356
|
+
if not pcm:
|
|
357
|
+
return
|
|
358
|
+
acc = self._accumulator
|
|
359
|
+
acc.extend(pcm)
|
|
360
|
+
frame_bytes = self._frame_bytes
|
|
361
|
+
try:
|
|
362
|
+
while len(acc) >= frame_bytes:
|
|
363
|
+
frame = bytes(acc[:frame_bytes])
|
|
364
|
+
del acc[:frame_bytes]
|
|
365
|
+
cb(frame)
|
|
307
366
|
except Exception:
|
|
308
|
-
logger.warning("portaudio-rx:
|
|
367
|
+
logger.warning("portaudio-rx: consumer callback failed", exc_info=True)
|
|
309
368
|
|
|
310
369
|
|
|
311
370
|
class _PortAudioTxStream:
|
|
@@ -795,13 +854,19 @@ class PortAudioBackend:
|
|
|
795
854
|
frame_ms: int = 20,
|
|
796
855
|
) -> RxStream:
|
|
797
856
|
sd, _ = self._ensure_deps()
|
|
798
|
-
blocksize
|
|
857
|
+
# blocksize=0 lets PortAudio use the engine-native period, mirroring a
|
|
858
|
+
# clean ``sd.rec`` capture. This is safe now that companion device
|
|
859
|
+
# selection forces the WASAPI host-API face (the WDM-KS face that
|
|
860
|
+
# rejected blocksize=0 with PortAudioError -9999 is no longer chosen).
|
|
861
|
+
# The PortAudio capture period stays engine-native; frame_ms only sizes
|
|
862
|
+
# the fixed frames re-chunked out to the consumer callback.
|
|
799
863
|
return _PortAudioRxStream(
|
|
800
864
|
sd,
|
|
801
865
|
device_index=int(device),
|
|
802
866
|
sample_rate=sample_rate,
|
|
803
867
|
channels=channels,
|
|
804
|
-
blocksize=
|
|
868
|
+
blocksize=0,
|
|
869
|
+
frame_ms=frame_ms,
|
|
805
870
|
)
|
|
806
871
|
|
|
807
872
|
def open_tx(
|
|
@@ -368,6 +368,199 @@ class TestPortAudioBackendDeps:
|
|
|
368
368
|
stream = backend.open_rx(AudioDeviceId(0))
|
|
369
369
|
assert isinstance(stream, RxStream)
|
|
370
370
|
|
|
371
|
+
@pytest.mark.asyncio()
|
|
372
|
+
async def test_open_rx_opens_callback_driven_blocksize_zero(self) -> None:
|
|
373
|
+
"""Capture must be callback-driven with blocksize=0 (engine-native).
|
|
374
|
+
|
|
375
|
+
Regression guard against the ~50 Hz TX "comb": the old implementation
|
|
376
|
+
read on a fixed-``blocksize=960`` blocking loop (``stream.read(960)`` in
|
|
377
|
+
``asyncio.to_thread``), which straddled the WASAPI shared-mode engine
|
|
378
|
+
period and dropped/duplicated a sample run once per 20 ms block. The
|
|
379
|
+
stream must now register a ``callback=`` rather than reading, and open
|
|
380
|
+
with ``blocksize=0`` (engine-native period), mirroring a clean
|
|
381
|
+
``sd.rec``. Companion device selection forces the WASAPI face on which
|
|
382
|
+
``blocksize=0`` opens (the WDM-KS face that rejected ``blocksize=0`` with
|
|
383
|
+
PortAudioError -9999 is no longer chosen).
|
|
384
|
+
"""
|
|
385
|
+
created: list[dict[str, object]] = []
|
|
386
|
+
|
|
387
|
+
class FakeSd:
|
|
388
|
+
class InputStream:
|
|
389
|
+
def __init__(self, **kw: object) -> None:
|
|
390
|
+
created.append(kw)
|
|
391
|
+
self.started = False
|
|
392
|
+
self.stopped = False
|
|
393
|
+
self.closed = False
|
|
394
|
+
|
|
395
|
+
def start(self) -> None:
|
|
396
|
+
self.started = True
|
|
397
|
+
|
|
398
|
+
def stop(self) -> None:
|
|
399
|
+
self.stopped = True
|
|
400
|
+
|
|
401
|
+
def close(self) -> None:
|
|
402
|
+
self.closed = True
|
|
403
|
+
|
|
404
|
+
def read(self, _frames: int) -> object: # pragma: no cover
|
|
405
|
+
raise AssertionError("capture must not use blocking read()")
|
|
406
|
+
|
|
407
|
+
backend = PortAudioBackend(dependency_loader=lambda: (FakeSd(), object()))
|
|
408
|
+
# frame_ms is advisory only now: the capture period is engine-native.
|
|
409
|
+
stream = backend.open_rx(
|
|
410
|
+
AudioDeviceId(0), sample_rate=48_000, channels=1, frame_ms=20
|
|
411
|
+
)
|
|
412
|
+
assert isinstance(stream, RxStream)
|
|
413
|
+
|
|
414
|
+
await stream.start(lambda _pcm: None)
|
|
415
|
+
assert stream.running
|
|
416
|
+
|
|
417
|
+
assert len(created) == 1
|
|
418
|
+
kwargs = created[0]
|
|
419
|
+
assert kwargs["blocksize"] == 0
|
|
420
|
+
assert callable(kwargs["callback"])
|
|
421
|
+
assert kwargs["samplerate"] == 48_000
|
|
422
|
+
assert kwargs["channels"] == 1
|
|
423
|
+
assert kwargs["dtype"] == "int16"
|
|
424
|
+
# device is passed as the integer index, unchanged.
|
|
425
|
+
assert kwargs["device"] == 0
|
|
426
|
+
|
|
427
|
+
await stream.stop()
|
|
428
|
+
assert not stream.running
|
|
429
|
+
|
|
430
|
+
@pytest.mark.asyncio()
|
|
431
|
+
async def test_open_rx_callback_emits_fixed_frame_ms_frames_lossless(self) -> None:
|
|
432
|
+
"""Re-chunk invariant: variable-size device blocks are losslessly
|
|
433
|
+
accumulated and re-emitted to the consumer as FIXED frame_ms-sized
|
|
434
|
+
frames (the downstream PCM-TX validator rejects any other size).
|
|
435
|
+
|
|
436
|
+
The PortAudio callback delivers engine-native blocks whose frame count
|
|
437
|
+
varies (480, 480, 200, 760, 480, ...). The capture path must accumulate
|
|
438
|
+
them and hand the consumer only whole frame_ms frames (960 samples =
|
|
439
|
+
1920 bytes s16le mono @ 48 kHz / 20 ms), with every sample delivered in
|
|
440
|
+
order, byte-for-byte equal to the input concatenation truncated to a
|
|
441
|
+
whole number of frames. No loss/dup/reorder. The re-chunk is of a
|
|
442
|
+
continuous callback stream, so it adds no scheduling seam (the ~50 Hz
|
|
443
|
+
comb came from the old blocking read's inter-read gap, not re-chunking).
|
|
444
|
+
"""
|
|
445
|
+
|
|
446
|
+
class FakeIndata:
|
|
447
|
+
def __init__(self, payload: bytes) -> None:
|
|
448
|
+
self._payload = payload
|
|
449
|
+
|
|
450
|
+
def tobytes(self) -> bytes:
|
|
451
|
+
return self._payload
|
|
452
|
+
|
|
453
|
+
captured_cb: dict[str, object] = {}
|
|
454
|
+
|
|
455
|
+
class FakeSd:
|
|
456
|
+
class InputStream:
|
|
457
|
+
def __init__(self, **kw: object) -> None:
|
|
458
|
+
captured_cb["cb"] = kw["callback"]
|
|
459
|
+
|
|
460
|
+
def start(self) -> None:
|
|
461
|
+
pass
|
|
462
|
+
|
|
463
|
+
def stop(self) -> None:
|
|
464
|
+
pass
|
|
465
|
+
|
|
466
|
+
def close(self) -> None:
|
|
467
|
+
pass
|
|
468
|
+
|
|
469
|
+
backend = PortAudioBackend(dependency_loader=lambda: (FakeSd(), object()))
|
|
470
|
+
stream = backend.open_rx(
|
|
471
|
+
AudioDeviceId(0), sample_rate=48_000, channels=1, frame_ms=20
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
received: list[bytes] = []
|
|
475
|
+
await stream.start(received.append)
|
|
476
|
+
|
|
477
|
+
cb = captured_cb["cb"]
|
|
478
|
+
assert callable(cb)
|
|
479
|
+
|
|
480
|
+
# A reference s16le mono stream split into VARIABLE-size device blocks
|
|
481
|
+
# (480, 480, 200, 760, 480 samples = 2400). The sequence crosses frame
|
|
482
|
+
# boundaries mid-block so re-chunking is genuinely exercised.
|
|
483
|
+
import struct
|
|
484
|
+
|
|
485
|
+
frame_samples = 960
|
|
486
|
+
frame_bytes = frame_samples * 2 # 1920 bytes (s16le mono)
|
|
487
|
+
# 2880 samples = exactly 3 whole frames once the final block lands.
|
|
488
|
+
total_samples = 2880
|
|
489
|
+
reference = b"".join(struct.pack("<h", v % 32768) for v in range(total_samples))
|
|
490
|
+
block_splits = (480, 480, 200, 760, 480) # samples; sums to 2400
|
|
491
|
+
offset = 0
|
|
492
|
+
for n_frames in block_splits:
|
|
493
|
+
chunk = reference[offset : offset + n_frames * 2]
|
|
494
|
+
offset += n_frames * 2
|
|
495
|
+
cb(FakeIndata(chunk), n_frames, None, None) # type: ignore[operator]
|
|
496
|
+
|
|
497
|
+
# 2400 buffered samples -> two whole 960-sample frames emerge; the
|
|
498
|
+
# trailing 480-sample remainder stays buffered (not yet a whole frame).
|
|
499
|
+
assert len(received) == 2
|
|
500
|
+
for frame in received:
|
|
501
|
+
assert len(frame) == frame_bytes # 1920 bytes / 20 ms each
|
|
502
|
+
assert b"".join(received) == reference[: 2 * frame_bytes] # in order, no dup
|
|
503
|
+
|
|
504
|
+
# A final 480-sample block completes the third frame, draining the
|
|
505
|
+
# remainder. All 2880 samples now delivered as 3 fixed frames.
|
|
506
|
+
cb(FakeIndata(reference[offset:]), 480, None, None) # type: ignore[operator]
|
|
507
|
+
assert len(received) == 3
|
|
508
|
+
assert all(len(f) == frame_bytes for f in received)
|
|
509
|
+
assert b"".join(received) == reference # every sample, in order
|
|
510
|
+
|
|
511
|
+
await stream.stop()
|
|
512
|
+
# After stop the consumer is detached and the accumulator is cleared: a
|
|
513
|
+
# late callback is a no-op (the audio thread may fire once during
|
|
514
|
+
# teardown).
|
|
515
|
+
cb(FakeIndata(b"\xff" * frame_bytes), 960, None, None) # type: ignore[operator]
|
|
516
|
+
assert len(received) == 3
|
|
517
|
+
|
|
518
|
+
@pytest.mark.asyncio()
|
|
519
|
+
async def test_open_rx_callback_honors_frame_ms(self) -> None:
|
|
520
|
+
"""frame_ms sizes the emitted frame: 10 ms -> 480 samples -> 960 bytes."""
|
|
521
|
+
|
|
522
|
+
class FakeIndata:
|
|
523
|
+
def __init__(self, payload: bytes) -> None:
|
|
524
|
+
self._payload = payload
|
|
525
|
+
|
|
526
|
+
def tobytes(self) -> bytes:
|
|
527
|
+
return self._payload
|
|
528
|
+
|
|
529
|
+
captured_cb: dict[str, object] = {}
|
|
530
|
+
|
|
531
|
+
class FakeSd:
|
|
532
|
+
class InputStream:
|
|
533
|
+
def __init__(self, **kw: object) -> None:
|
|
534
|
+
captured_cb["cb"] = kw["callback"]
|
|
535
|
+
|
|
536
|
+
def start(self) -> None:
|
|
537
|
+
pass
|
|
538
|
+
|
|
539
|
+
def stop(self) -> None:
|
|
540
|
+
pass
|
|
541
|
+
|
|
542
|
+
def close(self) -> None:
|
|
543
|
+
pass
|
|
544
|
+
|
|
545
|
+
backend = PortAudioBackend(dependency_loader=lambda: (FakeSd(), object()))
|
|
546
|
+
stream = backend.open_rx(
|
|
547
|
+
AudioDeviceId(0), sample_rate=48_000, channels=1, frame_ms=10
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
received: list[bytes] = []
|
|
551
|
+
await stream.start(received.append)
|
|
552
|
+
cb = captured_cb["cb"]
|
|
553
|
+
|
|
554
|
+
# 1000 samples in one block -> two 480-sample (960-byte) frames, 40 left.
|
|
555
|
+
block = b"\x01\x02" * 1000
|
|
556
|
+
cb(FakeIndata(block), 1000, None, None) # type: ignore[operator]
|
|
557
|
+
|
|
558
|
+
assert len(received) == 2
|
|
559
|
+
for frame in received:
|
|
560
|
+
assert len(frame) == 480 * 2 # 960 bytes / 10 ms each
|
|
561
|
+
|
|
562
|
+
await stream.stop()
|
|
563
|
+
|
|
371
564
|
def test_open_tx_returns_tx_stream(self) -> None:
|
|
372
565
|
class FakeSd:
|
|
373
566
|
class OutputStream:
|