Skip to content

refactor(avatar): simpler hand picker and home hamburger (TASK-22142) - #3047

Merged
jjramirezn merged 15 commits into
devfrom
review/22142-avatar-hand-rebased
Sep 8, 2026
Merged

jjramirezn merged 15 commits into
devfrom
review/22142-avatar-hand-rebased

Conversation

@0xkkonrad

@0xkkonrad 0xkkonrad commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The avatar picker shows eight tiles and a die in three columns. The first tile saves the user's initial. The other seven keep the current pick, include earned art when available, and draw from basics and unlocked badge avatars. Each art path appears once. Tapping saves immediately; rolling changes the hand without changing the pick.

The self profile places a 64px avatar button above the 40px share pill. Tapping the handle copies the profile link; tapping the share glyph opens sharing. Home uses the earlier 40px hamburger button to open /profile.

Copy includes names and lines for the twenty basics in English, Latin American Spanish and Brazilian Portuguese, plus three Argentine overrides. Counterparty and public-profile avatar behavior is unchanged.

Task: TASK-22142 — Build badge-linked avatar system v2. Rebased replacement for #3014, which superseded #2989. GitHub blocks force-pushes to the original branch, so the rebased history is published here.

Rebase and review

Rebased onto dev at 7b5b2ded3. Konrad chose to retain this eight-tile hand and hamburger button when resolving the conflict with dev's newer animated picker. Its unused animation, styles, deal helpers and tests are removed. Dev's sequential badge/avatar toasts and current toast border styling are preserved.

Three independent subagent reviews covered picker simplicity, component structure/comments, and behavior. The follow-up removes a redundant deal ref, replaces HomeTopNav's static class merge with its final classes, and trims stale or repetitive comments. Comments now explain constraints such as clipboard activation and separate copy/share hit areas.

The behavior review reproduced a failed-save edge: rolling while a save was pending could omit the saved avatar, leaving nothing checked after rejection. The picker now restores an eligible saved sticker to the hand. Regression tests cover that rollback and verify that successful saves keep the dealt hand. The queued-save review fix records the latest successful server key before storing an initial fallback. Regression tests cover API rejection and network failure after a successful sticker save, including reopening from local storage. Earned-tile badge names now use the existing localized badge-copy helper, matching the other badge surfaces; regression cases cover Spanish and Portuguese captions.

Behavior and accepted choices

  • The badge-earned link includes the newest badge with avatar art. Its art appears on the first deal, including a cold load before auth resolves. Closing consumes the badge hint.
  • Several different avatars from one badge may appear together. Deduplication is by art path; there is no per-badge cap.
  • Selected tiles use a 2px border and no shadow. The avatar button and share pill both have the design-system press treatment.
  • Names and descriptions occupy two lines so the grid remains even at 320px. The radio group excludes the roll button; arrow navigation wraps within columns.
  • The 16px share glyph has a 44px hit area. Its 16px gap exceeds the 14px hit-area extension so it does not overlap the copy segment.
  • The dashed roll border, custom Earned badge, verified-check green, and display: contents radio grouping retain the original design choices. On iOS 15.0–15.4, grouping announcements remain a known limitation.

Validation

Local: 512 suites pass (6,596 tests passed, 6 skipped); TypeScript, repository formatting and changed-file ESLint pass. All 57 avatar tests pass. Four new regressions reproduced the save-order fallback and untranslated earned-badge names before their fixes, and pass afterward. They cover API rejection, network failure, persistence after remount, and real Spanish/Portuguese catalogs.

All CI jobs pass at ae814c784, including web/native builds, screenshots and browser regression specs. Chip's current-head review reports no actionable defects and confirms both prior findings fixed; both threads are resolved. The local web build worker was terminated with SIGTERM without a compile diagnostic; CI verified both builds. Deployed-preview browser checks also confirm localized earned captions, eight tiles and loaded avatar art in es-419 and pt-BR at 320px, shown below.

Manual checks: open /profile, select the initial, roll several times, reopen the picker, and follow a badge-earned avatar link. Verify copy/share actions separately and confirm that the home hamburger opens /profile. Native shell and real iOS Safari require a device pass before release.

Screenshots

Fresh captures from the deployed preview at b0540c6e0. Verified at 320px; the full picker is also shown at 430px. All eight avatar images load, and the home hamburger links to /profile.

Picker at 320px Profile at 320px Home at 320px

