Skip to content

๐ŸŽจ Palette: ํ–ฅ์ƒ๋œ ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด ์•„์ด์ฝ˜ ๋ฒ„ํŠผ์— ํˆดํŒ ๋ฐ aria-disabled ์ ์šฉ - #731

Draft
seonghobae wants to merge 62 commits into
developfrom
fix-score-buttons-13185195304078487658
Draft

seonghobae wants to merge 62 commits into
developfrom
fix-score-buttons-13185195304078487658

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Buyer-visible accessibility owner

์ด PR์€ Score ์ €์žฅ/ํ‘œ์‹œ์™€ PDF pagination์—์„œ unavailable action์„ keyboard/AT ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ์œ ์ง€ํ•˜๋ฉด์„œ activation์€ fail closedํ•˜๋Š” canonical Score accessibility lane์ž…๋‹ˆ๋‹ค.

Exact current identity

  • Protected base: develop@314ddeae7b775a4957594b599358c8255617eb2e
  • Branch: fix-score-buttons-13185195304078487658
  • Exact head: 36719ab3b805cc64ce6be70eea35cacb3ce6ad94
  • Open / Draft / mergeable
  • Fresh compare: ahead 61 / behind 0, merge base exactly protected develop, exactly 12 intended Score UI/test/locales/doctoring/CHANGELOG files

No force update, destructive rebase, self-approval, gate weakening, predecessor verdict transfer or source-neutral wake commit is used.

Ownership / dependency topology

#1145 is the canonical Tempo Stability + Score/PDF semantic-naming owner. It currently owns the scorePdfBytes, scoreTranslator, scoreAttachments, selectedScoreAttachment, scoreError, pdf.js adapter naming and temporal naming contract. #731 owns accessibility semantics and must not overwrite those identifiers when both lineages converge.

The two Drafts currently share ScoreView.tsx, ScoreView.test.tsx, ScoreViewer.tsx, and ScoreViewer.test.tsx while #1145 also owns non-overlapping pdf.js/temporal naming files. Therefore #731 is not merge-ready even if its own checks turn green: before landing, it requires an ordinary, non-force reconciliation/restack onto #1145 or a verified protected successor that preserves both semantic naming and the accessibility contracts below. Until that tree is verified, neither PR is treated as superseded and no overlapping source is closed or discarded.

Current product contract

  • Add/Open/Remove score actions remain keyboard-focusable when no active project exists, expose aria-disabled, associate localized recovery copy, and block desktop-bridge mutation.
  • Add score rejects repeated activation while an attachment operation is already pending.
  • PDF Previous/Next remain focusable at first/last-page boundaries. aria-describedby points to persistent localized screen-reader-only reason text while application code guards activation.
  • EN boundary reasons remain Already at the first page / Already at the last page; KO remains ์ฒซ ๋ฒˆ์งธ ํŽ˜์ด์ง€์ž…๋‹ˆ๋‹ค / ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€์ž…๋‹ˆ๋‹ค.
  • Zoom and pagination icon controls now use the shared Base UI-backed Tooltip component. Enabled page tooltips expose the action; unavailable page tooltips combine action + reason. Escape dismisses visual hover/focus content without deleting the persistent assistive description.
  • Native title is not used for the icon-only zoom/page tooltip path. Fit-width and ScoreView enabled action titles remain separate existing semantics.
  • Bridge failures do not expose dependency-controlled local paths or secret-shaped details.

This follows the repository's existing shared-tooltip + persistent aria-describedby pattern already used by Practice Progress rather than maintaining a second Score-specific tooltip state machine.

Shared-tooltip RED โ†’ fix

Fresh review found that this canonical lane still implemented its own tooltip visibility, pointer-hit-testing, geometry and Escape state even though a reusable Base UI-backed tooltip primitive exists. That duplicated UI interaction ownership and left #1233 preserving the reusable-component form in a parallel lane.

  • RED e89ba127b18ad9f372ce6796573df36cb372f561 requires a persistent assistive boundary reason while hover/focus content is supplied by the shared tooltip and can be dismissed independently.
  • Fix c26fbe4269ca46d9c56db02a30b259ec653e5289 removes Score-specific tooltip state/geometry, keeps aria-disabled + guarded activation + persistent aria-describedby reasons, and moves zoom/page icon hover/focus content to Tooltip / TooltipTrigger / TooltipContent.
  • Doctoring 36719ab3b805cc64ce6be70eea35cacb3ce6ad94 makes docs/doctoring/accessible-disabled-score-navigation.md code-current with this division of responsibility.

