diff --git a/CLAUDE.md b/CLAUDE.md
index 43123a0..229637b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -157,7 +157,8 @@ Use a zod discriminated union on `finale.type`.
- `photo`: polaroid frame; body text is the photo description in italics (no image assets needed)
- `map` / `diagram`: monospace block, preserve whitespace, grid tables
- `signal`: animated blinking light driven by `signal` field (see §6.3)
-- Clues from **previous** chapters stay accessible in an "Evidence Locker" drawer.
+- Clues from **previous** chapters stay accessible in an "Evidence Locker" drawer. The locker searches clue titles and bodies (client-side, own clues only), filters by chapter, and lets each player star clues (`clue:pin`). The partner only ever gets the **count** of stars, never which clues.
+- Clue text uses `Noto Sans Symbols 2` as a fallback (Braille, alchemy symbols). Code fences (stencil grids, box-drawing keypads, SQL) are monospace at `line-height: 1.15`; wide tables and blocks scroll inside their card, never the page.
### Other engines
See each YAML for its schema. Summaries in §6.
@@ -179,8 +180,8 @@ See each YAML for its schema. Summaries in §6.
- Chapter view: narrative on top → my clues → lock panel → key ring.
- Correct answer → both players see the lock spring open (animation), `successText` reveals, the key flies onto the key ring, **Continue** button (either player can press) advances both.
- **Hints:** either player can request; tiers unlock in order; both players see revealed hints. Each hint adds **+2:00** penalty (or the game's `rules.hintPenaltySeconds`). Confirm dialog before revealing tier 3 ("This basically solves it. Sure?").
-- **Time limit:** games with `rules.timeLimitMinutes` show a countdown instead of a stopwatch. When elapsed + penalty time passes the limit, the server ends the game with `failEnding` (plus `reveal` for an accusation).
-- **Finale:** when all chapter keys are collected, the finale opens. For `accusation`, both players must agree: Player A proposes answers, Player B sees them and taps **Agree** or **Change**. Submit only when both agree. Wrong submission shows "Not quite. N attempts left" without revealing which part was wrong. After `maxAttempts`, show `failEnding` + `reveal`.
+- **Time limit:** games with `rules.timeLimitMinutes` show a countdown instead of a stopwatch. When elapsed + penalty time passes the limit, the server ends the game with `failEnding` (plus `reveal` for an accusation) and the results page shows **Out of time** instead of a rank. A `timeLimitLabel` containing "water" (Deep Lab Nereid) also draws the countdown as water rising behind the header (no wave with `prefers-reduced-motion`).
+- **Finale:** when all chapter keys are collected, the finale opens. For `accusation`, both players must agree: Player A proposes answers, Player B sees them and taps **Agree** or **Change**. Submit only when both agree. Wrong submission shows "Not quite. N attempts left" without revealing which part was wrong. After `maxAttempts`, show `failEnding` + `reveal`. Any number of questions works. On the last attempt (always, with `maxAttempts: 1`) submitting asks "One shot. Are you both sure?" first.
- For `escape` finales, it's just the last lock; on success show `successEnding`.
### 6.2 Defuse engine (game 6). See `tick-tock-together.yaml`
@@ -201,8 +202,8 @@ See each YAML for its schema. Summaries in §6.
- `predict` rounds: the `subject` role answers about themselves, the other guesses. Match = point.
- 3+ points in a round = key. Failing a round lets them replay it once with fresh questions.
- Draw questions randomly from the bank, never repeating within a session. (When a `predict` bank is too small for that, a question may come back once, asked about the other partner.)
-- `telepathy` rounds (Deep Cuts): no options, both type one word. Same word = point; case, spaces, punctuation and a trailing S are ignored.
-- `rank` rounds (Deep Cuts): the subject (cycled through `subjectPattern`) orders four items, the partner predicts. Point only if **both** the top and the bottom match.
+- `telepathy` rounds (Deep Cuts): no options, both type one word (max 30 characters). Same word = point; case, spaces, punctuation and a trailing S are ignored.
+- `rank` rounds (Deep Cuts): the subject (cycled through `subjectPattern`) orders four items (drag, or up/down buttons), the partner predicts. Point only if **both** the top and the bottom match; the reveal highlights both.
- A round can set its own `pointsForKey`.
### 6.5 Labyrinth engine (game 8). See `labyrinth-of-lanterns.yaml`
@@ -220,10 +221,10 @@ See each YAML for its schema. Summaries in §6.
Client → server:
`room:create {gameId}`, `room:join {code, playerToken?}`, `room:pickRole {role}`, `room:ready`,
-`lock:submit {lockId, value}`, `hint:request {lockId}`, `chapter:continue`,
+`lock:submit {lockId, value}`, `hint:request {lockId}`, `clue:pin {clueId}`, `chapter:continue`,
`finale:propose {answers}`, `finale:agree`, `finale:submit`,
`defuse:action {moduleId, action}`, `sync:answer {questionId, optionId | text | order}`,
-`maze:move {dir}` (`n/e/s/w`, or `f/l/r/b` with a relative compass), `notepad:update {text}`, `ping {emoji}`
+`maze:move {dir}` (`n/e/s/w`, or `f/l/r/b` / `forward/left/right/back` with a relative compass), `notepad:update {text}`, `ping {emoji}`
Server → client:
`room:state` (full sanitized per-role state, sent on every change), `lock:result {lockId, correct}`,
@@ -234,14 +235,15 @@ Keep it simple: after any mutation, broadcast a fresh per-role `room:state` to e
## 8. Scoring & results
- `finalTime = elapsed + penaltySeconds`
-- Rank badges: **Soulmate Sleuths** (no hints, under estimate) / **Dream Team** / **Getting There** / **Love Is Patient** 😅
+- Rank badges: **Soulmate Sleuths** (no hints, under estimate) / **Dream Team** / **Getting There** / **Love Is Patient** 😅 / **Out of time** (a time limit ran out)
+- **Nightmare Survivors ☠️**: a difficulty-5 game finished with zero hints. Shown on the results page and, once earned, on that game's library card.
- Results page: time, hints used, keys earned, wrong guesses, plus a "Play another" carousel. Store best results per game in localStorage.
## 9. Design direction
- Vibe: **date-night cozy meets noir**. Dark mode default, warm candlelit accents, per-game theme from YAML `theme`.
- Fonts: Playfair Display / Inter / Caveat (handwritten notes) / JetBrains Mono (logs, maps) from Google Fonts.
-- Home page: hero "Two players. One mystery. Every key needs both of you." + game library grid (cards show category chip, time, difficulty 🔑 out of 5).
+- Home page: hero "Two players. One mystery. Every key needs both of you." + game library grid (cards show category chip, time, difficulty 🔑 out of 5; difficulty 5 adds a **☠️ Nightmare** chip). Difficulty: 1 Easy · 2 Medium · 3 Hard · 4 Expert · 5 Nightmare. The library sorts easiest first and filters by category and difficulty.
- **Mobile-first.** Most couples will play on two phones. Clue cards stack vertically; lock panel is sticky at the bottom; evidence locker is a bottom sheet.
- Accessibility: all locks keyboard-operable, `prefers-reduced-motion` respected, colorblind-safe (defuse wires also show their color name as text label).
- Role color-coding: A = warm (amber), B = cool (teal), shown as a badge on every clue card ("Only you can see this").
@@ -250,10 +252,10 @@ Keep it simple: after any mutation, broadcast a fresh per-role `room:state` to e
`npm run validate-content` must check:
- Every YAML parses and passes its engine's zod schema
-- Story: every chapter has ≥1 clue for A **and** ≥1 for B; every lock has ≥1 answer and exactly 3 hints; finale answers exist in options
-- Defuse: all fixtures solve to their expected solution (with the game's ruleset); every module a level uses is defined
-- Labyrinth: grid rows equal length; exactly one S and E; exactly `lanternsRequired` K; every K and E reachable from S **without stepping on a trap** (BFS, respecting one-way gates); no cell where a gate leaves the Explorer stuck for good
-- Sync: ≥15 questions per round type in use
+- Story: every chapter has ≥1 clue for A **and** ≥1 for B; every lock has ≥1 answer and exactly 3 hints; finale answers exist in options; clue ids are unique; every signal clue has a `signal`; escape finales have A and B clues
+- Defuse: all fixtures solve to their expected solution (with the game's ruleset); every module a level uses is defined; for `overtime`, the keypad columns, password words and Morse frequencies match the solver's tables (`OVERTIME_TABLES`) and every password fixture column has exactly `lettersPerColumn` letters
+- Labyrinth: grid rows equal length; exactly one S and E; exactly `lanternsRequired` K; every K and E reachable from S **without stepping on a trap** (BFS, respecting one-way gates); no cell where a gate leaves the Explorer stuck for good; glyphs and gates never on walls or traps; every `lanterns` entry sits on a K
+- Sync: ≥15 questions per round type in use; every rank question has exactly 4 items
Run it in CI and as a pre-start step.
## 11. Build phases (do in order, commit after each)
diff --git a/GAMES.md b/GAMES.md
index 89876bd..03ab456 100644
--- a/GAMES.md
+++ b/GAMES.md
@@ -99,88 +99,136 @@ Navigator (A) has the map, Explorer (B) sees only their own cell. 3 lanterns, 3
---
+Difficulty: 1 Easy · 2 Medium · 3 Hard · 4 Expert · 5 Nightmare ☠️
+In the harder murder mysteries, **locks only give facts**. The killer is never handed to you; the accusation needs facts from several chapters.
+
## 9. Dead Air (murder mystery · 30 min · 🔑🔑🔑)
-Hint penalty +3:00. Two accusation attempts.
+Roles: **Detective** (A) / **Night Intern** (B). Hint penalty 3:00.
-| Ch | Lock | Answer |
-|----|------|--------|
-| 1 | Ghost Signal | `GHOST SIGNAL` |
-| 2 | The Last Cup | `23:06` |
-| 3 | The Studio Door | Kyle |
-| 4 | The Midnight Announcement | `THE SALE IS FORGED` |
+| Ch | Lock | A has | B has | Answer |
+|----|------|-------|-------|--------|
+| 1 | Last song | Track lengths | Run sheet (23:00 start, 2:00 intro, 1:30 talk) + alarm 23:31:35 (15 s rule) | `GHOST SIGNAL` (23:25:00–23:31:20) |
+| 2 | Honey last safe | Lab: OKAYEST DJ mug negative, ON AIR mug + honey positive; meeting minutes | Kitchen camera log (offline 23:09–23:21); generator test booked by M. Venter | `23:06` |
+| 3 | Studio door card | Card register (decimal); Kyle lost card at 22:30 meeting with Marisa | Door log in hex (0x1A1 at 23:12) | Kyle's card (0x1A1 = 417) |
+| 4 | Stencil message | 6×6 letter grid | Card with cut-out windows | `SALE IS FORGED` |
-**Accusation:** `marisa` · `honey` · `forged`.
+**Killer:** Marisa Venter. Booked the generator test to kill the camera, left the meeting 23:11–23:17, used Kyle's stolen card at 23:12 to take the EpiPen, put peanut oil in the honey. Motive: Rex would reveal on air she forged his signature to sell the station.
+**Red herrings:** Zanele (served the fatal tea), Kyle (his card), Tumi (engineer), Owen (superfan, stuck in reception).
+
+---
## 10. The Masquerade at Montague House (murder mystery · 40 min · 🔑🔑🔑🔑)
-Hint penalty +3:00. **One** accusation attempt.
+Roles: **Inspector** (A) / **Lady's Maid** (B). Hint penalty 3:00. **1 accusation attempt, 4 questions.**
-| Ch | Lock | Answer |
-|----|------|--------|
-| 1 | Who Wore What | Odette |
-| 2 | The Raven in the Conservatory | Ivy |
-| 3 | The Missing Dagger | `11` |
-| 4 | Julian's Confession | `MARSH WAS INNOCENT` |
+| Ch | Lock | A has | B has | Answer |
+|----|------|-------|-------|--------|
+| 1 | Who arrived as Raven | Logic clues 1–4 | Logic clues 5–8 | Odette (verified unique: Agatha Stag/crimson, Rupert Fox/green, Ivy Swan/black, Silas Lion/silver, Odette Raven/gold) |
+| 2 | Who the footman saw | Footman: Raven + black cloak | Cloakroom: Raven ↔ Swan swapped at 23:00, cloaks kept | Ivy |
+| 3 | Dagger pot | Gardener: primes not watered | Disturbed pots 4, 9, 11, 15; spotless gloves | `11` |
+| 4 | Julian's confession | Polybius numbers + method | Motto FORTUNE FAVOURS THE BOLD; Marsh family gossip | `MARSH WAS INNOCENT` |
-**Accusation:** `ivy` · `raven` · `dagger` · `father`.
+**Killer:** Ivy Marsh · wearing Odette's **Raven** mask · armoury dagger, buried in cactus pot 11 · Julian framed her father and took Montague House.
-## 11. The Kalahari Expedition (murder mystery · 60 min · 🔑🔑🔑🔑🔑)
-Hint penalty +4:00. **75-minute limit.** **One** accusation attempt.
+---
-| Ch | Lock | Answer |
-|----|------|--------|
-| 1 | Star Trails | `02:00` |
-| 2 | Footprints | `11` |
-| 3 | The Watch Rota | Pienaar |
-| 4 | Samuel's Note | `HE SMELLED OF PIPE SMOKE` |
-| 5 | The Diamonds | `KIMBERLEY` (the Big Hole) |
-| 6 | The Unsent Telegram | `SALTED` |
+## 11. The Kalahari Expedition (murder mystery · 60 min · ☠️ Nightmare)
+Roles: **Magistrate** (A) / **Camp Clerk** (B). Hint penalty 4:00. **75-minute time limit. 1 attempt, 4 questions.**
-**Accusation:** `dunmore` · `same` · `struck` · `fraud`.
+| Ch | Lock | A has | B has | Answer |
+|----|------|-------|-------|--------|
+| 1 | Lantern time | Star-trail photo: lantern at 60°–75° of arc | Shutter opened 22:00, sky turns 15°/hr; Clara alibis Reyes 22:00–04:00 | `02:00` |
+| 2 | Boot size | Print 31.5 cm, chevron, sand adds ~1 cm | Size card + boot inventory | `11` (Reyes & Dunmore have size 11 chevron) |
+| 3 | Watchman at 02:00 | Rota rules; Samuel's fake snakebite (4 cm marks, sedative) | Watchkeepers + Night 1 = Reyes; murder on Night 3 | Pienaar → figure went to north row (Dunmore, Kessler, Reyes) |
+| 4 | Samuel's note | Vigenère ciphertext + method | Key word KOFFIE; tobacco list (pipe: Reyes, Dunmore) | `HE SMELLED OF PIPE SMOKE` |
+| 5 | Diamond source | Gem report: sample K-3, never water-worn | Reference samples; prospectus "found by F. Dunmore" | `KIMBERLEY` |
+| 6 | Telegram | Book-cipher numbers | Expedition handbook | `SALTED` |
+
+**Elimination:** size 11 chevron → Reyes, Dunmore · Reyes alibied by Clara · pipe smoke → Dunmore.
+**Killer:** Felix Dunmore · struck Marlowe at the dig at 02:00 and put him in the pit · drugged Samuel and faked a snakebite · the diamond find was salted with Kimberley stones.
+
+---
## 12. The Alchemist's Vault (escape room · 25 min · 🔑🔑🔑)
-Hint penalty +3:00.
+Roles: **Apprentice** (A) / **Scribe** (B).
-| Lock | Answer |
-|------|--------|
-| The Five Flasks | `GENIUS` |
-| The Philosopher's Stone | `25` |
-| The Dotted Plaque | `80` |
-| Door (finale) | `234` |
+| Lock | A has | B has | Answer |
+|------|-------|-------|--------|
+| Cabinet | Flasks: numbers + flame colours | Element table + rainbow order | `GENIUS` (Ge N I U S) |
+| Stone dial | Two balanced scales | Silver = 5, gold = 3 × silver | `25` |
+| Dotted plaque | Braille ⠍⠑⠗⠉⠥⠗⠽ | Braille card; Mercury = Hg | `80` |
+| Vault (finale) | ☉ ☽ ♂ ♄ | Symbol → metal chart (+ element table from ch1) | `234` (79 + 47 + 26 + 82) |
+
+---
## 13. Submerged: Deep Lab Nereid (escape room · 35 min · 🔑🔑🔑🔑)
-Roles: **Pilot** (A) / **Diver** (B). Hint penalty +3:00. **40-minute limit**, shown as the water level.
+Roles: **Pilot** (A) / **Diver** (B). **40-minute time limit shown as a rising water gauge.**
| Lock | A has | B has | Answer |
|------|-------|-------|--------|
-| Pressure valves | Warning lights: ON ON ON off ON | Which lights each valve flips | `145` |
-| Breathing gas | 210 L at exactly 21% oxygen | Tank X 36%, Tank Y 15% | `60` |
-| Find the pod | 300 m east, then 200 m south | Chart: lab at E5, 100 m squares | `H7` |
-| Launch word (finale) | Keypresses 555·4·3·66·55·9·222 | The rewired keypad | `SURFACE` |
+| Hatch valves | Lights L1 L2 L3 L5 on | Valve → light wiring | `145` (unique solution) |
+| Breathing gas | 210 L at 21% | Tank X 36%, Y 15% | `60` |
+| Pod location | Sonar legs 300 m E, 200 m S | Chart, lab at E5, 100 m squares | `H7` |
+| Launch (finale) | Multi-tap code 555·4·3·66·55·9·222 | Rewired intercom keypad | `SURFACE` |
-## 14. The Kestrel Bank Job (escape room · 50 min · 🔑🔑🔑🔑🔑)
-Roles: **Inside Man** (A) / **The Wheel** (B). Hint penalty +4:00. **55-minute limit.**
+---
+
+## 14. The Kestrel Bank Job (escape room · 50 min · ☠️ Nightmare)
+Roles: **Inside Man** (A) / **The Wheel** (B). Hint penalty 4:00. **55-minute limit.**
| Lock | A has | B has | Answer |
|------|-------|-------|--------|
-| Staff door | Worn keys 0, 2, 6 (0 most) | Codes are family dates DDMM; Mia born 20 Jun | `2006` |
-| Laser hall | Column bit values 16/8/4/2/1 | Row masks 21, 12, 25, 17, 8 | `4` |
-| Guards | Guard 1 from 22:03 every 7, Guard 2 from 22:05 every 11 | Guard 3 from 22:02 every 6; need 4 clear minutes | `22:33` |
-| Vault dial | Sons' ages in Roman numerals: VII, XIX, XII | Atbash note: "my sons' ages, eldest first" | `19-12-07` |
-| Box number | SQL query + CLIENTS table | BOXES table | `317` |
-| Getaway (finale) | `MUTLEETSTHODIREAEP`, "rails = floors" | 3 floors; how a rail fence works | `OLD PIER` |
+| Staff door | Worn keys 0, 2, 6 (0 most worn) | Codes are DDMM family dates; social posts | `2006` (Mia, 20 June) |
+| Laser hall | Mask bit values per column | Row masks 21, 12, 25, 17, 8 | Column `4` |
+| Guards | Guards 1 & 2 timings | Guard 3 timing; need 4 clear minutes | `22:33` |
+| Vault dial | Sons' ages in Roman numerals | Atbash note "MY SONS AGES, ELDEST FIRST" | `19-12-07` |
+| Box | SQL query + CLIENTS | BOXES table | `317` |
+| Getaway (finale) | Rail-fence text | Building has 3 floors (= 3 rails) | `OLD PIER` |
+
+---
## 15. Tick Tock: Overtime (co-op defuse · 20 min · 🔑🔑🔑🔑)
-The sequel: its own manual (`ruleset: overtime`), indicator lights, and three new modules (Passwords, Morse Light, Say It Back).
-4 levels = 4 keys; the last level has all six modules and only 2 strikes. Fixtures in the YAML are the unit tests.
+4 levels = 4 keys. New: 3–6 wires, indicators (LUV, HUG, BAE, XOX, DTE), passwords, morse, simon. Level 4 runs all six modules with only 2 strikes.
+Rules are the GAMES-NEW.md Appendix A solver, ported to `server/src/engines/defuse.ts` (`ruleset: overtime`); all 40 fixtures in the YAML pass as unit tests.
## 16. In Sync: Deep Cuts (couples connection · 25 min · 🔑🔑🔑)
-Round 1 telepathy (type the same word, 3/5). Rounds 2 and 3 predict about A, then B (4/5).
-Round 4 ranking, subject alternating A/B (top **and** bottom must match, 3/5). One replay per round.
+Telepathy (type the same word, 3/5) · Spotlight A (4/5) · Spotlight B (4/5) · Ranking (top AND bottom must match, 3/5). 4 keys.
## 17. The Drowned Catacombs (co-op navigation · 20 min · 🔑🔑🔑)
-3 lanterns, 5 traps (1:00 each), and three one-way flood gates:
-(5,9) east only · (5,11) north only · (7,8) north only.
+13×13, 5 traps, 3 lanterns, **3 one-way flood gates**, sparse carvings.
-## 18. The Mirror Maze (co-op navigation · 30 min · 🔑🔑🔑🔑🔑)
-4 lanterns, 7 traps (1:30 each). The Navigator's map is served **mirrored left to right**; the Explorer has no compass
-(forward/left/right/back from the way they face, starting east). Two glyphs (crescent, star) appear twice.
+```
+############# S (1,1) E (11,11)
+#S..#.......# K (3,11) (7,3) (11,5)
+###.#.###.#.# T (2,3) (4,5) (4,7) (10,5) (10,11)
+#.T...#K#...# One-way: (5,9)→E (5,11)→N (7,8)→N
+#.#.#.#.#.###
+#.#.T.#...TK# Verified: all lanterns + exit reachable without traps,
+#.##.##.....# respecting gates, and no softlocks.
+#.#.T...#.#.#
+#.#.###.#.#.#
+#.......#.#.#
+#.###.#.#.#.#
+#..K#.....TE#
+#############
+```
+
+## 18. The Mirror Maze (co-op navigation · 30 min · ☠️ Nightmare)
+15×15, 7 traps, **4 lanterns**, Explorer has **relative controls only**, Navigator's map is **mirrored left-right**, two glyphs appear twice (☾ and ✦).
+
+```
+############### True layout (Navigator sees each row reversed)
+#S..#.........# S (1,1) facing east E (13,13)
+###.#.#.#####.# K (1,3) (1,13) (3,9) (13,9)
+#K#.....#...#.# T (2,13) (3,5) (5,6) (5,7) (9,5) (13,6) (13,10)
+#.####.##.#.#.#
+#..T.....T....#
+#.###T#.###..T#
+#...#T#.#.....#
+#.#.#.#.#.###.#
+#..K#.#.....#K#
+#.#.#.#.###.#T#
+#.#.........#.#
+#.#.#.#.###.#.#
+#KT...#......E#
+###############
+```
diff --git a/client/index.html b/client/index.html
index f5860fb..a1279a7 100644
--- a/client/index.html
+++ b/client/index.html
@@ -9,7 +9,7 @@
- setOrder([])}>
- Start over
-
- onSubmit(order)}>
- {order.length === items.length ? 'Lock in this order' : `Tap ${items.length - order.length} more`}
-
-
+
+ {place + 1}
+
+ {items[item]}
+
+ move(place, place - 1)}
+ aria-label={`Move ${items[item]} up, now number ${place + 1}`}
+ >
+ ▲
+
+ move(place, place + 1)}
+ aria-label={`Move ${items[item]} down, now number ${place + 1}`}
+ >
+ ▼
+
+
+
+ ))}
+
+
+ {announce}
+
+ onSubmit(order)}>
+ Lock in this order
+
);
}
@@ -189,8 +244,8 @@ export function SyncGame({ view, state, role, send }: Props) {
else if (type === 'telepathy') instruction = 'Type ONE word. The same word as your partner, hopefully.';
else if (type === 'rank') {
instruction = view.iAmSubject
- ? "This one's about you. Tap them in order, most to least. Be honest!"
- : `Tap them in the order ${subjectName} would, most to least. The top and the bottom have to match.`;
+ ? "This one's about you. Put them in order, most to least. Be honest!"
+ : `Put them in the order ${subjectName} would, most to least. The top and the bottom have to match.`;
} else instruction = view.iAmSubject ? "This one's about you. Answer honestly!" : `Guess what ${subjectName} will say.`;
/** An answer as the reveal cards show it. */
@@ -198,12 +253,19 @@ export function SyncGame({ view, state, role, send }: Props) {
if (typeof answer === 'string') return answer;
if (typeof answer === 'number') return q.options[answer];
return (
-
- {answer.map((item, place) => (
-
- {place + 1}. {q.options[item]}
-
- ))}
+
+ {answer.map((item, place) => {
+ // #1 and the last place are the ones that score.
+ const scores = place === 0 || place === answer.length - 1;
+ return (
+