Open the deployed picker preview. The pr-assets-3047 branch is removed when this PR closes by pr-assets-cleanup.yml.

Localized earned-badge captions verified on the deployed ae814c784 preview at 320px. Both screens retain all eight avatar tiles and load all avatar art. These captions use the existing badge translations.

Spanish (es-419) Portuguese (pt-BR)

Release considerations and follow-ups

Letter picks retain the device-local fallback for APIs that reject letter.<a-z>. The API's letter-key support is already on dev; verify that the production API release carries it before relying on durable cross-device letter picks. Basic and badge picks require no API change.

Existing code follow-ups remain separate: share the NavHeader circle recipe, repoint or remove the home-avatar fixture, remove the test-only avatarPool helper, and correct UserHeader's old home-sticker comment.

Mono documentation follow-ups remain separate from this code PR: update avatar component guidance and mapping in design/design.md, record the dashed-border and split-pill choices there, and explain badge avatar unlocks in product/support-answers/rewards-points-badges.md. The new clipboard analytics event sends only existing attribution categories; it does not send the copied URL. No privacy-document change was identified.

…er (TASK-22142)

The shipped picker stacked a title, three section headings and an Initials
group over five-column rows, and its successor was blocked for the yellow
bordered, shadowed tiles. This is the hand from the final mockup: eight dealt
tiles plus the die, slot 1 the user's initial as a real letter pick, at least
one earned card when any badge is held, no two tiles sharing an art file, and
every character named under its sticker. A selected tile carries a 2px edge and
no shadow; an earned tile carries the Earned badge and no coloured border.
Rolling re-deals and never touches the pick. The earn toast can point the first
hand at a badge. Adds the dice and menu icons to the registry.
…opy and share (TASK-22142)

The avatar inside the pill made the pill twice the height of any button in the
system and pushed the whole header off the design system. The avatar goes back
above, as a bordered round button that opens the picker, and the pill keeps its
shipped 40px chrome with two hit areas: the handle copies the profile link and
says so, the icon shares as before. The verified check shows once, in the name
row when there is one, else in the pill.
…inks the picker to its badge (TASK-22142)

Nobody read the avatar chip as the door to the whole menu. A 40px round menu
button, the nav circle recipe, replaces it with the same label and route. The
toast's "Choose avatar" now carries the badge code so the first hand shows that
badge's card.
…he copy-link label; drop the header and group keys (TASK-22142)

Twenty basics get a name and a line in en, es-419 and pt-BR, with three
Argentine overrides in es-AR. The keys that only the old header and groups
rendered are gone.
…-22142)

The hand-drawn 36px die put a radius and six-pixel pips outside the spacing
and radius scales and tripped the DS ratchet. The roll tile now shows the
single five-pip die icon at 24, the one size the icon scale allows here, and
keeps its dashed edge, white fill, label and one-turn spin.
…nk clears on close (TASK-22142)

A button that is not a radio cannot be a direct child of a radiogroup; the
group now wraps the eight tiles only and the die is its sibling in the grid.
The badge parameter from the earn toast used to outlive the first open, so
every later hand kept preferring that badge; closing the drawer clears it.
…d control (TASK-22142)

The framed avatar carried the hard shadow without the press that goes with
it, and the split pill had lost the press the shipped pill shows. The avatar
is the stroke Button now, so its press is the Button's own; the pill frame
presses as one surface on either segment, the shipped pill's values. The
share glyph is the pill's trailing 16px icon again, not a 32px box, with the
44px hit area kept.
…ASK-22142)

A Link around a Button is two tab stops and nested interactive content. The
link now carries the stroke button recipe itself, same circle, icon, label,
hit area and press, with one focus stop and the honest role for a control
that navigates.
…, names that survive 320px (TASK-22142)

A deep link from the earn toast opened the picker before the user had
loaded, so the hand dealt with no badges and an empty initial; the deal now
waits for the user and happens once per open. The focus ring was clipped by
the scroll box on the first and last rows. Sixteen-character names truncated
to eleven on a 320px screen; names wrap to two lines like their line, with a
fixed box so every tile keeps the same height.
…off the handle (TASK-22142)

Both from Chip's review of 340d8ac.

Most badges ship no avatar art, so a coalesced earn toast can pair a newest
badge with none and an older one with three. The link named the newest, and
`prefer` on a code with no art falls back to any avatar already held — so the
user tapped through to a hand holding none of what was just unlocked. Name the
newest code that has art instead.