The previous WCAG 1.4.13 RED/fix lineage remains provenance for the requirements that motivated this consolidation, but its custom hover-geometry implementation is no longer duplicated in ScoreViewer.

Preservation / succession

#1233 exact 0995a5ee5093e0a613420cd2034870f56f1e1036 preserves shared Tooltip use plus focusable aria-disabled pagination guards. Its valid reusable-component delta is now adopted and strengthened here: this lane additionally retains reason-specific EN/KO copy and a persistent assistive description when the visual tooltip is dismissed. #1233 must remain open while this canonical lineage is unmerged; do not close it merely because the source delta is present here. Only protected integration of a verified successor may satisfy PR-0 for that preservation lane.

Earlier succession receipts for #1158, #1162, #1167, #1173, #1178 and #1182 remain valid; their checks/reviews/status do not transfer.

Evidence boundary

Current source contracts verify focusable unavailable controls, boundary activation guards, localized reasons, persistent assistive descriptions, shared-tooltip focus/hover behavior and Escape dismissal. The exact final head must obtain its own hosted CI/build/security/SAST/SBOM/CodeQL and qualifying independent non-author review evidence; predecessor heads do not transfer.

Exact 36719ab3... has fresh repository CI/build/security/SAST/SBOM/CodeQL generations. At the latest read, build matrix jobs had begun on hosted Windows/macOS runners while repository npm-lock-validation remained queued; none of those nonterminal states is treated as GREEN.

UI Delivery Gate

FAIL. Source/jsdom contracts are stronger and the duplicate tooltip implementation is removed, but current-head packaged browser/Electron pointer/touch/keyboard, 400% zoom/reflow, forced-colors, Narrator/VoiceOver and qualifying independent review evidence are still absent. JA/ZH/VI/ES/DE/FR localization and the versioned translation-ledger requirement also remain outside this Score slice.

Commercial / merge gate

Keep Draft until #1145-or-successor reconciliation is complete and one unchanged exact descendant has all applicable repository/central CI, build, security, SAST, dependency, coverage, SBOM and CodeQL gates terminal-success, zero valid unresolved findings, qualifying independent non-author last-push approval, and satisfiable protected-branch contract. Queued, pending, skipped-required, cancelled, failed, stale, predecessor/base, author/self or administrative-bypass evidence is non-passing.

@google-labs-jules

Copy link
Copy Markdown

๐Ÿ‘‹ Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a ๐Ÿ‘€ emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share

Comment @coderabbitai help to get the list of available commands.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 53ddb4c7452f96594cea0244cda853489fb934b0.

  • Head SHA: 53ddb4c7452f96594cea0244cda853489fb934b0

  • Workflow run: 30684374373

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 3

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (5 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (5 files)"]
  R1 --> V1["required checks"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: f34402ace5f894028f1f42b93623f7529b7b8584
  • Workflow run: 31800468013
  • Workflow attempt: 5
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head f34402ace5f894028f1f42b93623f7529b7b8584.

  • Head SHA: f34402ace5f894028f1f42b93623f7529b7b8584

  • Workflow run: 31800468013

  • Workflow attempt: 5

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (7 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (7 files)"]
  R1 --> V1["required checks"]
Loading

@seonghobae
seonghobae dismissed opencode-agent[bot]โ€™s stale review August 3, 2026 00:08

Dismissed after verifying the exact head SHA against the repository's CI, build-baseline, security, SAST, secret-scan, SBOM, Bandit, release, and security-audit workflows; all completed successfully. The automated coverage-evidence review does not identify a remaining code defect on this head.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
โœ… Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 00:10
@seonghobae
seonghobae marked this pull request as draft August 3, 2026 01:05
auto-merge was automatically disabled August 3, 2026 01:05

Pull request was converted to draft

@seonghobae
seonghobae marked this pull request as ready for review August 3, 2026 01:05
@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 02:07
@google-labs-jules

Copy link
Copy Markdown

@coderabbitai review

Acknowledged.

Comment thread .github/workflows/bootstrap-score-disabled-styles.yml Fixed

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head b12adcdc0c449d845d7d32ac4797a02c822e3653.

  • Head SHA: b12adcdc0c449d845d7d32ac4797a02c822e3653

  • Workflow run: 30822326101

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 3

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (6 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (6 files)"]
  R1 --> V1["required checks"]
Loading

@opencode-agent
opencode-agent Bot disabled auto-merge August 3, 2026 16:47
@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 03:31
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 04:38
@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 06:17
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 07:20
@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 07:58
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 10:11
@seonghobae
seonghobae dismissed opencode-agent[bot]โ€™s stale review August 4, 2026 11:01

Dismissed because the only requested change came from the superseded central coverage environment. Exact-head repository checks succeeded and the prior security workflow artifact was removed; a fresh independent current-head approval remains mandatory.

@seonghobae
seonghobae enabled auto-merge (squash) August 4, 2026 11:03

Copy link
Copy Markdown
Collaborator Author

@cwl-noema-review @opencode-agent Please independently review exact head b12adcdc0c449d845d7d32ac4797a02c822e3653. Exact-head repository CI, security, SBOM, release, and build checks succeeded; the obsolete bootstrap security finding is resolved. Verify focusable aria-disabled behavior, guarded activation, tooltip/accessibility names, visible project requirement association, and full measured desktop coverage; approve only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

Complete-succession update: autogenerated #1186 9e74949ad821fa33894eded99490f154e9839385 was inspected file-by-file and closed unmerged after verification that it adds no unique Score accessibility delta. Its five files only replace native pagination disabled with aria-disabled, add first/last-page aria-describedby + native title, add subset regressions, and add EN/KO wording variants. Exact #731 b2974a4ea2a2918ffc14392b12fba5c6ca89a58f already owns the same state under the stronger author-controlled tooltip contract: activation guard, reason-specific description only while unavailable, pointer/focus visibility, Escape dismissal/refocus restoration, WCAG 2.2 SC 1.4.13 hit/hover geometry, and focused regressions. #1186's ์ด๋ฏธ ... Korean wording is an alternative copy, not a new state/contract. No #1186 checks/reviews/status transfer; #731 source SHA is unchanged.

@opencode-agent

opencode-agent Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Scheduled review-feedback autofix for this PR head.

  • Head SHA: b2974a4ea2a2918ffc14392b12fba5c6ca89a58f

Copy link
Copy Markdown
Collaborator Author

Complete-succession receipt: Jules #1196 exact 713018a23362007825b8b8e11cbf029f96bc896d changed only ScoreViewer.tsx by adding native localized title attributes for Zoom Out/In, Fit Width, Previous and Next. Current #731 exact b2974a4ea2a2918ffc14392b12fba5c6ca89a58f already carries those valid enabled-state title semantics and is stronger at unavailable pagination boundaries through focusable aria-disabled, reason-specific aria-describedby/role="tooltip", activation suppression, hover/focus persistence and Escape dismissal. #1196 had no unique tests, fixtures, locale resources, contracts, or other changed files. It was closed unmerged after this verification; none of its checks/reviews transfer here.

Copy link
Copy Markdown
Collaborator Author

2026-09-10 overlap sweep: #1200 dd72585959a54054dad17d90767ba53f6791f6f9 was reviewed file-by-file against this canonical Score accessibility lane and closed unmerged after complete succession. #1200's unique changed-file set was only ScoreViewer.tsx, ScoreViewer.test.tsx, and EN/KO locale entries; its semantic delta was focusable aria-disabled pagination + first/last-page reasons exposed via native title. This lane already owns those reasons and a stricter authored-tooltip contract (aria-describedby + role="tooltip", keyboard focus, pointer hover, Escape dismissal/re-entry, activation guards, hoverable content without invisible hit interception), plus dedicated regression/doctoring. No #1200 checks/reviews/status transfer here. Keep #731 as the sole Score accessibility writer.

@google-labs-jules

Copy link
Copy Markdown

2026-09-10 overlap sweep: #1200 dd72585959a54054dad17d90767ba53f6791f6f9 was reviewed file-by-file against this canonical Score accessibility lane and closed unmerged after complete succession. #1200's unique changed-file set was only ScoreViewer.tsx, ScoreViewer.test.tsx, and EN/KO locale entries; its semantic delta was focusable aria-disabled pagination + first/last-page reasons exposed via native title. This lane already owns those reasons and a stricter authored-tooltip contract (aria-describedby + role="tooltip", keyboard focus, pointer hover, Escape dismissal/re-entry, activation guards, hoverable content without invisible hit interception), plus dedicated regression/doctoring. No #1200 checks/reviews/status transfer here. Keep #731 as the sole Score accessibility writer.

Acknowledged. I will continue to treat this PR (#731) as the sole canonical lane for Score accessibility and proceed without importing the #1200 changes, as the required functionality (focusable aria-disabled pagination and localized tooltips) is already implemented here under the stricter authored-tooltip contract.

Copy link
Copy Markdown
Collaborator Author

Succession receipt: new Jules PR #1201 exact 07d6194394b99184c26b873aeded4400e4ac44c0 was compared file-by-file against this canonical Score accessibility lane. Its valid Score delta (focusable aria-disabled Add/Open/Remove plus fail-closed activation and unavailable-state explanation) is already fully represented here, with stronger aria-describedby recovery semantics and focused bridge-blocking/reference-integrity regression. #1201's global shared-Button click wrapper is intentionally not adopted because it widens primitive behavior without a shared-primitive contract and is unnecessary for this Score-owned action boundary. No unique valid test/fixture/localization/doctoring/security delta remains; predecessor checks/reviews do not transfer.

@google-labs-jules

Copy link
Copy Markdown

Succession receipt: new Jules PR #1201 exact 07d6194394b99184c26b873aeded4400e4ac44c0 was compared file-by-file against this canonical Score accessibility lane. Its valid Score delta (focusable aria-disabled Add/Open/Remove plus fail-closed activation and unavailable-state explanation) is already fully represented here, with stronger aria-describedby recovery semantics and focused bridge-blocking/reference-integrity regression. #1201's global shared-Button click wrapper is intentionally not adopted because it widens primitive behavior without a shared-primitive contract and is unnecessary for this Score-owned action boundary. No unique valid test/fixture/localization/doctoring/security delta remains; predecessor checks/reviews do not transfer.

Acknowledged. I understand that the changes from PR #1201 are already fully covered here, and the shared-Button click wrapper is intentionally omitted. I will maintain this canonical Score accessibility lane without importing the #1201 changes.

@opencode-agent

Copy link
Copy Markdown
Contributor

Scheduled review-feedback autofix for this PR head.

  • Head SHA: b2974a4ea2a2918ffc14392b12fba5c6ca89a58f

@opencode-agent

Copy link
Copy Markdown
Contributor

Scheduled review-feedback autofix for this PR head.

  • Head SHA: b2974a4ea2a2918ffc14392b12fba5c6ca89a58f

@opencode-agent

Copy link
Copy Markdown
Contributor

Scheduled review-feedback autofix for this PR head.

  • Head SHA: b2974a4ea2a2918ffc14392b12fba5c6ca89a58f

Copy link
Copy Markdown
Collaborator Author

Fresh preservation receipt: #1233 was mutated after the previous adoption receipt. Intervening b367155eccd94c22f2ede80e024892e39bca1947 removed shared Tooltip usage and replaced focusable boundary aria-disabled controls with native disabled, weakening the preserved accessibility contract. #1233 has now been non-force repaired through ordinary descendant 1db8197ba1f8104760a60430eab991f635b32686, whose tree restores the exact preservation semantics from 0995a5ee... while retaining the intervening history. This does not change #731 ownership or transfer evidence; #731 remains the stronger canonical accessibility owner and still requires semantic reconciliation with #1145 before landing.

@google-labs-jules

Copy link
Copy Markdown

Fresh preservation receipt: #1233 was mutated after the previous adoption receipt. Intervening b367155eccd94c22f2ede80e024892e39bca1947 removed shared Tooltip usage and replaced focusable boundary aria-disabled controls with native disabled, weakening the preserved accessibility contract. #1233 has now been non-force repaired through ordinary descendant 1db8197ba1f8104760a60430eab991f635b32686, whose tree restores the exact preservation semantics from 0995a5ee... while retaining the intervening history. This does not change #731 ownership or transfer evidence; #731 remains the stronger canonical accessibility owner and still requires semantic reconciliation with #1145 before landing.

Acknowledged. I confirm that PR #731 remains the canonical owner of these Score accessibility improvements and that the temporary regressions in #1233 (since repaired) do not change our lane here. I will proceed with semantic reconciliation with #1145 as instructed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: accessibility Accessibility and assistive-technology support maintenance priority: medium Normal-priority or P2 work status: draft Draft pull request type: maintenance Maintenance, build, dependency, or operational upkeep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants