microphone-cli 0.8.0__tar.gz → 0.9.0__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.
- microphone_cli-0.9.0/.devague/current +1 -0
- microphone_cli-0.9.0/.devague/current_plan +1 -0
- microphone_cli-0.9.0/.devague/deliveries/microphone-domain.json +39 -0
- microphone_cli-0.9.0/.devague/frames/microphone-domain.json +1027 -0
- microphone_cli-0.9.0/.devague/plans/microphone-domain.json +682 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.gitignore +5 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/CHANGELOG.md +40 -0
- microphone_cli-0.9.0/CLAUDE.md +263 -0
- microphone_cli-0.9.0/PKG-INFO +239 -0
- microphone_cli-0.9.0/README.md +222 -0
- microphone_cli-0.9.0/docs/acceptance-microphone-domain.md +152 -0
- microphone_cli-0.9.0/docs/plans/2026-09-06-microphone-domain-split.md +183 -0
- microphone_cli-0.9.0/docs/plans/2026-09-06-microphone-domain.md +131 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/docs/skill-sources.md +2 -0
- microphone_cli-0.9.0/docs/specs/2026-09-06-microphone-domain.md +173 -0
- microphone_cli-0.9.0/docs/xvf3800-parameters.md +86 -0
- microphone_cli-0.9.0/microphone_cli/__init__.py +19 -0
- microphone_cli-0.9.0/microphone_cli/access.py +387 -0
- microphone_cli-0.9.0/microphone_cli/activation.py +266 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/__init__.py +58 -13
- microphone_cli-0.9.0/microphone_cli/cli/_commands/__init__.py +5 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/array.py +563 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/_commands/cli.py +5 -5
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/_commands/doctor.py +6 -3
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/_commands/explain.py +2 -2
- microphone_cli-0.9.0/microphone_cli/cli/_commands/gain.py +348 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/inspect.py +245 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/learn.py +307 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/list_devices.py +144 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/overview.py +178 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/param.py +367 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/record.py +743 -0
- microphone_cli-0.9.0/microphone_cli/cli/_commands/stream.py +820 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/_commands/whoami.py +4 -3
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/_errors.py +3 -1
- microphone_cli-0.9.0/microphone_cli/devices.py +530 -0
- microphone_cli-0.9.0/microphone_cli/engine.py +427 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/explain/__init__.py +1 -1
- microphone_cli-0.9.0/microphone_cli/explain/catalog.py +769 -0
- microphone_cli-0.9.0/microphone_cli/mixer.py +289 -0
- microphone_cli-0.9.0/microphone_cli/usbctl.py +273 -0
- microphone_cli-0.9.0/microphone_cli/xvf3800.py +554 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/pyproject.toml +1 -1
- microphone_cli-0.9.0/scripts/acceptance/blind-consumer.sh +77 -0
- microphone_cli-0.9.0/scripts/acceptance/run.sh +117 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/proc/asound/card0/pcm3p/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/proc/asound/card1/pcm0c/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/proc/asound/card1/pcm0p/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/proc/asound/card1/stream0 +19 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/proc/asound/cards +4 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/run/user/1000/pipewire-0 +0 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/class/sound/card0/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/class/sound/card1/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/idProduct +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/idVendor +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/manufacturer +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/product +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-baseline/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/serial +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/proc/asound/card0/pcm3p/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/proc/asound/card2/pcm0c/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/proc/asound/card2/pcm0p/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/proc/asound/card2/stream0 +19 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/proc/asound/cards +4 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/run/user/1000/pipewire-0 +0 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/class/sound/card0/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/class/sound/card2/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/idProduct +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/idVendor +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/manufacturer +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/product +1 -0
- microphone_cli-0.9.0/tests/fixtures/host-renumbered/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/serial +1 -0
- microphone_cli-0.9.0/tests/fixtures/respeaker/proc/asound/card0/pcm0c/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/respeaker/proc/asound/cards +2 -0
- microphone_cli-0.9.0/tests/fixtures/respeaker/sys/class/sound/card0/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/respeaker/sys/devices/platform/NVDA8000:01/usb3/3-1/idProduct +1 -0
- microphone_cli-0.9.0/tests/fixtures/respeaker/sys/devices/platform/NVDA8000:01/usb3/3-1/idVendor +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/proc/asound/card0/pcm0c/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/proc/asound/card0/stream0 +19 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/proc/asound/card1/pcm0c/info +11 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/proc/asound/card1/stream0 +19 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/proc/asound/cards +4 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/run/user/1000/pipewire-0 +0 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/class/sound/card0/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/class/sound/card1/id +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/idProduct +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/idVendor +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/manufacturer +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/product +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.1/serial +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/idProduct +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/idVendor +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/manufacturer +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/product +1 -0
- microphone_cli-0.9.0/tests/fixtures/two-arrays/sys/devices/platform/NVDA8000:02/usb5/5-1/5-1.3/serial +1 -0
- microphone_cli-0.9.0/tests/test_access.py +255 -0
- microphone_cli-0.9.0/tests/test_activation.py +361 -0
- microphone_cli-0.9.0/tests/test_array.py +585 -0
- microphone_cli-0.9.0/tests/test_cli.py +363 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/tests/test_cli_introspection.py +5 -5
- microphone_cli-0.9.0/tests/test_devices.py +215 -0
- microphone_cli-0.9.0/tests/test_engine.py +425 -0
- microphone_cli-0.9.0/tests/test_gain.py +480 -0
- microphone_cli-0.9.0/tests/test_inspect.py +246 -0
- microphone_cli-0.9.0/tests/test_list.py +117 -0
- microphone_cli-0.9.0/tests/test_param.py +428 -0
- microphone_cli-0.9.0/tests/test_record.py +589 -0
- microphone_cli-0.9.0/tests/test_repo_hygiene.py +47 -0
- microphone_cli-0.9.0/tests/test_stream.py +511 -0
- microphone_cli-0.9.0/tests/test_usbctl.py +215 -0
- microphone_cli-0.9.0/tests/test_xvf3800.py +396 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/uv.lock +31 -31
- microphone_cli-0.8.0/CLAUDE.md +0 -28
- microphone_cli-0.8.0/PKG-INFO +0 -76
- microphone_cli-0.8.0/README.md +0 -59
- microphone_cli-0.8.0/microphone_cli/__init__.py +0 -13
- microphone_cli-0.8.0/microphone_cli/cli/_commands/__init__.py +0 -1
- microphone_cli-0.8.0/microphone_cli/cli/_commands/learn.py +0 -88
- microphone_cli-0.8.0/microphone_cli/cli/_commands/overview.py +0 -112
- microphone_cli-0.8.0/microphone_cli/explain/catalog.py +0 -130
- microphone_cli-0.8.0/tests/test_cli.py +0 -115
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/agent-config/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/ask-colleague/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/ask-colleague/prompts/review.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/ask-colleague/prompts/write.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/challenge/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/challenge/scripts/challenge.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/cicd/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/deviate/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/deviate/scripts/deviate.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/recall/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/recall/scripts/recall.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/remember/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/remember/scripts/remember.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/scope/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/scope/scripts/scope.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/summarize-delivery/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/summarize-delivery/scripts/summarize-delivery.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/think/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/think/scripts/think.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/validate-delivery/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/validate-delivery/scripts/validate-delivery.sh +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.claude/skills.local.yaml.example +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.flake8 +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.github/workflows/publish.yml +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.github/workflows/tests.yml +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/.markdownlint-cli2.yaml +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/AGENTS.colleague.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/LICENSE +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/culture.yaml +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/docs/steward/steward-suggestions.md +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/__main__.py +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/microphone_cli/cli/_output.py +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/sonar-project.properties +0 -0
- {microphone_cli-0.8.0 → microphone_cli-0.9.0}/tests/__init__.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
microphone-domain
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
microphone-domain
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plan_slug": "microphone-domain",
|
|
3
|
+
"schema_version": 2,
|
|
4
|
+
"created": "2026-09-06T19:58:21Z",
|
|
5
|
+
"updated": "2026-09-06T20:07:24Z",
|
|
6
|
+
"deviations": [
|
|
7
|
+
{
|
|
8
|
+
"id": "d1",
|
|
9
|
+
"what": "Wave-4 acceptance target is a Seeed ReSpeaker XVF3800 (XIAO variant) on the dev host, id 2886:001a serial 114993702263100642, reflashed from I2S to USB firmware v2.1.0 via dfu-util, instead of the Reachy Mini Lite (38fb:1001) the plan named; the Reachy Mini's array is on its own Pi at 192.168.1.162 and was never reachable from this host",
|
|
10
|
+
"task_ref": "t13",
|
|
11
|
+
"reason": "the connected robot's USB-C is a host port (Reachy Mini, not Lite); the user chose to bring up a separate ReSpeaker board and asked for the firmware update; issue #4 tracks CLI support for the DFU path",
|
|
12
|
+
"affects": [
|
|
13
|
+
"t13"
|
|
14
|
+
],
|
|
15
|
+
"origin": "llm",
|
|
16
|
+
"status": "approved",
|
|
17
|
+
"classification": "acceptable",
|
|
18
|
+
"seq": 1
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "d2",
|
|
22
|
+
"what": "Seeed's USB firmware v2.1.0 on the 2886:001a board does not implement DOA_VALUE_RADIANS (resid 20 cmd 19) and its DOA_VALUE (20/18) is two uint16 values (degrees 0-359, speech flag), not two uint32; 'array doa' fails with firmware status 66 while every other probed parameter (VERSION, BLD_*, AEC_*, AUDIO_MGR_MIC_GAIN, LED/GPO) reads correctly through the stdlib usbdevfs path",
|
|
23
|
+
"task_ref": "t13",
|
|
24
|
+
"reason": "the vendored PARAMETERS table is reachy_mini's 38fb:1001 map; the spec parked this exact unknown (v4) and hardware now answers it: the map is firmware-specific. Needs a uint16 type and a per-firmware DoA source before array doa can pass acceptance on this board",
|
|
25
|
+
"affects": [
|
|
26
|
+
"t13",
|
|
27
|
+
"t7",
|
|
28
|
+
"t3"
|
|
29
|
+
],
|
|
30
|
+
"origin": "llm",
|
|
31
|
+
"status": "approved",
|
|
32
|
+
"classification": "needs-follow-up",
|
|
33
|
+
"seq": 2
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"evidence": [],
|
|
37
|
+
"deltas": [],
|
|
38
|
+
"supersessions": []
|
|
39
|
+
}
|