The share glyph reaches 44px through a 14px `after:` inset, but sat 4px from
the handle, so the last ~10px of the url opened sharing instead of copying.
16px of margin puts the two hit areas side by side with nothing shared, and
stays on the spacing scale.
…SK-22142)

From Chip's review of 0bf49bd. The pill is 40px and the handle was `h-full`,
so the 2px strip above and below it did nothing while the share glyph beside it
already answered there. It grows through the same `after:` pseudo-element —
vertically only, so the two hit areas stay disjoint.
Keep the eight-tile hand and home menu after the competing dice flow landed on dev. Remove its unused components and preserve the sequential badge toasts and current toast styling.

Remove the redundant deal latch, trim historical comments, and restore a saved sticker after a failed save that followed a roll. Cover rollback and successful-save stability with regression tests.
@notion-workspace

Copy link
Copy Markdown

@vercel

vercel Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
peanut-wallet Ready Ready Preview Sep 8, 2026 5:10pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 6374f142-d8c5-41e3-bd29-63fa0ba50090

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 7299.02 → 7296.81 (-2.21)
Findings: -2 net (+31 new, -33 resolved)

🆕 New findings (31)

  • critical complexity — src/components/Global/Icons/Icon.tsx — CC 93, MI 73.1, SLOC 289
  • critical complexity — src/components/Avatar/AvatarPicker.tsx — CC 50, MI 58.61, SLOC 191
  • critical complexity — src/constants/analytics.consts.ts — CC 1, MI 29.95, SLOC 223
  • high hotspot — src/constants/analytics.consts.ts — 70 commits, +487/-29 lines since 6 months ago
  • high complexity — src/components/Avatar/avatar.utils.ts — CC 44, MI 64.74, SLOC 110
  • medium high-mdd — src/components/Avatar/AvatarPicker.tsx:30 — AvatarPicker: MDD 49.7 (uses across many lines from declarations)
  • medium high-mdd — src/components/Badges/BadgeEarnToast.tsx:41 — BadgeEarnToast: MDD 47.5 (uses across many lines from declarations)
  • medium high-dlt — src/components/Avatar/AvatarPicker.tsx:30 — AvatarPicker: DLT 44 (calls 44 distinct functions — high context load)
  • medium high-mdd — src/components/Profile/components/ProfileHeader.tsx:35 — ProfileHeader: MDD 41.2 (uses across many lines from declarations)
  • medium high-mdd — src/app/(mobile-ui)/dev/ds/foundations/icons/page.tsx:90 — IconsPage: MDD 31.7 (uses across many lines from declarations)
  • medium high-mdd — src/components/Badges/BadgeEarnToast.tsx:58 — : MDD 24.0 (uses across many lines from declarations)
  • medium complexity — src/components/Badges/BadgeEarnToast.tsx — CC 23, MI 61.48, SLOC 133
  • medium complexity — src/components/Profile/components/ProfileHeader.tsx — CC 19, MI 59.61, SLOC 64
  • medium complexity — src/components/Avatar/avatarPicker.utils.ts — CC 8, MI 59.97, SLOC 31
  • medium complexity — src/features/home/useHomeFlow.ts — CC 7, MI 60.48, SLOC 60
  • medium complexity — src/features/home/HomePage.tsx — CC 4, MI 64.79, SLOC 17
  • medium nextjs-raw-img — src/app/(mobile-ui)/dev/ds/foundations/icons/page.tsx:173 — Use next/image
  • medium react-effect-derives-state — src/components/Avatar/AvatarPicker.tsx:106 — small useEffect that only sets state from deps
  • low high-dlt — src/components/Badges/BadgeEarnToast.tsx:41 — BadgeEarnToast: DLT 29 (calls 29 distinct functions — high context load)
  • low high-dlt — src/components/Profile/components/ProfileHeader.tsx:35 — ProfileHeader: DLT 19 (calls 19 distinct functions — high context load)

…and 11 more.

✅ Resolved (33)

  • src/components/Global/Icons/Icon.tsx — CC 91, MI 73.05, SLOC 283
  • src/components/Avatar/AvatarPicker.tsx — CC 52, MI 59.03, SLOC 181
  • src/constants/analytics.consts.ts — CC 1, MI 30, SLOC 222
  • src/constants/analytics.consts.ts — 69 commits, +482/-28 lines since 6 months ago
  • src/components/Avatar/avatar.utils.ts — CC 45, MI 64.42, SLOC 129
  • src/components/Badges/BadgeEarnToast.tsx:41 — BadgeEarnToast: MDD 51.3 (uses across many lines from declarations)
  • src/components/Avatar/AvatarPicker.tsx:23 — AvatarPicker: MDD 50.0 (uses across many lines from declarations)
  • src/components/Avatar/AvatarPicker.tsx:23 — AvatarPicker: DLT 42 (calls 42 distinct functions — high context load)
  • src/components/Profile/components/ProfileHeader.tsx:29 — ProfileHeader: MDD 35.8 (uses across many lines from declarations)
  • src/app/(mobile-ui)/dev/ds/foundations/icons/page.tsx:88 — IconsPage: MDD 31.7 (uses across many lines from declarations)
  • src/components/Badges/BadgeEarnToast.tsx:58 — : MDD 26.7 (uses across many lines from declarations)
  • src/components/Badges/BadgeEarnToast.tsx — CC 22, MI 61.23, SLOC 127
  • src/features/home/views/HomeTopNav.tsx:21 — HomeTopNav: MDD 20.0 (uses across many lines from declarations)
  • src/components/Avatar/AvatarPicker.tsx:23 — AvatarPicker CC 17 SLOC 90
  • src/components/Profile/components/ProfileHeader.tsx — CC 14, MI 59.33, SLOC 42
  • src/features/home/useHomeFlow.ts — CC 7, MI 59.72, SLOC 63
  • src/components/Avatar/avatarPicker.utils.ts — CC 4, MI 63.56, SLOC 17
  • src/features/home/HomePage.tsx — CC 4, MI 63.89, SLOC 18
  • src/app/(mobile-ui)/dev/ds/foundations/icons/page.tsx:171 — Use next/image
  • src/components/Avatar/DiceRoll.tsx:17 — useEffect with empty deps + setState — derived state anti-pattern

…and 13 more.

📈 Painscore deltas (top movers)

File Before After Δ
src/components/Avatar/AvatarPicker.tsx 7.7 9.1 +1.3
src/components/Avatar/avatar.consts.ts 2.0 3.0 +1.0
src/components/Avatar/DiceRoll.tsx 5.7 0.0 -5.7

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • ✅ unit: 6619 ran, 0 failed, 0 skipped, 1.7m

📊 Coverage (unit)

metric %
statements 76.3%
branches 62.6%
functions 70.4%
lines 77.2%
⏱ 10 slowest test cases
time test
🐢 9.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Network failure keeps loading while retries remain, then shows the generic error
4.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › routes the KYC rejection on its wire code, and does not retry it
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_USER_NOT_PROVISIONED fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_RECENT_REFUND fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › User KYC not approved fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_SOURCE_OVER_MONTHLY_CAP fails fast with copy that names the real cause
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › a refused idempotency key tells the user to scan again, not to contact support
4.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › MANTECA_MERCHANT_VOLUME_NEAR_CAP fails fast with copy that names the real cause
3.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Scan that recovers on the retry lands on the payment screen, not an error
3.0s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Going offline blames the connection, and reconnecting clears it for the recovered scan
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

🖼 Visual diff — 12 screens moved

21 of 68 shots changed · 47 identical · baseline 7b5b2de → head ae814c7

worst % screen widths
42.10% avatar-picker 320, 430
10.70% long-full-name 320, 430
10.46% hugo-long-username 320, 430
9.45% profile 320, 430
6.09% home-avatar 320, 430
5.93% home 320, 430
2.35% empty-home 320, 430
0.99% reconsent 320, 430
0.07% add-money 320, 430
0.07% badges 320
0.07% limits 320
0.03% empty-accounts 430

job summary · before/after/diff images — artifact

Fixture screenshots, no backend. Advisory — this check never blocks a merge. Posted from the default branch by ds-shots-comment.yml; the report it renders is untrusted data.

@chip-peanut-bot chip-peanut-bot 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.

Chip review — no blocking findings — this is not an approval

One minor mixed-result avatar-save edge remains; the rest of the reviewed avatar, profile, badge-toast, home-nav, localization, and accessibility changes are coherent, and exact-head CI is green.

Findings

  • MINOR · src/components/Avatar/AvatarPicker.tsx:80 · A queued letter fallback is stamped against a stale server key
    Start with server avatar A, tap sticker B, then tap the initial before B settles, and let the letter request fail (the documented older-API or network fallback). B commits first, but this line records the letter mirror against render-stale A; the final refetch returns B, so useAvatarKey rejects the mirror and the UI lands on B even though the initial was the last tap. Track the latest successfully committed key through the drain and stamp the fallback against that value, with a success-then-letter-failure queue test.

Checked clean

  • Exact checkout, merge base, trusted PR metadata, and exact-head checks; aggregate CI, unit, typecheck, native export, design-system lint, and screenshot comparison completed successfully.
  • Avatar hand construction, art deduplication, preferred-badge deep link, cold-auth redeal, rolling, keyboard roving, serialized saves, and failed-save hand restoration.
  • Self versus counterparty profile rendering, copy/share hit-area split and analytics payload, plus the Home profile-menu route and haptic wiring.
  • Sibling API /update-user authorization, avatar-key shape, unlock validation, and letter-key compatibility contract.
  • Locale catalog coverage and cleanup of removed dice animation, CSS, and avatar helper references.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion by claude-opus: 0 finding(s), marked with the model name. It answers only product truth, missing tests and the cross-repo contract, so treat its findings as advice.

Exact head: b0540c6e0081 · Context: repo, api · Took 15m

Comment thread src/components/Avatar/AvatarPicker.tsx Outdated

@chip-peanut-bot chip-peanut-bot 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.

Chip review — no blocking findings — this is not an approval

The queued-letter fallback defect is fixed and exact-head CI is green. One minor localization defect remains in earned-avatar tiles.

Findings

  • MINOR · src/components/Avatar/AvatarPicker.tsx:124 · Badge tiles bypass localized badge copy
    In es-419 and pt-BR, earned tiles reach this branch and print the backend badge name verbatim. For example, BUG_WHISPERER renders Bug Whisperer beside otherwise localized picker copy even though badges.catalog.BUG_WHISPERER.name already provides Cazador de bugs and Caçador de bugs, and the existing badge surfaces resolve those strings through useBadgeCopy. Build this lookup from useBadgeCopy instead of the raw API name so the new picker does not mix languages.

Checked clean

  • P1 is fixed: each successful queued write advances the in-drain server key before a rejected or network-failed letter fallback is stored, with persistence-after-remount regression coverage.
  • Avatar hand composition, art-path deduplication, current-pick restoration, serialized save ordering, badge-hint consumption, and arrow-key roving.
  • Profile avatar, copy/share pill controls, and home profile-menu navigation.
  • Badge-earned toast routing and locale JSON structure.
  • Security pass found no new authorization, secret, credential, money, or unsafe-workflow surface.
  • All exact-head CI check runs completed successfully or were intentionally skipped, including unit, eslint, typecheck, format, native-export, analyze, ds-shots, and preview.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion by claude-opus: 0 finding(s), marked with the model name. It answers only product truth, missing tests and the cross-repo contract, so treat its findings as advice.

Exact head: 07498f7b2436 · Context: repo · Took 19m

Comment thread src/components/Avatar/AvatarPicker.tsx

@chip-peanut-bot chip-peanut-bot 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.

Chip review — no blocking findings — this is not an approval

No actionable defects. Both supplied prior findings are fixed, and exact-head CI is green.

Checked clean

  • P1: queued letter fallbacks now record the last successful server key, with API-rejection and network-failure remount coverage.
  • P2: earned badge tiles now resolve badge names through useBadgeCopy, with es-419 and pt-BR regression coverage.
  • Avatar hand dealing, save serialization, roll/save rollback, badge deep links, keyboard navigation, and letter fallback persistence.
  • Profile avatar and copy/share controls, Home menu navigation, shared Card/icon changes, and locale catalog updates.
  • Exact-head CI completed green, including ci-success, unit, typecheck, eslint, format, ds-lint, ds-shots, native-export, analyze, and preview checks.
  • Local Jest and TypeScript binaries were unavailable in the detached worktree; exact-head CI supplied those gates.

Security review: did not run — this change has no security, privacy or money surface, so it was not asked. This review is one reviewer short.

Third opinion by claude-opus: 0 finding(s), marked with the model name. It answers only product truth, missing tests and the cross-repo contract, so treat its findings as advice.

Exact head: ae814c784354 · Context: repo · Took 19m

@jjramirezn
jjramirezn merged commit cfef3c5 into dev Sep 8, 2026
26 of 27 checks passed

This branch was successfully deployed

1 active deployment
Preview — ae814c78 Deployed Sep 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants