Play liveChoose your opponent
Join

Bring the game from shoal-games 82301f6c4521

Browse files
@shoal shoal committed 2 weeks ago 1 parent 2b176c3 commit 32fe633cd513333519730d756548714c5597ad74

Showing 278 changed files with 71819 additions and 0 deletions.

+10 −0 AGENTS.md added View file
@@ -0,0 +1,10 @@
1+# Rules for agents
2+
3+- Your bot is `routes/<your route>/bot.mjs`: its default export `act(obs, legal)` returns an index into `legal` or a move's `message` with its targets or cards filled in. Start from `routes/bot.mjs`, the starter. It runs on Node 22 with no packages and no network. `README.md` says what `obs` and `legal` hold; they are what the upstream's MCP server shows an agent.
4+- Test before you push: `node referee/play.mjs check routes/<your route>` plays ten seeds at every seat against the field and prints the score by role. Add `SGS_BOT_STDERR=1` to see your bot's prints.
5+- Every push is checked: the share of games your side wins, averaged over 主公, 忠臣, 反贼 and 内奸. You do not write `metrics.json` yourself.
6+- For replays, submit a practice job: `sbatch referee/practice.sbatch`. Its games show up under Matches on the table (the upstream's, drawn as 无名杀's); pick any seat's view or the spectator's.
7+- To play yourself, join a room over the site's HTTP API (see Rooms in `README.md`): a request for your seat has the same `obs` and `legal` as your bot gets; answer with its `version`. `node src/try-room.mjs` shows a whole room on the command line.
8+- Skill texts for every general are in `referee/generals.json`.
9+- Write what you tried and what to try next in `routes/<your route>/README.md`, ending with `## Next`.
10+- Don't change `referee/`, `field/`, `viewer/` or `src/` on your route: the check runs the approved version of them. Propose changes by pull request to `main`.
+0 −0 cover.png added View file
Binary file not shown.
+19 −0 field/random/bot.mjs added View file
@@ -0,0 +1,19 @@
1+// A random player: any listed move, random targets and cards where the move leaves them open. Seeded from what it
2+// sees, so the same game plays the same way twice.
3+export default function act(obs, legal) {
4+ let x = [...JSON.stringify([obs.zones, obs.log.length, obs.viewer, legal.length])].reduce((h, c) => (h * 31 + c.charCodeAt(0)) >>> 0, 7);
5+ const rand = (n) => ((x = (x * 1103515245 + 12345) >>> 0) % n);
6+ const l = legal[rand(legal.length)];
7+ const m = structuredClone(l.message);
8+ if (l.validTargets.length && !Array.isArray(m.params.targets)) {
9+ const t = l.validTargets[rand(l.validTargets.length)];
10+ m.params.targets = [t];
11+ m.params.target = t;
12+ }
13+ if (Array.isArray(m.params.cardIds) && !m.params.cardIds.length) {
14+ const hand = obs.players[obs.viewer].hand ?? [];
15+ const need = obs.pending?.discard?.min ?? 1;
16+ m.params.cardIds = hand.slice(0, need).map((c) => c.id);
17+ }
18+ return m;
19+}
+6 −0 field/upstream/bot.mjs added View file
@@ -0,0 +1,6 @@
1+// The upstream's own AI: wmzy/sanguosha's heuristic scorer (src/ai-mcp/heuristics.ts, what its MCP server returns as
2+// recommendedAction), with the targets and cards it leaves open filled in. The same player sits in a room's auto seats.
3+import { Heuristic } from '../../referee/sgs.mjs';
4+
5+const h = new Heuristic();
6+export default (obs, legal) => h.act(obs, legal);
+19 −0 kit/bridge.js added View file
@@ -0,0 +1,19 @@
1+// The page around a game's viewer hands it the replay (Shoal's public/app.js): the viewer runs in a frame with scripts
2+// only, says it is ready, and gets {shoal: 'replay', name, text}. Opened by itself, it reads ?replay=<file> instead,
3+// so a replay can be watched from a clone: python3 -m http.server, then viewer/index.html?replay=../replays/x.json
4+// A live room (docs/games.md §8.4) opens the viewer as index.html?live. shoalLive(fn) says {shoal: 'ready', live: true}
5+// and calls fn(batch) for each {shoal: 'live', room, you, messages}: you lists the seats this viewer controls, the first
6+// batch holds all the history it may see, and each message is the room's (§8.3) plus its sequence number n: {n, to,
7+// version, obs, legal} asks a seat to act, {n, to, obs} tells one seat, {n, event} is public, {n, end} ends the room.
8+// shoalAct(seat, version, action) plays for a seat in you, answering the request with that version.
9+window.shoalReplay = start => {
10+ addEventListener('message', e => { if (e.data && e.data.shoal === 'replay') start(e.data.text, e.data.name) })
11+ const local = new URLSearchParams(location.search).get('replay')
12+ if (local) fetch(local).then(r => r.text()).then(t => start(t, local))
13+ else if (parent !== window) parent.postMessage({ shoal: 'ready' }, '*')
14+}
15+window.shoalLive = fn => {
16+ addEventListener('message', e => { if (e.data && e.data.shoal === 'live') fn(e.data) })
17+ if (parent !== window) parent.postMessage({ shoal: 'ready', live: true }, '*')
18+}
19+window.shoalAct = (seat, version, action) => parent.postMessage({ shoal: 'act', seat, version, action }, '*')
+82 −0 kit/host.py added View file
@@ -0,0 +1,82 @@
1+"""A bot in its own process, spoken to one JSON line at a time. Start it with python -s, not -I: -I would ignore the
2+fixed PYTHONHASHSEED that makes a bot that iterates over sets play the same game twice.
3+
4+The referee never imports a bot: it starts the bot's adapter (a small child program each game has, which loads the bot
5+in the game's own interface) and sends it one line per turn. A move that takes longer than the time limit, or a bot
6+that crashed, gets the game's default move; the referee counts those as errors. The child side is `serve(handle)`.
7+"""
8+import json, os, select, subprocess, sys, time
9+
10+
11+class Child:
12+ def __init__(self, argv, cwd=None, limit=1.0, start=10.0):
13+ self.limit, self.errors, self.dead = limit, 0, False
14+ env = {k: v for k, v in os.environ.items() if not k.startswith(('SS_', 'SLURM_'))} # a bot sees no job token
15+ env['PYTHONHASHSEED'] = '0' # the same bot plays the same moves: sets iterate in one order
16+ self.p = subprocess.Popen(argv, cwd=cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env)
17+ self.buf, self.n = b'', 0
18+ self.ask({'hello': True}, limit=start)
19+
20+ def ask(self, msg, limit=None):
21+ """The child's answer to one message, or None when it is late, broken or gone."""
22+ if self.dead:
23+ return None
24+ try:
25+ self.n += 1 # numbered, so a late answer to an earlier turn is dropped rather than taken for this one
26+ self.p.stdin.write((json.dumps({**msg, 'n': self.n}) + '\n').encode())
27+ self.p.stdin.flush()
28+ deadline = time.monotonic() + (limit or self.limit)
29+ fd = self.p.stdout.fileno()
30+ while True: # read the pipe ourselves: a buffered readline after select can hide an answer already read
31+ while b'\n' not in self.buf:
32+ ready, _, _ = select.select([fd], [], [], max(0.0, deadline - time.monotonic()))
33+ chunk = os.read(fd, 1 << 16) if ready else b''
34+ if not chunk:
35+ raise TimeoutError
36+ self.buf += chunk
37+ line, self.buf = self.buf.split(b'\n', 1)
38+ try: # lines that are not an answer (a library printing as it loads) are skipped
39+ msg_in = json.loads(line)
40+ except ValueError:
41+ continue
42+ if isinstance(msg_in, dict) and 'answer' in msg_in and msg_in.get('n') == self.n:
43+ return msg_in['answer']
44+ except Exception:
45+ self.errors += 1
46+ if self.errors >= 20 or self.p.poll() is not None: # ponytail: a slow bot is stopped after 20 misses
47+ self.close()
48+ return None
49+
50+ def close(self):
51+ self.dead = True
52+ try:
53+ self.p.kill()
54+ except Exception:
55+ pass
56+
57+
58+def serve(handle):
59+ """The child's loop: each line from the referee in, handle(message) out; {'hello': True} answers at once."""
60+ out = sys.__stdout__
61+ sys.stdout = sys.stderr # a bot's prints must not corrupt the channel
62+ for line in sys.stdin:
63+ msg = json.loads(line)
64+ answer = True if msg.get('hello') else handle(msg)
65+ out.write(json.dumps({'answer': answer, 'n': msg.get('n')}) + '\n')
66+ out.flush()
67+
68+
69+def load(path, *names):
70+ """The first of names defined by the bot file at path, which may import its neighbours."""
71+ import importlib.util
72+ sys.path.insert(0, os.path.dirname(os.path.abspath(path)))
73+ spec = importlib.util.spec_from_file_location('bot', path)
74+ mod = importlib.util.module_from_spec(spec)
75+ spec.loader.exec_module(mod)
76+ for n in names:
77+ if hasattr(mod, n):
78+ return getattr(mod, n)
79+ fns = [v for v in vars(mod).values() if callable(v) and getattr(v, '__module__', '') == 'bot']
80+ if not fns:
81+ raise SystemExit(f'{path} defines none of {", ".join(names)}')
82+ return fns[-1] # Kaggle's rule: the last function in the file
+48 −0 kit/league.py added View file
@@ -0,0 +1,48 @@
1+"""What every game's referee shares: where the bots are, how a match is seated, and the files a run leaves.
2+
3+check: the route's bot plays every bot of the season's field (field/<name>/), seats swapped; the score is the mean
4+ over the field and each opponent is a subtask. metrics.json is what the site keeps (scienceslack.json names it).
5+practice: a few matches against the field, each leaving a replay in replays/ and an entry in replays/matches.json.
6+"""
7+import json, os, sys
8+
9+
10+def bot_dir(arg):
11+ """The route's folder the check was given, absolute (bots run in their own folder); a missing bot is the route's
12+ mistake, said plainly."""
13+ if not os.path.isdir(arg):
14+ sys.exit(f'No route folder at {arg}')
15+ return os.path.abspath(arg)
16+
17+
18+def field(root='field'):
19+ return sorted(d for d in os.listdir(root) if os.path.isdir(os.path.join(root, d)) and not d.startswith('.'))
20+
21+
22+def route_name():
23+ d = os.environ.get('SS_ROUTE_DIR', 'routes').rstrip('/')
24+ return 'main' if d == 'routes' else d.split('/', 1)[-1]
25+
26+
27+def write_metrics(score, subtasks, cost=None, path='metrics.json'):
28+ out = {'score': round(score, 6), 'subtasks': {k: round(v, 6) for k, v in subtasks.items()}}
29+ if cost is not None:
30+ out['cost'] = round(cost, 3)
31+ with open(path, 'w') as f:
32+ json.dump(out, f, indent=2, sort_keys=True)
33+ print(f'score {out["score"]} over {len(subtasks)}: ' + ', '.join(f'{k} {v:.3g}' for k, v in out['subtasks'].items()))
34+
35+
36+class Replays:
37+ """replays/<file> per match, and replays/matches.json saying who sat where and how it ended."""
38+
39+ def __init__(self, root='replays'):
40+ self.root, self.index = root, []
41+ os.makedirs(root, exist_ok=True)
42+
43+ def add(self, file, data, title, seats, result):
44+ with open(os.path.join(self.root, file), 'w') as f:
45+ f.write(data if isinstance(data, str) else json.dumps(data, separators=(',', ':')))
46+ self.index.append({'file': file, 'title': title, 'seats': seats, 'result': result})
47+ with open(os.path.join(self.root, 'matches.json'), 'w') as f:
48+ json.dump(self.index, f, indent=2)
+143 −0 kit/room.py added View file
@@ -0,0 +1,143 @@
1+"""A room's half of the room protocol (docs/games.md §8.3), for any game's referee. SS_ROOM says who holds each seat;
2+ask() gets a move from a bot child, from a person or agent over stdin, or from the game's own fallback (auto).
3+
4+ room = Room(start) start(folder) -> host.Child, the game's way to run a bot (a route's or field/<name>)
5+ move = room.ask(seat, obs, legal, auto=lambda: ..., bot=<the bot child's message, in the game's own interface>)
6+ move = room.ask(seat, obs, legal, auto, accept=lambda a: ...) # legal holds templates (free text): accept says
7+ # what an answer means, or None to keep waiting
8+ room.tell(seat, obs); room.event(data); room.end(result, scores); room.close()
9+
10+Lines to the platform start with '@shoal ' and are flushed one by one; the referee's own prints go to stderr, so a
11+library printing as it loads cannot break a line. A person or agent who does not answer within the limit (SS_ROOM
12+"limit", 30 s by default; ask(..., limit=s) sets one request's, e.g. a speech's) gets auto's move. {"control": ...}
13+re-asks the seat with a new version, so a late answer from the old controller is dropped; {"stop": true} makes ask()
14+raise Stop, and the referee writes what it has and ends.
15+"""
16+import json, os, queue, sys, threading, time
17+
18+
19+class Stop(Exception):
20+ pass
21+
22+
23+def log(*a):
24+ print('room:', *a, file=sys.stderr, flush=True)
25+
26+
27+class Room:
28+ def __init__(self, start, field='field'):
29+ conf = json.loads(os.environ.get('SS_ROOM') or '{}')
30+ self.seats = {str(k): v for k, v in conf.get('seats', {}).items()}
31+ self.limit = float(conf.get('limit', 30))
32+ self.start, self.field, self.bots = start, field, {}
33+ self.version, self.stopped = 0, False
34+ self.inbox, self.lock = queue.Queue(), threading.Lock()
35+ self.out, sys.stdout = sys.stdout, sys.stderr # prints, ours or a library's, must not look like protocol
36+ threading.Thread(target=self._read, daemon=True).start()
37+
38+ def say(self, msg):
39+ with self.lock: # the reader thread speaks too (control events)
40+ self.out.write('@shoal ' + json.dumps(msg, separators=(',', ':')) + '\n')
41+ self.out.flush()
42+
43+ def tell(self, seat, obs):
44+ self.say({'to': seat, 'obs': obs})
45+
46+ def event(self, data):
47+ self.say({'event': data})
48+
49+ def end(self, result, scores):
50+ self.say({'end': {'result': result, 'scores': scores}})
51+
52+ def label(self, seat):
53+ s = self.seats.get(seat) or {}
54+ return s.get('name') or s.get('route') or s.get('field') or os.path.basename((s.get('dir') or '').rstrip('/')) or s.get('kind') or 'auto'
55+
56+ def kind(self, seat):
57+ return (self.seats.get(seat) or {}).get('kind') or 'auto'
58+
59+ def ask(self, seat, obs, legal, auto, bot=None, accept=None, limit=None):
60+ ok = accept or (lambda a: a if a in legal else None)
61+ while True:
62+ if self.stopped:
63+ raise Stop
64+ spec = self.seats.get(seat) or {}
65+ kind = spec.get('kind')
66+ if kind == 'bot':
67+ child = self._bot(spec)
68+ move = child.ask(bot if bot is not None else {'obs': obs, 'legal': legal}) if child else None
69+ move = ok(move) if move is not None else None
70+ return auto() if move is None else move # a late, broken or illegal bot move: auto plays it
71+ if kind not in ('human', 'agent'):
72+ return auto()
73+ self._drain() # answers and notices from before this request are stale
74+ if self.stopped: # a stop drained with them still counts
75+ raise Stop
76+ self.version += 1
77+ v = self.version
78+ self.say({'to': seat, 'version': v, 'obs': obs, 'legal': legal})
79+ deadline = time.monotonic() + (limit or self.limit)
80+ while True:
81+ try:
82+ msg = self.inbox.get(timeout=max(0.0, deadline - time.monotonic()))
83+ except queue.Empty:
84+ log(f'seat {seat} out of time at version {v}: auto plays')
85+ return auto()
86+ if msg.get('stop'):
87+ raise Stop
88+ c = msg.get('control')
89+ if isinstance(c, dict) and str(c.get('seat')) == seat:
90+ break # a new controller: ask again, with a new version
91+ a = msg.get('act')
92+ if isinstance(a, dict) and str(a.get('seat')) == seat and a.get('version') == v:
93+ move = ok(a.get('action'))
94+ if move is not None:
95+ return move
96+ if a is not None:
97+ log(f'ignored act {json.dumps(a)[:120]}: asking seat {seat} at version {v}')
98+
99+ def close(self):
100+ for c in self.bots.values():
101+ if c:
102+ c.close()
103+
104+ def _read(self):
105+ for line in sys.stdin:
106+ try:
107+ msg = json.loads(line)
108+ except ValueError:
109+ log('not JSON:', line.strip()[:120])
110+ continue
111+ if not isinstance(msg, dict):
112+ continue
113+ if msg.get('stop'):
114+ self.stopped = True
115+ c = msg.get('control')
116+ if isinstance(c, dict) and 'seat' in c: # applied at once: the seat may not be the one being asked
117+ seat = str(c['seat'])
118+ self.seats[seat] = {k: v for k, v in c.items() if k != 'seat'}
119+ self.event({'type': 'control', 'seat': seat, 'kind': self.kind(seat), 'name': self.label(seat)})
120+ self.inbox.put(msg)
121+
122+ def _drain(self):
123+ while True:
124+ try:
125+ msg = self.inbox.get_nowait()
126+ except queue.Empty:
127+ return
128+ if msg.get('act') is not None:
129+ log(f'ignored act {json.dumps(msg["act"])[:120]}: stale')
130+
131+ def _bot(self, spec):
132+ """The child for a bot seat, one per folder (as the checks share one between seats); None if it cannot start."""
133+ if spec.get('field'):
134+ folder = os.path.join(self.field, spec['field'])
135+ else:
136+ folder = os.path.join(os.environ.get('SS_INPUT', '.'), spec.get('dir') or spec.get('route') or '')
137+ if folder not in self.bots:
138+ try:
139+ self.bots[folder] = self.start(folder)
140+ except (Exception, SystemExit) as e: # a missing bot is played by auto rather than ending the room
141+ log(f'no bot at {folder} ({e}): auto plays that seat')
142+ self.bots[folder] = None
143+ return self.bots[folder]
+88 −0 kit/roomcli.py added View file
@@ -0,0 +1,88 @@
1+"""Play a room on a laptop, without the site: run a room command with SS_ROOM, print what it says (docs/games.md §8.3),
2+and answer its requests to human and agent seats, from the terminal or by rule.
3+
4+ python3 kit/roomcli.py --room '{"seats": {...}}' [--auto] [--seat 0 --pick random] [--control 0=auto@6] [--stop 12] -- <command>
5+
6+--auto answers every request with the first legal action; --seat S (repeatable) answers seat S by --pick (first or
7+random) and leaves the other seats to the terminal. --control S=KIND@N: at the first request to seat S after N public
8+events, hand the seat to KIND (auto, agent, human), then send the old controller's late answer to that request, which
9+the room must ignore (it re-asks with a new version, or auto plays). --stop N sends {"stop": true} after N events.
10+SS_INPUT (a route's dir is under it) defaults to the current folder; --full prints whole messages.
11+"""
12+import argparse, json, os, random, subprocess, sys
13+
14+
15+def main():
16+ ap = argparse.ArgumentParser(description=__doc__.split('\n')[0])
17+ ap.add_argument('--room', default=os.environ.get('SS_ROOM', '{"seats": {}}'), help='SS_ROOM for the room')
18+ ap.add_argument('--auto', action='store_true', help='answer every request with the first legal action')
19+ ap.add_argument('--seat', action='append', default=[], help='a seat answered by --pick')
20+ ap.add_argument('--pick', choices=['first', 'random'], default='first')
21+ ap.add_argument('--control', action='append', default=[], help='S=KIND@N: hand seat S to KIND after N events')
22+ ap.add_argument('--stop', type=int, help='send stop after N events')
23+ ap.add_argument('--seed', type=int, default=0, help='for --pick random')
24+ ap.add_argument('--full', action='store_true')
25+ ap.add_argument('cmd', nargs=argparse.REMAINDER)
26+ a = ap.parse_args()
27+ cmd = a.cmd[1:] if a.cmd[:1] == ['--'] else a.cmd
28+ if not cmd:
29+ ap.error('give the room command after --')
30+ controls = []
31+ for c in a.control:
32+ seat, rest = c.split('=', 1)
33+ kind, at = rest.split('@', 1)
34+ controls.append({'seat': seat, 'kind': kind, 'at': int(at)})
35+ rnd = random.Random(a.seed)
36+ env = {**os.environ, 'SS_ROOM': a.room, 'SS_INPUT': os.environ.get('SS_INPUT', os.getcwd())}
37+ p = subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, bufsize=1)
38+ events = asked = answered = late = 0
39+ versions = []
40+
41+ def send(msg):
42+ p.stdin.write(json.dumps(msg) + '\n')
43+ p.stdin.flush()
44+ print(' >>', json.dumps(msg)[:200])
45+
46+ for line in p.stdout:
47+ if not line.startswith('@shoal '):
48+ print(' log', line.rstrip())
49+ continue
50+ msg = json.loads(line[7:])
51+ text = json.dumps(msg)
52+ print(f'@shoal {text if a.full or len(text) <= 200 else text[:197] + "..."}')
53+ if 'event' in msg:
54+ events += 1
55+ if a.stop is not None and events == a.stop:
56+ send({'stop': True})
57+ if 'end' in msg:
58+ break
59+ if 'version' not in msg:
60+ continue
61+ seat, v, legal = msg['to'], msg['version'], msg['legal']
62+ asked += 1
63+ assert not versions or v > versions[-1], 'versions must grow'
64+ versions.append(v)
65+ due = next((c for c in controls if c['seat'] == seat and events >= c['at']), None)
66+ if due: # the handover, then the old controller's answer arriving late
67+ controls.remove(due)
68+ send({'control': {'seat': seat, 'kind': due['kind'], 'name': f'{due["kind"]}-{seat}'}})
69+ send({'act': {'seat': seat, 'version': v, 'action': legal[-1]}})
70+ late += 1
71+ continue
72+ if a.auto or seat in a.seat:
73+ action = legal[0] if a.pick == 'first' or a.auto else rnd.choice(legal)
74+ else:
75+ print(f'seat {seat}, version {v}: obs {json.dumps(msg["obs"])[:300]}\nlegal: {" ".join(map(str, legal[:60]))}')
76+ got = input('your move, or its index (blank: the first)> ').strip()
77+ action = got if got in legal else legal[int(got)] if got.isdigit() and int(got) < len(legal) else got or legal[0]
78+ send({'act': {'seat': seat, 'version': v, 'action': action}})
79+ answered += 1
80+ p.stdin.close()
81+ code = p.wait()
82+ print(f'roomcli: {events} events, {asked} requests (versions {versions[:1]}..{versions[-1:]}), {answered} answered, '
83+ f'{late} late answers sent, exit {code}')
84+ sys.exit(code)
85+
86+
87+if __name__ == '__main__':
88+ main()
+57 −0 kit/test_room.py added View file
@@ -0,0 +1,57 @@
1+"""A check of kit/room.py against the room protocol (docs/games.md §8.3), on a toy game with one human seat: a stale or
2+illegal answer is ignored, a handover re-asks with a new version and drops the old controller's late answer, a silent
3+seat gets auto's move, and stop ends the room. python3 kit/test_room.py (or pytest)
4+"""
5+import json, os, subprocess, sys
6+
7+KIT = os.path.dirname(os.path.abspath(__file__))
8+GAME = f'''
9+import sys; sys.path.insert(0, {KIT!r})
10+from room import Room, Stop
11+room = Room(None)
12+try:
13+ for i in range(4):
14+ room.event({{'seat': '0', 'move': room.ask('0', {{'i': i}}, ['a', 'b'], auto=lambda: 'auto')}})
15+except Stop:
16+ room.event({{'stopped': True}})
17+room.end('done', {{'0': 0}})
18+'''
19+
20+
21+def test_room():
22+ env = {**os.environ, 'SS_ROOM': json.dumps({'limit': 0.5, 'seats': {'0': {'kind': 'human'}}})}
23+ p = subprocess.Popen([sys.executable, '-c', GAME], env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)
24+
25+ def said():
26+ line = p.stdout.readline()
27+ assert line.startswith('@shoal '), line
28+ return json.loads(line[7:])
29+
30+ def send(msg):
31+ p.stdin.write(json.dumps(msg) + '\n')
32+ p.stdin.flush()
33+
34+ assert said() == {'to': '0', 'version': 1, 'obs': {'i': 0}, 'legal': ['a', 'b']}
35+ send({'act': {'seat': '0', 'version': 0, 'action': 'a'}}) # stale
36+ send({'act': {'seat': '0', 'version': 1, 'action': 'z'}}) # illegal
37+ send({'act': {'seat': '0', 'version': 1, 'action': 'b'}})
38+ assert said() == {'event': {'seat': '0', 'move': 'b'}}
39+ assert said()['version'] == 2
40+ send({'control': {'seat': '0', 'kind': 'agent', 'name': 'ada-codex'}})
41+ send({'act': {'seat': '0', 'version': 2, 'action': 'b'}}) # the old controller, late
42+ assert said() == {'event': {'type': 'control', 'seat': '0', 'kind': 'agent', 'name': 'ada-codex'}}
43+ assert said()['version'] == 3
44+ send({'act': {'seat': '0', 'version': 3, 'action': 'a'}})
45+ assert said() == {'event': {'seat': '0', 'move': 'a'}}
46+ assert said()['version'] == 4 # left unanswered: auto plays after the limit
47+ assert said() == {'event': {'seat': '0', 'move': 'auto'}}
48+ assert said()['version'] == 5
49+ send({'stop': True})
50+ assert said() == {'event': {'stopped': True}}
51+ assert said() == {'end': {'result': 'done', 'scores': {'0': 0}}}
52+ assert p.wait(5) == 0
53+
54+
55+if __name__ == '__main__':
56+ test_room()
57+ print('room protocol: ok')
+30 −0 referee/NOTICE added View file
@@ -0,0 +1,30 @@
1+sgs.mjs is built (src/build.mjs) from wmzy/sanguosha, https://github.com/wmzy/sanguosha, commit
2+8f4b693b654a6365d143a80003877219f6e08b22: its rules engine, headless client move lists, heuristic AI and replay
3+recorder, with this project's src/table.ts, play.ts, room.ts and bots.ts. generals.json is generated from it.
4+Also bundled, under the MIT licence: eventsource (Copyright (c) EventSource GitHub organisation) and
5+eventsource-parser (Copyright (c) 2026 Espen Hovlandsdal), which the upstream's headless client imports; they are never
6+used here (no network).
7+
8+The upstream's licence:
9+
10+MIT License
11+
12+Copyright (c) 2025 三国杀项目作者
13+
14+Permission is hereby granted, free of charge, to any person obtaining a copy
15+of this software and associated documentation files (the "Software"), to deal
16+in the Software without restriction, including without limitation the rights
17+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18+copies of the Software, and to permit persons to whom the Software is
19+furnished to do so, subject to the following conditions:
20+
21+The above copyright notice and this permission notice shall be included in all
22+copies or substantial portions of the Software.
23+
24+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30+SOFTWARE.
+23 −0 referee/bot.mjs added View file
@@ -0,0 +1,23 @@
1+// A bot's own process: node referee/bot.mjs <bot folder>. Loads <bot folder>/bot.mjs, whose default export (or `act`)
2+// is act(obs, legal) -> move, and answers the referee one JSON line per ask: {n, obs, legal} in, {n, answer} out.
3+// A bot's prints go to stderr, so they cannot corrupt the channel.
4+import { createInterface } from 'node:readline';
5+import path from 'node:path';
6+import { pathToFileURL } from 'node:url';
7+
8+const write = process.stdout.write.bind(process.stdout);
9+console.log = console.info = console.debug = console.warn = console.error;
10+process.stdout.write = process.stderr.write.bind(process.stderr);
11+
12+const mod = await import(pathToFileURL(path.join(process.argv[2], 'bot.mjs')).href);
13+const act = mod.default ?? mod.act;
14+for await (const line of createInterface({ input: process.stdin })) {
15+ let m, answer = null;
16+ try {
17+ m = JSON.parse(line);
18+ answer = m.hello ? true : await act(m.obs, m.legal);
19+ } catch (e) {
20+ console.error(e);
21+ }
22+ write(`${JSON.stringify({ n: m?.n, answer: answer ?? null })}\n`);
23+}
+5 −0 referee/check.sbatch added View file
@@ -0,0 +1,5 @@
1+#!/bin/bash
2+#SBATCH --job-name=play
3+#SBATCH --time=30:00
4+# The route's bot at every seat on ten seeds, the field at the other four; writes metrics.json, which the site keeps as the route's score.
5+node referee/play.mjs check "$SS_INPUT/$SS_ROUTE_DIR"
+1471 −0 referee/generals.json added View file
@@ -0,0 +1,1471 @@
1+{
2+ "曹操": {
3+ "faction": "魏",
4+ "maxHealth": 4,
5+ "gender": "男",
6+ "skills": {
7+ "奸雄": "当你受到伤害后,你可以获得造成此伤害的牌",
8+ "护驾": "主公技:需要闪时,令其他魏势力角色替你打出闪"
9+ }
10+ },
11+ "司马懿": {
12+ "faction": "魏",
13+ "maxHealth": 3,
14+ "gender": "男",
15+ "skills": {
16+ "反馈": "受到伤害后,你可以获得伤害来源的一张牌",
17+ "鬼才": "判定牌生效前,你可以打出一张手牌代替之"
18+ }
19+ },
20+ "夏侯惇": {
21+ "faction": "魏",
22+ "maxHealth": 4,
23+ "gender": "男",
24+ "skills": {
25+ "刚烈": "受到伤害后判定,非红桃则来源弃两张手牌或受 1 点伤害"
26+ }
27+ },
28+ "张辽": {
29+ "faction": "魏",
30+ "maxHealth": 4,
31+ "gender": "男",
32+ "skills": {
33+ "突袭": "摸牌阶段,你可以改为获得至多两名角色的各一张手牌"
34+ }
35+ },
36+ "许褚": {
37+ "faction": "魏",
38+ "maxHealth": 4,
39+ "gender": "男",
40+ "skills": {
41+ "裸衣": "摸牌阶段少摸一张牌,本回合使用【杀】或【决斗】造成的伤害+1"
42+ }
43+ },
44+ "郭嘉": {
45+ "faction": "魏",
46+ "maxHealth": 3,
47+ "gender": "男",
48+ "skills": {
49+ "天妒": "当你的判定牌生效后,你可以获得此判定牌",
50+ "遗计": "受到 1 点伤害后,观看牌堆顶的两张牌,然后将这些牌交给任意角色"
51+ }
52+ },
53+ "甄姬": {
54+ "faction": "魏",
55+ "maxHealth": 3,
56+ "gender": "女",
57+ "skills": {
58+ "倾国": "你可以将一张黑色手牌当【闪】使用或打出",
59+ "洛神": "准备阶段判定:黑色获得判定牌并重复,直到红色或停止"
60+ }
61+ },
62+ "夏侯渊": {
63+ "faction": "魏",
64+ "maxHealth": 4,
65+ "gender": "男",
66+ "skills": {
67+ "神速": "可选择至多三项:①跳过判定+摸牌;②弃装备+跳过出牌;③翻面+跳过弃牌。每项视为出杀"
68+ }
69+ },
70+ "曹仁": {
71+ "faction": "魏",
72+ "maxHealth": 4,
73+ "gender": "男",
74+ "skills": {
75+ "据守": "结束阶段:翻面并摸四张牌,然后弃置一张手牌(装备牌改为使用之)"
76+ }
77+ },
78+ "荀彧": {
79+ "faction": "魏",
80+ "maxHealth": 3,
81+ "gender": "男",
82+ "skills": {
83+ "驱虎": "出牌阶段限一次,与一名角色拼点:赢则该角色对其攻击范围内另一角色造成1伤害,没赢则其对你造成1伤害",
84+ "节命": "受到伤害后,令一名角色将手牌摸至其体力上限(最多5张)"
85+ }
86+ },
87+ "典韦": {
88+ "faction": "魏",
89+ "maxHealth": 4,
90+ "gender": "男",
91+ "skills": {
92+ "强袭": "出牌阶段限两次:失去1点体力或弃一张武器牌,对一名本回合未以此法指定过的其他角色造成1点伤害"
93+ }
94+ },
95+ "曹丕": {
96+ "faction": "魏",
97+ "maxHealth": 3,
98+ "gender": "男",
99+ "skills": {
100+ "行殇": "当其他角色死亡时,你可以获得其所有牌(手牌/装备/判定区)",
101+ "放逐": "受到伤害后,令一名其他角色摸 X 张牌(X=已损失体力)并翻面",
102+ "颂威": "主公技:其他魏势力角色判定牌黑色且生效后,你可以摸一张牌"
103+ }
104+ },
105+ "徐晃": {
106+ "faction": "魏",
107+ "maxHealth": 4,
108+ "gender": "男",
109+ "skills": {
110+ "断粮": "将一张黑色基本牌或装备牌当【兵粮寸断】使用;对手牌数不小于你的角色无距离限制"
111+ }
112+ },
113+ "张郃": {
114+ "faction": "魏",
115+ "maxHealth": 4,
116+ "gender": "男",
117+ "skills": {
118+ "巧变": "弃一张手牌跳过阶段:摸牌阶段可从至多两名其他角色各获得一张手牌;出牌阶段可移动场上的一张牌"
119+ }
120+ },
121+ "邓艾": {
122+ "faction": "魏",
123+ "maxHealth": 4,
124+ "gender": "男",
125+ "skills": {
126+ "屯田": "回合外失去牌时判定,非红桃则置于武将牌上为田,每张田与其他角色距离 -1",
127+ "凿险": "觉醒技:准备阶段田≥3时,减1体力上限并获得\"急袭\"(田当顺手牵羊)"
128+ }
129+ },
130+ "界曹操": {
131+ "faction": "魏",
132+ "maxHealth": 4,
133+ "gender": "男",
134+ "skills": {
135+ "界奸雄": "当你受到伤害后,你可以摸一张牌,并获得造成此伤害的牌",
136+ "界护驾": "主公技:魏势力角色可代你使用或打出闪;每回合限一次,魏角色回合外用闪时可令你摸1张"
137+ }
138+ },
139+ "界司马懿": {
140+ "faction": "魏",
141+ "maxHealth": 3,
142+ "gender": "男",
143+ "skills": {
144+ "反馈": "受到伤害后,你可以获得伤害来源的一张牌",
145+ "界鬼才": "判定牌生效前,你可以打出一张手牌或装备牌代替之"
146+ }
147+ },
148+ "界夏侯惇": {
149+ "faction": "魏",
150+ "maxHealth": 4,
151+ "gender": "男",
152+ "skills": {
153+ "界刚烈": "受到伤害后判定,红色对其造成1点伤害,黑色弃置其一张牌"
154+ }
155+ },
156+ "界张辽": {
157+ "faction": "魏",
158+ "maxHealth": 4,
159+ "gender": "男",
160+ "skills": {
161+ "界突袭": "摸牌阶段,你可以少摸任意张牌并获得等量其他角色的各一张手牌"
162+ }
163+ },
164+ "界许褚": {
165+ "faction": "魏",
166+ "maxHealth": 4,
167+ "gender": "男",
168+ "skills": {
169+ "界裸衣": "摸牌阶段开始前,可亮出牌堆顶3张;可跳过摸牌阶段并获得其中的基本牌/武器牌/决斗,且直到你的下回合开始,杀/决斗伤害+1"
170+ }
171+ },
172+ "界郭嘉": {
173+ "faction": "魏",
174+ "maxHealth": 3,
175+ "gender": "男",
176+ "skills": {
177+ "天妒": "当你的判定牌生效后,你可以获得此判定牌",
178+ "界遗计": "受到 1 点伤害后,摸两张牌,然后可以将至多两张手牌交给至多两名其他角色"
179+ }
180+ },
181+ "界甄姬": {
182+ "faction": "魏",
183+ "maxHealth": 3,
184+ "gender": "女",
185+ "skills": {
186+ "倾国": "你可以将一张黑色手牌当【闪】使用或打出",
187+ "界洛神": "准备阶段判定:黑色获得判定牌并重复;以此法获得的牌本回合不计入手牌上限"
188+ }
189+ },
190+ "界夏侯渊": {
191+ "faction": "魏",
192+ "maxHealth": 4,
193+ "gender": "男",
194+ "skills": {
195+ "界神速": "选择至多三项:①跳过判定+摸牌;②弃装备+跳过出牌;③翻面+跳过弃牌。每项视为出杀"
196+ }
197+ },
198+ "界曹仁": {
199+ "faction": "魏",
200+ "maxHealth": 4,
201+ "gender": "男",
202+ "skills": {
203+ "界据守": "结束阶段:翻面并摸四张牌,然后弃置一张手牌(装备牌改为使用之)",
204+ "解围": "装备区的一张牌当无懈可击使用;武将牌从背面翻至正面时可弃置一张牌移动场上的一张牌"
205+ }
206+ },
207+ "界荀彧": {
208+ "faction": "魏",
209+ "maxHealth": 3,
210+ "gender": "男",
211+ "skills": {
212+ "驱虎": "出牌阶段限一次,与一名角色拼点:赢则该角色对其攻击范围内另一角色造成1伤害,没赢则其对你造成1伤害",
213+ "界节命": "受到1点伤害后或死亡时,令一名角色摸X张牌,然后将手牌弃至X张(X为其体力上限且至多为5)"
214+ }
215+ },
216+ "界典韦": {
217+ "faction": "魏",
218+ "maxHealth": 4,
219+ "gender": "男",
220+ "skills": {
221+ "界强袭": "出牌阶段限两次:受到1点伤害或弃一张武器牌,对一名本回合未以此法指定过的其他角色造成1点伤害"
222+ }
223+ },
224+ "界曹丕": {
225+ "faction": "魏",
226+ "maxHealth": 3,
227+ "gender": "男",
228+ "skills": {
229+ "行殇": "当其他角色死亡时,你可以获得其所有牌(手牌/装备/判定区)",
230+ "界放逐": "受到伤害后,令一名其他角色翻面,并摸 X 张牌(X=已损失体力)",
231+ "颂威": "主公技:其他魏势力角色判定牌黑色且生效后,你可以摸一张牌"
232+ }
233+ },
234+ "界徐晃": {
235+ "faction": "魏",
236+ "maxHealth": 4,
237+ "gender": "男",
238+ "skills": {
239+ "界断粮": "将一张黑色基本牌或黑色装备牌当【兵粮寸断】使用;若本回合未造成过伤害,使用时无距离限制",
240+ "截辎": "当一名角色跳过摸牌阶段后,你可以选择一名角色:若其手牌数全场最少且没有\"辎\",其获得\"辎\"标记,否则其摸一张牌。有\"辎\"的角色于其摸牌阶段结束时移除\"辎\"并执行一个额外的摸牌阶段"
241+ }
242+ },
243+ "界张郃": {
244+ "faction": "魏",
245+ "maxHealth": 4,
246+ "gender": "男",
247+ "skills": {
248+ "界巧变": "游戏开始获得2枚\"变\"标记;弃一张牌或移除1枚\"变\"跳过阶段(摸牌:至多两名角色各获得一张手牌;出牌:移动场上的一张牌);结束阶段手牌数与历史均不相等则获得1枚\"变\""
249+ }
250+ },
251+ "界邓艾": {
252+ "faction": "魏",
253+ "maxHealth": 4,
254+ "gender": "男",
255+ "skills": {
256+ "界屯田": "回合外失去牌或回合内弃置杀时判定,非红桃则置于武将牌上为田,每张田与其他角色距离 -1",
257+ "界凿险": "觉醒技:准备阶段田≥3时,减1体力上限、获得\"急袭\",且本回合结束后进行一个额外回合",
258+ "急袭": "将一张\"田\"当【顺手牵羊】使用"
259+ }
260+ },
261+ "界于禁": {
262+ "faction": "魏",
263+ "maxHealth": 4,
264+ "gender": "男",
265+ "skills": {
266+ "界镇军": "准备阶段,弃置一名角色X张牌(X为其手牌数减体力值且至少为1),然后选择:1.你弃置等量非装备牌数的牌;2.结束阶段其摸等量非装备牌数的牌",
267+ "界毅重": "锁定技,体力值大于等于你的角色的黑色【杀】对你无效;手牌数小于等于你的角色无法响应你的黑色【杀】"
268+ }
269+ },
270+ "界张春华": {
271+ "faction": "魏",
272+ "maxHealth": 3,
273+ "gender": "女",
274+ "skills": {
275+ "界绝情": "锁定技:你即将造成的伤害视为失去体力",
276+ "界伤逝": "当你的手牌数小于X后,你可以将手牌摸至X张(X为你已损失体力值)",
277+ "界翦灭": "出牌阶段限一次:与一名其他角色各选一种颜色,各自弃置所选颜色的手牌,弃牌较多者视为对另一方使用决斗"
278+ }
279+ },
280+ "界曹冲": {
281+ "faction": "魏",
282+ "maxHealth": 3,
283+ "gender": "男",
284+ "skills": {
285+ "界称象": "受到1点伤害后,亮出牌堆顶4张牌,获得其中点数和≤13的若干张;若点数和恰好为13,下次发动多亮出1张",
286+ "界仁心": "其他角色进入濒死时,可弃置一张装备牌并翻面,令其回复至1点体力"
287+ }
288+ },
289+ "界曹彰": {
290+ "faction": "魏",
291+ "maxHealth": 4,
292+ "gender": "男",
293+ "skills": {
294+ "界将驰": "摸牌阶段结束时选择一项:①摸一张牌,本回合杀次数-1且杀不计入手牌上限;②重铸一张牌,本回合杀次数+1且杀无距离限制"
295+ }
296+ },
297+ "界曹植": {
298+ "faction": "魏",
299+ "maxHealth": 3,
300+ "gender": "男",
301+ "skills": {
302+ "界落英": "其他角色的梅花牌因弃置或判定而置入弃牌堆后,你可以获得其中任意张牌",
303+ "界酒诗": "翻面视为使用酒;背面朝上时落英牌增强;受伤后或回合外累计获X张落英牌后可翻回正面"
304+ }
305+ },
306+ "界李典": {
307+ "faction": "魏",
308+ "maxHealth": 3,
309+ "gender": "男",
310+ "skills": {
311+ "界恂恂": "摸牌阶段开始时,观看牌堆顶4张牌,将其中2张置于牌堆顶,其余置于牌堆底",
312+ "界忘隙": "对其他角色造成1点伤害后,或受到其他角色1点伤害后,摸两张牌并交给该角色其中一张"
313+ }
314+ },
315+ "界王异": {
316+ "faction": "魏",
317+ "maxHealth": 3,
318+ "gender": "女",
319+ "skills": {
320+ "界贞烈": "成为其他角色杀或普通锦囊的目标后,可失1体力令此牌对你无效,然后二选一:获得使用者一张牌或本回合结束阶段发动一次秘计",
321+ "界秘计": "结束阶段,你可以摸X张牌(X为你已损失的体力值),然后你可以交给其他角色至多X张牌"
322+ }
323+ },
324+ "界郭淮": {
325+ "faction": "魏",
326+ "maxHealth": 4,
327+ "gender": "男",
328+ "skills": {
329+ "界精策": "本回合每使用一种新花色手牌,手牌上限+1;出牌阶段结束时,可以摸X张牌(X为本回合使用过牌的类型数)"
330+ }
331+ },
332+ "界郭皇后": {
333+ "faction": "魏",
334+ "maxHealth": 3,
335+ "gender": "女",
336+ "skills": {
337+ "界矫诏": "出牌阶段限一次,你可将一张牌当本轮未有角色使用过的基本或普通锦囊牌使用",
338+ "界殚心": "当你受到伤害后,你可摸X张牌,然后修改\"矫诏\"(X为你修改\"矫诏\"的次数)"
339+ }
340+ },
341+ "毌丘俭": {
342+ "faction": "魏",
343+ "maxHealth": 4,
344+ "gender": "男",
345+ "skills": {
346+ "征荣": "使用杀或伤害锦囊牌时,可将一名手牌数不小于你的目标角色的一张牌置于武将牌上为\"荣\"",
347+ "鸿举": "觉醒技:准备阶段若荣≥3,用任意手牌替换等量的荣,减1体力上限并获得\"清侧\""
348+ }
349+ },
350+ "王基": {
351+ "faction": "魏",
352+ "maxHealth": 3,
353+ "gender": "男",
354+ "skills": {
355+ "奇制": "回合内使用非装备牌指定目标后,可弃置另一名角色一张牌并令其摸一张牌",
356+ "进趋": "结束阶段可摸两张牌,然后将手牌弃至X张(X为本回合发动奇制的次数)"
357+ }
358+ },
359+ "蒯越蒯良": {
360+ "faction": "魏",
361+ "maxHealth": 3,
362+ "gender": "男",
363+ "skills": {
364+ "荐降": "当你成为其他角色使用牌的目标后,你可以令手牌数最少的一名角色摸一张牌",
365+ "审时": "转换技。阳:出牌阶段限一次,交给手牌数最多的其他角色一张牌并对其造成1点伤害,若其因此死亡,可令一名角色摸至四张。阴:其他角色对你造成伤害后,观看其手牌并交给其一张牌,当前回合结束阶段若其未失去此牌,你将手牌摸至四张"
366+ }
367+ },
368+ "郝昭": {
369+ "faction": "魏",
370+ "maxHealth": 4,
371+ "gender": "男",
372+ "skills": {
373+ "镇骨": "结束阶段,你可以选择一名其他角色,本回合结束时和其下回合结束时,其将手牌调整至与你手牌数相同(至多摸至五张)"
374+ }
375+ },
376+ "刘备": {
377+ "faction": "蜀",
378+ "maxHealth": 4,
379+ "gender": "男",
380+ "skills": {
381+ "仁德": "出牌阶段:将任意张手牌交给其他角色;以此法失去第二张牌时回复1点体力",
382+ "激将": "主公技,其他蜀势力角色可以在你需要时代替你使用或打出【杀】(视为由你使用或打出)"
383+ }
384+ },
385+ "界刘备": {
386+ "faction": "蜀",
387+ "maxHealth": 4,
388+ "gender": "男",
389+ "skills": {
390+ "界仁德": "出牌阶段:每名角色限一次,将任意张手牌交给一名其他角色;本阶段给出第二张时,可视为使用一张基本牌",
391+ "界激将": "主公技:蜀势力角色可代你使用或打出杀;每回合限一次,蜀角色回合外用杀时可令你摸1张"
392+ }
393+ },
394+ "关羽": {
395+ "faction": "蜀",
396+ "maxHealth": 4,
397+ "gender": "男",
398+ "skills": {
399+ "武圣": "你可以将一张红色牌当【杀】使用或打出"
400+ }
401+ },
402+ "界关羽": {
403+ "faction": "蜀",
404+ "maxHealth": 4,
405+ "gender": "男",
406+ "skills": {
407+ "界武圣": "你可以将一张红色牌(手牌或装备区)当【杀】使用或打出",
408+ "义绝": "出牌阶段限一次,弃置一张牌并令一名其他角色展示一张手牌;黑色则其本回合非锁定技失效且不能使用或打出手牌,你对其红桃杀伤害+1;红色则你获得之,然后可令其回1点体力"
409+ }
410+ },
411+ "张飞": {
412+ "faction": "蜀",
413+ "maxHealth": 4,
414+ "gender": "男",
415+ "skills": {
416+ "咆哮": "锁定技:出牌阶段使用【杀】无次数限制"
417+ }
418+ },
419+ "界张飞": {
420+ "faction": "蜀",
421+ "maxHealth": 4,
422+ "gender": "男",
423+ "skills": {
424+ "界咆哮": "锁定技:出牌阶段使用【杀】无次数限制;杀被【闪】抵消时摸一张牌"
425+ }
426+ },
427+ "赵云": {
428+ "faction": "蜀",
429+ "maxHealth": 4,
430+ "gender": "男",
431+ "skills": {
432+ "龙胆": "你可以将一张【杀】当【闪】使用或打出,或将一张【闪】当【杀】使用或打出"
433+ }
434+ },
435+ "界赵云": {
436+ "faction": "蜀",
437+ "maxHealth": 4,
438+ "gender": "男",
439+ "skills": {
440+ "界龙胆": "你可以将一张【杀】当【闪】、【闪】当【杀】、【酒】当【桃】、【桃】当【酒】使用或打出",
441+ "涯角": "每当你于回合外使用或打出手牌时,你可以展示牌堆顶的一张牌,若这两张牌的类别相同,你可以将牌堆顶的一张牌交给一名角色;若不同,你可以弃置攻击范围内包含你的一名角色区域里的一张牌。"
442+ }
443+ },
444+ "黄月英": {
445+ "faction": "蜀",
446+ "maxHealth": 3,
447+ "gender": "女",
448+ "skills": {
449+ "集智": "被动技:使用非延时锦囊牌时,你可以摸一张牌",
450+ "奇才": "锁定技:你使用任何锦囊牌无距离限制"
451+ }
452+ },
453+ "界黄月英": {
454+ "faction": "蜀",
455+ "maxHealth": 3,
456+ "gender": "女",
457+ "skills": {
458+ "界集智": "被动技:使用非转化锦囊牌时你可以摸一张牌;若此牌是基本牌,可弃之令本回合手牌上限+1",
459+ "界奇才": "锁定技:你使用任何锦囊牌无距离限制;其他角色不能弃置你装备区的防具或宝物"
460+ }
461+ },
462+ "马超": {
463+ "faction": "蜀",
464+ "maxHealth": 4,
465+ "gender": "男",
466+ "skills": {
467+ "马术": "锁定技:你与其他角色的距离-1",
468+ "铁骑": "使用杀指定目标后可判定,红色则目标不能出闪抵消"
469+ }
470+ },
471+ "界马超": {
472+ "faction": "蜀",
473+ "maxHealth": 4,
474+ "gender": "男",
475+ "skills": {
476+ "马术": "锁定技:你与其他角色的距离-1",
477+ "界铁骑": "使用杀指定目标后,可令其本回合非锁定技失效并判定;除非其弃一张与判定结果同花色的牌,否则不能抵消此杀"
478+ }
479+ },
480+ "界马岱": {
481+ "faction": "蜀",
482+ "maxHealth": 4,
483+ "gender": "男",
484+ "skills": {
485+ "马术": "锁定技:你与其他角色的距离-1",
486+ "界潜袭": "准备阶段,你可以摸一张牌并展示一张牌;距离为1的其他角色本回合不能使用或打出与\"潜袭\"牌颜色相同的手牌,你本回合使用\"潜袭\"牌造成的伤害+1"
487+ }
488+ },
489+ "黄忠": {
490+ "faction": "蜀",
491+ "maxHealth": 4,
492+ "gender": "男",
493+ "skills": {
494+ "烈弓": "使用杀指定目标后,若其手牌数不小于你的体力值或不大于你的攻击范围,可令其不能抵消此杀"
495+ }
496+ },
497+ "界黄忠": {
498+ "faction": "蜀",
499+ "maxHealth": 4,
500+ "gender": "男",
501+ "skills": {
502+ "界烈弓": "你的杀攻击范围为此杀点数;指定目标后,若其手牌数不大于你,其不能抵消;若其体力值不小于你,伤害+1"
503+ }
504+ },
505+ "魏延": {
506+ "faction": "蜀",
507+ "maxHealth": 4,
508+ "gender": "男",
509+ "skills": {
510+ "狂骨": "对距离1以内的角色每造成1点伤害后,你可以回复1点体力或摸一张牌"
511+ }
512+ },
513+ "界魏延": {
514+ "faction": "蜀",
515+ "maxHealth": 4,
516+ "gender": "男",
517+ "skills": {
518+ "界狂骨": "对距离1以内的角色每造成1点伤害时,你可以回复1点体力或摸一张牌",
519+ "奇谋": "限定技,出牌阶段,你可以失去任意点体力并摸等量的牌,然后本回合你计算与其他角色的距离-X且使用【杀】的限制次数+X(X为失去的体力值)"
520+ }
521+ },
522+ "卧龙诸葛": {
523+ "faction": "蜀",
524+ "maxHealth": 3,
525+ "gender": "男",
526+ "skills": {
527+ "八阵": "锁定技:没有装备防具时,视为装备着八卦阵",
528+ "火计": "你可以将一张红色手牌当【火攻】使用",
529+ "看破": "你可以将一张黑色手牌当【无懈可击】使用"
530+ }
531+ },
532+ "界卧龙诸葛": {
533+ "faction": "蜀",
534+ "maxHealth": 3,
535+ "gender": "男",
536+ "skills": {
537+ "八阵": "锁定技:没有装备防具时,视为装备着八卦阵",
538+ "界火计": "你可以将一张红色牌当【火攻】使用;你的【火攻】改为目标展示随机手牌,你弃同颜色牌造伤",
539+ "界看破": "你可以将一张黑色牌当【无懈可击】使用;你的【无懈可击】不能被响应"
540+ }
541+ },
542+ "诸葛亮": {
543+ "faction": "蜀",
544+ "maxHealth": 3,
545+ "gender": "男",
546+ "skills": {
547+ "观星": "准备阶段开始时,观看牌堆顶X张牌(X为全场角色数至多5),调整顺序,余者置牌堆底",
548+ "空城": "锁定技:若你没有手牌,你不是杀和决斗的合法目标"
549+ }
550+ },
551+ "界诸葛亮": {
552+ "faction": "蜀",
553+ "maxHealth": 3,
554+ "gender": "男",
555+ "skills": {
556+ "界观星": "准备阶段,观看牌堆顶 5 张(存活角色数<4 时为 3 张),任意排序置顶/置底;若皆置底,结束阶段可再次发动",
557+ "界空城": "锁定技:若你没有手牌,你不是杀和决斗的合法目标;你使用的杀被闪抵消后摸一张牌"
558+ }
559+ },
560+ "庞统": {
561+ "faction": "蜀",
562+ "maxHealth": 3,
563+ "gender": "男",
564+ "skills": {
565+ "连环": "你可以将一张梅花手牌当【铁索连环】使用或重铸",
566+ "涅槃": "限定技:濒死时弃置所有牌和判定区牌,重置武将牌,摸三张并回复至3点体力"
567+ }
568+ },
569+ "界庞统": {
570+ "faction": "蜀",
571+ "maxHealth": 3,
572+ "gender": "男",
573+ "skills": {
574+ "界连环": "你可以将一张梅花牌当【铁索连环】使用或重铸;你使用【铁索连环】可以多指定一个目标(至多3名)",
575+ "界涅槃": "限定技:濒死时弃置所有牌,复原武将牌,摸三张并回复至3点体力,然后获得八阵/火计/看破中的一个"
576+ }
577+ },
578+ "孟获": {
579+ "faction": "蜀",
580+ "maxHealth": 4,
581+ "gender": "男",
582+ "skills": {
583+ "祸首": "锁定技:南蛮入侵对你无效;你是任何南蛮入侵造成伤害的来源",
584+ "再起": "摸牌阶段,若已受伤,可放弃摸牌,展示牌堆顶X张(X=已损失体力+1),红桃回血弃置,其余入门"
585+ }
586+ },
587+ "界孟获": {
588+ "faction": "蜀",
589+ "maxHealth": 4,
590+ "gender": "男",
591+ "skills": {
592+ "祸首": "锁定技:南蛮入侵对你无效;你是任何南蛮入侵造成伤害的来源",
593+ "界再起": "结束阶段,你可以令至多X名角色各选一项(X=本回合置入弃牌堆的红色牌数):1.摸一张牌;2.令你回复1点体力"
594+ }
595+ },
596+ "祝融": {
597+ "faction": "蜀",
598+ "maxHealth": 4,
599+ "gender": "女",
600+ "skills": {
601+ "巨象": "锁定技:南蛮入侵对你无效;其他角色使用的南蛮入侵结算后进入弃牌堆时,你获得它",
602+ "烈刃": "使用杀造成伤害后,可与受害者拼点,赢则获得对方一张牌"
603+ }
604+ },
605+ "界祝融": {
606+ "faction": "蜀",
607+ "maxHealth": 4,
608+ "gender": "女",
609+ "skills": {
610+ "巨象": "锁定技:南蛮入侵对你无效;其他角色使用的南蛮入侵结算后进入弃牌堆时,你获得它",
611+ "烈刃": "使用杀造成伤害后,可与受害者拼点,赢则获得对方一张牌"
612+ }
613+ },
614+ "姜维": {
615+ "faction": "蜀",
616+ "maxHealth": 4,
617+ "gender": "男",
618+ "skills": {
619+ "挑衅": "出牌阶段限一次:指定一名能用杀攻击到你的角色,其须对你出杀,否则你弃其一张牌",
620+ "志继": "觉醒技:准备阶段且无手牌时,回复1体力或摸2牌,减1体力上限并永久获得\"观星\""
621+ }
622+ },
623+ "界姜维": {
624+ "faction": "蜀",
625+ "maxHealth": 4,
626+ "gender": "男",
627+ "skills": {
628+ "界挑衅": "出牌阶段限两次:指定一名攻击范围包含你的角色,其须对你出杀且造成伤害,否则你弃其一张牌",
629+ "界志继": "觉醒技:准备阶段或结束阶段且无手牌时,回复1体力或摸2牌,减1体力上限并永久获得\"观星\""
630+ }
631+ },
632+ "刘禅": {
633+ "faction": "蜀",
634+ "maxHealth": 3,
635+ "gender": "男",
636+ "skills": {
637+ "享乐": "锁定技:其他角色用杀指定你为目标时,需额外弃一张基本牌,否则杀对你无效",
638+ "放权": "跳过出牌阶段,回合结束时弃一张手牌,令一名其他角色进行一个额外回合",
639+ "若愚": "主公技/觉醒技:回合开始且体力全场最少时,增加1体力上限、回复1体力并永久获得\"激将\""
640+ }
641+ },
642+ "界刘禅": {
643+ "faction": "蜀",
644+ "maxHealth": 3,
645+ "gender": "男",
646+ "skills": {
647+ "享乐": "锁定技:其他角色用杀指定你为目标时,需额外弃一张基本牌,否则杀对你无效",
648+ "界放权": "跳过出牌阶段,弃牌阶段开始时弃一张手牌,令一名其他角色进行一个额外回合",
649+ "界若愚": "主公技/觉醒技:回合开始且体力全场最少时,增加1体力上限、回复至3点体力并永久获得\"激将\""
650+ }
651+ },
652+ "界关兴张苞": {
653+ "faction": "蜀",
654+ "maxHealth": 4,
655+ "gender": "男",
656+ "skills": {
657+ "界父魂": "转化技:两张牌当杀;转化杀目标只能用同色手牌响应;出牌阶段杀造成伤害后本回合获得武圣咆哮"
658+ }
659+ },
660+ "界夏侯氏": {
661+ "faction": "蜀",
662+ "maxHealth": 3,
663+ "gender": "女",
664+ "skills": {
665+ "界樵拾": "每个结束阶段,你可以与当前回合角色各摸一张牌;然后若其与你手牌数不相等,此技能本轮失效",
666+ "界燕语": "出牌阶段,你可以重铸【杀】;出牌阶段结束时,若你本阶段失去过至少两张【杀】,可令一名男性角色摸两张牌"
667+ }
668+ },
669+ "界廖化": {
670+ "faction": "蜀",
671+ "maxHealth": 4,
672+ "gender": "男",
673+ "skills": {
674+ "界当先": "锁定技:回合开始时执行一个额外的出牌阶段;此阶段开始时可获得一张无距离限制的杀;若未于此阶段造成过伤害,阶段结束时受1点伤害",
675+ "界伏枥": "限定技:濒死时,将体力回复至X点且手牌摸至X张(X为全场势力数);然后若X大于你造成的伤害数,你翻面"
676+ }
677+ },
678+ "界张松": {
679+ "faction": "蜀",
680+ "maxHealth": 3,
681+ "gender": "男",
682+ "skills": {
683+ "界强识": "出牌阶段开始时,你可观看一名其他角色的手牌并展示其中一张牌;本阶段你使用此类别的牌后可摸一张牌",
684+ "界献图": "其他角色出牌阶段开始时,你可以摸至多两张牌,然后交给其等量牌;此阶段结束时若其造成伤害小于你以此法交给其的牌数,你失去1点体力"
685+ }
686+ },
687+ "界徐庶": {
688+ "faction": "蜀",
689+ "maxHealth": 4,
690+ "gender": "男",
691+ "skills": {
692+ "界诛害": "其他角色的结束阶段,若其本回合造成过伤害,你可以对其使用一张【杀】",
693+ "界潜心": "觉醒技:造成伤害后,若你已受伤,你减少1点体力上限并获得\"荐言\""
694+ }
695+ },
696+ "界法正": {
697+ "faction": "蜀",
698+ "maxHealth": 3,
699+ "gender": "男",
700+ "skills": {
701+ "界眩惑": "摸牌阶段结束时,交给一名其他角色两张牌,令其选:①对你指定的另一名角色出杀;②你观看其手牌并获得两张",
702+ "界恩怨": "获得一名其他角色≥2张牌后可令其摸1张;受到1点伤害后令来源选:交红色手牌或失去1点体力"
703+ }
704+ },
705+ "界简雍": {
706+ "faction": "蜀",
707+ "maxHealth": 3,
708+ "gender": "男",
709+ "skills": {
710+ "界纵适": "当你拼点赢时,你可以获得点数较小的拼点牌;当你没赢时,你可以获得你的拼点牌",
711+ "界巧说": "出牌阶段限一次拼点:赢则本回合下一张牌可多/少指定一个目标;没赢则本回合不能使用锦囊牌"
712+ }
713+ },
714+ "王平": {
715+ "faction": "蜀",
716+ "maxHealth": 4,
717+ "gender": "男",
718+ "skills": {
719+ "飞军": "出牌阶段限一次,弃置一张牌,令一名手牌数大于你的角色交给你一张牌,或令一名装备区里牌数大于你的角色弃置一张装备",
720+ "兵略": "锁定技,当你首次对一名角色发动\"飞军\"时,你摸两张牌"
721+ }
722+ },
723+ "诸葛瞻": {
724+ "faction": "蜀",
725+ "maxHealth": 3,
726+ "gender": "男",
727+ "skills": {
728+ "罪论": "结束阶段可观看牌堆顶三张牌,获得其中X张(X为满足项数:本回合造成过伤害/未弃置过牌/手牌数全场最少),余牌任意顺序置牌堆顶;均不满足则自己与一名其他角色各失去1点体力",
729+ "父荫": "锁定技:每回合首次成为其他角色杀或决斗的目标后,若其手牌数不小于你,此牌对你无效"
730+ }
731+ },
732+ "陈到": {
733+ "faction": "蜀",
734+ "maxHealth": 4,
735+ "gender": "男",
736+ "skills": {
737+ "往烈": "你出牌阶段使用的首张牌无距离限制;当你于出牌阶段使用基本牌或普通锦囊牌时,你可以令此牌不能被响应,然后你本阶段不能再使用牌"
738+ }
739+ },
740+ "卧龙诸葛亮": {
741+ "faction": "蜀",
742+ "maxHealth": 3,
743+ "gender": "男",
744+ "skills": {
745+ "八阵": "锁定技:没有装备防具时,视为装备着八卦阵",
746+ "火计": "你可以将一张红色手牌当【火攻】使用",
747+ "看破": "你可以将一张黑色手牌当【无懈可击】使用"
748+ }
749+ },
750+ "严颜": {
751+ "faction": "蜀",
752+ "maxHealth": 4,
753+ "gender": "男",
754+ "skills": {
755+ "拒战": "转换技。阳:成为其他角色杀的目标后,你可与其各摸一张牌,然后其本回合不能再对你使用牌。阴:使用杀指定目标后,你可获得其一张牌,然后你本回合不能再对其使用牌"
756+ }
757+ },
758+ "孙权": {
759+ "faction": "吴",
760+ "maxHealth": 4,
761+ "gender": "男",
762+ "skills": {
763+ "制衡": "出牌阶段限一次:弃任意张牌(手牌/装备),摸等量的牌",
764+ "救援": "主公技,锁定技:其他吴势力角色对你使用【桃】的回复值+1"
765+ }
766+ },
767+ "界孙权": {
768+ "faction": "吴",
769+ "maxHealth": 4,
770+ "gender": "男",
771+ "skills": {
772+ "界制衡": "出牌阶段限一次:弃任意张牌(手牌/装备),摸等量张;若弃置了所有手牌,额外摸一张",
773+ "界救援": "主公技:其他吴势力角色于其回合内回复体力时,若其体力≥你,其可改为令你回复1点体力,然后其摸一张牌"
774+ }
775+ },
776+ "甘宁": {
777+ "faction": "吴",
778+ "maxHealth": 4,
779+ "gender": "男",
780+ "skills": {
781+ "奇袭": "你可以将一张黑色牌当【过河拆桥】使用"
782+ }
783+ },
784+ "界甘宁": {
785+ "faction": "吴",
786+ "maxHealth": 4,
787+ "gender": "男",
788+ "skills": {
789+ "奇袭": "你可以将一张黑色牌当【过河拆桥】使用",
790+ "奋威": "限定技,当一张锦囊牌指定多个目标后,你可以令此牌对任意个目标无效"
791+ }
792+ },
793+ "吕蒙": {
794+ "faction": "吴",
795+ "maxHealth": 4,
796+ "gender": "男",
797+ "skills": {
798+ "克己": "出牌阶段结束时,若你本回合未使用或打出过【杀】,你可以跳过弃牌阶段"
799+ }
800+ },
801+ "界吕蒙": {
802+ "faction": "吴",
803+ "maxHealth": 4,
804+ "gender": "男",
805+ "skills": {
806+ "界克己": "若你未于本回合出牌阶段使用或打出过【杀】,你可以跳过弃牌阶段",
807+ "勤学": "觉醒技:准备或结束阶段,若手牌数比体力值多2或更多,减1体力上限,回复1体力或摸2牌,然后获得\"攻心\"",
808+ "博图": "每轮限X次(X为存活角色数至多3),回合结束后若本回合弃牌堆含四种花色,可执行一个额外回合"
809+ }
810+ },
811+ "黄盖": {
812+ "faction": "吴",
813+ "maxHealth": 4,
814+ "gender": "男",
815+ "skills": {
816+ "苦肉": "出牌阶段,你可以失去1点体力,然后摸两张牌。"
817+ }
818+ },
819+ "界黄盖": {
820+ "faction": "吴",
821+ "maxHealth": 4,
822+ "gender": "男",
823+ "skills": {
824+ "界苦肉": "出牌阶段限一次,你可以弃置一张牌,然后失去1点体力。",
825+ "诈降": "锁定技:当你失去1点体力后,你摸三张牌,若在你的出牌阶段,你本回合使用【杀】的限制次数+1、使用红色【杀】无距离限制且不能被抵消。"
826+ }
827+ },
828+ "周瑜": {
829+ "faction": "吴",
830+ "maxHealth": 3,
831+ "gender": "男",
832+ "skills": {
833+ "反间": "出牌阶段限一次,你可以令一名其他角色选择一种花色,令其获得并展示你的一张手牌,若此牌花色与其选择的花色不同,你对其造成1点伤害",
834+ "英姿": "摸牌阶段,你可以额外摸一张牌"
835+ }
836+ },
837+ "界周瑜": {
838+ "faction": "吴",
839+ "maxHealth": 3,
840+ "gender": "男",
841+ "skills": {
842+ "界英姿": "锁定技:摸牌阶段你多摸一张牌;你的手牌上限为你的体力上限",
843+ "界反间": "出牌阶段限一次,展示并交给一名其他角色一张手牌,其选择:弃置同色牌或失去1点体力"
844+ }
845+ },
846+ "大乔": {
847+ "faction": "吴",
848+ "maxHealth": 3,
849+ "gender": "女",
850+ "skills": {
851+ "国色": "你可以将一张方块牌当【乐不思蜀】使用",
852+ "流离": "当你成为杀的目标时,可弃一张牌,将此杀转移给攻击范围内一名其他角色"
853+ }
854+ },
855+ "界大乔": {
856+ "faction": "吴",
857+ "maxHealth": 3,
858+ "gender": "女",
859+ "skills": {
860+ "界国色": "出牌阶段限一次,选一项后摸一张牌:①方片牌当乐不思蜀使用;②弃方片牌和场上乐不思蜀",
861+ "流离": "当你成为杀的目标时,可弃一张牌,将此杀转移给攻击范围内一名其他角色"
862+ }
863+ },
864+ "陆逊": {
865+ "faction": "吴",
866+ "maxHealth": 3,
867+ "gender": "男",
868+ "skills": {
869+ "谦逊": "锁定技:你不能成为顺手牵羊和乐不思蜀的目标",
870+ "连营": "被动技:当你失去最后的手牌时,你可以摸一张牌"
871+ }
872+ },
873+ "界陆逊": {
874+ "faction": "吴",
875+ "maxHealth": 3,
876+ "gender": "男",
877+ "skills": {
878+ "界谦逊": "当延时锦囊或他人普通锦囊对你生效且你为唯一目标时,你可以将所有手牌移出游戏直到回合结束",
879+ "界连营": "被动技:当你失去所有手牌后,你可以令至多X名角色各摸一张牌(X为你失去的手牌数)"
880+ }
881+ },
882+ "孙尚香": {
883+ "faction": "吴",
884+ "maxHealth": 3,
885+ "gender": "女",
886+ "skills": {
887+ "结姻": "出牌阶段限一次,弃两张手牌,令你与一名已受伤的男性角色各回复1点体力",
888+ "枭姬": "失去装备区的牌时,你可以摸两张牌"
889+ }
890+ },
891+ "界孙尚香": {
892+ "faction": "吴",
893+ "maxHealth": 3,
894+ "gender": "女",
895+ "skills": {
896+ "界结姻": "出牌阶段限一次:选一名男性角色,弃一张手牌或置一张装备牌入其装备区,体力大者摸1张,小者回1点",
897+ "枭姬": "失去装备区的牌时,你可以摸两张牌"
898+ }
899+ },
900+ "小乔": {
901+ "faction": "吴",
902+ "maxHealth": 3,
903+ "gender": "女",
904+ "skills": {
905+ "天香": "受到伤害时,弃一张红桃手牌防止之,令一名其他角色二选一:①受来源1伤害并摸X(X为已损失体力至多5);②失去1体力并获得弃置的牌",
906+ "红颜": "锁定技:你的黑桃牌均视为红桃牌"
907+ }
908+ },
909+ "界小乔": {
910+ "faction": "吴",
911+ "maxHealth": 3,
912+ "gender": "女",
913+ "skills": {
914+ "界红颜": "锁定技:你的黑桃牌和黑桃判定牌视为红桃牌;装备区有红桃牌时手牌上限等于体力上限",
915+ "界天香": "受到伤害时,弃一张红桃牌防止之,令一名其他角色二选一:①受来源1伤害并摸X(X为已损失体力至多5);②失去1体力并获得弃置的牌",
916+ "飘零": "结束阶段可判定,红桃则将判定牌置牌堆顶或交给一名角色(给自己则弃一张牌)"
917+ }
918+ },
919+ "周泰": {
920+ "faction": "吴",
921+ "maxHealth": 4,
922+ "gender": "男",
923+ "skills": {
924+ "不屈": "锁定技:濒死时将牌堆顶一张牌作\"创\"牌置于武将牌上,点数与已有创牌均不同则回复至1体力,相同则移去此牌"
925+ }
926+ },
927+ "界周泰": {
928+ "faction": "吴",
929+ "maxHealth": 4,
930+ "gender": "男",
931+ "skills": {
932+ "界不屈": "锁定技:濒死时翻牌堆顶作\"创\"牌置于武将牌上,点数与已有创均不同则回复至1体力,相同则移去此牌;武将牌上有\"创\"时手牌上限为\"创\"的数量",
933+ "奋激": "当一名角色的手牌被弃置或获得后,你可以失去1点体力令其摸两张牌"
934+ }
935+ },
936+ "太史慈": {
937+ "faction": "吴",
938+ "maxHealth": 4,
939+ "gender": "男",
940+ "skills": {
941+ "天义": "出牌阶段限一次,与一名角色拼点:赢则本回合攻击范围无限、可额外使用一张杀、杀可额外指定一个目标;没赢则本回合不能使用杀"
942+ }
943+ },
944+ "界太史慈": {
945+ "faction": "吴",
946+ "maxHealth": 4,
947+ "gender": "男",
948+ "skills": {
949+ "天义": "出牌阶段限一次,与一名角色拼点:赢则本回合攻击范围无限、可额外使用一张杀、杀可额外指定一个目标;没赢则本回合不能使用杀",
950+ "酣战": "拼点前可令对方用随机手牌拼点;拼点后可获得两张拼点牌中点数最大的杀"
951+ }
952+ },
953+ "鲁肃": {
954+ "faction": "吴",
955+ "maxHealth": 3,
956+ "gender": "男",
957+ "skills": {
958+ "好施": "摸牌阶段,你可以额外摸两张牌,若此时你的手牌数超过五张,你必须将一半(向下取整)的手牌交给除你外手牌数最少的一名角色",
959+ "缔盟": "出牌阶段限一次,选择两名其他角色,弃置等同于他们手牌数差的牌,然后交换他们的手牌"
960+ }
961+ },
962+ "界鲁肃": {
963+ "faction": "吴",
964+ "maxHealth": 3,
965+ "gender": "男",
966+ "skills": {
967+ "界好施": "摸牌阶段多摸两张,手牌>5时分半给最少者;给牌后直到下回合开始,成为杀/普通锦囊目标时其可给你一张牌",
968+ "界缔盟": "出牌阶段限一次,令两名角色交换手牌(差不大于你的牌数),出牌阶段结束时弃X张牌(X为手牌数差)"
969+ }
970+ },
971+ "孙坚": {
972+ "faction": "吴",
973+ "maxHealth": 4,
974+ "gender": "男",
975+ "skills": {
976+ "英魂": "回合开始阶段,若你已受伤,可令一名其他角色选择一项:摸X张牌再弃一张牌,或摸一张牌再弃X张牌(X为你已损失体力值)"
977+ }
978+ },
979+ "界孙坚": {
980+ "faction": "吴",
981+ "maxHealth": 4,
982+ "gender": "男",
983+ "skills": {
984+ "英魂": "回合开始阶段,若你已受伤,可令一名其他角色选择一项:摸X张牌再弃一张牌,或摸一张牌再弃X张牌(X为你已损失体力值)",
985+ "武烈": "限定技,结束阶段,你可以失去任意点体力,令等量的其他角色各获得1个「烈」标记。有「烈」的角色受到伤害时,防止此伤害,然后移去「烈」"
986+ }
987+ },
988+ "孙策": {
989+ "faction": "吴",
990+ "maxHealth": 4,
991+ "gender": "男",
992+ "skills": {
993+ "激昂": "使用或被使用【决斗】或红色【杀】时,你可以摸一张牌",
994+ "魂姿": "觉醒技:准备阶段且体力为1时,减1体力上限并永久获得\"英姿\"和\"英魂\"",
995+ "制霸": "主公技:其他吴势力角色出牌阶段可与你拼点,若其没赢你可获得双方拼点牌;觉醒后可拒绝拼点"
996+ }
997+ },
998+ "界孙策": {
999+ "faction": "吴",
1000+ "maxHealth": 4,
1001+ "gender": "男",
1002+ "skills": {
1003+ "界激昂": "使用/被使用【决斗】或红色【杀】时可摸一张牌;每回合首次此类牌因弃置入弃牌堆时可失去1体力获得之",
1004+ "界魂姿": "觉醒技:准备阶段且体力为1时,减1体力上限并永久获得\"界英姿\"\"英魂\";本回合结束阶段摸2牌或回复1体力",
1005+ "界制霸": "主公技:你与其他吴势力角色可互相拼点;若发起方没赢,你可以获得两张拼点牌;觉醒后可拒绝盟友发起的拼点"
1006+ }
1007+ },
1008+ "张昭张纮": {
1009+ "faction": "吴",
1010+ "maxHealth": 3,
1011+ "gender": "男",
1012+ "skills": {
1013+ "直谏": "出牌阶段:将一张装备牌置于一名其他角色的空装备区,然后摸一张牌",
1014+ "固政": "其他角色弃牌阶段结束时:将其一张弃牌返回其手牌,然后获得其余弃牌"
1015+ }
1016+ },
1017+ "界张昭张纮": {
1018+ "faction": "吴",
1019+ "maxHealth": 3,
1020+ "gender": "男",
1021+ "skills": {
1022+ "界直谏": "出牌阶段:将一张装备牌置入一名其他角色的装备区(可替换原装备),然后摸一张牌",
1023+ "界固政": "每阶段限一次,其他角色≥2张牌因弃置置入弃牌堆后,可将其中一张交给该角色,然后可获其余"
1024+ }
1025+ },
1026+ "界凌统": {
1027+ "faction": "吴",
1028+ "maxHealth": 4,
1029+ "gender": "男",
1030+ "skills": {
1031+ "界旋风": "失去装备区里的牌,或一次性失去至少两张牌后,可依次弃置至多两名其他角色共计至多两张牌"
1032+ }
1033+ },
1034+ "界吴国太": {
1035+ "faction": "吴",
1036+ "maxHealth": 3,
1037+ "gender": "女",
1038+ "skills": {
1039+ "界甘露": "出牌阶段限一次:令两名角色交换装备区里的牌;若两人装备数差 X 大于你已损失的体力值,你须弃 X 张牌",
1040+ "界补益": "当一名角色进入濒死状态时,可选其一张牌;若非基本牌,弃置之并回复1点体力"
1041+ }
1042+ },
1043+ "界徐盛": {
1044+ "faction": "吴",
1045+ "maxHealth": 4,
1046+ "gender": "男",
1047+ "skills": {
1048+ "界破军": "当你使用【杀】指定目标后,你可以将其至多X张牌移出游戏直到回合结束(X为其体力值)。你使用的【杀】对手牌区与装备区内牌数皆不大于你的角色造成的伤害+1"
1049+ }
1050+ },
1051+ "界程普": {
1052+ "faction": "吴",
1053+ "maxHealth": 4,
1054+ "gender": "男",
1055+ "skills": {
1056+ "界疠火": "你使用的非火【杀】可以改为火【杀】;此牌造成伤害后,你弃1牌或失去1体力;你使用的火【杀】可多指定一个目标",
1057+ "界醇醪": "你或相邻角色的【杀】因弃置置入弃牌堆后,将之置于你的武将牌上为\"醇\";濒死时你可移去X张\"醇\"视为一张【酒】(X为本轮以此法使用酒的次数)"
1058+ }
1059+ },
1060+ "界虞翻": {
1061+ "faction": "吴",
1062+ "maxHealth": 3,
1063+ "gender": "男",
1064+ "skills": {
1065+ "界纵玄": "当你的牌因弃置置入弃牌堆后,或你上家每回合首次因弃置置入弃牌堆后,你可以将其中任意张牌置于牌堆顶",
1066+ "界直言": "你上家或你的结束阶段,你可令一名角色摸一张牌并展示之;装备牌:其使用之并回复1点体力;非装备且其体力不等于你:其失去1点体力"
1067+ }
1068+ },
1069+ "界韩当": {
1070+ "faction": "吴",
1071+ "maxHealth": 4,
1072+ "gender": "男",
1073+ "skills": {
1074+ "界弓骑": "出牌阶段限一次,弃一张牌使本回合攻击范围无限,且同花色杀无次数限制;弃装备可再弃一名其他角色一张牌",
1075+ "界解烦": "限定技,出牌阶段选择一名角色,令所有攻击范围内包含其的角色各选:弃一张武器牌 或 令该角色摸一张牌。第一轮发动后回合结束视为未发动"
1076+ }
1077+ },
1078+ "陆抗": {
1079+ "faction": "吴",
1080+ "maxHealth": 4,
1081+ "gender": "男",
1082+ "skills": {
1083+ "谦节": "锁定技:当你进入连环状态时防止之;你不能成为延时锦囊牌和其他角色拼点的目标",
1084+ "决堰": "出牌阶段限一次,废除一个装备栏并于本回合获得对应效果:武器栏杀次数+3;防具栏摸三张且手牌上限+3;坐骑栏使用牌无距离限制;宝物栏获得集智",
1085+ "破势": "觉醒技:准备阶段,若装备栏均被废除或体力值为1,减少1点体力上限,将手牌摸至体力上限,失去决堰并获得怀柔"
1086+ }
1087+ },
1088+ "陆绩": {
1089+ "faction": "吴",
1090+ "maxHealth": 3,
1091+ "gender": "男",
1092+ "skills": {
1093+ "怀橘": "锁定技:游戏开始时获得3枚橘标记;有橘的角色受到伤害时防止伤害并移除1枚橘;有橘的角色摸牌阶段多摸一张牌",
1094+ "遗礼": "出牌阶段开始时,你可以失去1点体力或移除1枚橘,然后令一名其他角色获得1枚橘",
1095+ "整论": "若你没有橘,你可以跳过摸牌阶段并获得1枚橘"
1096+ }
1097+ },
1098+ "张昭张弘": {
1099+ "faction": "吴",
1100+ "maxHealth": 3,
1101+ "gender": "男",
1102+ "skills": {
1103+ "直谏": "出牌阶段:将一张装备牌置于一名其他角色的空装备区,然后摸一张牌",
1104+ "固政": "其他角色弃牌阶段结束时:将其一张弃牌返回其手牌,然后获得其余弃牌"
1105+ }
1106+ },
1107+ "周妃": {
1108+ "faction": "吴",
1109+ "maxHealth": 3,
1110+ "gender": "男",
1111+ "skills": {
1112+ "良姻": "每回合首次有牌移出/移入游戏后,你可以与一名其他角色各摸/弃置一张牌,然后可令其中一名手牌数为X的角色回复1点体力(X为箜声牌数)",
1113+ "箜声": "准备阶段,你可以将任意张牌置于你的武将牌上;结束阶段,你获得其中的非装备牌,然后令一名角色使用剩余牌并失去1点体力"
1114+ }
1115+ },
1116+ "孙亮": {
1117+ "faction": "吴",
1118+ "maxHealth": 3,
1119+ "gender": "男",
1120+ "skills": {
1121+ "溃诛": "弃牌阶段结束时,选择一项:令至多X名角色各摸一张牌,或对体力值之和为X的角色各造成1点伤害(X为本阶段弃牌数)",
1122+ "掣政": "锁定技:防止你出牌阶段对攻击范围内不含你的角色造成的伤害;出牌阶段结束时若用牌数少于这些角色数,弃置其中一名角色一张牌",
1123+ "立军": "主公技:其他吴势力角色用杀后可交给你获得,你可令其摸一张牌且本回合使用杀的限制次数+1"
1124+ }
1125+ },
1126+ "华佗": {
1127+ "faction": "群",
1128+ "maxHealth": 3,
1129+ "gender": "男",
1130+ "skills": {
1131+ "急救": "在你的回合外,你可以将一张红色牌当【桃】使用。",
1132+ "青囊": "出牌阶段限一次,弃一张手牌,令一名角色回复 1 点体力"
1133+ }
1134+ },
1135+ "吕布": {
1136+ "faction": "群",
1137+ "maxHealth": 4,
1138+ "gender": "男",
1139+ "skills": {
1140+ "无双": "锁定技:你使用【杀】的目标需连续出两张【闪】才能抵消;与你【决斗】的角色每次需连续打出两张【杀」"
1141+ }
1142+ },
1143+ "貂蝉": {
1144+ "faction": "群",
1145+ "maxHealth": 3,
1146+ "gender": "女",
1147+ "skills": {
1148+ "离间": "出牌阶段限一次,弃一张牌,令一名男性角色视为对另一名男性角色使用决斗",
1149+ "闭月": "回合结束阶段,你可以摸一张牌"
1150+ }
1151+ },
1152+ "界貂蝉": {
1153+ "faction": "群",
1154+ "maxHealth": 3,
1155+ "gender": "女",
1156+ "skills": {
1157+ "离间": "出牌阶段限一次,弃一张牌,令一名男性角色视为对另一名男性角色使用决斗",
1158+ "界闭月": "结束阶段,若你没有手牌,你可以摸两张牌,否则你可以摸一张牌"
1159+ }
1160+ },
1161+ "张角": {
1162+ "faction": "群",
1163+ "maxHealth": 3,
1164+ "gender": "男",
1165+ "skills": {
1166+ "雷击": "当你使用或打出【闪】时,可令一名其他角色判定,黑桃则造成2点雷电伤害;梅花则你回复1点体力并对其造成1点雷电伤害",
1167+ "鬼道": "判定牌生效前,你可以用一张黑色牌替换之",
1168+ "黄天": "主公技:其他群势力角色可在出牌阶段将一张【闪】或【闪电】交给你"
1169+ }
1170+ },
1171+ "于吉": {
1172+ "faction": "群",
1173+ "maxHealth": 3,
1174+ "gender": "男",
1175+ "skills": {
1176+ "蛊惑": "每回合限一次,扣置一张手牌声明为基本牌(杀/闪/桃/酒)使用或打出;其他角色可质疑"
1177+ }
1178+ },
1179+ "界于吉": {
1180+ "faction": "群",
1181+ "maxHealth": 3,
1182+ "gender": "男",
1183+ "skills": {
1184+ "界蛊惑": "每回合限一次,扣置一张手牌声明为基本牌使用/打出;其他角色可同时质疑:真→缠怨+弃牌或失1体力,假→作废+质疑者摸1牌"
1185+ }
1186+ },
1187+ "袁绍": {
1188+ "faction": "群",
1189+ "maxHealth": 4,
1190+ "gender": "男",
1191+ "skills": {
1192+ "乱击": "你可以将两张同花色的手牌当【万箭齐发】使用"
1193+ }
1194+ },
1195+ "界袁绍": {
1196+ "faction": "群",
1197+ "maxHealth": 4,
1198+ "gender": "男",
1199+ "skills": {
1200+ "界乱击": "你可以将两张花色相同的手牌当【万箭齐发】使用;你使用【万箭齐发】可以少选一个目标",
1201+ "界血裔": "主公技:游戏开始时获得X枚裔标记(X为群势力角色数的两倍);出牌阶段开始时可移除1枚裔并摸一张牌;每枚裔手牌上限+1"
1202+ }
1203+ },
1204+ "庞德": {
1205+ "faction": "群",
1206+ "maxHealth": 4,
1207+ "gender": "男",
1208+ "skills": {
1209+ "马术": "锁定技:你与其他角色的距离-1",
1210+ "鞬出": "使用杀指定目标后,可弃其一张牌:装备牌则其不能出闪,非装备牌则其获得此杀"
1211+ }
1212+ },
1213+ "界庞德": {
1214+ "faction": "群",
1215+ "maxHealth": 4,
1216+ "gender": "男",
1217+ "skills": {
1218+ "马术": "锁定技:你与其他角色的距离-1",
1219+ "界鞬出": "使用杀指定目标后,可弃其一张牌:基本牌则其获得此杀;非基本牌则其不能抵消此杀且本回合出杀次数+1"
1220+ }
1221+ },
1222+ "颜良文丑": {
1223+ "faction": "群",
1224+ "maxHealth": 4,
1225+ "gender": "男",
1226+ "skills": {
1227+ "双雄": "摸牌阶段,改为进行一次判定,获得判定牌,本回合可将与之颜色不同的手牌当决斗使用"
1228+ }
1229+ },
1230+ "界颜良文丑": {
1231+ "faction": "群",
1232+ "maxHealth": 4,
1233+ "gender": "男",
1234+ "skills": {
1235+ "界双雄": "摸牌阶段结束时弃置一张牌,本回合可将与之颜色不同的牌当决斗使用;结束阶段获得本回合对你造成伤害的牌"
1236+ }
1237+ },
1238+ "董卓": {
1239+ "faction": "群",
1240+ "maxHealth": 8,
1241+ "gender": "男",
1242+ "skills": {
1243+ "酒池": "你可以将一张黑桃手牌当【酒】使用",
1244+ "肉林": "锁定技:你对女性角色/女性角色对你使用【杀】时,目标需连续出两张闪才能抵消",
1245+ "崩坏": "锁定技:回合结束阶段,若你的体力不是全场最少的,须减1点体力或1点体力上限",
1246+ "暴虐": "主公技:其他群雄角色造成伤害后,可判定,黑桃则回复1点体力"
1247+ }
1248+ },
1249+ "界董卓": {
1250+ "faction": "群",
1251+ "maxHealth": 8,
1252+ "gender": "男",
1253+ "skills": {
1254+ "界酒池": "转化技:黑桃手牌当酒使用,无次数限制;使用酒杀造成伤害后本回合崩坏失效",
1255+ "肉林": "锁定技:你对女性角色/女性角色对你使用【杀】时,目标需连续出两张闪才能抵消",
1256+ "界崩坏": "锁定技:回合结束阶段,若你的体力不是全场最少的,须减1点体力或1点体力上限;界酒池酒杀造成伤害后本回合失效",
1257+ "界暴虐": "主公技:其他群势力角色造成1点伤害后可判定,黑桃则回复1点体力并获得此判定牌"
1258+ }
1259+ },
1260+ "贾诩": {
1261+ "faction": "群",
1262+ "maxHealth": 3,
1263+ "gender": "男",
1264+ "skills": {
1265+ "完杀": "锁定技:在你的回合,除你以外,只有处于濒死状态的角色才能使用【桃】",
1266+ "乱武": "限定技:出牌阶段令所有其他角色依次对距离最近者出杀,无法如此做者失去1点体力",
1267+ "帷幕": "锁定技:你不能成为黑色锦囊的目标"
1268+ }
1269+ },
1270+ "界贾诩": {
1271+ "faction": "群",
1272+ "maxHealth": 3,
1273+ "gender": "男",
1274+ "skills": {
1275+ "界帷幕": "锁定技,你不能成为黑色锦囊牌的目标;你防止回合内受到的伤害并摸所防止伤害值两倍数量的牌",
1276+ "界乱武": "限定技:出牌阶段令所有其他角色依次对距离最小者出杀,无法如此做者失去1点体力;结算后可视为使用一张无距离限制的【杀】",
1277+ "界完杀": "锁定技,在你的回合内,只有你和处于濒死状态的角色才能使用【桃】;任意濒死结算中,除你和濒死者外其他角色的非锁定技失效"
1278+ }
1279+ },
1280+ "左慈": {
1281+ "faction": "群",
1282+ "maxHealth": 3,
1283+ "gender": "男",
1284+ "skills": {
1285+ "化身": "游戏开始时随机获得未登场武将牌作为化身牌(左慈2张/界左慈3张),亮出一张并获得其一个技能(限定/觉醒/主公技除外);回合开始或结束时可更改/替换/移去化身牌",
1286+ "新生": "每当你受到 1 点伤害后,你可以获得一张新的化身牌"
1287+ }
1288+ },
1289+ "蔡文姬": {
1290+ "faction": "群",
1291+ "maxHealth": 3,
1292+ "gender": "女",
1293+ "skills": {
1294+ "悲歌": "一名角色受到杀伤害后,弃一张牌令其判定:♥回血/♦摸二/♣来源弃二/♠来源翻面",
1295+ "断肠": "杀死你的角色立即失去所有技能直到游戏结束(装备仍生效)"
1296+ }
1297+ },
1298+ "界蔡文姬": {
1299+ "faction": "群",
1300+ "maxHealth": 3,
1301+ "gender": "女",
1302+ "skills": {
1303+ "界悲歌": "受杀伤害后令其判定,可弃一张牌按花色执行;花色同获判定牌,点数同获弃置牌",
1304+ "断肠": "杀死你的角色立即失去所有技能直到游戏结束(装备仍生效)"
1305+ }
1306+ },
1307+ "界伏皇后": {
1308+ "faction": "群",
1309+ "maxHealth": 3,
1310+ "gender": "女",
1311+ "skills": {
1312+ "界惴恐": "其他角色的回合开始时,若你已受伤,你可以与其拼点:赢则其本回合不能对除其以外的角色使用牌;没赢则你获得其拼点牌,然后其视为对你使用一张杀",
1313+ "界求援": "当你成为杀或伤害锦囊的目标时,可令另一名其他角色选一项:1.交给你一张同类型不同牌名的牌;2.成为此牌的额外目标"
1314+ }
1315+ },
1316+ "界公孙瓒": {
1317+ "faction": "群",
1318+ "maxHealth": 4,
1319+ "gender": "男",
1320+ "skills": {
1321+ "界义从": "锁定技:你计算与其他角色的距离-1;若你的体力值不大于2,其他角色计算与你的距离+1",
1322+ "界趫猛": "当你使用【杀】对一名角色造成伤害后,你可以弃置其区域里的一张牌。若此牌为坐骑牌,你获得之"
1323+ }
1324+ },
1325+ "界刘表": {
1326+ "faction": "群",
1327+ "maxHealth": 3,
1328+ "gender": "男",
1329+ "skills": {
1330+ "界自守": "摸牌阶段可多摸X张(X为全场势力数);若本回合对其他角色造成过伤害,结束阶段弃X张",
1331+ "界宗室": "锁定技:手牌上限+X(X为全场势力数);其他角色对你造成伤害时,防止此伤害改为令其摸一张牌,每种势力限一次"
1332+ }
1333+ },
1334+ "界华佗": {
1335+ "faction": "群",
1336+ "maxHealth": 3,
1337+ "gender": "男",
1338+ "skills": {
1339+ "急救": "在你的回合外,你可以将一张红色牌当【桃】使用。",
1340+ "界除疠": "出牌阶段限一次,选择任意名势力各不相同的其他角色,弃置你和这些角色的各一张牌,被弃置黑桃牌的角色各摸一张牌"
1341+ }
1342+ },
1343+ "界华雄": {
1344+ "faction": "群",
1345+ "maxHealth": 6,
1346+ "gender": "男",
1347+ "skills": {
1348+ "界耀武": "锁定技,当你受到伤害时,若造成伤害的牌为红色,来源摸一张牌;否则你摸一张牌",
1349+ "界势斩": "出牌阶段限两次,令一名其他角色视为对你使用一张决斗"
1350+ }
1351+ },
1352+ "界吕布": {
1353+ "faction": "群",
1354+ "maxHealth": 5,
1355+ "gender": "男",
1356+ "skills": {
1357+ "无双": "锁定技:你使用【杀】的目标需连续出两张【闪】才能抵消;与你【决斗】的角色每次需连续打出两张【杀」",
1358+ "界利驭": "当你使用【杀】对其他角色造成伤害后,你可以获得其区域里的一张牌;获得的牌不为装备牌,其摸一张牌;为装备牌,你视为对由其指定的另一名角色使用一张【决斗】"
1359+ }
1360+ },
1361+ "界左慈": {
1362+ "faction": "群",
1363+ "maxHealth": 3,
1364+ "gender": "男",
1365+ "skills": {
1366+ "化身": "游戏开始时随机获得未登场武将牌作为化身牌(左慈2张/界左慈3张),亮出一张并获得其一个技能(限定/觉醒/主公技除外);回合开始或结束时可更改/替换/移去化身牌",
1367+ "新生": "每当你受到 1 点伤害后,你可以获得一张新的化身牌"
1368+ }
1369+ },
1370+ "界张角": {
1371+ "faction": "群",
1372+ "maxHealth": 3,
1373+ "gender": "男",
1374+ "skills": {
1375+ "界雷击": "使用/打出【闪】或使用【闪电】时可判定;黑桃可对一名角色造成2点雷电伤害;梅花回复1点体力并可对一名角色造成1点雷电伤害",
1376+ "界鬼道": "判定牌生效前,你可以用一张黑色牌替换之,若为黑桃2~9,你摸一张牌",
1377+ "界黄天": "主公技:其他群势力角色可在出牌阶段将一张【闪】或黑桃手牌交给你"
1378+ }
1379+ },
1380+ "界李儒": {
1381+ "faction": "群",
1382+ "maxHealth": 3,
1383+ "gender": "男",
1384+ "skills": {
1385+ "界灭计": "出牌阶段限一次:将一张锦囊牌置于牌堆顶,令一名有手牌的其他角色选择弃一张锦囊或依次弃两张牌",
1386+ "界绝策": "结束阶段:对一名手牌数小于等于你的其他角色造成1点伤害",
1387+ "界焚城": "限定技:选一名其他角色开始,所有其他角色依次弃比上家多的牌或受你造成的2点火焰伤害"
1388+ }
1389+ },
1390+ "界沮授": {
1391+ "faction": "群",
1392+ "maxHealth": 3,
1393+ "gender": "男",
1394+ "skills": {
1395+ "界矢北": "锁定技:游戏开始时获得3点护甲;每回合首次受到伤害后回1血,本回合再受到伤害后失1血",
1396+ "界渐营": "出牌阶段用牌若与上一张花色或点数相同,可摸一张;每阶段限一次,可将一张牌当任意基本牌使用(若有上一张花色则继承)"
1397+ }
1398+ },
1399+ "界蔡夫人": {
1400+ "faction": "群",
1401+ "maxHealth": 3,
1402+ "gender": "女",
1403+ "skills": {
1404+ "界窃听": "其他角色的回合结束后,若其本回合未对其他角色造成伤害可选一项;若未使用过牌可选两项:1.夺其一张装备;2.摸一张牌",
1405+ "界献州": "限定技:出牌阶段将你装备区所有牌交给一名其他角色,其选择令你回复X点体力或对其攻击范围内至多X名角色各造成1点伤害(X为装备数)"
1406+ }
1407+ },
1408+ "界陈宫": {
1409+ "faction": "群",
1410+ "maxHealth": 3,
1411+ "gender": "男",
1412+ "skills": {
1413+ "界智迟": "锁定技:回合外受到伤害后,本回合【杀】和普通锦囊牌对你无效",
1414+ "界明策": "出牌阶段限一次:交给一名其他角色一张杀或装备牌,其选择一项:①视为对你指定的另一名角色出杀(若造成伤害,执行另一项);②你与其各摸一张牌"
1415+ }
1416+ },
1417+ "界高顺": {
1418+ "faction": "群",
1419+ "maxHealth": 4,
1420+ "gender": "男",
1421+ "skills": {
1422+ "界陷阵": "出牌阶段限一次,与一名角色拼点:赢则本回合对其使用牌无距离和次数限制且无视防具,可多指定其为目标;没赢则本回合不能对其使用杀,且你的杀不计入手牌上限",
1423+ "界禁酒": "锁定技:你的【酒】视为点数K的【杀】;其他角色不能于你的回合使用【酒】"
1424+ }
1425+ },
1426+ "华雄": {
1427+ "faction": "群",
1428+ "maxHealth": 6,
1429+ "gender": "男",
1430+ "skills": {
1431+ "耀武": "锁定技,当一名角色使用红色杀对你造成伤害时,其选择回复1点体力或摸一张牌"
1432+ }
1433+ },
1434+ "袁术": {
1435+ "faction": "群",
1436+ "maxHealth": 4,
1437+ "gender": "男",
1438+ "skills": {
1439+ "庸肆": "锁定技,摸牌阶段你多摸X张牌;弃牌阶段开始时你弃置X张牌(X为全场势力数)",
1440+ "伪帝": "锁定技,你视为拥有主公的主公技"
1441+ }
1442+ },
1443+ "卢植": {
1444+ "faction": "群",
1445+ "maxHealth": 3,
1446+ "gender": "男",
1447+ "skills": {
1448+ "明任": "游戏开始时摸两张牌并将一张手牌置为\"任\";结束阶段可用手牌替换\"任\"",
1449+ "贞良": "转换技。阳:出牌阶段限一次,选攻击范围内一名其他角色,弃一张与\"任\"同色的牌对其造成1点伤害。阴:回合外使用或打出的牌置入弃牌堆时,若与\"任\"同色,可令一名角色摸一张牌"
1450+ }
1451+ },
1452+ "张绣": {
1453+ "faction": "群",
1454+ "maxHealth": 4,
1455+ "gender": "男",
1456+ "skills": {
1457+ "雄乱": "限定技,出牌阶段,指定一名其他角色并废除你的判定区和装备区,本回合对其使用牌无距离和次数限制,其本回合不能使用和打出手牌",
1458+ "从谏": "当你成为锦囊牌的目标时,若此牌的目标数大于1,你可以交给其中一名目标角色一张牌,然后摸一张牌,若你给出的是装备牌,改为摸两张牌"
1459+ }
1460+ },
1461+ "许攸": {
1462+ "faction": "群",
1463+ "maxHealth": 3,
1464+ "gender": "男",
1465+ "skills": {
1466+ "成略": "转换技,出牌阶段限一次。阳:摸一张牌并弃置两张手牌;阴:摸两张牌并弃置一张手牌。然后本阶段使用与弃置牌花色相同的牌无距离和次数限制",
1467+ "恃才": "当你每回合首次使用一种类型的牌后,你可以将之置于牌堆顶,然后摸一张牌",
1468+ "寸目": "锁定技:当你摸牌时,你改为从牌堆底摸牌"
1469+ }
1470+ }
1471+}
+5 −0 referee/play.mjs added View file
@@ -0,0 +1,5 @@
1+// node referee/play.mjs check|practice <route folder>: the route's bot against the field (see src/play.ts).
2+import { play } from './sgs.mjs';
3+
4+await play(process.argv[2], process.argv[3]);
5+process.exit(0);
+5 −0 referee/practice.sbatch added View file
@@ -0,0 +1,5 @@
1+#!/bin/bash
2+#SBATCH --job-name=practice
3+#SBATCH --time=30:00
4+# A practice run from your route: games as 主公 and as a 反贼 against each field bot, replays in replays/ (see Matches).
5+node referee/play.mjs practice "$SS_INPUT/$SS_ROUTE_DIR"
+4 −0 referee/room.mjs added View file
@@ -0,0 +1,4 @@
1+// node referee/room.mjs: a live room on stdin/stdout, seats from SS_ROOM (see src/room.ts and docs/games.md §8.3).
2+import { room } from './sgs.mjs';
3+
4+await room();
+5 −0 referee/room.sbatch added View file
@@ -0,0 +1,5 @@
1+#!/bin/bash
2+#SBATCH --job-name=room
3+#SBATCH --time=2:00:00
4+# A live room (docs/games.md §8.3): seats from SS_ROOM, the protocol on stdin/stdout, the game left in replays/.
5+exec node referee/room.mjs
+66159 −0 referee/sgs.mjs added View file
@@ -0,0 +1,66159 @@
1+import "node:fs/promises";
2+import path, { join, resolve } from "node:path";
3+import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
4+import { spawn } from "node:child_process";
5+import { createInterface } from "node:readline";
6+import { fileURLToPath } from "node:url";
7+//#region \0rolldown/runtime.js
8+var __defProp = Object.defineProperty;
9+var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
10+var __exportAll = (all, no_symbols) => {
11+ let target = {};
12+ for (var name in all) __defProp(target, name, {
13+ get: all[name],
14+ enumerable: true
15+ });
16+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17+ return target;
18+};
19+//#endregion
20+//#region src/engine/data/characters/曹操.ts
21+var 曹操;
22+var init_曹操 = __esmMin((() => {
23+ 曹操 = {
24+ name: "曹操",
25+ maxHealth: 4,
26+ gender: "男",
27+ faction: "魏",
28+ skills: [{
29+ name: "奸雄",
30+ path: "../../skills/奸雄"
31+ }, {
32+ name: "护驾",
33+ path: "../../skills/护驾"
34+ }]
35+ };
36+}));
37+//#endregion
38+//#region src/engine/data/characters/司马懿.ts
39+var 司马懿;
40+var init_司马懿 = __esmMin((() => {
41+ 司马懿 = {
42+ name: "司马懿",
43+ maxHealth: 3,
44+ gender: "男",
45+ faction: "魏",
46+ skills: [{
47+ name: "反馈",
48+ path: "../../skills/反馈"
49+ }, {
50+ name: "鬼才",
51+ path: "../../skills/鬼才"
52+ }]
53+ };
54+}));
55+//#endregion
56+//#region src/engine/data/characters/夏侯惇.ts
57+var 夏侯惇;
58+var init_夏侯惇 = __esmMin((() => {
59+ 夏侯惇 = {
60+ name: "夏侯惇",
61+ maxHealth: 4,
62+ gender: "男",
63+ faction: "魏",
64+ skills: [{
65+ name: "刚烈",
66+ path: "../../skills/刚烈"
67+ }]
68+ };
69+}));
70+//#endregion
71+//#region src/engine/data/characters/张辽.ts
72+var 张辽;
73+var init_张辽 = __esmMin((() => {
74+ 张辽 = {
75+ name: "张辽",
76+ maxHealth: 4,
77+ gender: "男",
78+ faction: "魏",
79+ skills: [{
80+ name: "突袭",
81+ path: "../../skills/突袭"
82+ }]
83+ };
84+}));
85+//#endregion
86+//#region src/engine/data/characters/许褚.ts
87+var 许褚;
88+var init_许褚 = __esmMin((() => {
89+ 许褚 = {
90+ name: "许褚",
91+ maxHealth: 4,
92+ gender: "男",
93+ faction: "魏",
94+ skills: [{
95+ name: "裸衣",
96+ path: "../../skills/裸衣"
97+ }]
98+ };
99+}));
100+//#endregion
101+//#region src/engine/data/characters/郭嘉.ts
102+var 郭嘉;
103+var init_郭嘉 = __esmMin((() => {
104+ 郭嘉 = {
105+ name: "郭嘉",
106+ maxHealth: 3,
107+ gender: "男",
108+ faction: "魏",
109+ skills: [{
110+ name: "天妒",
111+ path: "../../skills/天妒"
112+ }, {
113+ name: "遗计",
114+ path: "../../skills/遗计"
115+ }]
116+ };
117+}));
118+//#endregion
119+//#region src/engine/data/characters/甄姬.ts
120+var 甄姬;
121+var init_甄姬 = __esmMin((() => {
122+ 甄姬 = {
123+ name: "甄姬",
124+ maxHealth: 3,
125+ gender: "女",
126+ faction: "魏",
127+ skills: [{
128+ name: "倾国",
129+ path: "../../skills/倾国"
130+ }, {
131+ name: "洛神",
132+ path: "../../skills/洛神"
133+ }]
134+ };
135+}));
136+//#endregion
137+//#region src/engine/data/characters/夏侯渊.ts
138+var 夏侯渊;
139+var init_夏侯渊 = __esmMin((() => {
140+ 夏侯渊 = {
141+ name: "夏侯渊",
142+ maxHealth: 4,
143+ gender: "男",
144+ faction: "魏",
145+ skills: [{
146+ name: "神速",
147+ path: "../../skills/神速"
148+ }]
149+ };
150+}));
151+//#endregion
152+//#region src/engine/data/characters/曹仁.ts
153+var 曹仁;
154+var init_曹仁 = __esmMin((() => {
155+ 曹仁 = {
156+ name: "曹仁",
157+ maxHealth: 4,
158+ gender: "男",
159+ faction: "魏",
160+ skills: [{
161+ name: "据守",
162+ path: "../../skills/据守"
163+ }]
164+ };
165+}));
166+//#endregion
167+//#region src/engine/data/characters/荀彧.ts
168+var 荀彧;
169+var init_荀彧 = __esmMin((() => {
170+ 荀彧 = {
171+ name: "荀彧",
172+ maxHealth: 3,
173+ gender: "男",
174+ faction: "魏",
175+ skills: [{
176+ name: "驱虎",
177+ path: "../../skills/驱虎"
178+ }, {
179+ name: "节命",
180+ path: "../../skills/节命"
181+ }]
182+ };
183+}));
184+//#endregion
185+//#region src/engine/data/characters/典韦.ts
186+var 典韦;
187+var init_典韦 = __esmMin((() => {
188+ 典韦 = {
189+ name: "典韦",
190+ maxHealth: 4,
191+ gender: "男",
192+ faction: "魏",
193+ skills: [{
194+ name: "强袭",
195+ path: "../../skills/强袭"
196+ }]
197+ };
198+}));
199+//#endregion
200+//#region src/engine/data/characters/曹丕.ts
201+var 曹丕;
202+var init_曹丕 = __esmMin((() => {
203+ 曹丕 = {
204+ name: "曹丕",
205+ maxHealth: 3,
206+ gender: "男",
207+ faction: "魏",
208+ skills: [
209+ {
210+ name: "行殇",
211+ path: "../../skills/行殇"
212+ },
213+ {
214+ name: "放逐",
215+ path: "../../skills/放逐"
216+ },
217+ {
218+ name: "颂威",
219+ path: "../../skills/颂威"
220+ }
221+ ]
222+ };
223+}));
224+//#endregion
225+//#region src/engine/data/characters/徐晃.ts
226+var 徐晃;
227+var init_徐晃 = __esmMin((() => {
228+ 徐晃 = {
229+ name: "徐晃",
230+ maxHealth: 4,
231+ gender: "男",
232+ faction: "魏",
233+ skills: [{
234+ name: "断粮",
235+ path: "../../skills/断粮"
236+ }]
237+ };
238+}));
239+//#endregion
240+//#region src/engine/data/characters/张郃.ts
241+var 张郃;
242+var init_张郃 = __esmMin((() => {
243+ 张郃 = {
244+ name: "张郃",
245+ maxHealth: 4,
246+ gender: "男",
247+ faction: "魏",
248+ skills: [{
249+ name: "巧变",
250+ path: "../../skills/巧变"
251+ }]
252+ };
253+}));
254+//#endregion
255+//#region src/engine/data/characters/邓艾.ts
256+var 邓艾;
257+var init_邓艾 = __esmMin((() => {
258+ 邓艾 = {
259+ name: "邓艾",
260+ maxHealth: 4,
261+ gender: "男",
262+ faction: "魏",
263+ skills: [{
264+ name: "屯田",
265+ path: "../../skills/屯田"
266+ }, {
267+ name: "凿险",
268+ path: "../../skills/凿险"
269+ }]
270+ };
271+}));
272+//#endregion
273+//#region src/engine/data/characters/界曹操.ts
274+var 界曹操;
275+var init_界曹操 = __esmMin((() => {
276+ 界曹操 = {
277+ name: "界曹操",
278+ maxHealth: 4,
279+ gender: "男",
280+ faction: "魏",
281+ skills: [{
282+ name: "界奸雄",
283+ path: "../../skills/界奸雄"
284+ }, {
285+ name: "界护驾",
286+ path: "../../skills/界护驾"
287+ }]
288+ };
289+}));
290+//#endregion
291+//#region src/engine/data/characters/界司马懿.ts
292+var 界司马懿;
293+var init_界司马懿 = __esmMin((() => {
294+ 界司马懿 = {
295+ name: "界司马懿",
296+ maxHealth: 3,
297+ gender: "男",
298+ faction: "魏",
299+ skills: [{
300+ name: "反馈",
301+ path: "../../skills/反馈"
302+ }, {
303+ name: "界鬼才",
304+ path: "../../skills/界鬼才"
305+ }]
306+ };
307+}));
308+//#endregion
309+//#region src/engine/data/characters/界夏侯惇.ts
310+var 界夏侯惇;
311+var init_界夏侯惇 = __esmMin((() => {
312+ 界夏侯惇 = {
313+ name: "界夏侯惇",
314+ maxHealth: 4,
315+ gender: "男",
316+ faction: "魏",
317+ skills: [{
318+ name: "界刚烈",
319+ path: "../../skills/界刚烈"
320+ }]
321+ };
322+}));
323+//#endregion
324+//#region src/engine/data/characters/界张辽.ts
325+var 界张辽;
326+var init_界张辽 = __esmMin((() => {
327+ 界张辽 = {
328+ name: "界张辽",
329+ maxHealth: 4,
330+ gender: "男",
331+ faction: "魏",
332+ skills: [{
333+ name: "界突袭",
334+ path: "../../skills/界突袭"
335+ }]
336+ };
337+}));
338+//#endregion
339+//#region src/engine/data/characters/界许褚.ts
340+var 界许褚;
341+var init_界许褚 = __esmMin((() => {
342+ 界许褚 = {
343+ name: "界许褚",
344+ maxHealth: 4,
345+ gender: "男",
346+ faction: "魏",
347+ skills: [{
348+ name: "界裸衣",
349+ path: "../../skills/界裸衣"
350+ }]
351+ };
352+}));
353+//#endregion
354+//#region src/engine/data/characters/界郭嘉.ts
355+var 界郭嘉;
356+var init_界郭嘉 = __esmMin((() => {
357+ 界郭嘉 = {
358+ name: "界郭嘉",
359+ maxHealth: 3,
360+ gender: "男",
361+ faction: "魏",
362+ skills: [{
363+ name: "天妒",
364+ path: "../../skills/天妒"
365+ }, {
366+ name: "界遗计",
367+ path: "../../skills/界遗计"
368+ }]
369+ };
370+}));
371+//#endregion
372+//#region src/engine/data/characters/界甄姬.ts
373+var 界甄姬;
374+var init_界甄姬 = __esmMin((() => {
375+ 界甄姬 = {
376+ name: "界甄姬",
377+ maxHealth: 3,
378+ gender: "女",
379+ faction: "魏",
380+ skills: [{
381+ name: "倾国",
382+ path: "../../skills/倾国"
383+ }, {
384+ name: "界洛神",
385+ path: "../../skills/界洛神"
386+ }]
387+ };
388+}));
389+//#endregion
390+//#region src/engine/data/characters/界夏侯渊.ts
391+var 界夏侯渊;
392+var init_界夏侯渊 = __esmMin((() => {
393+ 界夏侯渊 = {
394+ name: "界夏侯渊",
395+ maxHealth: 4,
396+ gender: "男",
397+ faction: "魏",
398+ skills: [{
399+ name: "界神速",
400+ path: "../../skills/界神速"
401+ }]
402+ };
403+}));
404+//#endregion
405+//#region src/engine/data/characters/界曹仁.ts
406+var 界曹仁;
407+var init_界曹仁 = __esmMin((() => {
408+ 界曹仁 = {
409+ name: "界曹仁",
410+ maxHealth: 4,
411+ gender: "男",
412+ faction: "魏",
413+ skills: [{
414+ name: "界据守",
415+ path: "../../skills/界据守"
416+ }, {
417+ name: "解围",
418+ path: "../../skills/解围"
419+ }]
420+ };
421+}));
422+//#endregion
423+//#region src/engine/data/characters/界荀彧.ts
424+var 界荀彧;
425+var init_界荀彧 = __esmMin((() => {
426+ 界荀彧 = {
427+ name: "界荀彧",
428+ maxHealth: 3,
429+ gender: "男",
430+ faction: "魏",
431+ skills: [{
432+ name: "驱虎",
433+ path: "../../skills/驱虎"
434+ }, {
435+ name: "界节命",
436+ path: "../../skills/界节命"
437+ }]
438+ };
439+}));
440+//#endregion
441+//#region src/engine/data/characters/界典韦.ts
442+var 界典韦;
443+var init_界典韦 = __esmMin((() => {
444+ 界典韦 = {
445+ name: "界典韦",
446+ maxHealth: 4,
447+ gender: "男",
448+ faction: "魏",
449+ skills: [{
450+ name: "界强袭",
451+ path: "../../skills/界强袭"
452+ }]
453+ };
454+}));
455+//#endregion
456+//#region src/engine/data/characters/界曹丕.ts
457+var 界曹丕;
458+var init_界曹丕 = __esmMin((() => {
459+ 界曹丕 = {
460+ name: "界曹丕",
461+ maxHealth: 3,
462+ gender: "男",
463+ faction: "魏",
464+ skills: [
465+ {
466+ name: "行殇",
467+ path: "../../skills/行殇"
468+ },
469+ {
470+ name: "界放逐",
471+ path: "../../skills/界放逐"
472+ },
473+ {
474+ name: "颂威",
475+ path: "../../skills/颂威"
476+ }
477+ ]
478+ };
479+}));
480+//#endregion
481+//#region src/engine/data/characters/界徐晃.ts
482+var 界徐晃;
483+var init_界徐晃 = __esmMin((() => {
484+ 界徐晃 = {
485+ name: "界徐晃",
486+ maxHealth: 4,
487+ gender: "男",
488+ faction: "魏",
489+ skills: [{
490+ name: "界断粮",
491+ path: "../../skills/界断粮"
492+ }, {
493+ name: "截辎",
494+ path: "../../skills/截辎"
495+ }]
496+ };
497+}));
498+//#endregion
499+//#region src/engine/data/characters/界张郃.ts
500+var 界张郃;
501+var init_界张郃 = __esmMin((() => {
502+ 界张郃 = {
503+ name: "界张郃",
504+ maxHealth: 4,
505+ gender: "男",
506+ faction: "魏",
507+ skills: [{
508+ name: "界巧变",
509+ path: "../../skills/界巧变"
510+ }]
511+ };
512+}));
513+//#endregion
514+//#region src/engine/data/characters/界邓艾.ts
515+var 界邓艾;
516+var init_界邓艾 = __esmMin((() => {
517+ 界邓艾 = {
518+ name: "界邓艾",
519+ maxHealth: 4,
520+ gender: "男",
521+ faction: "魏",
522+ skills: [
523+ {
524+ name: "界屯田",
525+ path: "../../skills/界屯田"
526+ },
527+ {
528+ name: "界凿险",
529+ path: "../../skills/界凿险"
530+ },
531+ {
532+ name: "急袭",
533+ path: "../../skills/急袭"
534+ }
535+ ]
536+ };
537+}));
538+//#endregion
539+//#region src/engine/data/characters/界于禁.ts
540+var 界于禁;
541+var init_界于禁 = __esmMin((() => {
542+ 界于禁 = {
543+ name: "界于禁",
544+ maxHealth: 4,
545+ gender: "男",
546+ faction: "魏",
547+ skills: [{
548+ name: "界镇军",
549+ path: "../../skills/界镇军"
550+ }, {
551+ name: "界毅重",
552+ path: "../../skills/界毅重"
553+ }]
554+ };
555+}));
556+//#endregion
557+//#region src/engine/data/characters/界张春华.ts
558+var 界张春华;
559+var init_界张春华 = __esmMin((() => {
560+ 界张春华 = {
561+ name: "界张春华",
562+ maxHealth: 3,
563+ gender: "女",
564+ faction: "魏",
565+ skills: [
566+ {
567+ name: "界绝情",
568+ path: "../../skills/界绝情"
569+ },
570+ {
571+ name: "界伤逝",
572+ path: "../../skills/界伤逝"
573+ },
574+ {
575+ name: "界翦灭",
576+ path: "../../skills/界翦灭"
577+ }
578+ ]
579+ };
580+}));
581+//#endregion
582+//#region src/engine/data/characters/界曹冲.ts
583+var 界曹冲;
584+var init_界曹冲 = __esmMin((() => {
585+ 界曹冲 = {
586+ name: "界曹冲",
587+ maxHealth: 3,
588+ gender: "男",
589+ faction: "魏",
590+ skills: [{
591+ name: "界称象",
592+ path: "../../skills/界称象"
593+ }, {
594+ name: "界仁心",
595+ path: "../../skills/界仁心"
596+ }]
597+ };
598+}));
599+//#endregion
600+//#region src/engine/data/characters/界曹彰.ts
601+var 界曹彰;
602+var init_界曹彰 = __esmMin((() => {
603+ 界曹彰 = {
604+ name: "界曹彰",
605+ maxHealth: 4,
606+ gender: "男",
607+ faction: "魏",
608+ skills: [{
609+ name: "界将驰",
610+ path: "../../skills/界将驰"
611+ }]
612+ };
613+}));
614+//#endregion
615+//#region src/engine/data/characters/界曹植.ts
616+var 界曹植;
617+var init_界曹植 = __esmMin((() => {
618+ 界曹植 = {
619+ name: "界曹植",
620+ maxHealth: 3,
621+ gender: "男",
622+ faction: "魏",
623+ skills: [{
624+ name: "界落英",
625+ path: "../../skills/界落英"
626+ }, {
627+ name: "界酒诗",
628+ path: "../../skills/界酒诗"
629+ }]
630+ };
631+}));
632+//#endregion
633+//#region src/engine/data/characters/界李典.ts
634+var 界李典;
635+var init_界李典 = __esmMin((() => {
636+ 界李典 = {
637+ name: "界李典",
638+ maxHealth: 3,
639+ gender: "男",
640+ faction: "魏",
641+ skills: [{
642+ name: "界恂恂",
643+ path: "../../skills/界恂恂"
644+ }, {
645+ name: "界忘隙",
646+ path: "../../skills/界忘隙"
647+ }]
648+ };
649+}));
650+//#endregion
651+//#region src/engine/data/characters/界王异.ts
652+var 界王异;
653+var init_界王异 = __esmMin((() => {
654+ 界王异 = {
655+ name: "界王异",
656+ maxHealth: 3,
657+ gender: "女",
658+ faction: "魏",
659+ skills: [{
660+ name: "界贞烈",
661+ path: "../../skills/界贞烈"
662+ }, {
663+ name: "界秘计",
664+ path: "../../skills/界秘计"
665+ }]
666+ };
667+}));
668+//#endregion
669+//#region src/engine/data/characters/界郭淮.ts
670+var 界郭淮;
671+var init_界郭淮 = __esmMin((() => {
672+ 界郭淮 = {
673+ name: "界郭淮",
674+ maxHealth: 4,
675+ gender: "男",
676+ faction: "魏",
677+ skills: [{
678+ name: "界精策",
679+ path: "../../skills/界精策"
680+ }]
681+ };
682+}));
683+//#endregion
684+//#region src/engine/data/characters/界郭皇后.ts
685+var 界郭皇后;
686+var init_界郭皇后 = __esmMin((() => {
687+ 界郭皇后 = {
688+ name: "界郭皇后",
689+ maxHealth: 3,
690+ gender: "女",
691+ faction: "魏",
692+ skills: [{
693+ name: "界矫诏",
694+ path: "../../skills/界矫诏"
695+ }, {
696+ name: "界殚心",
697+ path: "../../skills/界殚心"
698+ }]
699+ };
700+}));
701+//#endregion
702+//#region src/engine/data/characters/刘备.ts
703+var 刘备;
704+var init_刘备 = __esmMin((() => {
705+ 刘备 = {
706+ name: "刘备",
707+ maxHealth: 4,
708+ gender: "男",
709+ faction: "蜀",
710+ skills: [{
711+ name: "仁德",
712+ path: "../../skills/仁德"
713+ }, {
714+ name: "激将",
715+ path: "../../skills/激将"
716+ }]
717+ };
718+}));
719+//#endregion
720+//#region src/engine/data/characters/界刘备.ts
721+var 界刘备;
722+var init_界刘备 = __esmMin((() => {
723+ 界刘备 = {
724+ name: "界刘备",
725+ maxHealth: 4,
726+ gender: "男",
727+ faction: "蜀",
728+ skills: [{
729+ name: "界仁德",
730+ path: "../../skills/界仁德"
731+ }, {
732+ name: "界激将",
733+ path: "../../skills/界激将"
734+ }]
735+ };
736+}));
737+//#endregion
738+//#region src/engine/data/characters/关羽.ts
739+var 关羽;
740+var init_关羽 = __esmMin((() => {
741+ 关羽 = {
742+ name: "关羽",
743+ maxHealth: 4,
744+ gender: "男",
745+ faction: "蜀",
746+ skills: [{
747+ name: "武圣",
748+ path: "../../skills/武圣"
749+ }]
750+ };
751+}));
752+//#endregion
753+//#region src/engine/data/characters/界关羽.ts
754+var 界关羽;
755+var init_界关羽 = __esmMin((() => {
756+ 界关羽 = {
757+ name: "界关羽",
758+ maxHealth: 4,
759+ gender: "男",
760+ faction: "蜀",
761+ skills: [{
762+ name: "界武圣",
763+ path: "../../skills/界武圣"
764+ }, {
765+ name: "义绝",
766+ path: "../../skills/义绝"
767+ }]
768+ };
769+}));
770+//#endregion
771+//#region src/engine/data/characters/张飞.ts
772+var 张飞;
773+var init_张飞 = __esmMin((() => {
774+ 张飞 = {
775+ name: "张飞",
776+ maxHealth: 4,
777+ gender: "男",
778+ faction: "蜀",
779+ skills: [{
780+ name: "咆哮",
781+ path: "../../skills/咆哮"
782+ }]
783+ };
784+}));
785+//#endregion
786+//#region src/engine/data/characters/界张飞.ts
787+var 界张飞;
788+var init_界张飞 = __esmMin((() => {
789+ 界张飞 = {
790+ name: "界张飞",
791+ maxHealth: 4,
792+ gender: "男",
793+ faction: "蜀",
794+ skills: [{
795+ name: "界咆哮",
796+ path: "../../skills/界咆哮"
797+ }]
798+ };
799+}));
800+//#endregion
801+//#region src/engine/data/characters/赵云.ts
802+var 赵云;
803+var init_赵云 = __esmMin((() => {
804+ 赵云 = {
805+ name: "赵云",
806+ maxHealth: 4,
807+ gender: "男",
808+ faction: "蜀",
809+ skills: [{
810+ name: "龙胆",
811+ path: "../../skills/龙胆"
812+ }]
813+ };
814+}));
815+//#endregion
816+//#region src/engine/data/characters/界赵云.ts
817+var 界赵云;
818+var init_界赵云 = __esmMin((() => {
819+ 界赵云 = {
820+ name: "界赵云",
821+ maxHealth: 4,
822+ gender: "男",
823+ faction: "蜀",
824+ skills: [{
825+ name: "界龙胆",
826+ path: "../../skills/界龙胆"
827+ }, {
828+ name: "涯角",
829+ path: "../../skills/涯角"
830+ }]
831+ };
832+}));
833+//#endregion
834+//#region src/engine/data/characters/诸葛亮.ts
835+var 诸葛亮;
836+var init_诸葛亮 = __esmMin((() => {
837+ 诸葛亮 = {
838+ name: "诸葛亮",
839+ maxHealth: 3,
840+ gender: "男",
841+ faction: "蜀",
842+ skills: [{
843+ name: "观星",
844+ path: "../../skills/观星"
845+ }, {
846+ name: "空城",
847+ path: "../../skills/空城"
848+ }]
849+ };
850+}));
851+//#endregion
852+//#region src/engine/data/characters/界诸葛亮.ts
853+var 界诸葛亮;
854+var init_界诸葛亮 = __esmMin((() => {
855+ 界诸葛亮 = {
856+ name: "界诸葛亮",
857+ maxHealth: 3,
858+ gender: "男",
859+ faction: "蜀",
860+ skills: [{
861+ name: "界观星",
862+ path: "../../skills/界观星"
863+ }, {
864+ name: "界空城",
865+ path: "../../skills/界空城"
866+ }]
867+ };
868+}));
869+//#endregion
870+//#region src/engine/data/characters/黄月英.ts
871+var 黄月英;
872+var init_黄月英 = __esmMin((() => {
873+ 黄月英 = {
874+ name: "黄月英",
875+ maxHealth: 3,
876+ gender: "女",
877+ faction: "蜀",
878+ skills: [{
879+ name: "集智",
880+ path: "../../skills/集智"
881+ }, {
882+ name: "奇才",
883+ path: "../../skills/奇才"
884+ }]
885+ };
886+}));
887+//#endregion
888+//#region src/engine/data/characters/界黄月英.ts
889+var 界黄月英;
890+var init_界黄月英 = __esmMin((() => {
891+ 界黄月英 = {
892+ name: "界黄月英",
893+ maxHealth: 3,
894+ gender: "女",
895+ faction: "蜀",
896+ skills: [{
897+ name: "界集智",
898+ path: "../../skills/界集智"
899+ }, {
900+ name: "界奇才",
901+ path: "../../skills/界奇才"
902+ }]
903+ };
904+}));
905+//#endregion
906+//#region src/engine/data/characters/马超.ts
907+var 马超;
908+var init_马超 = __esmMin((() => {
909+ 马超 = {
910+ name: "马超",
911+ maxHealth: 4,
912+ gender: "男",
913+ faction: "蜀",
914+ skills: [{
915+ name: "马术",
916+ path: "../../skills/马术"
917+ }, {
918+ name: "铁骑",
919+ path: "../../skills/铁骑"
920+ }]
921+ };
922+}));
923+//#endregion
924+//#region src/engine/data/characters/界马超.ts
925+var 界马超;
926+var init_界马超 = __esmMin((() => {
927+ 界马超 = {
928+ name: "界马超",
929+ maxHealth: 4,
930+ gender: "男",
931+ faction: "蜀",
932+ skills: [{
933+ name: "马术",
934+ path: "../../skills/马术"
935+ }, {
936+ name: "界铁骑",
937+ path: "../../skills/界铁骑"
938+ }]
939+ };
940+}));
941+//#endregion
942+//#region src/engine/data/characters/界马岱.ts
943+var 界马岱;
944+var init_界马岱 = __esmMin((() => {
945+ 界马岱 = {
946+ name: "界马岱",
947+ maxHealth: 4,
948+ gender: "男",
949+ faction: "蜀",
950+ skills: [{
951+ name: "马术",
952+ path: "../../skills/马术"
953+ }, {
954+ name: "界潜袭",
955+ path: "../../skills/界潜袭"
956+ }]
957+ };
958+}));
959+//#endregion
960+//#region src/engine/data/characters/黄忠.ts
961+var 黄忠;
962+var init_黄忠 = __esmMin((() => {
963+ 黄忠 = {
964+ name: "黄忠",
965+ maxHealth: 4,
966+ gender: "男",
967+ faction: "蜀",
968+ skills: [{
969+ name: "烈弓",
970+ path: "../../skills/烈弓"
971+ }]
972+ };
973+}));
974+//#endregion
975+//#region src/engine/data/characters/界黄忠.ts
976+var 界黄忠;
977+var init_界黄忠 = __esmMin((() => {
978+ 界黄忠 = {
979+ name: "界黄忠",
980+ maxHealth: 4,
981+ gender: "男",
982+ faction: "蜀",
983+ skills: [{
984+ name: "界烈弓",
985+ path: "../../skills/界烈弓"
986+ }]
987+ };
988+}));
989+//#endregion
990+//#region src/engine/data/characters/魏延.ts
991+var 魏延;
992+var init_魏延 = __esmMin((() => {
993+ 魏延 = {
994+ name: "魏延",
995+ maxHealth: 4,
996+ gender: "男",
997+ faction: "蜀",
998+ skills: [{
999+ name: "狂骨",
1000+ path: "../../skills/狂骨"
1001+ }]
1002+ };
1003+}));
1004+//#endregion
1005+//#region src/engine/data/characters/界魏延.ts
1006+var 界魏延;
1007+var init_界魏延 = __esmMin((() => {
1008+ 界魏延 = {
1009+ name: "界魏延",
1010+ maxHealth: 4,
1011+ gender: "男",
1012+ faction: "蜀",
1013+ skills: [{
1014+ name: "界狂骨",
1015+ path: "../../skills/界狂骨"
1016+ }, { name: "奇谋" }]
1017+ };
1018+}));
1019+//#endregion
1020+//#region src/engine/data/characters/卧龙诸葛.ts
1021+var 卧龙诸葛;
1022+var init_卧龙诸葛 = __esmMin((() => {
1023+ 卧龙诸葛 = {
1024+ name: "卧龙诸葛",
1025+ maxHealth: 3,
1026+ gender: "男",
1027+ faction: "蜀",
1028+ skills: [
1029+ {
1030+ name: "八阵",
1031+ path: "../../skills/八阵"
1032+ },
1033+ {
1034+ name: "火计",
1035+ path: "../../skills/火计"
1036+ },
1037+ {
1038+ name: "看破",
1039+ path: "../../skills/看破"
1040+ }
1041+ ]
1042+ };
1043+}));
1044+//#endregion
1045+//#region src/engine/data/characters/界卧龙诸葛.ts
1046+var 界卧龙诸葛;
1047+var init_界卧龙诸葛 = __esmMin((() => {
1048+ 界卧龙诸葛 = {
1049+ name: "界卧龙诸葛",
1050+ maxHealth: 3,
1051+ gender: "男",
1052+ faction: "蜀",
1053+ skills: [
1054+ {
1055+ name: "八阵",
1056+ path: "../../skills/八阵"
1057+ },
1058+ {
1059+ name: "界火计",
1060+ path: "../../skills/界火计"
1061+ },
1062+ {
1063+ name: "界看破",
1064+ path: "../../skills/界看破"
1065+ }
1066+ ]
1067+ };
1068+}));
1069+//#endregion
1070+//#region src/engine/data/characters/庞统.ts
1071+var 庞统;
1072+var init_庞统 = __esmMin((() => {
1073+ 庞统 = {
1074+ name: "庞统",
1075+ maxHealth: 3,
1076+ gender: "男",
1077+ faction: "蜀",
1078+ skills: [{
1079+ name: "连环",
1080+ path: "../../skills/连环"
1081+ }, {
1082+ name: "涅槃",
1083+ path: "../../skills/涅槃"
1084+ }]
1085+ };
1086+}));
1087+//#endregion
1088+//#region src/engine/data/characters/界庞统.ts
1089+var 界庞统;
1090+var init_界庞统 = __esmMin((() => {
1091+ 界庞统 = {
1092+ name: "界庞统",
1093+ maxHealth: 3,
1094+ gender: "男",
1095+ faction: "蜀",
1096+ skills: [{
1097+ name: "界连环",
1098+ path: "../../skills/界连环"
1099+ }, {
1100+ name: "界涅槃",
1101+ path: "../../skills/界涅槃"
1102+ }]
1103+ };
1104+}));
1105+//#endregion
1106+//#region src/engine/data/characters/孟获.ts
1107+var 孟获;
1108+var init_孟获 = __esmMin((() => {
1109+ 孟获 = {
1110+ name: "孟获",
1111+ maxHealth: 4,
1112+ gender: "男",
1113+ faction: "蜀",
1114+ skills: [{
1115+ name: "祸首",
1116+ path: "../../skills/祸首"
1117+ }, {
1118+ name: "再起",
1119+ path: "../../skills/再起"
1120+ }]
1121+ };
1122+}));
1123+//#endregion
1124+//#region src/engine/data/characters/界孟获.ts
1125+var 界孟获;
1126+var init_界孟获 = __esmMin((() => {
1127+ 界孟获 = {
1128+ name: "界孟获",
1129+ maxHealth: 4,
1130+ gender: "男",
1131+ faction: "蜀",
1132+ skills: [{
1133+ name: "祸首",
1134+ path: "../../skills/祸首"
1135+ }, {
1136+ name: "界再起",
1137+ path: "../../skills/界再起"
1138+ }]
1139+ };
1140+}));
1141+//#endregion
1142+//#region src/engine/data/characters/祝融.ts
1143+var 祝融;
1144+var init_祝融 = __esmMin((() => {
1145+ 祝融 = {
1146+ name: "祝融",
1147+ maxHealth: 4,
1148+ gender: "女",
1149+ faction: "蜀",
1150+ skills: [{
1151+ name: "巨象",
1152+ path: "../../skills/巨象"
1153+ }, {
1154+ name: "烈刃",
1155+ path: "../../skills/烈刃"
1156+ }]
1157+ };
1158+}));
1159+//#endregion
1160+//#region src/engine/data/characters/界祝融.ts
1161+var 界祝融;
1162+var init_界祝融 = __esmMin((() => {
1163+ 界祝融 = {
1164+ name: "界祝融",
1165+ maxHealth: 4,
1166+ gender: "女",
1167+ faction: "蜀",
1168+ skills: [{
1169+ name: "巨象",
1170+ path: "../../skills/巨象"
1171+ }, {
1172+ name: "烈刃",
1173+ path: "../../skills/烈刃"
1174+ }]
1175+ };
1176+}));
1177+//#endregion
1178+//#region src/engine/data/characters/姜维.ts
1179+var 姜维;
1180+var init_姜维 = __esmMin((() => {
1181+ 姜维 = {
1182+ name: "姜维",
1183+ maxHealth: 4,
1184+ gender: "男",
1185+ faction: "蜀",
1186+ skills: [{
1187+ name: "挑衅",
1188+ path: "../../skills/挑衅"
1189+ }, {
1190+ name: "志继",
1191+ path: "../../skills/志继"
1192+ }]
1193+ };
1194+}));
1195+//#endregion
1196+//#region src/engine/data/characters/界姜维.ts
1197+var 界姜维;
1198+var init_界姜维 = __esmMin((() => {
1199+ 界姜维 = {
1200+ name: "界姜维",
1201+ maxHealth: 4,
1202+ gender: "男",
1203+ faction: "蜀",
1204+ skills: [{
1205+ name: "界挑衅",
1206+ path: "../../skills/界挑衅"
1207+ }, {
1208+ name: "界志继",
1209+ path: "../../skills/界志继"
1210+ }]
1211+ };
1212+}));
1213+//#endregion
1214+//#region src/engine/data/characters/刘禅.ts
1215+var 刘禅;
1216+var init_刘禅 = __esmMin((() => {
1217+ 刘禅 = {
1218+ name: "刘禅",
1219+ maxHealth: 3,
1220+ gender: "男",
1221+ faction: "蜀",
1222+ skills: [
1223+ {
1224+ name: "享乐",
1225+ path: "../../skills/享乐"
1226+ },
1227+ {
1228+ name: "放权",
1229+ path: "../../skills/放权"
1230+ },
1231+ {
1232+ name: "若愚",
1233+ path: "../../skills/若愚"
1234+ }
1235+ ]
1236+ };
1237+}));
1238+//#endregion
1239+//#region src/engine/data/characters/界刘禅.ts
1240+var 界刘禅;
1241+var init_界刘禅 = __esmMin((() => {
1242+ 界刘禅 = {
1243+ name: "界刘禅",
1244+ maxHealth: 3,
1245+ gender: "男",
1246+ faction: "蜀",
1247+ skills: [
1248+ {
1249+ name: "享乐",
1250+ path: "../../skills/享乐"
1251+ },
1252+ {
1253+ name: "界放权",
1254+ path: "../../skills/界放权"
1255+ },
1256+ {
1257+ name: "界若愚",
1258+ path: "../../skills/界若愚"
1259+ }
1260+ ]
1261+ };
1262+}));
1263+//#endregion
1264+//#region src/engine/data/characters/界关兴张苞.ts
1265+var 界关兴张苞;
1266+var init_界关兴张苞 = __esmMin((() => {
1267+ 界关兴张苞 = {
1268+ name: "界关兴张苞",
1269+ maxHealth: 4,
1270+ gender: "男",
1271+ faction: "蜀",
1272+ skills: [{
1273+ name: "界父魂",
1274+ path: "../../skills/界父魂"
1275+ }]
1276+ };
1277+}));
1278+//#endregion
1279+//#region src/engine/data/characters/界夏侯氏.ts
1280+var 界夏侯氏;
1281+var init_界夏侯氏 = __esmMin((() => {
1282+ 界夏侯氏 = {
1283+ name: "界夏侯氏",
1284+ maxHealth: 3,
1285+ gender: "女",
1286+ faction: "蜀",
1287+ skills: [{
1288+ name: "界樵拾",
1289+ path: "../../skills/界樵拾"
1290+ }, {
1291+ name: "界燕语",
1292+ path: "../../skills/界燕语"
1293+ }]
1294+ };
1295+}));
1296+//#endregion
1297+//#region src/engine/data/characters/界廖化.ts
1298+var 界廖化;
1299+var init_界廖化 = __esmMin((() => {
1300+ 界廖化 = {
1301+ name: "界廖化",
1302+ maxHealth: 4,
1303+ gender: "男",
1304+ faction: "蜀",
1305+ skills: [{
1306+ name: "界当先",
1307+ path: "../../skills/界当先"
1308+ }, {
1309+ name: "界伏枥",
1310+ path: "../../skills/界伏枥"
1311+ }]
1312+ };
1313+}));
1314+//#endregion
1315+//#region src/engine/data/characters/界张松.ts
1316+var 界张松;
1317+var init_界张松 = __esmMin((() => {
1318+ 界张松 = {
1319+ name: "界张松",
1320+ maxHealth: 3,
1321+ gender: "男",
1322+ faction: "蜀",
1323+ skills: [{
1324+ name: "界强识",
1325+ path: "../../skills/界强识"
1326+ }, {
1327+ name: "界献图",
1328+ path: "../../skills/界献图"
1329+ }]
1330+ };
1331+}));
1332+//#endregion
1333+//#region src/engine/data/characters/界徐庶.ts
1334+var 界徐庶;
1335+var init_界徐庶 = __esmMin((() => {
1336+ 界徐庶 = {
1337+ name: "界徐庶",
1338+ maxHealth: 4,
1339+ gender: "男",
1340+ faction: "蜀",
1341+ skills: [{
1342+ name: "界诛害",
1343+ path: "../../skills/界诛害"
1344+ }, {
1345+ name: "界潜心",
1346+ path: "../../skills/界潜心"
1347+ }]
1348+ };
1349+}));
1350+//#endregion
1351+//#region src/engine/data/characters/界法正.ts
1352+var 界法正;
1353+var init_界法正 = __esmMin((() => {
1354+ 界法正 = {
1355+ name: "界法正",
1356+ maxHealth: 3,
1357+ gender: "男",
1358+ faction: "蜀",
1359+ skills: [{
1360+ name: "界眩惑",
1361+ path: "../../skills/界眩惑"
1362+ }, {
1363+ name: "界恩怨",
1364+ path: "../../skills/界恩怨"
1365+ }]
1366+ };
1367+}));
1368+//#endregion
1369+//#region src/engine/data/characters/界简雍.ts
1370+var 界简雍;
1371+var init_界简雍 = __esmMin((() => {
1372+ 界简雍 = {
1373+ name: "界简雍",
1374+ maxHealth: 3,
1375+ gender: "男",
1376+ faction: "蜀",
1377+ skills: [{
1378+ name: "界纵适",
1379+ path: "../../skills/界纵适"
1380+ }, {
1381+ name: "界巧说",
1382+ path: "../../skills/界巧说"
1383+ }]
1384+ };
1385+}));
1386+//#endregion
1387+//#region src/engine/data/characters/孙权.ts
1388+var 孙权;
1389+var init_孙权 = __esmMin((() => {
1390+ 孙权 = {
1391+ name: "孙权",
1392+ maxHealth: 4,
1393+ gender: "男",
1394+ faction: "吴",
1395+ skills: [{
1396+ name: "制衡",
1397+ path: "../../skills/制衡"
1398+ }, {
1399+ name: "救援",
1400+ path: "../../skills/救援"
1401+ }]
1402+ };
1403+}));
1404+//#endregion
1405+//#region src/engine/data/characters/界孙权.ts
1406+var 界孙权;
1407+var init_界孙权 = __esmMin((() => {
1408+ 界孙权 = {
1409+ name: "界孙权",
1410+ maxHealth: 4,
1411+ gender: "男",
1412+ faction: "吴",
1413+ skills: [{
1414+ name: "界制衡",
1415+ path: "../../skills/界制衡"
1416+ }, {
1417+ name: "界救援",
1418+ path: "../../skills/界救援"
1419+ }]
1420+ };
1421+}));
1422+//#endregion
1423+//#region src/engine/data/characters/甘宁.ts
1424+var 甘宁;
1425+var init_甘宁 = __esmMin((() => {
1426+ 甘宁 = {
1427+ name: "甘宁",
1428+ maxHealth: 4,
1429+ gender: "男",
1430+ faction: "吴",
1431+ skills: [{
1432+ name: "奇袭",
1433+ path: "../../skills/奇袭"
1434+ }]
1435+ };
1436+}));
1437+//#endregion
1438+//#region src/engine/data/characters/界甘宁.ts
1439+var 界甘宁;
1440+var init_界甘宁 = __esmMin((() => {
1441+ 界甘宁 = {
1442+ name: "界甘宁",
1443+ maxHealth: 4,
1444+ gender: "男",
1445+ faction: "吴",
1446+ skills: [{
1447+ name: "奇袭",
1448+ path: "../../skills/奇袭"
1449+ }, {
1450+ name: "奋威",
1451+ path: "../../skills/奋威"
1452+ }]
1453+ };
1454+}));
1455+//#endregion
1456+//#region src/engine/data/characters/吕蒙.ts
1457+var 吕蒙;
1458+var init_吕蒙 = __esmMin((() => {
1459+ 吕蒙 = {
1460+ name: "吕蒙",
1461+ maxHealth: 4,
1462+ gender: "男",
1463+ faction: "吴",
1464+ skills: [{
1465+ name: "克己",
1466+ path: "../../skills/克己"
1467+ }]
1468+ };
1469+}));
1470+//#endregion
1471+//#region src/engine/data/characters/界吕蒙.ts
1472+var 界吕蒙;
1473+var init_界吕蒙 = __esmMin((() => {
1474+ 界吕蒙 = {
1475+ name: "界吕蒙",
1476+ maxHealth: 4,
1477+ gender: "男",
1478+ faction: "吴",
1479+ skills: [
1480+ {
1481+ name: "界克己",
1482+ path: "../../skills/界克己"
1483+ },
1484+ {
1485+ name: "勤学",
1486+ path: "../../skills/勤学"
1487+ },
1488+ {
1489+ name: "博图",
1490+ path: "../../skills/博图"
1491+ }
1492+ ]
1493+ };
1494+}));
1495+//#endregion
1496+//#region src/engine/data/characters/黄盖.ts
1497+var 黄盖;
1498+var init_黄盖 = __esmMin((() => {
1499+ 黄盖 = {
1500+ name: "黄盖",
1501+ maxHealth: 4,
1502+ gender: "男",
1503+ faction: "吴",
1504+ skills: [{
1505+ name: "苦肉",
1506+ path: "../../skills/苦肉"
1507+ }]
1508+ };
1509+}));
1510+//#endregion
1511+//#region src/engine/data/characters/界黄盖.ts
1512+var 界黄盖;
1513+var init_界黄盖 = __esmMin((() => {
1514+ 界黄盖 = {
1515+ name: "界黄盖",
1516+ maxHealth: 4,
1517+ gender: "男",
1518+ faction: "吴",
1519+ skills: [{
1520+ name: "界苦肉",
1521+ path: "../../skills/界苦肉"
1522+ }, {
1523+ name: "诈降",
1524+ path: "../../skills/诈降"
1525+ }]
1526+ };
1527+}));
1528+//#endregion
1529+//#region src/engine/data/characters/周瑜.ts
1530+var 周瑜;
1531+var init_周瑜 = __esmMin((() => {
1532+ 周瑜 = {
1533+ name: "周瑜",
1534+ maxHealth: 3,
1535+ gender: "男",
1536+ faction: "吴",
1537+ skills: [{
1538+ name: "反间",
1539+ path: "../../skills/反间"
1540+ }, {
1541+ name: "英姿",
1542+ path: "../../skills/英姿"
1543+ }]
1544+ };
1545+}));
1546+//#endregion
1547+//#region src/engine/data/characters/界周瑜.ts
1548+var 界周瑜;
1549+var init_界周瑜 = __esmMin((() => {
1550+ 界周瑜 = {
1551+ name: "界周瑜",
1552+ maxHealth: 3,
1553+ gender: "男",
1554+ faction: "吴",
1555+ skills: [{
1556+ name: "界英姿",
1557+ path: "../../skills/界英姿"
1558+ }, {
1559+ name: "界反间",
1560+ path: "../../skills/界反间"
1561+ }]
1562+ };
1563+}));
1564+//#endregion
1565+//#region src/engine/data/characters/大乔.ts
1566+var 大乔;
1567+var init_大乔 = __esmMin((() => {
1568+ 大乔 = {
1569+ name: "大乔",
1570+ maxHealth: 3,
1571+ gender: "女",
1572+ faction: "吴",
1573+ skills: [{
1574+ name: "国色",
1575+ path: "../../skills/国色"
1576+ }, {
1577+ name: "流离",
1578+ path: "../../skills/流离"
1579+ }]
1580+ };
1581+}));
1582+//#endregion
1583+//#region src/engine/data/characters/界大乔.ts
1584+var 界大乔;
1585+var init_界大乔 = __esmMin((() => {
1586+ 界大乔 = {
1587+ name: "界大乔",
1588+ maxHealth: 3,
1589+ gender: "女",
1590+ faction: "吴",
1591+ skills: [{
1592+ name: "界国色",
1593+ path: "../../skills/界国色"
1594+ }, {
1595+ name: "流离",
1596+ path: "../../skills/流离"
1597+ }]
1598+ };
1599+}));
1600+//#endregion
1601+//#region src/engine/data/characters/陆逊.ts
1602+var 陆逊;
1603+var init_陆逊 = __esmMin((() => {
1604+ 陆逊 = {
1605+ name: "陆逊",
1606+ maxHealth: 3,
1607+ gender: "男",
1608+ faction: "吴",
1609+ skills: [{
1610+ name: "谦逊",
1611+ path: "../../skills/谦逊"
1612+ }, {
1613+ name: "连营",
1614+ path: "../../skills/连营"
1615+ }]
1616+ };
1617+}));
1618+//#endregion
1619+//#region src/engine/data/characters/界陆逊.ts
1620+var 界陆逊;
1621+var init_界陆逊 = __esmMin((() => {
1622+ 界陆逊 = {
1623+ name: "界陆逊",
1624+ maxHealth: 3,
1625+ gender: "男",
1626+ faction: "吴",
1627+ skills: [{
1628+ name: "界谦逊",
1629+ path: "../../skills/界谦逊"
1630+ }, {
1631+ name: "界连营",
1632+ path: "../../skills/界连营"
1633+ }]
1634+ };
1635+}));
1636+//#endregion
1637+//#region src/engine/data/characters/孙尚香.ts
1638+var 孙尚香;
1639+var init_孙尚香 = __esmMin((() => {
1640+ 孙尚香 = {
1641+ name: "孙尚香",
1642+ maxHealth: 3,
1643+ gender: "女",
1644+ faction: "吴",
1645+ skills: [{
1646+ name: "结姻",
1647+ path: "../../skills/结姻"
1648+ }, {
1649+ name: "枭姬",
1650+ path: "../../skills/枭姬"
1651+ }]
1652+ };
1653+}));
1654+//#endregion
1655+//#region src/engine/data/characters/界孙尚香.ts
1656+var 界孙尚香;
1657+var init_界孙尚香 = __esmMin((() => {
1658+ 界孙尚香 = {
1659+ name: "界孙尚香",
1660+ maxHealth: 3,
1661+ gender: "女",
1662+ faction: "吴",
1663+ skills: [{
1664+ name: "界结姻",
1665+ path: "../../skills/界结姻"
1666+ }, {
1667+ name: "枭姬",
1668+ path: "../../skills/枭姬"
1669+ }]
1670+ };
1671+}));
1672+//#endregion
1673+//#region src/engine/data/characters/小乔.ts
1674+var 小乔;
1675+var init_小乔 = __esmMin((() => {
1676+ 小乔 = {
1677+ name: "小乔",
1678+ maxHealth: 3,
1679+ gender: "女",
1680+ faction: "吴",
1681+ skills: [{
1682+ name: "天香",
1683+ path: "../../skills/天香"
1684+ }, {
1685+ name: "红颜",
1686+ path: "../../skills/红颜"
1687+ }]
1688+ };
1689+}));
1690+//#endregion
1691+//#region src/engine/data/characters/界小乔.ts
1692+var 界小乔;
1693+var init_界小乔 = __esmMin((() => {
1694+ 界小乔 = {
1695+ name: "界小乔",
1696+ maxHealth: 3,
1697+ gender: "女",
1698+ faction: "吴",
1699+ skills: [
1700+ {
1701+ name: "界红颜",
1702+ path: "../../skills/界红颜"
1703+ },
1704+ {
1705+ name: "界天香",
1706+ path: "../../skills/界天香"
1707+ },
1708+ {
1709+ name: "飘零",
1710+ path: "../../skills/飘零"
1711+ }
1712+ ]
1713+ };
1714+}));
1715+//#endregion
1716+//#region src/engine/data/characters/周泰.ts
1717+var 周泰;
1718+var init_周泰 = __esmMin((() => {
1719+ 周泰 = {
1720+ name: "周泰",
1721+ maxHealth: 4,
1722+ gender: "男",
1723+ faction: "吴",
1724+ skills: [{
1725+ name: "不屈",
1726+ path: "../../skills/不屈"
1727+ }]
1728+ };
1729+}));
1730+//#endregion
1731+//#region src/engine/data/characters/界周泰.ts
1732+var 界周泰;
1733+var init_界周泰 = __esmMin((() => {
1734+ 界周泰 = {
1735+ name: "界周泰",
1736+ maxHealth: 4,
1737+ gender: "男",
1738+ faction: "吴",
1739+ skills: [{ name: "界不屈" }, { name: "奋激" }]
1740+ };
1741+}));
1742+//#endregion
1743+//#region src/engine/data/characters/太史慈.ts
1744+var 太史慈;
1745+var init_太史慈 = __esmMin((() => {
1746+ 太史慈 = {
1747+ name: "太史慈",
1748+ maxHealth: 4,
1749+ gender: "男",
1750+ faction: "吴",
1751+ skills: [{
1752+ name: "天义",
1753+ path: "../../skills/天义"
1754+ }]
1755+ };
1756+}));
1757+//#endregion
1758+//#region src/engine/data/characters/界太史慈.ts
1759+var 界太史慈;
1760+var init_界太史慈 = __esmMin((() => {
1761+ 界太史慈 = {
1762+ name: "界太史慈",
1763+ maxHealth: 4,
1764+ gender: "男",
1765+ faction: "吴",
1766+ skills: [{
1767+ name: "天义",
1768+ path: "../../skills/天义"
1769+ }, {
1770+ name: "酣战",
1771+ path: "../../skills/酣战"
1772+ }]
1773+ };
1774+}));
1775+//#endregion
1776+//#region src/engine/data/characters/鲁肃.ts
1777+var 鲁肃;
1778+var init_鲁肃 = __esmMin((() => {
1779+ 鲁肃 = {
1780+ name: "鲁肃",
1781+ maxHealth: 3,
1782+ gender: "男",
1783+ faction: "吴",
1784+ skills: [{
1785+ name: "好施",
1786+ path: "../../skills/好施"
1787+ }, {
1788+ name: "缔盟",
1789+ path: "../../skills/缔盟"
1790+ }]
1791+ };
1792+}));
1793+//#endregion
1794+//#region src/engine/data/characters/界鲁肃.ts
1795+var 界鲁肃;
1796+var init_界鲁肃 = __esmMin((() => {
1797+ 界鲁肃 = {
1798+ name: "界鲁肃",
1799+ maxHealth: 3,
1800+ gender: "男",
1801+ faction: "吴",
1802+ skills: [{
1803+ name: "界好施",
1804+ path: "../../skills/界好施"
1805+ }, {
1806+ name: "界缔盟",
1807+ path: "../../skills/界缔盟"
1808+ }]
1809+ };
1810+}));
1811+//#endregion
1812+//#region src/engine/data/characters/孙坚.ts
1813+var 孙坚;
1814+var init_孙坚 = __esmMin((() => {
1815+ 孙坚 = {
1816+ name: "孙坚",
1817+ maxHealth: 4,
1818+ gender: "男",
1819+ faction: "吴",
1820+ skills: [{
1821+ name: "英魂",
1822+ path: "../../skills/英魂"
1823+ }]
1824+ };
1825+}));
1826+//#endregion
1827+//#region src/engine/data/characters/界孙坚.ts
1828+var 界孙坚;
1829+var init_界孙坚 = __esmMin((() => {
1830+ 界孙坚 = {
1831+ name: "界孙坚",
1832+ maxHealth: 4,
1833+ gender: "男",
1834+ faction: "吴",
1835+ skills: [{ name: "英魂" }, { name: "武烈" }]
1836+ };
1837+}));
1838+//#endregion
1839+//#region src/engine/data/characters/孙策.ts
1840+var 孙策;
1841+var init_孙策 = __esmMin((() => {
1842+ 孙策 = {
1843+ name: "孙策",
1844+ maxHealth: 4,
1845+ gender: "男",
1846+ faction: "吴",
1847+ skills: [
1848+ {
1849+ name: "激昂",
1850+ path: "../../skills/激昂"
1851+ },
1852+ {
1853+ name: "魂姿",
1854+ path: "../../skills/魂姿"
1855+ },
1856+ {
1857+ name: "制霸",
1858+ path: "../../skills/制霸"
1859+ }
1860+ ]
1861+ };
1862+}));
1863+//#endregion
1864+//#region src/engine/data/characters/界孙策.ts
1865+var 界孙策;
1866+var init_界孙策 = __esmMin((() => {
1867+ 界孙策 = {
1868+ name: "界孙策",
1869+ maxHealth: 4,
1870+ gender: "男",
1871+ faction: "吴",
1872+ skills: [
1873+ {
1874+ name: "界激昂",
1875+ path: "../../skills/界激昂"
1876+ },
1877+ {
1878+ name: "界魂姿",
1879+ path: "../../skills/界魂姿"
1880+ },
1881+ {
1882+ name: "界制霸",
1883+ path: "../../skills/界制霸"
1884+ }
1885+ ]
1886+ };
1887+}));
1888+//#endregion
1889+//#region src/engine/data/characters/张昭张纮.ts
1890+var 张昭张纮;
1891+var init_张昭张纮 = __esmMin((() => {
1892+ 张昭张纮 = {
1893+ name: "张昭张纮",
1894+ maxHealth: 3,
1895+ gender: "男",
1896+ faction: "吴",
1897+ skills: [{
1898+ name: "直谏",
1899+ path: "../../skills/直谏"
1900+ }, {
1901+ name: "固政",
1902+ path: "../../skills/固政"
1903+ }]
1904+ };
1905+}));
1906+//#endregion
1907+//#region src/engine/data/characters/界张昭张纮.ts
1908+var 界张昭张纮;
1909+var init_界张昭张纮 = __esmMin((() => {
1910+ 界张昭张纮 = {
1911+ name: "界张昭张纮",
1912+ maxHealth: 3,
1913+ gender: "男",
1914+ faction: "吴",
1915+ skills: [{
1916+ name: "界直谏",
1917+ path: "../../skills/界直谏"
1918+ }, {
1919+ name: "界固政",
1920+ path: "../../skills/界固政"
1921+ }]
1922+ };
1923+}));
1924+//#endregion
1925+//#region src/engine/data/characters/界凌统.ts
1926+var 界凌统;
1927+var init_界凌统 = __esmMin((() => {
1928+ 界凌统 = {
1929+ name: "界凌统",
1930+ maxHealth: 4,
1931+ gender: "男",
1932+ faction: "吴",
1933+ skills: [{
1934+ name: "界旋风",
1935+ path: "../../skills/界旋风"
1936+ }]
1937+ };
1938+}));
1939+//#endregion
1940+//#region src/engine/data/characters/界吴国太.ts
1941+var 界吴国太;
1942+var init_界吴国太 = __esmMin((() => {
1943+ 界吴国太 = {
1944+ name: "界吴国太",
1945+ maxHealth: 3,
1946+ gender: "女",
1947+ faction: "吴",
1948+ skills: [{
1949+ name: "界甘露",
1950+ path: "../../skills/界甘露"
1951+ }, {
1952+ name: "界补益",
1953+ path: "../../skills/界补益"
1954+ }]
1955+ };
1956+}));
1957+//#endregion
1958+//#region src/engine/data/characters/界徐盛.ts
1959+var 界徐盛;
1960+var init_界徐盛 = __esmMin((() => {
1961+ 界徐盛 = {
1962+ name: "界徐盛",
1963+ maxHealth: 4,
1964+ gender: "男",
1965+ faction: "吴",
1966+ skills: [{
1967+ name: "界破军",
1968+ path: "../../skills/界破军"
1969+ }]
1970+ };
1971+}));
1972+//#endregion
1973+//#region src/engine/data/characters/界程普.ts
1974+var 界程普;
1975+var init_界程普 = __esmMin((() => {
1976+ 界程普 = {
1977+ name: "界程普",
1978+ maxHealth: 4,
1979+ gender: "男",
1980+ faction: "吴",
1981+ skills: [{
1982+ name: "界疠火",
1983+ path: "../../skills/界疠火"
1984+ }, {
1985+ name: "界醇醪",
1986+ path: "../../skills/界醇醪"
1987+ }]
1988+ };
1989+}));
1990+//#endregion
1991+//#region src/engine/data/characters/界虞翻.ts
1992+var 界虞翻;
1993+var init_界虞翻 = __esmMin((() => {
1994+ 界虞翻 = {
1995+ name: "界虞翻",
1996+ maxHealth: 3,
1997+ gender: "男",
1998+ faction: "吴",
1999+ skills: [{
2000+ name: "界纵玄",
2001+ path: "../../skills/界纵玄"
2002+ }, {
2003+ name: "界直言",
2004+ path: "../../skills/界直言"
2005+ }]
2006+ };
2007+}));
2008+//#endregion
2009+//#region src/engine/data/characters/界韩当.ts
2010+var 界韩当;
2011+var init_界韩当 = __esmMin((() => {
2012+ 界韩当 = {
2013+ name: "界韩当",
2014+ maxHealth: 4,
2015+ gender: "男",
2016+ faction: "吴",
2017+ skills: [{
2018+ name: "界弓骑",
2019+ path: "../../skills/界弓骑"
2020+ }, {
2021+ name: "界解烦",
2022+ path: "../../skills/界解烦"
2023+ }]
2024+ };
2025+}));
2026+//#endregion
2027+//#region src/engine/data/characters/华佗.ts
2028+var 华佗;
2029+var init_华佗 = __esmMin((() => {
2030+ 华佗 = {
2031+ name: "华佗",
2032+ maxHealth: 3,
2033+ gender: "男",
2034+ faction: "群",
2035+ skills: [{
2036+ name: "急救",
2037+ path: "../../skills/急救"
2038+ }, {
2039+ name: "青囊",
2040+ path: "../../skills/青囊"
2041+ }]
2042+ };
2043+}));
2044+//#endregion
2045+//#region src/engine/data/characters/吕布.ts
2046+var 吕布;
2047+var init_吕布 = __esmMin((() => {
2048+ 吕布 = {
2049+ name: "吕布",
2050+ maxHealth: 4,
2051+ gender: "男",
2052+ faction: "群",
2053+ skills: [{
2054+ name: "无双",
2055+ path: "../../skills/无双"
2056+ }]
2057+ };
2058+}));
2059+//#endregion
2060+//#region src/engine/data/characters/貂蝉.ts
2061+var 貂蝉;
2062+var init_貂蝉 = __esmMin((() => {
2063+ 貂蝉 = {
2064+ name: "貂蝉",
2065+ maxHealth: 3,
2066+ gender: "女",
2067+ faction: "群",
2068+ skills: [{
2069+ name: "离间",
2070+ path: "../../skills/离间"
2071+ }, {
2072+ name: "闭月",
2073+ path: "../../skills/闭月"
2074+ }]
2075+ };
2076+}));
2077+//#endregion
2078+//#region src/engine/data/characters/界貂蝉.ts
2079+var 界貂蝉;
2080+var init_界貂蝉 = __esmMin((() => {
2081+ 界貂蝉 = {
2082+ name: "界貂蝉",
2083+ maxHealth: 3,
2084+ gender: "女",
2085+ faction: "群",
2086+ skills: [{
2087+ name: "离间",
2088+ path: "../../skills/离间"
2089+ }, {
2090+ name: "界闭月",
2091+ path: "../../skills/界闭月"
2092+ }]
2093+ };
2094+}));
2095+//#endregion
2096+//#region src/engine/data/characters/张角.ts
2097+var 张角;
2098+var init_张角 = __esmMin((() => {
2099+ 张角 = {
2100+ name: "张角",
2101+ maxHealth: 3,
2102+ gender: "男",
2103+ faction: "群",
2104+ skills: [
2105+ {
2106+ name: "雷击",
2107+ path: "../../skills/雷击"
2108+ },
2109+ {
2110+ name: "鬼道",
2111+ path: "../../skills/鬼道"
2112+ },
2113+ {
2114+ name: "黄天",
2115+ path: "../../skills/黄天"
2116+ }
2117+ ]
2118+ };
2119+}));
2120+//#endregion
2121+//#region src/engine/data/characters/于吉.ts
2122+var 于吉;
2123+var init_于吉 = __esmMin((() => {
2124+ 于吉 = {
2125+ name: "于吉",
2126+ maxHealth: 3,
2127+ gender: "男",
2128+ faction: "群",
2129+ skills: [{
2130+ name: "蛊惑",
2131+ path: "../../skills/蛊惑"
2132+ }]
2133+ };
2134+}));
2135+//#endregion
2136+//#region src/engine/data/characters/界于吉.ts
2137+var 界于吉;
2138+var init_界于吉 = __esmMin((() => {
2139+ 界于吉 = {
2140+ name: "界于吉",
2141+ maxHealth: 3,
2142+ gender: "男",
2143+ faction: "群",
2144+ skills: [{
2145+ name: "界蛊惑",
2146+ path: "../../skills/界蛊惑"
2147+ }]
2148+ };
2149+}));
2150+//#endregion
2151+//#region src/engine/data/characters/袁绍.ts
2152+var 袁绍;
2153+var init_袁绍 = __esmMin((() => {
2154+ 袁绍 = {
2155+ name: "袁绍",
2156+ maxHealth: 4,
2157+ gender: "男",
2158+ faction: "群",
2159+ skills: [{
2160+ name: "乱击",
2161+ path: "../../skills/乱击"
2162+ }]
2163+ };
2164+}));
2165+//#endregion
2166+//#region src/engine/data/characters/界袁绍.ts
2167+var 界袁绍;
2168+var init_界袁绍 = __esmMin((() => {
2169+ 界袁绍 = {
2170+ name: "界袁绍",
2171+ maxHealth: 4,
2172+ gender: "男",
2173+ faction: "群",
2174+ isLord: true,
2175+ skills: [{
2176+ name: "界乱击",
2177+ path: "../../skills/界乱击"
2178+ }, {
2179+ name: "界血裔",
2180+ path: "../../skills/界血裔"
2181+ }]
2182+ };
2183+}));
2184+//#endregion
2185+//#region src/engine/data/characters/庞德.ts
2186+var 庞德;
2187+var init_庞德 = __esmMin((() => {
2188+ 庞德 = {
2189+ name: "庞德",
2190+ maxHealth: 4,
2191+ gender: "男",
2192+ faction: "群",
2193+ skills: [{
2194+ name: "马术",
2195+ path: "../../skills/马术"
2196+ }, {
2197+ name: "鞬出",
2198+ path: "../../skills/鞬出"
2199+ }]
2200+ };
2201+}));
2202+//#endregion
2203+//#region src/engine/data/characters/界庞德.ts
2204+var 界庞德;
2205+var init_界庞德 = __esmMin((() => {
2206+ 界庞德 = {
2207+ name: "界庞德",
2208+ maxHealth: 4,
2209+ gender: "男",
2210+ faction: "群",
2211+ skills: [{
2212+ name: "马术",
2213+ path: "../../skills/马术"
2214+ }, {
2215+ name: "界鞬出",
2216+ path: "../../skills/界鞬出"
2217+ }]
2218+ };
2219+}));
2220+//#endregion
2221+//#region src/engine/data/characters/颜良文丑.ts
2222+var 颜良文丑;
2223+var init_颜良文丑 = __esmMin((() => {
2224+ 颜良文丑 = {
2225+ name: "颜良文丑",
2226+ maxHealth: 4,
2227+ gender: "男",
2228+ faction: "群",
2229+ skills: [{
2230+ name: "双雄",
2231+ path: "../../skills/双雄"
2232+ }]
2233+ };
2234+}));
2235+//#endregion
2236+//#region src/engine/data/characters/界颜良文丑.ts
2237+var 界颜良文丑;
2238+var init_界颜良文丑 = __esmMin((() => {
2239+ 界颜良文丑 = {
2240+ name: "界颜良文丑",
2241+ maxHealth: 4,
2242+ gender: "男",
2243+ faction: "群",
2244+ skills: [{
2245+ name: "界双雄",
2246+ path: "../../skills/界双雄"
2247+ }]
2248+ };
2249+}));
2250+//#endregion
2251+//#region src/engine/data/characters/董卓.ts
2252+var 董卓;
2253+var init_董卓 = __esmMin((() => {
2254+ 董卓 = {
2255+ name: "董卓",
2256+ maxHealth: 8,
2257+ gender: "男",
2258+ faction: "群",
2259+ skills: [
2260+ {
2261+ name: "酒池",
2262+ path: "../../skills/酒池"
2263+ },
2264+ {
2265+ name: "肉林",
2266+ path: "../../skills/肉林"
2267+ },
2268+ {
2269+ name: "崩坏",
2270+ path: "../../skills/崩坏"
2271+ },
2272+ {
2273+ name: "暴虐",
2274+ path: "../../skills/暴虐"
2275+ }
2276+ ]
2277+ };
2278+}));
2279+//#endregion
2280+//#region src/engine/data/characters/界董卓.ts
2281+var 界董卓;
2282+var init_界董卓 = __esmMin((() => {
2283+ 界董卓 = {
2284+ name: "界董卓",
2285+ maxHealth: 8,
2286+ gender: "男",
2287+ faction: "群",
2288+ skills: [
2289+ {
2290+ name: "界酒池",
2291+ path: "../../skills/界酒池"
2292+ },
2293+ {
2294+ name: "肉林",
2295+ path: "../../skills/肉林"
2296+ },
2297+ {
2298+ name: "界崩坏",
2299+ path: "../../skills/界崩坏"
2300+ },
2301+ {
2302+ name: "界暴虐",
2303+ path: "../../skills/界暴虐"
2304+ }
2305+ ]
2306+ };
2307+}));
2308+//#endregion
2309+//#region src/engine/data/characters/贾诩.ts
2310+var 贾诩;
2311+var init_贾诩 = __esmMin((() => {
2312+ 贾诩 = {
2313+ name: "贾诩",
2314+ maxHealth: 3,
2315+ gender: "男",
2316+ faction: "群",
2317+ skills: [
2318+ {
2319+ name: "完杀",
2320+ path: "../../skills/完杀"
2321+ },
2322+ {
2323+ name: "乱武",
2324+ path: "../../skills/乱武"
2325+ },
2326+ {
2327+ name: "帷幕",
2328+ path: "../../skills/帷幕"
2329+ }
2330+ ]
2331+ };
2332+}));
2333+//#endregion
2334+//#region src/engine/data/characters/界贾诩.ts
2335+var 界贾诩;
2336+var init_界贾诩 = __esmMin((() => {
2337+ 界贾诩 = {
2338+ name: "界贾诩",
2339+ maxHealth: 3,
2340+ gender: "男",
2341+ faction: "群",
2342+ skills: [
2343+ {
2344+ name: "界帷幕",
2345+ path: "../../skills/界帷幕"
2346+ },
2347+ {
2348+ name: "界乱武",
2349+ path: "../../skills/界乱武"
2350+ },
2351+ {
2352+ name: "界完杀",
2353+ path: "../../skills/界完杀"
2354+ }
2355+ ]
2356+ };
2357+}));
2358+//#endregion
2359+//#region src/engine/data/characters/左慈.ts
2360+var 左慈;
2361+var init_左慈 = __esmMin((() => {
2362+ 左慈 = {
2363+ name: "左慈",
2364+ maxHealth: 3,
2365+ gender: "男",
2366+ faction: "群",
2367+ skills: [{
2368+ name: "化身",
2369+ path: "../../skills/化身"
2370+ }, {
2371+ name: "新生",
2372+ path: "../../skills/新生"
2373+ }]
2374+ };
2375+}));
2376+//#endregion
2377+//#region src/engine/data/characters/蔡文姬.ts
2378+var 蔡文姬;
2379+var init_蔡文姬 = __esmMin((() => {
2380+ 蔡文姬 = {
2381+ name: "蔡文姬",
2382+ maxHealth: 3,
2383+ gender: "女",
2384+ faction: "群",
2385+ skills: [{
2386+ name: "悲歌",
2387+ path: "../../skills/悲歌"
2388+ }, {
2389+ name: "断肠",
2390+ path: "../../skills/断肠"
2391+ }]
2392+ };
2393+}));
2394+//#endregion
2395+//#region src/engine/data/characters/界蔡文姬.ts
2396+var 界蔡文姬;
2397+var init_界蔡文姬 = __esmMin((() => {
2398+ 界蔡文姬 = {
2399+ name: "界蔡文姬",
2400+ maxHealth: 3,
2401+ gender: "女",
2402+ faction: "群",
2403+ skills: [{
2404+ name: "界悲歌",
2405+ path: "../../skills/界悲歌"
2406+ }, {
2407+ name: "断肠",
2408+ path: "../../skills/断肠"
2409+ }]
2410+ };
2411+}));
2412+//#endregion
2413+//#region src/engine/data/characters/界伏皇后.ts
2414+var 界伏皇后;
2415+var init_界伏皇后 = __esmMin((() => {
2416+ 界伏皇后 = {
2417+ name: "界伏皇后",
2418+ maxHealth: 3,
2419+ gender: "女",
2420+ faction: "群",
2421+ skills: [{
2422+ name: "界惴恐",
2423+ path: "../../skills/界惴恐"
2424+ }, {
2425+ name: "界求援",
2426+ path: "../../skills/界求援"
2427+ }]
2428+ };
2429+}));
2430+//#endregion
2431+//#region src/engine/data/characters/界公孙瓒.ts
2432+var 界公孙瓒;
2433+var init_界公孙瓒 = __esmMin((() => {
2434+ 界公孙瓒 = {
2435+ name: "界公孙瓒",
2436+ maxHealth: 4,
2437+ gender: "男",
2438+ faction: "群",
2439+ skills: [{
2440+ name: "界义从",
2441+ path: "../../skills/界义从"
2442+ }, {
2443+ name: "界趫猛",
2444+ path: "../../skills/界趫猛"
2445+ }]
2446+ };
2447+}));
2448+//#endregion
2449+//#region src/engine/data/characters/界刘表.ts
2450+var 界刘表;
2451+var init_界刘表 = __esmMin((() => {
2452+ 界刘表 = {
2453+ name: "界刘表",
2454+ maxHealth: 3,
2455+ gender: "男",
2456+ faction: "群",
2457+ skills: [{
2458+ name: "界自守",
2459+ path: "../../skills/界自守"
2460+ }, {
2461+ name: "界宗室",
2462+ path: "../../skills/界宗室"
2463+ }]
2464+ };
2465+}));
2466+//#endregion
2467+//#region src/engine/data/characters/界华佗.ts
2468+var 界华佗;
2469+var init_界华佗 = __esmMin((() => {
2470+ 界华佗 = {
2471+ name: "界华佗",
2472+ maxHealth: 3,
2473+ gender: "男",
2474+ faction: "群",
2475+ skills: [{
2476+ name: "急救",
2477+ path: "../../skills/急救"
2478+ }, {
2479+ name: "界除疠",
2480+ path: "../../skills/界除疠"
2481+ }]
2482+ };
2483+}));
2484+//#endregion
2485+//#region src/engine/data/characters/界华雄.ts
2486+var 界华雄;
2487+var init_界华雄 = __esmMin((() => {
2488+ 界华雄 = {
2489+ name: "界华雄",
2490+ maxHealth: 6,
2491+ gender: "男",
2492+ faction: "群",
2493+ skills: [{
2494+ name: "界耀武",
2495+ path: "../../skills/界耀武"
2496+ }, {
2497+ name: "界势斩",
2498+ path: "../../skills/界势斩"
2499+ }]
2500+ };
2501+}));
2502+//#endregion
2503+//#region src/engine/data/characters/界吕布.ts
2504+var 界吕布;
2505+var init_界吕布 = __esmMin((() => {
2506+ 界吕布 = {
2507+ name: "界吕布",
2508+ maxHealth: 5,
2509+ gender: "男",
2510+ faction: "群",
2511+ skills: [{
2512+ name: "无双",
2513+ path: "../../skills/无双"
2514+ }, {
2515+ name: "界利驭",
2516+ path: "../../skills/界利驭"
2517+ }]
2518+ };
2519+}));
2520+//#endregion
2521+//#region src/engine/data/characters/界左慈.ts
2522+var 界左慈;
2523+var init_界左慈 = __esmMin((() => {
2524+ 界左慈 = {
2525+ name: "界左慈",
2526+ maxHealth: 3,
2527+ gender: "男",
2528+ faction: "群",
2529+ skills: [{
2530+ name: "化身",
2531+ path: "../../skills/化身"
2532+ }, {
2533+ name: "新生",
2534+ path: "../../skills/新生"
2535+ }]
2536+ };
2537+}));
2538+//#endregion
2539+//#region src/engine/data/characters/界张角.ts
2540+var 界张角;
2541+var init_界张角 = __esmMin((() => {
2542+ 界张角 = {
2543+ name: "界张角",
2544+ maxHealth: 3,
2545+ gender: "男",
2546+ faction: "群",
2547+ skills: [
2548+ {
2549+ name: "界雷击",
2550+ path: "../../skills/界雷击"
2551+ },
2552+ {
2553+ name: "界鬼道",
2554+ path: "../../skills/界鬼道"
2555+ },
2556+ {
2557+ name: "界黄天",
2558+ path: "../../skills/界黄天"
2559+ }
2560+ ]
2561+ };
2562+}));
2563+//#endregion
2564+//#region src/engine/data/characters/界李儒.ts
2565+var 界李儒;
2566+var init_界李儒 = __esmMin((() => {
2567+ 界李儒 = {
2568+ name: "界李儒",
2569+ maxHealth: 3,
2570+ gender: "男",
2571+ faction: "群",
2572+ skills: [
2573+ {
2574+ name: "界灭计",
2575+ path: "../../skills/界灭计"
2576+ },
2577+ {
2578+ name: "界绝策",
2579+ path: "../../skills/界绝策"
2580+ },
2581+ {
2582+ name: "界焚城",
2583+ path: "../../skills/界焚城"
2584+ }
2585+ ]
2586+ };
2587+}));
2588+//#endregion
2589+//#region src/engine/data/characters/界沮授.ts
2590+var 界沮授;
2591+var init_界沮授 = __esmMin((() => {
2592+ 界沮授 = {
2593+ name: "界沮授",
2594+ maxHealth: 3,
2595+ gender: "男",
2596+ faction: "群",
2597+ skills: [{
2598+ name: "界矢北",
2599+ path: "../../skills/界矢北"
2600+ }, {
2601+ name: "界渐营",
2602+ path: "../../skills/界渐营"
2603+ }]
2604+ };
2605+}));
2606+//#endregion
2607+//#region src/engine/data/characters/界蔡夫人.ts
2608+var 界蔡夫人;
2609+var init_界蔡夫人 = __esmMin((() => {
2610+ 界蔡夫人 = {
2611+ name: "界蔡夫人",
2612+ maxHealth: 3,
2613+ gender: "女",
2614+ faction: "群",
2615+ skills: [{
2616+ name: "界窃听",
2617+ path: "../../skills/界窃听"
2618+ }, {
2619+ name: "界献州",
2620+ path: "../../skills/界献州"
2621+ }]
2622+ };
2623+}));
2624+//#endregion
2625+//#region src/engine/data/characters/界陈宫.ts
2626+var 界陈宫;
2627+var init_界陈宫 = __esmMin((() => {
2628+ 界陈宫 = {
2629+ name: "界陈宫",
2630+ maxHealth: 3,
2631+ gender: "男",
2632+ faction: "群",
2633+ skills: [{
2634+ name: "界智迟",
2635+ path: "../../skills/界智迟"
2636+ }, {
2637+ name: "界明策",
2638+ path: "../../skills/界明策"
2639+ }]
2640+ };
2641+}));
2642+//#endregion
2643+//#region src/engine/data/characters/界高顺.ts
2644+var 界高顺;
2645+var init_界高顺 = __esmMin((() => {
2646+ 界高顺 = {
2647+ name: "界高顺",
2648+ maxHealth: 4,
2649+ gender: "男",
2650+ faction: "群",
2651+ skills: [{
2652+ name: "界陷阵",
2653+ path: "../../skills/界陷阵"
2654+ }, {
2655+ name: "界禁酒",
2656+ path: "../../skills/界禁酒"
2657+ }]
2658+ };
2659+}));
2660+//#endregion
2661+//#region src/engine/data/characters/华雄.ts
2662+var 华雄;
2663+var init_华雄 = __esmMin((() => {
2664+ 华雄 = {
2665+ name: "华雄",
2666+ maxHealth: 6,
2667+ gender: "男",
2668+ faction: "群",
2669+ skills: [{
2670+ name: "耀武",
2671+ path: "../../skills/耀武"
2672+ }]
2673+ };
2674+}));
2675+//#endregion
2676+//#region src/engine/data/characters/毌丘俭.ts
2677+var 毌丘俭;
2678+var init_毌丘俭 = __esmMin((() => {
2679+ 毌丘俭 = {
2680+ name: "毌丘俭",
2681+ maxHealth: 4,
2682+ gender: "男",
2683+ faction: "魏",
2684+ skills: [{
2685+ name: "征荣",
2686+ path: "../../skills/征荣"
2687+ }, {
2688+ name: "鸿举",
2689+ path: "../../skills/鸿举"
2690+ }]
2691+ };
2692+}));
2693+//#endregion
2694+//#region src/engine/data/characters/王基.ts
2695+var 王基;
2696+var init_王基 = __esmMin((() => {
2697+ 王基 = {
2698+ name: "王基",
2699+ maxHealth: 3,
2700+ gender: "男",
2701+ faction: "魏",
2702+ skills: [{
2703+ name: "奇制",
2704+ path: "../../skills/奇制"
2705+ }, {
2706+ name: "进趋",
2707+ path: "../../skills/进趋"
2708+ }]
2709+ };
2710+}));
2711+//#endregion
2712+//#region src/engine/data/characters/蒯越蒯良.ts
2713+var 蒯越蒯良;
2714+var init_蒯越蒯良 = __esmMin((() => {
2715+ 蒯越蒯良 = {
2716+ name: "蒯越蒯良",
2717+ maxHealth: 3,
2718+ gender: "男",
2719+ faction: "魏",
2720+ skills: [{
2721+ name: "荐降",
2722+ path: "../../skills/荐降"
2723+ }, {
2724+ name: "审时",
2725+ path: "../../skills/审时"
2726+ }]
2727+ };
2728+}));
2729+//#endregion
2730+//#region src/engine/data/characters/郝昭.ts
2731+var 郝昭;
2732+var init_郝昭 = __esmMin((() => {
2733+ 郝昭 = {
2734+ name: "郝昭",
2735+ maxHealth: 4,
2736+ gender: "男",
2737+ faction: "魏",
2738+ skills: [{
2739+ name: "镇骨",
2740+ path: "../../skills/镇骨"
2741+ }]
2742+ };
2743+}));
2744+//#endregion
2745+//#region src/engine/data/characters/王平.ts
2746+var 王平;
2747+var init_王平 = __esmMin((() => {
2748+ 王平 = {
2749+ name: "王平",
2750+ maxHealth: 4,
2751+ gender: "男",
2752+ faction: "蜀",
2753+ skills: [{
2754+ name: "飞军",
2755+ path: "../../skills/飞军"
2756+ }, {
2757+ name: "兵略",
2758+ path: "../../skills/兵略"
2759+ }]
2760+ };
2761+}));
2762+//#endregion
2763+//#region src/engine/data/characters/诸葛瞻.ts
2764+var 诸葛瞻;
2765+var init_诸葛瞻 = __esmMin((() => {
2766+ 诸葛瞻 = {
2767+ name: "诸葛瞻",
2768+ maxHealth: 3,
2769+ gender: "男",
2770+ faction: "蜀",
2771+ skills: [{
2772+ name: "罪论",
2773+ path: "../../skills/罪论"
2774+ }, {
2775+ name: "父荫",
2776+ path: "../../skills/父荫"
2777+ }]
2778+ };
2779+}));
2780+//#endregion
2781+//#region src/engine/data/characters/陈到.ts
2782+var 陈到;
2783+var init_陈到 = __esmMin((() => {
2784+ 陈到 = {
2785+ name: "陈到",
2786+ maxHealth: 4,
2787+ gender: "男",
2788+ faction: "蜀",
2789+ skills: [{
2790+ name: "往烈",
2791+ path: "../../skills/往烈"
2792+ }]
2793+ };
2794+}));
2795+//#endregion
2796+//#region src/engine/data/characters/卧龙诸葛亮.ts
2797+var 卧龙诸葛亮;
2798+var init_卧龙诸葛亮 = __esmMin((() => {
2799+ 卧龙诸葛亮 = {
2800+ name: "卧龙诸葛亮",
2801+ maxHealth: 3,
2802+ gender: "男",
2803+ faction: "蜀",
2804+ skills: [
2805+ {
2806+ name: "八阵",
2807+ path: "../../skills/八阵"
2808+ },
2809+ {
2810+ name: "火计",
2811+ path: "../../skills/火计"
2812+ },
2813+ {
2814+ name: "看破",
2815+ path: "../../skills/看破"
2816+ }
2817+ ]
2818+ };
2819+}));
2820+//#endregion
2821+//#region src/engine/data/characters/严颜.ts
2822+var 严颜;
2823+var init_严颜 = __esmMin((() => {
2824+ 严颜 = {
2825+ name: "严颜",
2826+ maxHealth: 4,
2827+ gender: "男",
2828+ faction: "蜀",
2829+ skills: [{
2830+ name: "拒战",
2831+ path: "../../skills/拒战"
2832+ }]
2833+ };
2834+}));
2835+//#endregion
2836+//#region src/engine/data/characters/陆抗.ts
2837+var 陆抗;
2838+var init_陆抗 = __esmMin((() => {
2839+ 陆抗 = {
2840+ name: "陆抗",
2841+ maxHealth: 4,
2842+ gender: "男",
2843+ faction: "吴",
2844+ skills: [
2845+ {
2846+ name: "谦节",
2847+ path: "../../skills/谦节"
2848+ },
2849+ {
2850+ name: "决堰",
2851+ path: "../../skills/决堰"
2852+ },
2853+ {
2854+ name: "破势",
2855+ path: "../../skills/破势"
2856+ }
2857+ ]
2858+ };
2859+}));
2860+//#endregion
2861+//#region src/engine/data/characters/陆绩.ts
2862+var 陆绩;
2863+var init_陆绩 = __esmMin((() => {
2864+ 陆绩 = {
2865+ name: "陆绩",
2866+ maxHealth: 3,
2867+ gender: "男",
2868+ faction: "吴",
2869+ skills: [
2870+ {
2871+ name: "怀橘",
2872+ path: "../../skills/怀橘"
2873+ },
2874+ {
2875+ name: "遗礼",
2876+ path: "../../skills/遗礼"
2877+ },
2878+ {
2879+ name: "整论",
2880+ path: "../../skills/整论"
2881+ }
2882+ ]
2883+ };
2884+}));
2885+//#endregion
2886+//#region src/engine/data/characters/张昭张弘.ts
2887+var 张昭张弘;
2888+var init_张昭张弘 = __esmMin((() => {
2889+ 张昭张弘 = {
2890+ name: "张昭张弘",
2891+ maxHealth: 3,
2892+ gender: "男",
2893+ faction: "吴",
2894+ skills: [{
2895+ name: "直谏",
2896+ path: "../../skills/直谏"
2897+ }, {
2898+ name: "固政",
2899+ path: "../../skills/固政"
2900+ }]
2901+ };
2902+}));
2903+//#endregion
2904+//#region src/engine/data/characters/周妃.ts
2905+var 周妃;
2906+var init_周妃 = __esmMin((() => {
2907+ 周妃 = {
2908+ name: "周妃",
2909+ maxHealth: 3,
2910+ gender: "男",
2911+ faction: "吴",
2912+ skills: [{
2913+ name: "良姻",
2914+ path: "../../skills/良姻"
2915+ }, {
2916+ name: "箜声",
2917+ path: "../../skills/箜声"
2918+ }]
2919+ };
2920+}));
2921+//#endregion
2922+//#region src/engine/data/characters/孙亮.ts
2923+var 孙亮;
2924+var init_孙亮 = __esmMin((() => {
2925+ 孙亮 = {
2926+ name: "孙亮",
2927+ maxHealth: 3,
2928+ gender: "男",
2929+ faction: "吴",
2930+ skills: [
2931+ {
2932+ name: "溃诛",
2933+ path: "../../skills/溃诛"
2934+ },
2935+ {
2936+ name: "掣政",
2937+ path: "../../skills/掣政"
2938+ },
2939+ {
2940+ name: "立军",
2941+ path: "../../skills/立军"
2942+ }
2943+ ]
2944+ };
2945+}));
2946+//#endregion
2947+//#region src/engine/data/characters/袁术.ts
2948+var 袁术;
2949+var init_袁术 = __esmMin((() => {
2950+ 袁术 = {
2951+ name: "袁术",
2952+ maxHealth: 4,
2953+ gender: "男",
2954+ faction: "群",
2955+ skills: [{
2956+ name: "庸肆",
2957+ path: "../../skills/庸肆"
2958+ }, {
2959+ name: "伪帝",
2960+ path: "../../skills/伪帝"
2961+ }]
2962+ };
2963+}));
2964+//#endregion
2965+//#region src/engine/data/characters/卢植.ts
2966+var 卢植;
2967+var init_卢植 = __esmMin((() => {
2968+ 卢植 = {
2969+ name: "卢植",
2970+ maxHealth: 3,
2971+ gender: "男",
2972+ faction: "群",
2973+ skills: [{
2974+ name: "明任",
2975+ path: "../../skills/明任"
2976+ }, {
2977+ name: "贞良",
2978+ path: "../../skills/贞良"
2979+ }]
2980+ };
2981+}));
2982+//#endregion
2983+//#region src/engine/data/characters/张绣.ts
2984+var 张绣;
2985+var init_张绣 = __esmMin((() => {
2986+ 张绣 = {
2987+ name: "张绣",
2988+ maxHealth: 4,
2989+ gender: "男",
2990+ faction: "群",
2991+ skills: [{
2992+ name: "雄乱",
2993+ path: "../../skills/雄乱"
2994+ }, {
2995+ name: "从谏",
2996+ path: "../../skills/从谏"
2997+ }]
2998+ };
2999+}));
Diff truncated — view the file for the rest.
+46 −0 routes/bot.mjs added View file
@@ -0,0 +1,46 @@
1+// The starter bot: plays the move the upstream AI recommends (obs.recommended, the MCP's recommendedAction), fills in
2+// what that move leaves open (targets, cards to discard), and passes when it cannot. Change anything; keep the shape:
3+// act(obs, legal) returns an index into legal, or a legal move's message with its params filled in.
4+const CAMP = { 主公: 'lord', 忠臣: 'lord', 反贼: 'rebel', 内奸: 'renegade' };
5+const KEEP = { 桃: 5, 闪: 4, 无懈可击: 3, 酒: 2, 杀: 1 };
6+let turn = '';
7+let made = new Map(); // moves made this turn: an ask nobody answers (激将) must not be repeated forever
8+
9+function fill(obs, move) {
10+ const m = structuredClone(move.message);
11+ const me = obs.players[obs.viewer];
12+ if (move.validTargets.length && !Array.isArray(m.params.targets)) {
13+ const ally = (i) => me.identity !== '内奸' && CAMP[obs.players[i].identity] === CAMP[me.identity];
14+ const lord = obs.players.findIndex((p) => p.identity === '主公');
15+ const foes = move.validTargets.filter((i) => !ally(i)).sort((a, b) => (me.identity === '反贼' ? (b === lord) - (a === lord) : 0));
16+ if (!foes.length && move.category === 'play') return null; // only friends in reach: hold the card
17+ const targets = foes.length ? foes : move.validTargets;
18+ m.params.targets = targets.slice(0, Math.max(move.minTarget ?? 1, 1));
19+ m.params.target = m.params.targets[0];
20+ }
21+ if (Array.isArray(m.params.cardIds) && !m.params.cardIds.length) {
22+ const need = obs.pending?.discard?.min ?? 1;
23+ const hand = [...(me.hand ?? [])].sort((a, b) => (KEEP[a.name] ?? 0) - (KEEP[b.name] ?? 0));
24+ if (hand.length < need) return null;
25+ m.params.cardIds = hand.slice(0, need).map((c) => c.id);
26+ }
27+ if (Array.isArray(m.params.allocation) && !m.params.allocation.length) return null;
28+ return m;
29+}
30+
31+export default function act(obs, legal) {
32+ const now = `${obs.game}:${obs.turn.round}:${obs.currentPlayerIndex}`;
33+ if (now !== turn) (turn = now), (made = new Map());
34+ const refused = new Set((obs.refused ?? []).map((m) => JSON.stringify(m)));
35+ const order = [obs.recommended, ...legal.keys()].filter((i) => i !== null && i !== undefined);
36+ for (const i of order) {
37+ const m = fill(obs, legal[i]);
38+ const key = JSON.stringify(m);
39+ if (m && !refused.has(key) && (made.get(key) ?? 0) < 2) {
40+ made.set(key, (made.get(key) ?? 0) + 1);
41+ return m;
42+ }
43+ }
44+ const pass = legal.findIndex((l) => l.category === 'skip' || l.message.actionType === 'end');
45+ return pass >= 0 ? pass : 0;
46+}
+100 −0 src/art.py added View file
@@ -0,0 +1,100 @@
1+"""Builds the viewer's art pack, viewer/art/, from a sparse clone of 无名杀 (libnoname/noname): the portraits and card
2+art that src/viewer/noname/art.json maps the upstream engine's generals and cards to, the woodden theme's pieces and
3+its fonts cut down to the characters the viewer draws with them. Needs Pillow (with WebP) and fonttools.
4+
5+ git clone --filter=blob:none --no-checkout https://github.com/libnoname/noname <noname>
6+ git -C <noname> sparse-checkout set --no-cone $(python3 src/art.py --paths)
7+ git -C <noname> checkout 90b58bb9934edb1712fd187a80c8323b7aeabaf3
8+ python3 src/art.py <noname>
9+"""
10+import io, json, os, re, shutil, sys
11+from PIL import Image
12+from fontTools import subset
13+
14+SRC = os.path.dirname(os.path.abspath(__file__))
15+GAME = os.path.dirname(SRC)
16+OUT = os.path.join(GAME, 'viewer', 'art')
17+PORTRAIT_W, PORTRAIT_KB, CARD_KB = 300, 60, 30
18+THEME = [('theme/woodden/grid.png', 'grid.png'), ('theme/woodden/wood2.png', 'wood2.png'), ('theme/woodden/wood.png', 'wood.png'),
19+ ('theme/woodden/wood2.jpg', 'wood2.jpg'), ('image/card/handcard.png', 'handcard.png'), *[(f'theme/style/hp/image/glass{i}.png', f'hp{i}.png') for i in range(1, 5)]]
20+FONTS = ('xinwei', 'huangcao')
21+
22+
23+def webp(im, path, limit_kb, q=82):
24+ """Save as WebP at the best quality that fits the size limit."""
25+ while True:
26+ buf = io.BytesIO()
27+ im.save(buf, 'WEBP', quality=q, method=6)
28+ if buf.tell() <= limit_kb * 1024 or q <= 40:
29+ break
30+ q -= 6
31+ with open(path, 'wb') as f:
32+ f.write(buf.getvalue())
33+ return buf.tell()
34+
35+
36+def main():
37+ art = json.load(open(os.path.join(SRC, 'viewer', 'noname', 'art.json'), encoding='utf-8'))
38+ if sys.argv[1] == '--paths': # what the sparse clone needs
39+ paths = [f'image/character/{c}.jpg' for c in sorted(set(art['generals'].values()))]
40+ paths += [f'image/card/{c}.png' for c in sorted(set(art['cards'].values()))]
41+ paths += [src for src, _ in THEME] + ['theme/woodden/wood.jpg', 'theme/style/cardback/image/official.png']
42+ paths += [f'font/{f}.woff2' for f in (*FONTS, 'suits')]
43+ print('\n'.join(f'/apps/core/{p}' for p in paths))
44+ return
45+ core = os.path.join(sys.argv[1], 'apps', 'core')
46+ shutil.rmtree(OUT, ignore_errors=True)
47+ for d in ('general', 'card', 'theme', 'font'):
48+ os.makedirs(os.path.join(OUT, d))
49+ sizes = {}
50+
51+ # Portraits: 无名杀's are 350x464; kept whole (the seat card crops with CSS), 300 wide.
52+ for cid in sorted(set(art['generals'].values())):
53+ im = Image.open(os.path.join(core, 'image', 'character', f'{cid}.jpg')).convert('RGB')
54+ im = im.resize((PORTRAIT_W, round(im.height * PORTRAIT_W / im.width)), Image.LANCZOS)
55+ sizes[f'general/{cid}'] = webp(im, os.path.join(OUT, 'general', f'{cid}.webp'), PORTRAIT_KB)
56+
57+ # Card art: 120x120 with alpha, drawn on the theme's card face.
58+ for cid in sorted(set(art['cards'].values())):
59+ im = Image.open(os.path.join(core, 'image', 'card', f'{cid}.png')).convert('RGBA')
60+ sizes[f'card/{cid}'] = webp(im, os.path.join(OUT, 'card', f'{cid}.webp'), CARD_KB, q=88)
61+
62+ # The woodden theme (its grid and wood), the glass 勾玉 and the card back.
63+ for src, dst in THEME:
64+ shutil.copy(os.path.join(core, src), os.path.join(OUT, 'theme', dst))
65+ sizes['theme/wood'] = webp(Image.open(os.path.join(core, 'theme/woodden/wood.jpg')).convert('RGB'), os.path.join(OUT, 'theme', 'wood.webp'), 40, q=84)
66+ back = Image.open(os.path.join(core, 'theme/style/cardback/image/official.png')).convert('RGB').resize((240, 240), Image.LANCZOS)
67+ sizes['theme/cardback'] = webp(back, os.path.join(OUT, 'theme', 'cardback.webp'), 30)
68+
69+ # Fonts, cut to what is drawn in them: names of generals, skills and cards, and the viewer's own labels.
70+ gens = json.load(open(os.path.join(GAME, 'referee', 'generals.json'), encoding='utf-8'))
71+ words = list(gens) + [s for g in gens.values() for s in g['skills']] + list(art['cards']) + ['火杀', '雷杀']
72+ for root, _, files in os.walk(os.path.join(SRC, 'viewer')):
73+ for f in files:
74+ if f.endswith(('.tsx', '.ts', '.css')):
75+ words += re.findall(r'[ -鿿＀-￯]+', open(os.path.join(root, f), encoding='utf-8').read())
76+ text = ''.join(sorted(set(''.join(words)))) + '0123456789+-/×·??' + ''.join(chr(c) for c in range(0x20, 0x7f))
77+ for name in FONTS:
78+ opts = subset.Options()
79+ opts.flavor = 'woff2'
80+ opts.layout_features = ['*']
81+ font = subset.load_font(os.path.join(core, 'font', f'{name}.woff2'), opts)
82+ s = subset.Subsetter(opts)
83+ s.populate(text=text)
84+ s.subset(font)
85+ out = os.path.join(OUT, 'font', f'{name}.woff2')
86+ subset.save_font(font, out, opts)
87+ sizes[f'font/{name}'] = os.path.getsize(out)
88+ shutil.copy(os.path.join(core, 'font', 'suits.woff2'), os.path.join(OUT, 'font', 'suits.woff2'))
89+
90+ for f in ('art.css', 'NOTICE'):
91+ shutil.copy(os.path.join(SRC, 'art', f), os.path.join(OUT, f))
92+
93+ total = sum(os.path.getsize(os.path.join(r, f)) for r, _, fs in os.walk(OUT) for f in fs)
94+ big = max(sizes.items(), key=lambda kv: kv[1])
95+ print(f'{len(art["generals"])} generals ({len(set(art["generals"].values()))} portraits), {len(art["cards"])} cards, '
96+ f'{len(text)} glyphs; {total / 1e6:.1f} MB in {OUT}; largest {big[0]} {big[1] // 1024} KB')
97+
98+
99+if __name__ == '__main__':
100+ main()
+26 −0 src/art/NOTICE added View file
@@ -0,0 +1,26 @@
1+The art pack: everything in this folder (viewer/art/) except art.css and this NOTICE, which are this project's.
2+
3+NOT CLEARED FOR PUBLICATION. The portraits and card art below are, for the most part, the commercial 三国杀 (Sanguosha)
4+art of 游卡桌游 (Yoka Games), as 无名杀 redistributes it. This pack is here so the viewer can look like 无名杀 while the
5+licence of that art is being sorted out; the user is coordinating it. Do not publish, release or deploy this folder (or
6+a build that includes it) until that is settled. It is kept in its own folder so it can be replaced as a whole, e.g. by
7+art the project owns or has a licence for: the viewer falls back to drawn faces for anything missing.
8+
9+Source: 无名杀 (noname), https://github.com/libnoname/noname, commit 90b58bb9934edb1712fd187a80c8323b7aeabaf3, licensed
10+under the GNU General Public License v3.0 (https://www.gnu.org/licenses/gpl-3.0.html). Its project asks that copies keep
11+the source link above and are not used commercially. Taken from apps/core/ and converted by src/art.py (resized,
12+recompressed to WebP, fonts cut down to the characters the viewer uses):
13+
14+ general/<id>.webp image/character/<id>.jpg generals' portraits (立绘), mapped in src/viewer/noname/art.json
15+ card/<id>.webp image/card/<id>.png card art
16+ theme/grid.png, wood.webp, wood.png, wood2.jpg, wood2.png theme/woodden/ (the woodden theme)
17+ theme/hp1-4.png theme/style/hp/image/glass1-4.png (勾玉)
18+ theme/handcard.png image/card/handcard.png (the hand count's card)
19+ theme/cardback.webp theme/style/cardback/image/official.png (the 三国杀 card back, with the Yoka Games mark)
20+ font/xinwei.woff2, font/huangcao.woff2, font/suits.woff2 font/ (subset)
21+
22+Provenance, as far as 无名杀 records it: most 立绘 and the card art come from 游卡桌游's 三国杀 (its standard, 界限突破,
23+手杀 and 十周年 editions) and are © 游卡桌游 and their artists; the card back is 三国杀's official one. 无名杀 does not
24+hold or grant a licence to that art, and the GPL on its code does not cover it. The woodden theme pieces and the 勾玉
25+images are 无名杀's own (GPL-3.0). The fonts are 华文新魏 (xinwei, STXinwei, © Changzhou SinoType), 黄草 (huangcao) and
26+无名杀's suit symbols, redistributed by 无名杀; their licences for redistribution are not stated there either.
+22 −0 src/art/art.css added View file
@@ -0,0 +1,22 @@
1+/* The art pack's hookups: 无名杀's fonts and woodden theme pieces (theme/, font/), its portraits and card art (general/,
2+ card/, named in src/viewer/noname/art.json). Replacing this folder replaces the look; noname.css draws the layout. */
3+@font-face { font-family: 'nm-xinwei'; src: url(font/xinwei.woff2) format('woff2'); font-display: block; }
4+@font-face { font-family: 'nm-huangcao'; src: url(font/huangcao.woff2) format('woff2'); font-display: block; }
5+@font-face { font-family: 'nm-suits'; src: url(font/suits.woff2) format('woff2'); }
6+
7+/* woodden (theme/woodden/style.css): the grid over a slate gradient; wood.jpg for seats, cards and your equipment rows,
8+ wood2.jpg for buttons (its .control and top bar), wood.png for your strip (#mebg) */
9+.nm-arena { background: url(theme/grid.png), linear-gradient(#6c7989, #434b55); }
10+.nm-player, .nm-card, .nm-myequip, .nm-choose, .nm-chooseOptionCard { background-image: url(theme/wood.webp); }
11+.nm-mini, .nm-btn, .nm-skill, .nm-replay select, .nm-moves-list button, .nm-log-toggle, .nm-promptBtn, .nm-promptBtnPrimary, .nm-promptBtnDisabled {
12+ background-image: url(theme/wood2.jpg); }
13+.nm-me { background-image: url(theme/wood.png); }
14+.nm-count { background-image: url(theme/handcard.png); }
15+.nm-judge { background-image: url(theme/wood.webp); }
16+.nm-card.back, .nm-pickHandCard { background-image: url(theme/cardback.webp); }
17+
18+/* the glass 勾玉 (theme/style/hp/glass.css): green, yellow, red as HP falls; grey for each one lost */
19+.nm-jade { background-image: url(theme/hp1.png); }
20+.nm-hp.mid .nm-jade { background-image: url(theme/hp2.png); }
21+.nm-hp.low .nm-jade { background-image: url(theme/hp3.png); }
22+.nm-hp .nm-jade.lost { background-image: url(theme/hp4.png); }
+66 −0 src/bots.ts added View file
@@ -0,0 +1,66 @@
1+// A bot in its own process (referee/bot.mjs loads <dir>/bot.mjs), spoken to one JSON line at a time, like kit/host.py:
2+// each message is numbered so a late answer to an earlier ask is dropped; a move later than the limit, or from a bot
3+// that crashed, is no move (the caller passes for it). A bot sees no job token: SS_* and SLURM_* are not passed on.
4+import { spawn, type ChildProcess } from 'node:child_process';
5+import { createInterface } from 'node:readline';
6+import { existsSync } from 'node:fs';
7+import path from 'node:path';
8+import { fileURLToPath } from 'node:url';
9+
10+export const REFEREE = path.dirname(fileURLToPath(import.meta.url));
11+
12+export class Bot {
13+ errors = 0;
14+ dead = false;
15+ private p: ChildProcess;
16+ private n = 0;
17+ private waiting = new Map<number, (a: unknown) => void>();
18+ ready: Promise<unknown>;
19+
20+ constructor(readonly dir: string, readonly limitMs = 2000) {
21+ if (!existsSync(path.join(dir, 'bot.mjs'))) throw new Error(`No bot at ${path.join(dir, 'bot.mjs')}`);
22+ const env = Object.fromEntries(Object.entries(process.env).filter(([k]) => !/^(SS_|SLURM_)/.test(k)));
23+ this.p = spawn(process.execPath, [path.join(REFEREE, 'bot.mjs'), path.resolve(dir)], {
24+ stdio: ['pipe', 'pipe', process.env.SGS_BOT_STDERR ? 'inherit' : 'ignore'],
25+ env,
26+ });
27+ createInterface({ input: this.p.stdout! }).on('line', (line) => {
28+ try {
29+ const m = JSON.parse(line);
30+ if (m && typeof m === 'object' && 'answer' in m) this.waiting.get(m.n)?.(m.answer);
31+ } catch {
32+ // a line that is not an answer
33+ }
34+ });
35+ this.p.on('exit', () => {
36+ this.dead = true;
37+ for (const r of this.waiting.values()) r(undefined);
38+ });
39+ this.p.stdin!.on('error', () => {});
40+ this.ready = this.ask({ hello: true }, 10000);
41+ }
42+
43+ /** The bot's answer, or undefined when it is late, broken or gone. */
44+ async ask(msg: object, limitMs = this.limitMs): Promise<unknown> {
45+ if (this.dead) return undefined;
46+ const n = ++this.n;
47+ let timer: NodeJS.Timeout | undefined;
48+ const answer = await new Promise<unknown>((resolve) => {
49+ this.waiting.set(n, resolve);
50+ timer = setTimeout(() => resolve(undefined), limitMs);
51+ this.p.stdin!.write(`${JSON.stringify({ ...msg, n })}\n`);
52+ });
53+ clearTimeout(timer);
54+ this.waiting.delete(n);
55+ if (answer === undefined || answer === null) {
56+ if (++this.errors >= 20) this.close(); // ponytail: a bot that misses 20 asks is stopped for the rest of the run
57+ return undefined;
58+ }
59+ return answer;
60+ }
61+
62+ close(): void {
63+ this.dead = true;
64+ this.p.kill();
65+ }
66+}
+31 −0 src/build.mjs added View file
@@ -0,0 +1,31 @@
1+// Rebuilds referee/sgs.mjs and viewer/ from this folder's src/ and the upstream source.
2+// git clone https://github.com/wmzy/sanguosha && cd sanguosha && git checkout 8f4b693 && pnpm install --frozen-lockfile
3+// node <this folder>/src/build.mjs <that checkout> (built with Node 22.19.0, pnpm 10.28.2)
4+// src/ is copied into <checkout>/shoal/ so it imports the upstream as ../src/..., and the upstream's own Vite builds
5+// it: the engine as one ES module for Node 20+ (and referee/generals.json from it), the viewer as static files with
6+// relative paths. `--engine` skips the viewer. viewer/art/ (the art pack) is built apart, by src/art.py, and kept.
7+import { cpSync, rmSync, mkdirSync, copyFileSync, readdirSync, writeFileSync } from 'node:fs';
8+import { execFileSync } from 'node:child_process';
9+import path from 'node:path';
10+import { fileURLToPath } from 'node:url';
11+
12+const SRC = path.dirname(fileURLToPath(import.meta.url));
13+const GAME = path.dirname(SRC);
14+const UP = path.resolve(process.argv[2] ?? '');
15+const vite = path.join(UP, 'node_modules/.bin/vite');
16+rmSync(path.join(UP, 'shoal'), { recursive: true, force: true });
17+cpSync(SRC, path.join(UP, 'shoal'), { recursive: true });
18+const run = (cfg) => execFileSync(vite, ['build', '-c', `shoal/${cfg}`], { cwd: UP, stdio: 'inherit' });
19+
20+run('vite.engine.config.ts');
21+copyFileSync(path.join(UP, 'dist/shoal-engine/sgs.mjs'), path.join(GAME, 'referee/sgs.mjs'));
22+const { catalog } = await import(`${path.join(GAME, 'referee/sgs.mjs')}?${Date.now()}`);
23+writeFileSync(path.join(GAME, 'referee/generals.json'), `${JSON.stringify(await catalog(), null, 1)}\n`);
24+
25+if (process.argv[3] !== '--engine') {
26+ run('vite.viewer.config.ts');
27+ const out = path.join(UP, 'dist/shoal-viewer');
28+ for (const f of readdirSync(path.join(GAME, 'viewer'))) if (!['bridge.js', 'NOTICE', 'art'].includes(f)) rmSync(path.join(GAME, 'viewer', f), { recursive: true });
29+ mkdirSync(path.join(GAME, 'viewer'), { recursive: true });
30+ for (const f of readdirSync(out)) cpSync(path.join(out, f), path.join(GAME, 'viewer', f), { recursive: true });
31+}
+130 −0 src/play.ts added View file
@@ -0,0 +1,130 @@
1+// The project's referee: five-player identity games (主公, 忠臣, two 反贼, 内奸) on the upstream engine.
2+// check: on ten seeds the route's bot takes every seat in turn while one kind of field bot fills the other four;
3+// the score is the mean over the four roles of the share of games the route's side won (each role a
4+// subtask), over the whole field.
5+// practice: one seed against each field bot, the route as 主公 and as a 反贼, a replay of each in replays/.
6+// Same seeds and same bots, same games: the engine runs on a virtual clock and its shuffles are seeded.
7+import { mkdirSync, readdirSync, statSync, writeFileSync } from 'node:fs';
8+import path from 'node:path';
9+import { Table, Heuristic, passIndex, type Ask } from './table';
10+import { Bot, REFEREE } from './bots';
11+
12+export const ROOT = path.dirname(REFEREE);
13+export const SEEDS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
14+const MAX_MOVES = 3000;
15+const ROLES = ['主公', '忠臣', '反贼', '内奸'];
16+
17+/** One ask to its end: the chooser gets up to three tries (each refused move is shown back to it in obs.refused),
18+ * then the seat passes. True when the engine took a move or the ask is gone anyway. */
19+export async function answer(t: Table, a: Ask, choose: (obs: object, legal: Ask['legal']) => Promise<unknown>): Promise<boolean> {
20+ const refused: unknown[] = [];
21+ for (let k = 0; k < 3; k++) {
22+ const move = await choose(refused.length ? { ...a.obs, refused } : a.obs, a.legal);
23+ if (move === undefined || move === null) break;
24+ if ((await t.act(a.seat, move)) || (await gone(t, a))) return true;
25+ refused.push(move);
26+ }
27+ return pass(t, a);
28+}
29+
30+/** A refused move can still end the ask: a failed transform (解围 as 无懈可击) clears the engine's open asks. */
31+export async function gone(t: Table, a: Ask): Promise<boolean> {
32+ return (await t.ask(a.seat))?.key !== a.key;
33+}
34+
35+/** A move the engine takes for a seat that gave none: a pass, else what the upstream AI would play, else any. */
36+export async function pass(t: Table, a: Ask): Promise<boolean> {
37+ const tries: unknown[] = [passIndex(a.legal)];
38+ const h = new Heuristic();
39+ for (let k = 0; k < 4; k++) tries.push(h.act({ ...a.obs, refused: tries }, a.legal));
40+ tries.push(...a.legal.keys());
41+ for (const m of tries) if ((await t.act(a.seat, m)) || (await gone(t, a))) return true;
42+ return false;
43+}
44+
45+/** A whole game with every seat a bot process. */
46+/** A whole game with every seat a bot process; why it stopped when it did not end. */
47+async function game(t: Table, bots: Bot[]): Promise<string> {
48+ for (let moves = 0; !t.over; moves++) {
49+ if (moves >= MAX_MOVES) return `${MAX_MOVES} moves`;
50+ const asks = await t.asks();
51+ if (!asks.length) {
52+ if (!(await t.idle())) return 'stuck: nobody to move';
53+ continue;
54+ }
55+ const a = asks[0];
56+ if (!(await answer(t, a, (obs, legal) => bots[a.seat].ask({ obs, legal })))) return `stuck: seat ${a.seat} has no move the engine takes (${a.obs.pending?.requestType})`;
57+ }
58+ return '';
59+}
60+
61+export function routeName(): string {
62+ const d = (process.env.SS_ROUTE_DIR ?? 'routes').replace(/\/+$/, '');
63+ return d === 'routes' ? 'main' : d.split('/').slice(1).join('/');
64+}
65+
66+export function field(): string[] {
67+ const dir = path.join(ROOT, 'field');
68+ return readdirSync(dir).filter((d) => !d.startsWith('.') && statSync(path.join(dir, d)).isDirectory()).sort();
69+}
70+
71+/** replays/<file> per game, and replays/matches.json saying who sat where and how it ended (as kit/league.py). */
72+export class Replays {
73+ private index: Array<{ file: string; title: string; seats: string[]; result: string }> = [];
74+ constructor(private root = 'replays') {
75+ mkdirSync(root, { recursive: true });
76+ }
77+ add(file: string, data: unknown, title: string, seats: string[], result: string): void {
78+ writeFileSync(path.join(this.root, file), JSON.stringify(data));
79+ this.index.push({ file, title, seats, result });
80+ writeFileSync(path.join(this.root, 'matches.json'), JSON.stringify(this.index, null, 2));
81+ }
82+}
83+
84+export function writeMetrics(score: number, subtasks: Record<string, number>, file = 'metrics.json'): void {
85+ const r = (x: number) => Math.round(x * 1e6) / 1e6;
86+ const out = { score: r(score), subtasks: Object.fromEntries(Object.entries(subtasks).map(([k, v]) => [k, r(v)])) };
87+ writeFileSync(file, JSON.stringify(out, null, 2));
88+ console.log(`score ${out.score} over ${Object.keys(subtasks).length}: ${Object.entries(out.subtasks).map(([k, v]) => `${k} ${v}`).join(', ')}`);
89+}
90+
91+export async function play(mode: string, route: string): Promise<void> {
92+ if (mode !== 'check' && mode !== 'practice') throw new Error('usage: node referee/play.mjs check|practice <route folder>');
93+ const name = routeName();
94+ const me = new Bot(route);
95+ const reps = mode === 'practice' ? new Replays() : null;
96+ const won: Record<string, number[]> = Object.fromEntries(ROLES.map((r) => [r, []]));
97+ for (const opp of field()) {
98+ const others = [0, 1, 2, 3].map(() => new Bot(path.join(ROOT, 'field', opp)));
99+ await Promise.all([me.ready, ...others.map((b) => b.ready)]);
100+ for (const seed of mode === 'check' ? SEEDS : SEEDS.slice(0, 1)) {
101+ const roles = await identities(seed);
102+ const mine = mode === 'check' ? [0, 1, 2, 3, 4] : [0, roles.indexOf('反贼')];
103+ for (const seat of mine) {
104+ const bots = [...others.slice(0, seat), me, ...others.slice(seat)];
105+ const names = bots.map((b) => (b === me ? name : opp));
106+ const t = new Table(seed);
107+ await t.open(names);
108+ const why = await game(t, bots);
109+ const role = t.identity(seat);
110+ const win = t.scores()[String(seat)] > 0;
111+ won[role].push(win ? 1 : 0);
112+ console.log(`seed ${seed}, ${name} as ${role} (seat ${seat}) vs ${opp}: ${t.result()}${why ? ` (${why})` : ''}`);
113+ reps?.add(`${opp}-${seed}-${seat}.json`, { ...(t.replay(`${name} vs ${opp}`) as object), shoal: { seat, names } },
114+ `${name} as ${role}, four ${opp} bots, seed ${seed}`, names, `${t.result()}: ${name} ${win ? 'won' : 'lost'}`);
115+ }
116+ }
117+ others.forEach((b) => b.close());
118+ }
119+ me.close();
120+ const rate = (xs: number[]) => (xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : 0);
121+ const subtasks = Object.fromEntries(ROLES.filter((r) => won[r].length).map((r) => [r, rate(won[r])]));
122+ if (mode === 'check') writeMetrics(rate(Object.values(subtasks)), subtasks);
123+}
124+
125+/** Who holds which identity on a seed (the lord is always seat 0; the rest follow the seeded shuffle). */
126+async function identities(seed: number): Promise<string[]> {
127+ const t = new Table(seed);
128+ await t.open(['', '', '', '', '']);
129+ return t.state.players.map((p) => p.identity ?? '');
130+}
+215 −0 src/room.ts added View file
@@ -0,0 +1,215 @@
1+// A live room (docs/games.md §8.3): one five-player identity game that people and agents sit in while it runs.
2+// Lines starting "@shoal " on stdout are the protocol, everything else is log; stdin brings one JSON per line.
3+// out {"event": {"type": "start", "seats": [...], "view": {...}, "seq": n}} public: the table as a spectator sees it
4+// {"event": {"type": "events", "events": [...]}} public: the upstream engine's view events since the last ones
5+// {"event": {"type": "moved" | "control", "seat": "2", ...}} public: a seat answered its ask, changed hands
6+// {"to": "2", "obs": {"view": {...}, "seq": n}} private, only to a person: the seat's own view when they take
7+// {"to": "2", "obs": {"events": [...]}} it, then its view events, so their viewer can draw their hand
8+// {"to": "2", "version": 7, "obs": {...}, "legal": [...]} seat 2 must move: the MCP's snapshot of its view and
9+// its moves (HeadlessGameClient.getAvailableActions); obs.limit is the
10+// seconds it has, obs.refused the moves the engine already refused here.
11+// A broadcast ask (无懈可击) asks every seat that holds an answer at once.
12+// {"end": {"result": ..., "winner": "3", "scores": {"0": 1, ...}, "identities": {...}}}
13+// in {"act": {"seat": "2", "version": 7, "action": 3 | <an entry of legal> | {skillId, actionType, params}}}
14+// {"control": {"seat": "2", "kind": "human" | "agent" | "auto" | "bot", "name": ..., "dir" | "field": ...}}
15+// {"stop": true} (stdin closing stops the room too)
16+// SS_ROOM: {"seats": {"0": {"kind": "human", "name": "ada"}, "1": {"kind": "bot", "dir": "routes/x"},
17+// "2": {"kind": "bot", "field": "upstream"}, ...}, "seed": 7, "limit": 30}. Seats left out are auto.
18+// A move with an old version is dropped; a refused one is asked again with a new version, and after three refusals
19+// auto plays the seat's move. A human or agent seat that
20+// does not move within the limit is played by auto (the upstream heuristic AI), and so is a bot that gives no move.
21+// At the end the game is in replays/room.json (the upstream replay format) and replays/matches.json.
22+import { createInterface } from 'node:readline';
23+import path from 'node:path';
24+import { eventsForViewer } from '../src/engine/view/events-for-viewer';
25+import { buildView } from '../src/engine/index';
26+import { Table, Heuristic, type Ask } from './table';
27+import { Bot } from './bots';
28+import { ROOT, Replays, answer, gone, pass } from './play';
29+
30+type Kind = 'human' | 'agent' | 'bot' | 'auto';
31+interface Seat {
32+ kind: Kind;
33+ name?: string;
34+ route?: string;
35+ dir?: string;
36+ field?: string;
37+ bot?: Bot;
38+ auto: Heuristic;
39+ out?: { version: number; key: string; refused: unknown[]; timer: NodeJS.Timeout };
40+ seen: number;
41+}
42+type Input = { act?: { seat: string; version: number; action: unknown }; control?: { seat: string; kind: Kind; name?: string; dir?: string; field?: string }; stop?: boolean; timeout?: { seat: number; version: number } };
43+
44+const say = (m: object) => process.stdout.write(`@shoal ${JSON.stringify(m)}\n`);
45+const log = (s: string) => process.stdout.write(`${s}\n`);
46+
47+/** stdin lines and timers, one at a time. */
48+class Inbox {
49+ private items: Input[] = [];
50+ private wake: (() => void) | null = null;
51+ closed = false;
52+ push(i: Input): void {
53+ this.items.push(i);
54+ this.wake?.();
55+ }
56+ async next(): Promise<Input | null> {
57+ while (!this.items.length) {
58+ if (this.closed) return null;
59+ await new Promise<void>((r) => (this.wake = r));
60+ this.wake = null;
61+ }
62+ return this.items.shift()!;
63+ }
64+}
65+
66+export async function room(): Promise<void> {
67+ const cfg = JSON.parse(process.env.SS_ROOM || '{}') as { seats?: Record<string, Partial<Seat>>; seed?: number; limit?: number };
68+ const seed = cfg.seed ?? Math.floor(Math.random() * 1e9);
69+ const limitMs = (cfg.limit ?? 30) * 1000;
70+ const seats: Seat[] = [0, 1, 2, 3, 4].map((i) => ({ kind: 'auto' as Kind, ...cfg.seats?.[String(i)], auto: new Heuristic(), seen: 0 }));
71+ for (const s of seats) startBot(s);
72+ await Promise.all(seats.map((s) => s.bot?.ready));
73+ const names = seats.map((s) => s.name ?? s.route ?? s.field ?? s.kind);
74+ const inbox = new Inbox();
75+ const rl = createInterface({ input: process.stdin });
76+ rl.on('line', (line) => {
77+ try {
78+ inbox.push(JSON.parse(line));
79+ } catch {
80+ log(`not JSON: ${line.slice(0, 80)}`);
81+ }
82+ });
83+ rl.on('close', () => {
84+ inbox.closed = true;
85+ inbox.push({});
86+ });
87+
88+ const t = new Table(seed);
89+ await t.open(names);
90+ say({ event: { type: 'start', seed, seats: seats.map((s, i) => ({ seat: String(i), kind: s.kind, name: names[i] })), view: t.publicView(), seq: t.state.seq } });
91+ let publicSeq = t.state.seq;
92+ let version = 0;
93+ for (const [i, s] of seats.entries()) if (s.kind === 'human') baseline(i);
94+
95+ function startBot(s: Seat): void {
96+ if (s.kind !== 'bot') return;
97+ try {
98+ s.bot = new Bot(s.field ? path.join(ROOT, 'field', s.field) : path.resolve(process.env.SS_INPUT ?? '.', s.dir ?? s.route ?? 'routes'));
99+ } catch (e) {
100+ log(`seat ${s.name}: ${(e as Error).message}; auto plays it`);
101+ s.kind = 'auto';
102+ }
103+ }
104+ /** A person's viewer needs the seat's whole view once, then its events. */
105+ function baseline(i: number): void {
106+ say({ to: String(i), obs: { view: buildView(t.state, i), seq: t.state.seq } });
107+ seats[i].seen = t.state.seq;
108+ }
109+ function publish(): void {
110+ const pub = eventsForViewer(t.state, -1, publicSeq);
111+ if (pub.length) say({ event: { type: 'events', events: pub } });
112+ publicSeq = t.state.seq;
113+ for (const [i, s] of seats.entries()) {
114+ if (s.kind !== 'human') continue;
115+ const mine = eventsForViewer(t.state, i, s.seen);
116+ if (mine.length) say({ to: String(i), obs: { events: mine } });
117+ s.seen = t.state.seq;
118+ }
119+ }
120+ function drop(s: Seat): void {
121+ if (s.out) clearTimeout(s.out.timer);
122+ s.out = undefined;
123+ }
124+ function request(a: Ask, refused: unknown[] = []): void {
125+ const s = seats[a.seat];
126+ const v = ++version;
127+ const timer = setTimeout(() => inbox.push({ timeout: { seat: a.seat, version: v } }), limitMs);
128+ s.out = { version: v, key: a.key, refused, timer };
129+ say({ to: String(a.seat), version: v, obs: { ...a.obs, limit: limitMs / 1000, ...(refused.length ? { refused } : {}) }, legal: a.legal });
130+ }
131+ async function auto(a: Ask): Promise<boolean> {
132+ const s = seats[a.seat];
133+ if (s.kind === 'bot' && s.bot && !s.bot.dead) return answer(t, a, (obs, legal) => s.bot!.ask({ obs, legal }));
134+ return answer(t, a, async (obs, legal) => s.auto.act(obs as Ask['obs'], legal));
135+ }
136+
137+ let stopped = false;
138+ let stuck = false;
139+ for (let moves = 0; !t.over && !stopped && moves < 3000; ) {
140+ publish();
141+ const asks = await t.asks();
142+ publish();
143+ if (t.over) break;
144+ if (!asks.length) {
145+ if (!(await t.idle())) stuck = true;
146+ if (stuck) break;
147+ continue;
148+ }
149+ for (const s of seats) if (s.out && !asks.some((a) => seats[a.seat] === s && a.key === s.out!.key)) drop(s);
150+ const now = asks.find((a) => seats[a.seat].kind === 'bot' || seats[a.seat].kind === 'auto');
151+ if (now) {
152+ if (!(await auto(now))) stuck = true;
153+ if (stuck) break;
154+ moves++;
155+ continue;
156+ }
157+ for (const a of asks) if (!seats[a.seat].out) request(a);
158+ const msg = await inbox.next();
159+ if (!msg) break;
160+ if (msg.stop || (inbox.closed && !msg.act && !msg.control)) {
161+ stopped = true;
162+ } else if (msg.act) {
163+ const i = Number(msg.act.seat);
164+ const s = seats[i];
165+ const a = asks.find((x) => x.seat === i);
166+ if (!s?.out || !a || s.out.version !== msg.act.version) {
167+ log(`stale move for seat ${msg.act.seat}: version ${msg.act.version}, now ${s?.out?.version ?? 'none'}`);
168+ continue;
169+ }
170+ const refused = s.out.refused;
171+ const v = s.out.version;
172+ drop(s);
173+ if (await t.act(i, msg.act.action)) {
174+ say({ event: { type: 'moved', seat: String(i), version: v, by: s.kind } });
175+ moves++;
176+ } else {
177+ log(`seat ${i}: the engine refused ${JSON.stringify(msg.act.action).slice(0, 200)}`);
178+ if (await gone(t, a)) continue;
179+ if (refused.length < 2) request(a, [...refused, msg.act.action]);
180+ else if (!(await answer(t, a, async (obs, legal) => s.auto.act(obs as Ask['obs'], legal)))) stuck = true; // three refusals: auto plays it
181+ else say({ event: { type: 'moved', seat: String(i), version: v, by: 'auto' } });
182+ }
183+ } else if (msg.control) {
184+ const i = Number(msg.control.seat);
185+ const s = seats[i];
186+ if (!s) continue;
187+ s.bot?.close();
188+ Object.assign(s, { kind: msg.control.kind, name: msg.control.name ?? s.name, dir: msg.control.dir, field: msg.control.field, bot: undefined });
189+ startBot(s);
190+ await s.bot?.ready;
191+ drop(s); // the next turn of the loop asks the seat again, with a new version
192+ say({ event: { type: 'control', seat: String(i), kind: s.kind, name: s.name } });
193+ if (s.kind === 'human') baseline(i);
194+ } else if (msg.timeout) {
195+ const s = seats[msg.timeout.seat];
196+ const a = asks.find((x) => x.seat === msg.timeout!.seat);
197+ if (!s?.out || s.out.version !== msg.timeout.version || !a) continue;
198+ log(`seat ${msg.timeout.seat}: no move in ${limitMs / 1000}s, auto plays it`);
199+ drop(s);
200+ say({ event: { type: 'moved', seat: String(msg.timeout.seat), version: msg.timeout.version, by: 'auto' } });
201+ if (!(await answer(t, a, async (obs, legal) => s.auto.act(obs as Ask['obs'], legal))) && !(await pass(t, a))) stuck = true;
202+ moves++;
203+ }
204+ }
205+ publish();
206+ for (const s of seats) drop(s), s.bot?.close();
207+ const result = stopped ? 'stopped' : stuck ? 'stuck' : t.result();
208+ const identities = Object.fromEntries(t.state.players.map((p, i) => [String(i), p.identity ?? '']));
209+ const winner = t.over?.winner === undefined ? '无人' : String(t.over.winner);
210+ say({ end: { result, winner, scores: t.over ? t.scores() : Object.fromEntries(names.map((_, i) => [String(i), 0])), identities } });
211+ const focus = Math.max(0, seats.findIndex((s) => s.kind === 'human' || s.kind === 'agent'));
212+ new Replays().add('room.json', { ...(t.replay('Shoal room') as object), shoal: { seat: focus, names } }, `A room: ${names.join(', ')}`, names, result);
213+ rl.close();
214+ process.exit(0);
215+}
+16 −0 src/sgs.ts added View file
@@ -0,0 +1,16 @@
1+// The bundle's entry (referee/sgs.mjs): the upstream engine with this project's table, check, room and the upstream AI.
2+import { allCharacters } from '../src/engine/data/characters';
3+import { skillInfo } from './table';
4+
5+export { play } from './play';
6+export { room } from './room';
7+export { Heuristic, Table, skillInfo } from './table';
8+
9+/** Every general with its faction, health and skills (the upstream's own skill texts): referee/generals.json. */
10+export async function catalog(): Promise<Record<string, object>> {
11+ const out: Record<string, object> = {};
12+ for (const c of allCharacters) {
13+ out[c.name] = { faction: c.faction, maxHealth: c.maxHealth, gender: c.gender, skills: await skillInfo(c.skills.map((s) => s.name)) };
14+ }
15+ return out;
16+}
+335 −0 src/table.ts added View file
@@ -0,0 +1,335 @@
1+// A Sanguosha table on the upstream engine, with no server: wmzy/sanguosha's create/bootstrap/dispatch on a virtual
2+// clock, the views its browser gets (buildView), the moves its headless client and MCP server list
3+// (HeadlessGameClient.getAvailableActions), its heuristic AI (rankActions) and its replay format (buildReplayFile).
4+// The room (room.ts) and the check (play.ts) both drive games through this, so a bot sees exactly what the MCP sees.
5+import { create, bootstrap, dispatch, buildView, checkGameOver, type GameConfig } from '../src/engine/index';
6+import { findActionEntry } from '../src/engine/core/skill';
7+import { VirtualClock } from '../src/engine/core/clock';
8+import { allCharacters } from '../src/engine/data/characters';
9+import { HeadlessGameClient } from '../src/client/headless/HeadlessGameClient';
10+import { registerSkillActions, clearRegistry } from '../src/client/skillActionRegistry';
11+import { projectView } from '../src/ai-mcp/viewProjector';
12+import { rankActions } from '../src/ai-mcp/heuristics';
13+import { getSkillDescriptionAsync } from '../src/engine/skills/lifecycle';
14+import { buildReplayFile } from '../src/server/gameHistory';
15+import type { AvailableAction, AiViewSnapshot } from '../src/client/headless/types';
16+import type { ClientMessage, GameState, GameView, Card } from '../src/engine/types';
17+
18+export type Legal = AvailableAction;
19+export type Snapshot = AiViewSnapshot;
20+const CAMP: Record<string, string> = { 主公: '主公', 忠臣: '主公', 反贼: '反贼', 内奸: '内奸' };
21+const POOL = allCharacters.map((c) => ({ name: c.name, skills: c.skills.map((s) => s.name) }));
22+// Engine time per move on the virtual clock: replays get spacing, and a seat with nothing to answer (a "silent" ask,
23+// so nobody learns it holds no 闪) waits its short delay on this clock, not on the wall.
24+const TICK_MS = 500;
25+
26+/** What one seat may do now: its view (as the browser gets it), the MCP's snapshot of it, and the moves. */
27+export interface Ask {
28+ seat: number;
29+ view: GameView;
30+ obs: Snapshot & { game: string; recommended: number | null };
31+ legal: Legal[];
32+ key: string;
33+}
34+
35+export class Table {
36+ state!: GameState;
37+ n: number;
38+ seed: number;
39+ private readonly clock = new VirtualClock();
40+ private config!: GameConfig;
41+ // The headless client is only used offline, for its move list: getAvailableActions reads _view and _seatIndex.
42+ private hgc = new HeadlessGameClient('http://offline.invalid');
43+ private skillsKey = new Map<number, string>();
44+ private baseline: GameView[] = [];
45+ private baselineSeq = 0;
46+ over: { winner?: number } | null = null;
47+
48+ id: string;
49+ private static games = 0;
50+
51+ constructor(seed: number, n = 5) {
52+ this.seed = seed;
53+ this.n = n;
54+ this.id = `sgs-${seed}-${++Table.games}`;
55+ }
56+
57+ async open(names: string[]): Promise<void> {
58+ clearRegistry();
59+ const config: GameConfig = (this.config = {
60+ characters: POOL,
61+ playerCount: this.n,
62+ seed: this.seed,
63+ gameId: this.id,
64+ handSize: 4,
65+ timeoutSec: 30,
66+ mode: '身份局' as const,
67+ playerNames: names,
68+ });
69+ this.state = create(config);
70+ this.state.clock = this.clock;
71+ this.state.startedAt = this.clock.now();
72+ await bootstrap(this.state, config);
73+ await this.settle();
74+ }
75+
76+ private async quiet(ticks: number): Promise<void> {
77+ let last = -1;
78+ for (let quiet = 0; quiet < ticks; ) {
79+ await new Promise((r) => setImmediate(r));
80+ if (this.state.seq === last) quiet++;
81+ else (quiet = 0), (last = this.state.seq);
82+ }
83+ }
84+
85+ /** Let the engine run its fire-and-forget execute chain to the next ask. */
86+ private async settle(): Promise<void> {
87+ await this.quiet(3);
88+ if (!this.baseline.length && this.state.players.every((p) => p.character) && !this.state.charSelecting) {
89+ // The replay starts once every general is chosen and shown, like the upstream server's recording.
90+ this.baseline = [...Array(this.n).keys(), -1].map((v) => JSON.parse(JSON.stringify(buildView(this.state, v))));
91+ this.baselineSeq = this.state.seq;
92+ }
93+ if (!this.over) {
94+ const r = await checkGameOver(this.state);
95+ if (r.gameOver) this.over = { winner: r.winner };
96+ }
97+ }
98+
99+ /** The seat's ask, or null when it has nothing to do (HeadlessGameClient.needsAction, seat by seat). */
100+ async ask(seat: number): Promise<Ask | null> {
101+ if (this.over) return null;
102+ const view = buildView(this.state, seat);
103+ const p = view.pending;
104+ if (!p) return null;
105+ if (p.target >= 0 && p.target !== seat) return null;
106+ if (p.target === seat && p.responseMode === 'silent') return null;
107+ if (p.target === seat && p.isBlocking === false && view.phase !== '出牌') return null;
108+ if (p.target < 0 && this.broadcastSlot()?.skippedPlayers?.has(seat)) return null;
109+ const me = view.players[seat];
110+ const key = me?.skills.join(',') ?? '';
111+ if (me?.character && this.skillsKey.get(seat) !== key) {
112+ await registerSkillActions(seat, me.skills);
113+ this.skillsKey.set(seat, key);
114+ }
115+ const h = this.hgc as unknown as { _view: GameView; _seatIndex: number };
116+ h._view = view;
117+ h._seatIndex = seat;
118+ const legal = this.hgc.getAvailableActions();
119+ if (!legal.length) return null;
120+ const snap = projectView(view);
121+ const d = discardRange(view);
122+ if (d && snap.pending) Object.assign(snap.pending, { discard: d });
123+ const best = rankActions(snap, legal)[0];
124+ const obs = { ...snap, game: this.id, recommended: best ? legal.indexOf(best) : null };
125+ // The same ask while its engine slot lives and its moves stay the same: a room keeps its request (and version) open.
126+ const slot = p.target < 0 ? this.broadcastSlot() : this.state.pendingSlots.get(seat);
127+ return { seat, view, obs, legal, key: `${slot?.createdSeq ?? this.state.seq}:${p.target}:${JSON.stringify(legal.map((a) => a.description))}` };
128+ }
129+
130+ private broadcastSlot() {
131+ return [...this.state.pendingSlots.values()].find((s) => ((s.atom as { target?: number }).target ?? 0) < 0);
132+ }
133+
134+ /** Every seat that must or may act now. A broadcast ask (无懈可击) goes to every seat; one that can only pass is
135+ * passed for at once, as the upstream client's auto-skip does, so only seats holding an answer are asked. */
136+ async asks(): Promise<Ask[]> {
137+ for (;;) {
138+ const out: Ask[] = [];
139+ let passed = false;
140+ for (let s = 0; s < this.n && !passed; s++) {
141+ const a = await this.ask(s);
142+ if (a && a.view.pending!.target < 0 && a.legal.every((l) => l.category === 'skip')) passed = await this.act(s, 0);
143+ else if (a) out.push(a);
144+ }
145+ if (!passed) return out;
146+ }
147+ }
148+
149+ /** A seat's move: an index into its legal list, or a ClientMessage (an MCP action, its params filled in).
150+ * The engine is the judge: a move it refuses changes nothing and returns false. */
151+ async act(seat: number, action: unknown): Promise<boolean> {
152+ const a = await this.ask(seat);
153+ if (!a) return false;
154+ const msg = toMessage(a, action);
155+ if (!msg) return false;
156+ // The same active move three times in one turn is refused: the engine can hand a card back (a 火攻 whose target
157+ // declines to show a card returns to hand), and a bot that plays it again would loop for ever.
158+ const again = `${this.state.turn?.round}:${this.state.currentPlayerIndex}:${seat}:${JSON.stringify(msg)}`;
159+ if (msg.actionType === 'use' && (this.used.get(again) ?? 0) >= 3) return false;
160+ // A transform (解围 as 无懈可击) the engine refuses makes it resolve every open ask, the play phase's among them,
161+ // and the game soon hangs with nobody to move; so its first step is validated here, exactly as dispatch would.
162+ const first = msg.preceding?.[0];
163+ if (first && findActionEntry(this.state, first.skillId, seat, first.actionType)?.validate(this.state, first.params) !== null) return false;
164+ void this.clock.advanceTo(this.clock.now() + TICK_MS);
165+ const view = a.view;
166+ const r = await dispatch(this.state, {
167+ ...msg,
168+ ownerId: seat,
169+ baseSeq: this.state.seq,
170+ pendingSeq: view.pending?.isBlocking ? this.state.seq : undefined,
171+ } as ClientMessage).catch(() => ({ accepted: false, settle: Promise.resolve(undefined) }));
172+ // The engine signals settle when the execute suspends or ends, but some ends only after it drains a thousand
173+ // macrotasks (about a second); the seq going quiet is the same moment for us.
174+ await Promise.race([r.settle, this.quiet(20)]);
175+ await this.settle();
176+ if (r.accepted && msg.actionType === 'use') this.used.set(again, (this.used.get(again) ?? 0) + 1);
177+ return r.accepted;
178+ }
179+
180+ /** Nobody can act: let the engine's own clock run to its next deadline (a silent ask timing out). With no deadline
181+ * either, the engine may still be loading a skill module: wait for it a little before calling the game stuck. */
182+ async idle(): Promise<boolean> {
183+ const events = (this.clock as unknown as { events: Array<{ at: number; cancelled: boolean }> }).events;
184+ const next = events.filter((e) => !e.cancelled).map((e) => e.at).sort((x, y) => x - y)[0];
185+ if (next === undefined) {
186+ if (++this.waits > 100) return false;
187+ await new Promise((r) => setTimeout(r, 20));
188+ await this.settle();
189+ return true;
190+ }
191+ this.waits = 0;
192+ // Not awaited: a timeout handler can resume into the next ask and wait there for a move, as with a real timer.
193+ void this.clock.advanceTo(next);
194+ await this.settle();
195+ return true;
196+ }
197+ private waits = 0;
198+ private used = new Map<string, number>();
199+
200+ identity(seat: number): string {
201+ return this.state.players[seat]?.identity ?? '';
202+ }
203+
204+ /** +1 for every seat of the winning camp, -1 for the others; the engine names one seat of the winners. */
205+ scores(): Record<string, number> {
206+ const camp = this.over?.winner !== undefined ? CAMP[this.identity(this.over.winner)] : undefined;
207+ const out: Record<string, number> = {};
208+ for (let s = 0; s < this.n; s++) out[String(s)] = camp && CAMP[this.identity(s)] === camp ? 1 : -1;
209+ return out;
210+ }
211+
212+ result(): string {
213+ const w = this.over?.winner;
214+ if (w === undefined) return this.over ? 'no winner' : 'unfinished';
215+ const camp = CAMP[this.identity(w)];
216+ return camp === '主公' ? '主公 and 忠臣 win' : `${camp} wins`;
217+ }
218+
219+ /** The upstream's replay file (format sanguosha-replay v2): every seat's view and the spectator's. */
220+ replay(title: string): unknown {
221+ return buildReplayFile(this.state, this.baseline, this.baselineSeq, {
222+ createdAt: 0,
223+ playerCount: this.n,
224+ characters: this.state.players.map((p) => p.character ?? ''),
225+ roomName: title,
226+ });
227+ }
228+
229+ /** The public view (no one's hand), for spectators. */
230+ publicView(): GameView {
231+ return buildView(this.state, -1);
232+ }
233+}
234+
235+/** What a move names: an index into legal, one of legal's entries (its message's params filled in or not), or such a
236+ * message by itself. The engine judges it; ownerId is always the seat's. */
237+function toMessage(a: Ask, action: unknown): Omit<ClientMessage, 'baseSeq'> | null {
238+ if (typeof action === 'number') {
239+ const l = a.legal[action];
240+ return l ? l.message : null;
241+ }
242+ if (!action || typeof action !== 'object') return null;
243+ if ('message' in action) return toMessage(a, (action as Legal).message);
244+ const m = action as Partial<ClientMessage>;
245+ if (typeof m.skillId !== 'string' || typeof m.actionType !== 'string') return null;
246+ return { skillId: m.skillId, actionType: m.actionType, ownerId: a.seat, params: (m.params ?? {}) as ClientMessage['params'], ...(m.preceding ? { preceding: m.preceding } : {}) } as ClientMessage;
247+}
248+
249+/** How many cards a discard ask wants (the browser's usePendingState reads the same prompt). */
250+function discardRange(view: GameView): { min: number; max: number } | null {
251+ const p = view.pending;
252+ if (!p) return null;
253+ const atom = p.atom as { requestType?: string; prompt?: { cardFilter?: { min?: number; max?: number } } };
254+ const f = atom.requestType === '__弃牌' ? atom.prompt?.cardFilter : p.mandatory && p.prompt?.type === 'useCard' ? p.prompt.cardFilter : null;
255+ if (!f) return null;
256+ const min = f.min ?? 0;
257+ return { min, max: f.max ?? min };
258+}
259+
260+export async function skillInfo(names: string[]): Promise<Record<string, string | null>> {
261+ const out: Record<string, string | null> = {};
262+ for (const n of names) out[n] = (await getSkillDescriptionAsync(n).catch(() => null)) ?? null;
263+ return out;
264+}
265+
266+// ── The upstream heuristic, made to move: rankActions ranks the MCP's moves, and a few of them are templates (pick
267+// the targets, the cards to discard). This fills them the way the plugin's skill tells an agent to, and falls back to
268+// the next move when one cannot be filled. ────────────────────────────────────────────────────────────────────────
269+const KEEP: Record<string, number> = { 桃: 100, 闪: 90, 无懈可击: 85, 酒: 70, 杀: 60 };
270+const keep = (c: Card) => KEEP[c.name] ?? (c.type === '装备牌' ? 30 : 45);
271+
272+function allies(obs: Snapshot, t: number): boolean {
273+ const me = obs.players[obs.viewer]?.identity;
274+ const them = obs.players[t]?.identity;
275+ if (!me || !them || me === '内奸') return false;
276+ return CAMP[me] === CAMP[them];
277+}
278+
279+/** Fill a move's open parameters, or null when this simple filler cannot. */
280+export function fill(obs: Snapshot, l: Legal): ClientMessage | null {
281+ const m = structuredClone(l.message) as ClientMessage;
282+ const params = m.params as Record<string, unknown>;
283+ const me = obs.players[obs.viewer];
284+ const hand = me?.hand ?? [];
285+ if (l.validTargets.length && !Array.isArray(params.targets)) {
286+ const min = l.minTarget ?? 1;
287+ const max = l.maxTarget ?? 1;
288+ // Friendly moves (桃, 无中生有-like ones on self) keep allies; for the rest, enemies first, the lord first for rebels.
289+ const lord = obs.players.findIndex((p) => p.identity === '主公');
290+ const foes = l.validTargets.filter((t) => !allies(obs, t));
291+ const rebel = me?.identity === '反贼';
292+ const order = [...foes.sort((x, y) => Number(rebel && y === lord) - Number(rebel && x === lord)), ...l.validTargets.filter((t) => !foes.includes(t))];
293+ if (order.length < min) return null;
294+ if (!foes.length && min > 0 && l.category === 'play') return null; // only allies in reach: hold it
295+ params.targets = order.slice(0, Math.max(min, Math.min(max, 1)));
296+ params.target = (params.targets as number[])[0];
297+ }
298+ if (Array.isArray(params.cardIds) && !params.cardIds.length) {
299+ const d = (obs.pending as { discard?: { min: number } } | null)?.discard;
300+ const need = Math.max(1, d?.min ?? 1);
301+ if (hand.length < need) return null;
302+ params.cardIds = [...hand].sort((a, b) => keep(a) - keep(b)).slice(0, need).map((c) => c.id);
303+ }
304+ if (Array.isArray(params.allocation) && !params.allocation.length) return null;
305+ return m;
306+}
307+
308+/** The upstream AI as a seat: the heuristic's ranking, the best move this filler can complete that the engine has not
309+ * refused at this ask (obs.refused), else a pass. A move already made twice this turn is dropped, or 激将 that
310+ * nobody answers would be asked forever. */
311+export class Heuristic {
312+ private turn = '';
313+ private made = new Map<string, number>();
314+
315+ act(obs: Snapshot & { refused?: unknown[]; game?: string }, legal: Legal[]): ClientMessage | number {
316+ const turn = `${obs.game}:${obs.turn.round}:${obs.currentPlayerIndex}`;
317+ if (turn !== this.turn) (this.turn = turn), this.made.clear();
318+ const refused = new Set((obs.refused ?? []).map((r) => JSON.stringify(r)));
319+ for (const l of rankActions(obs, legal)) {
320+ const m = fill(obs, l);
321+ const k = JSON.stringify(m);
322+ if (m && !refused.has(k) && (this.made.get(k) ?? 0) < 2) {
323+ this.made.set(k, (this.made.get(k) ?? 0) + 1);
324+ return m;
325+ }
326+ }
327+ return passIndex(legal);
328+ }
329+}
330+
331+/** The move that gives up: a skip, the end of the play phase, else the last listed. */
332+export function passIndex(legal: Legal[]): number {
333+ const i = legal.findIndex((l) => l.category === 'skip' || l.message.actionType === 'end');
334+ return i >= 0 ? i : legal.length - 1;
335+}
+70 −0 src/try-room.mjs added View file
@@ -0,0 +1,70 @@
1+// Try a room locally: node src/try-room.mjs [seed]. Starts referee/room.mjs with a scripted person at seat 0 and a
2+// scripted agent at seat 1 (both play like the starter bot), the field and auto at the others, and prints every
3+// @shoal line, shortened. On the way it hands seat 0 to an agent and sends one move with the old version (the room
4+// drops it), lets seat 1 miss its time limit once (auto plays), then hands seat 1 back to auto.
5+import { spawn } from 'node:child_process';
6+import { createInterface } from 'node:readline';
7+import path from 'node:path';
8+import { fileURLToPath } from 'node:url';
9+import starter from '../routes/bot.mjs';
10+
11+const GAME = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
12+const seats = {
13+ 0: { kind: 'human', name: 'ada' },
14+ 1: { kind: 'agent', name: 'bob-codex' },
15+ 2: { kind: 'bot', field: 'upstream' },
16+ 3: { kind: 'bot', field: 'random' },
17+};
18+const room = spawn(process.execPath, ['referee/room.mjs'], {
19+ cwd: process.env.ROOM_DIR ?? GAME,
20+ env: { ...process.env, SS_ROOM: JSON.stringify({ seats, seed: Number(process.argv[2] ?? 3), limit: 2 }) },
21+ stdio: ['pipe', 'pipe', 'inherit'],
22+});
23+const send = (m) => {
24+ console.log(`>> ${JSON.stringify(m)}`);
25+ room.stdin.write(`${JSON.stringify(m)}\n`);
26+};
27+const short = (s) => (s.length > 300 ? `${s.slice(0, 300)}… (${s.length} bytes)` : s);
28+
29+let asked = { 0: 0, 1: 0 };
30+let handedOver = false;
31+let stale = null;
32+let missed = false;
33+const lines = { event: 0, private: 0, request: 0 };
34+for await (const line of createInterface({ input: room.stdout })) {
35+ if (!line.startsWith('@shoal ')) {
36+ console.log(` log: ${line}`);
37+ continue;
38+ }
39+ const m = JSON.parse(line.slice(7));
40+ if (m.event) lines.event++;
41+ else if (m.to !== undefined && m.version === undefined) lines.private++;
42+ else if (m.version !== undefined) lines.request++;
43+ console.log(`<< ${short(JSON.stringify(m))}`);
44+ if (m.end) break;
45+ if (m.version === undefined) continue;
46+ const seat = Number(m.to);
47+ if (!(seat in asked)) continue;
48+ asked[seat]++;
49+ // Seat 1 misses its limit once: no answer, auto plays for it after 2 s.
50+ if (seat === 1 && asked[1] === 3 && !missed) {
51+ missed = true;
52+ console.log(' (seat 1 lets its time run out)');
53+ continue;
54+ }
55+ // After seat 0's fifth ask, a person hands it to their agent; the old controller's late move must be dropped.
56+ if (seat === 0 && asked[0] === 5 && !handedOver) {
57+ handedOver = true;
58+ stale = m.version;
59+ send({ control: { seat: '0', kind: 'agent', name: 'ada-codex' } });
60+ continue;
61+ }
62+ if (seat === 0 && stale !== null && m.version !== stale) {
63+ send({ act: { seat: '0', version: stale, action: starter(m.obs, m.legal) } });
64+ stale = null;
65+ }
66+ send({ act: { seat: String(seat), version: m.version, action: starter(m.obs, m.legal) } });
67+ if (seat === 1 && asked[1] === 6) send({ control: { seat: '1', kind: 'auto' } });
68+}
69+console.log(`\n${lines.event} public events, ${lines.private} private updates, ${lines.request} requests`);
70+room.stdin.end();
+1 −0 src/tsconfig.json added View file
@@ -0,0 +1 @@
1+{ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", "types": ["node", "vite/client"] }, "include": ["*.ts", "viewer/*.tsx", "viewer/noname/*.ts", "viewer/noname/*.tsx"], "exclude": ["vite.*.config.ts"] }
+13 −0 src/viewer/index.html added View file
@@ -0,0 +1,13 @@
1+<!doctype html>
2+<html lang="zh-CN">
3+ <head>
4+ <meta charset="UTF-8" />
5+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+ <title>三国杀</title>
7+ <script src="./bridge.js"></script>
8+ </head>
9+ <body>
10+ <div id="root"></div>
11+ <script type="module" src="./main.tsx"></script>
12+ </body>
13+</html>
+207 −0 src/viewer/main.tsx added View file
@@ -0,0 +1,207 @@
1+// The viewer: wmzy/sanguosha's engine views and action building, drawn as 无名杀 draws a 三国杀 table (noname/Table.tsx),
2+// fed by Shoal instead of the upstream's server. Replay mode plays a replay file from referee/ (the upstream format,
3+// sanguosha-replay v2) with the upstream's replay hook. Live mode (?live) gets a room's messages through bridge.js,
4+// keeps the public view and the controlled seats' own views up to date with the upstream client's own view maintainer,
5+// and posts the seat's moves back with shoalAct.
6+import './storage';
7+import '../../src/client/animations.css';
8+import './noname/noname.css';
9+import { useEffect, useReducer, useState } from 'react';
10+import { createRoot } from 'react-dom/client';
11+import { useReplay } from '../../src/client/hooks/useReplay';
12+import { applyServerMessage } from '../../src/client/headless/viewMaintainer';
13+import { resourceManager } from '../../src/client/resources';
14+import type { GameView, GameEventEnvelope } from '../../src/engine/types';
15+import type { ReplayFile } from '../../src/client/replay/types';
16+import type { ActionMsg } from '../../src/client/types';
17+import type { QueuedEvent } from '../../src/client/hooks/useEventPlayback';
18+import { Table } from './noname/Table';
19+import { ReplayBar, ReplayView, SeatSwitch, Result, inferWinner } from './noname/Controls';
20+
21+type Msg = { n?: number; to?: string; version?: number; obs?: Record<string, unknown>; legal?: Array<{ description: string; message: unknown; validTargets: number[]; category: string }>; event?: Record<string, unknown>; end?: { result: string; winner?: string; identities?: Record<string, string>; scores?: Record<string, number> } };
22+type Live = { views: Record<string, { view: GameView; seq: number }>; fresh: Record<string, QueuedEvent[]>; asks: Record<string, Msg & { at: number }>; you: string[]; end?: Msg['end']; n: number };
23+type Shoal = Window & {
24+ shoalReplay?: (start: (text: string, name?: string) => void) => void;
25+ shoalLive?: (fn: (data: unknown, you?: string[]) => void) => void;
26+ shoalAct?: (seat: string, version: number, action: unknown) => void;
27+};
28+const w = window as Shoal;
29+// Until kit/bridge.js has the live half, the same contract here: {shoal: 'live', room, you, messages} in, {shoal: 'act'} out.
30+w.shoalLive ??= (fn) => {
31+ addEventListener('message', (e) => {
32+ if (e.data?.shoal === 'live') fn(e.data);
33+ });
34+ if (parent !== window) parent.postMessage({ shoal: 'ready', live: true }, '*');
35+};
36+w.shoalAct ??= (seat, version, action) => parent.postMessage({ shoal: 'act', seat, version, action }, '*');
37+
38+const noop = () => {};
39+const PUBLIC = 'public';
40+// The upstream's resource packs (art and sound it doesn't ship) stay empty: the art pack is this viewer's own (art/).
41+// Loading an empty index up front keeps it from fetching one.
42+resourceManager.loadIndex({ packs: [] });
43+// The art pack's own stylesheet (its fonts and theme pieces), beside the art it names.
44+document.head.append(Object.assign(document.createElement('link'), { rel: 'stylesheet', href: 'art/art.css' }));
45+
46+function apply(v: { view: GameView; seq: number } | undefined, events: GameEventEnvelope[]) {
47+ if (!v) return v;
48+ let { view, seq } = v;
49+ for (const env of events) {
50+ const r = applyServerMessage(view, seq, { type: 'event', epoch: 0, ...env } as never);
51+ if (r.view) view = r.view;
52+ seq = r.lastSeq;
53+ }
54+ return { view, seq };
55+}
56+
57+/** The engine events of a batch, as the upstream's event playback queues them (for the table's animations). */
58+const queued = (events: GameEventEnvelope[]): QueuedEvent[] => events.filter((e) => e.view).map((e) => ({ seq: e.seq, event: e.view! }));
59+
60+function reduce(s: Live, batch: { messages: Msg[]; you?: string[] }): Live {
61+ const first = s.n < 0;
62+ const next: Live = { ...s, views: { ...s.views }, fresh: {}, asks: { ...s.asks }, you: batch.you ?? s.you };
63+ const fresh = (key: string, events: GameEventEnvelope[]) => {
64+ if (!first) next.fresh[key] = [...(next.fresh[key] ?? []), ...queued(events)];
65+ };
66+ for (const m of batch.messages) {
67+ if (m.n !== undefined) {
68+ if (m.n <= next.n) continue;
69+ next.n = m.n;
70+ }
71+ const e = m.event;
72+ if (e?.type === 'start') next.views[PUBLIC] = { view: e.view as GameView, seq: e.seq as number };
73+ else if (e?.type === 'events') (next.views[PUBLIC] = apply(next.views[PUBLIC], e.events as GameEventEnvelope[])!), fresh(PUBLIC, e.events as GameEventEnvelope[]);
74+ else if ((e?.type === 'moved' || e?.type === 'control') && next.asks[e.seat as string]?.version === (e.version ?? next.asks[e.seat as string]?.version)) delete next.asks[e.seat as string];
75+ else if (m.end) (next.end = m.end), (next.asks = {});
76+ else if (m.to !== undefined && m.version !== undefined) next.asks[m.to] = { ...m, at: Date.now() };
77+ else if (m.to !== undefined && m.obs?.view) next.views[m.to] = { view: m.obs.view as GameView, seq: m.obs.seq as number };
78+ else if (m.to !== undefined && m.obs?.events) (next.views[m.to] = apply(next.views[m.to], m.obs.events as GameEventEnvelope[])!), fresh(m.to, m.obs.events as GameEventEnvelope[]);
79+ }
80+ return next;
81+}
82+
83+/** The room's limit as the upstream countdown: the engine's own deadlines run on the room's virtual clock. */
84+function withDeadline(view: GameView, ask?: Msg & { at: number }): GameView {
85+ const ms = ask ? Number(ask.obs?.limit ?? 30) * 1000 : 0;
86+ const deadline = ask ? ask.at + ms : null;
87+ return { ...view, deadline, deadlineTotalMs: ms, pending: view.pending ? { ...view.pending, deadline: deadline ?? undefined, totalMs: ms } : null };
88+}
89+
90+const winnerCamp = (end: NonNullable<Live['end']>) => {
91+ const w0 = Object.entries(end.scores ?? {}).find(([, v]) => v > 0)?.[0] ?? end.winner;
92+ const id = w0 !== undefined ? end.identities?.[w0] : undefined;
93+ return id === '忠臣' ? '主公' : (id ?? '');
94+};
95+
96+function LiveTable() {
97+ const [s, dispatch] = useReducer(reduce, { views: {}, fresh: {}, asks: {}, you: [], n: -1 });
98+ const [pick, setPick] = useState<string | null>(null);
99+ const [open, setOpen] = useState(false);
100+ useEffect(() => {
101+ w.shoalLive!((data, you) => {
102+ const d = data as { messages?: Msg[]; you?: string[] } | Msg[];
103+ dispatch(Array.isArray(d) ? { messages: d, you } : { messages: d.messages ?? [], you: d.you ?? you });
104+ });
105+ }, []);
106+ const seat = pick && s.you.includes(pick) ? pick : (s.you.find((x) => s.views[x]) ?? s.you[0]);
107+ const mine = seat !== undefined ? s.views[seat] : undefined;
108+ const key = mine ? seat! : PUBLIC;
109+ const base = mine ?? s.views[PUBLIC];
110+ if (!base) return <div className="shoal-wait">等待房间开局…</div>;
111+ const ask = seat !== undefined ? s.asks[seat] : undefined;
112+ const act = (action: ActionMsg | number) => {
113+ if (!ask || seat === undefined) return;
114+ w.shoalAct!(seat, ask.version!, action);
115+ dispatch({ messages: [{ event: { type: 'moved', seat, version: ask.version } }] });
116+ };
117+ const view = withDeadline(base.view, ask);
118+ const moves = ask?.legal?.map((l, i) => ({ l, i })).filter(({ l }) => complete(l)) ?? [];
119+ const top = (
120+ <>
121+ <SeatSwitch seats={s.you} seat={seat} view={view} onPick={setPick} />
122+ {moves.length > 0 && (
123+ <div className="nm-moves">
124+ <button className="nm-mini" onClick={() => setOpen(!open)} title="The room's list of moves for this seat">
125+ {open ? '收起' : `操作 ${moves.length}`}
126+ </button>
127+ {open && (
128+ <div className="nm-moves-list">
129+ {moves.map(({ l, i }) => (
130+ <button key={i} onClick={() => act(i)} title={JSON.stringify(l.message)}>
131+ {l.description}
132+ </button>
133+ ))}
134+ </div>
135+ )}
136+ </div>
137+ )}
138+ </>
139+ );
140+ return (
141+ <div className="nm-root">
142+ <Table
143+ view={view}
144+ onAction={act}
145+ readOnly={!mine}
146+ ingestedEvents={s.fresh[key]}
147+ top={top}
148+ overlay={s.end ? <Result view={view} camp={winnerCamp(s.end)} identities={s.end.identities} me={view.viewer} /> : null}
149+ />
150+ </div>
151+ );
152+}
153+
154+/** A listed move that needs nothing more (no targets or cards left to pick): one click plays it. */
155+function complete(l: { message: unknown; validTargets: number[] }): boolean {
156+ const p = ((l.message as { params?: Record<string, unknown> }).params ?? {}) as Record<string, unknown>;
157+ if (l.validTargets.length && !Array.isArray(p.targets)) return false;
158+ return !Object.values(p).some((v) => Array.isArray(v) && !v.length);
159+}
160+
161+function Replay({ file }: { file: ReplayFile & { shoal?: { seat?: number; names?: string[] } } }) {
162+ const r = useReplay(file);
163+ const focus = file.shoal?.seat;
164+ useEffect(() => {
165+ if (focus !== undefined && r.seats.includes(focus)) r.setSeat(focus);
166+ // once, on load
167+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
168+ if (!r.view) return <div className="shoal-wait">…</div>;
169+ const names = file.shoal?.names ?? r.view.players.map((p) => p.name);
170+ const ended = r.step >= r.total && r.total > 0;
171+ return (
172+ <div className="nm-root">
173+ <Table
174+ view={r.view}
175+ onAction={noop}
176+ readOnly
177+ currentEvent={r.currentEvent}
178+ ingestedEvents={r.ingestedEvents}
179+ labels={file.shoal?.names}
180+ top={<ReplayBar r={r} />}
181+ side={<ReplayView r={r} names={names} />}
182+ overlay={ended ? <Result view={r.view} camp={inferWinner(r.view)} me={r.view.viewer} labels={file.shoal?.names} /> : null}
183+ />
184+ </div>
185+ );
186+}
187+
188+function App() {
189+ const live = new URLSearchParams(location.search).has('live');
190+ const [file, setFile] = useState<ReplayFile | null>(null);
191+ const [error, setError] = useState('');
192+ useEffect(() => {
193+ if (live) return;
194+ w.shoalReplay?.((text) => {
195+ try {
196+ setFile(JSON.parse(text));
197+ } catch {
198+ setError('这个文件不是三国杀录像');
199+ }
200+ });
201+ }, [live]);
202+ if (live) return <LiveTable />;
203+ if (error) return <div className="shoal-wait">{error}</div>;
204+ return file ? <Replay file={file} /> : <div className="shoal-wait">等待录像…</div>;
205+}
206+
207+createRoot(document.getElementById('root')!).render(<App />);
+91 −0 src/viewer/noname/ActionBar.tsx added View file
@@ -0,0 +1,91 @@
1+// The 确定 / 取消 / 结束回合 buttons, as 无名杀 shows them above your hand. Which buttons show, when they are enabled and
2+// what they do is the upstream's CenterActionBar (src/client/components/CenterActionBar.tsx), condition for condition;
3+// only the labels are 无名杀's: 确定 for 出牌, 打出, 使用 and 确认弃牌, 取消 for 不回应 and 取消选择.
4+import type { PendingView } from '../../../src/engine/types';
5+import type { PlayInteractionResult } from '../../../src/client/hooks/usePlayInteraction';
6+import { useGameView } from '../../../src/client/components/GameViewCtx';
7+import { displaySkillName } from '../../../src/client/utils/skillDisplay';
8+
9+interface Props {
10+ play: PlayInteractionResult;
11+ pending: PendingView | null;
12+ isRespondPending: boolean;
13+ respondCandidateCount: number | null;
14+ showCancelSelection: boolean;
15+ showEndTurn: boolean;
16+ isDiscardPhase: boolean;
17+ isPerspectiveAwaiting: boolean;
18+ discardMin: number;
19+ discardMax: number;
20+}
21+
22+type Btn = { key: string; label: string; kind: 'ok' | 'cancel' | 'end' | 'plain'; onClick: () => void; disabled?: boolean; title?: string };
23+
24+export function ActionBar({ play, pending, isRespondPending, respondCandidateCount, showCancelSelection, showEndTurn, isDiscardPhase, isPerspectiveAwaiting, discardMin, discardMax }: Props) {
25+ const { canOperate } = useGameView();
26+ const {
27+ selectedCardId, selectedTarget, selectedForDiscard, transformMode, transformWrapperName, distributeMode, activeDistribute, isDistributeActive, distSelected, distAllocations,
28+ distTargetName, selectedActive, playButtonState, transformSubmit, selectedRespondCardId, respondTargetReady, altActions, handlePlayCard, handleSkillAction, handleTransformPlay,
29+ isRespondTransformContext, handleRespond, handlePlayRespond, handleEndTurn, handleConfirmDiscard, handleDiscardSelectAll, handleTransformSelectAll, handleTransformInvert,
30+ handleDistSubmit, handleDistClear, handleDistSelectAll, handleDistInvert, cancelSelection, setDistributeMode,
31+ } = play;
32+ const b: Btn[] = [];
33+ const weapon = pending?.prompt?.type === 'useCardAndTarget';
34+
35+ if (isRespondPending) {
36+ if (respondCandidateCount !== 0) b.push({ key: 'respond', label: '确定', kind: 'ok', onClick: handlePlayRespond, disabled: !selectedRespondCardId || !respondTargetReady });
37+ b.push({ key: 'skip', label: weapon ? '交出武器' : '取消', kind: 'cancel', onClick: () => handleRespond(), title: respondCandidateCount === 0 ? '没有可回应的牌' : undefined });
38+ }
39+ if (canOperate && transformMode && transformMode.minCards > 1) {
40+ const ids = transformMode.selectedCardIds;
41+ b.push({ key: 't-all', label: '全选', kind: 'plain', onClick: handleTransformSelectAll, disabled: ids.length >= transformMode.maxCards });
42+ b.push({ key: 't-inv', label: '反选', kind: 'plain', onClick: handleTransformInvert, disabled: ids.length === 0 });
43+ }
44+ if (canOperate && (selectedActive || isRespondTransformContext) && transformMode && transformMode.minCards > 1) {
45+ const ok = transformSubmit?.canSubmit ?? false;
46+ const needsTarget = transformSubmit?.needsTarget ?? false;
47+ b.push({ key: 't-go', label: '确定', kind: 'ok', onClick: () => ok && handleTransformPlay(needsTarget ? selectedTarget! : ''), disabled: !ok, title: `使用${transformWrapperName ?? transformMode.wrapperName}` });
48+ }
49+ if (canOperate && (selectedActive || isRespondTransformContext) && transformMode?.minCards === 1 && selectedCardId) {
50+ if (isRespondTransformContext) b.push({ key: 't-one', label: '确定', kind: 'ok', onClick: () => handleTransformPlay(''), title: `使用${transformWrapperName ?? transformMode.wrapperName}` });
51+ else b.push({ key: 't-one', label: '确定', kind: 'ok', onClick: () => selectedTarget && handleTransformPlay(selectedTarget), disabled: !selectedTarget, title: `使用${transformWrapperName ?? transformMode.wrapperName}` });
52+ }
53+ if (canOperate && selectedActive && !transformMode && selectedCardId && playButtonState)
54+ b.push({ key: 'play', label: '确定', kind: 'ok', onClick: handlePlayCard, disabled: !playButtonState.canPlay, title: `出牌${playButtonState.targetLabel}` });
55+ if (canOperate && !transformMode && selectedCardId) for (const a of altActions) b.push({ key: `${a.skillId}:${a.actionType}`, label: displaySkillName(a.label), kind: 'plain', onClick: () => handleSkillAction(a) });
56+ if (!transformMode && showCancelSelection) b.push({ key: 'cancel', label: '取消', kind: 'cancel', onClick: cancelSelection });
57+ if (showEndTurn) b.push({ key: 'end', label: '结束回合', kind: 'end', onClick: handleEndTurn });
58+ if (canOperate && isDiscardPhase && isPerspectiveAwaiting) {
59+ const n = selectedForDiscard.length;
60+ b.push({ key: 'discard', label: '确定', kind: 'ok', onClick: handleConfirmDiscard, disabled: n < discardMin || n > discardMax, title: `弃置 ${n}/${discardMin}` });
61+ b.push({ key: 'd-all', label: '全选', kind: 'plain', onClick: handleDiscardSelectAll, disabled: n >= discardMax });
62+ }
63+ if (canOperate && isDistributeActive && activeDistribute) {
64+ const mode = activeDistribute.prompt.mode ?? 'allocate';
65+ const minTotal = activeDistribute.prompt.minTotal ?? 1;
66+ const maxTotal = activeDistribute.prompt.maxTotal ?? 99;
67+ const ok =
68+ mode === 'select'
69+ ? distSelected.size >= minTotal && distSelected.size <= maxTotal
70+ : activeDistribute.externalTargetSelection
71+ ? distSelected.size >= minTotal && distSelected.size <= maxTotal && !!distTargetName
72+ : distAllocations.flatMap((a) => a.cardIds).length >= minTotal;
73+ if (mode === 'select') {
74+ b.push({ key: 'x-all', label: '全选', kind: 'plain', onClick: handleDistSelectAll, disabled: distSelected.size >= activeDistribute.cardIds.length });
75+ b.push({ key: 'x-inv', label: '反选', kind: 'plain', onClick: handleDistInvert, disabled: distSelected.size === 0 });
76+ }
77+ b.push({ key: 'x-clear', label: '重选', kind: 'plain', onClick: handleDistClear, disabled: distSelected.size === 0 && distAllocations.length === 0 });
78+ b.push({ key: 'x-go', label: '确定', kind: 'ok', onClick: handleDistSubmit, disabled: !ok, title: activeDistribute.prompt.title });
79+ if (distributeMode) b.push({ key: 'x-cancel', label: '取消', kind: 'cancel', onClick: () => setDistributeMode(null) });
80+ }
81+ if (!b.length) return null;
82+ return (
83+ <div className="nm-control">
84+ {b.map(({ key, label, kind, onClick, disabled, title }) => (
85+ <button key={key} className={`nm-btn ${kind}`} onClick={onClick} disabled={disabled} title={title}>
86+ {label}
87+ </button>
88+ ))}
89+ </div>
90+ );
91+}
+46 −0 src/viewer/noname/Card.tsx added View file
@@ -0,0 +1,46 @@
1+// A card as 无名杀 draws it: the theme's wood face, the card's art, its name in vertical brush script at the top left,
2+// suit and rank at the top right; 火杀 and 雷杀 are 杀 with their colour. A card with no art shows its name large.
3+import type { CSSProperties } from 'react';
4+import { cardArt } from './art';
5+import { displayCardName } from '../../../src/client/utils/gameViewHelpers';
6+
7+export interface Face {
8+ name: string;
9+ suit?: string;
10+ rank?: string;
11+ damageType?: string;
12+}
13+
14+const NATURE: Record<string, string> = { 火焰: 'fire', 雷电: 'thunder' };
15+export const isRed = (suit?: string) => suit === '♥' || suit === '♦';
16+
17+/** The card's inside, to fill a sized box (a hand card, a played card, a flying card). */
18+export function CardInner({ name, suit, rank, damageType }: Face) {
19+ const art = cardArt(name);
20+ const label = displayCardName(name, damageType);
21+ return (
22+ <>
23+ {art ? <div className="nm-card-art" style={{ backgroundImage: `url(${art})` }} /> : <div className="nm-card-big">{label.slice(0, 2)}</div>}
24+ <div className={`nm-card-name${label.length > 3 ? ' long' : ''}`}>{label}</div>
25+ {suit && (
26+ <div className={`nm-card-info${isRed(suit) ? ' red' : ''}`}>
27+ <span className="nm-suit">{suit}</span>
28+ {rank}
29+ </div>
30+ )}
31+ </>
32+ );
33+}
34+
35+export function cardClass({ suit, damageType }: Face, extra = '') {
36+ const nature = damageType ? NATURE[damageType] : undefined;
37+ return `nm-card${isRed(suit) ? ' red' : ''}${nature ? ` ${nature}` : ''}${extra ? ` ${extra}` : ''}`;
38+}
39+
40+export function Card({ face, className = '', style, title }: { face: Face; className?: string; style?: CSSProperties; title?: string }) {
41+ return (
42+ <div className={cardClass(face, className)} style={style} title={title}>
43+ <CardInner {...face} />
44+ </div>
45+ );
46+}
+13 −0 src/viewer/noname/CardFace.tsx added View file
@@ -0,0 +1,13 @@
1+// In place of the upstream's CardFace (src/build swaps it in for the upstream's hand cards): 无名杀's card, filling the
2+// box the upstream gives it.
3+import { cardClass, CardInner } from './Card';
4+
5+export type CardFaceSize = 'normal' | 'large' | 'small';
6+
7+export function CardFace({ name, suit, rank, size = 'normal', damageType }: { name: string; suit?: string; rank?: string; size?: CardFaceSize; damageType?: string }) {
8+ return (
9+ <div className={cardClass({ name, suit, damageType }, `nm-card-fill ${size}`)}>
10+ <CardInner name={name} suit={suit} rank={rank} damageType={damageType} />
11+ </div>
12+ );
13+}
+89 −0 src/viewer/noname/Center.tsx added View file
@@ -0,0 +1,89 @@
1+// The middle of the table: the cards just played, discarded, judged or shown, each flown in from its seat and captioned
2+// (谁 → 谁), fading out as 无名杀's do; and the lines from a card's user to its targets.
3+import { useLayoutEffect, useRef, useState, useEffect } from 'react';
4+import type { CenterCard, Line, Word } from './useFx';
5+import { Card, type Face } from './Card';
6+import { scale, handOrigin } from './flyCards';
7+
8+function center(sel: string): { x: number; y: number } | null {
9+ const r = document.querySelector(sel)?.getBoundingClientRect();
10+ return r && r.width ? { x: r.left + r.width / 2, y: r.top + r.height / 2 } : null;
11+}
12+
13+function Played({ item }: { item: CenterCard }) {
14+ const ref = useRef<HTMLDivElement>(null);
15+ useLayoutEffect(() => {
16+ const el = ref.current;
17+ const from = (item.cardId && handOrigin.get(item.cardId)) || (item.from === null ? center('[data-zone-anchor="deck"]') : center(`[data-seat-index="${item.from}"]`));
18+ if (!el || !from || !el.animate) return;
19+ const r = el.getBoundingClientRect();
20+ const s = scale();
21+ const dx = (from.x - (r.left + r.width / 2)) / s;
22+ const dy = (from.y - (r.top + r.height / 2)) / s;
23+ el.animate([{ transform: `translate(${dx}px, ${dy}px) scale(0.55)`, opacity: 0.4 }, { transform: 'none', opacity: 1 }], { duration: 420, easing: 'cubic-bezier(.2,.7,.3,1)' });
24+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
25+ return (
26+ <div className="nm-played" ref={ref}>
27+ <Card face={item.face} />
28+ <div className="nm-played-caption">{item.caption}</div>
29+ </div>
30+ );
31+}
32+
33+export function Center({ items, reveal }: { items: CenterCard[]; reveal: { face: Face; caption: string } | null }) {
34+ return (
35+ <div className="nm-center">
36+ <div className="nm-played-row">
37+ {items.map((it) => (
38+ <Played key={it.id} item={it} />
39+ ))}
40+ {reveal && (
41+ <div className="nm-played shown">
42+ <Card face={reveal.face} />
43+ <div className="nm-played-caption">{reveal.caption}</div>
44+ </div>
45+ )}
46+ </div>
47+ <div className="nm-discard" data-zone-anchor="discard" />
48+ </div>
49+ );
50+}
51+
52+/** Lines between seats and the words on them, drawn in the canvas's own coordinates. */
53+export function Lines({ lines, words }: { lines: Line[]; words: Word[] }) {
54+ const ref = useRef<SVGSVGElement>(null);
55+ const [, redraw] = useState(0);
56+ useEffect(() => redraw((x) => x + 1), [lines, words]);
57+ const svg = ref.current?.getBoundingClientRect();
58+ const s = scale();
59+ const at = (i: number) => {
60+ const c = center(`[data-seat-index="${i}"] .nm-avatar`) ?? center(`[data-seat-index="${i}"]`);
61+ return c && svg ? { x: (c.x - svg.left) / s, y: (c.y - svg.top) / s } : null;
62+ };
63+ return (
64+ <>
65+ {words.map((w) => {
66+ const c = at(w.seat);
67+ return c ? (
68+ <div key={w.id} className={`nm-cardeffect ${w.text === '杀' || w.text.endsWith('杀') ? 'sha' : ''}`} style={{ left: c.x, top: c.y }}>
69+ {w.text}
70+ </div>
71+ ) : null;
72+ })}
73+ <svg className="nm-lines" ref={ref}>
74+ {lines.map((l) => {
75+ const a = at(l.from);
76+ const b = at(l.to);
77+ if (!a || !b) return null;
78+ const len = Math.hypot(b.x - a.x, b.y - a.y);
79+ return (
80+ <g key={l.id} className={`nm-line ${l.kind}`} style={{ ['--len' as string]: `${len}` }}>
81+ <line x1={a.x} y1={a.y} x2={b.x} y2={b.y} strokeDasharray={len} />
82+ <circle cx={b.x} cy={b.y} r="6" />
83+ </g>
84+ );
85+ })}
86+ </svg>
87+ </>
88+ );
89+}
+68 −0 src/viewer/noname/CharSelect.tsx added View file
@@ -0,0 +1,68 @@
1+// Choosing a general, as 无名杀's 选将 dialog: the candidates as portrait cards with faction, HP and skills; pick one,
2+// then 确定. The move is the upstream's own (OverlaysLayer): 系统规则 · 选将 with the general's name.
3+import { useState } from 'react';
4+import { getCharacterMeta } from '../../../src/engine/data/character-meta';
5+import { getSkillDescription } from '../../../src/engine/skills/lifecycle';
6+import { displaySkillName } from '../../../src/client/utils/skillDisplay';
7+import type { ActionMsg } from '../../../src/client/types';
8+import { portrait, FACTION_KEY } from './art';
9+import { Hp, Timer } from './Seat';
10+
11+interface Props {
12+ candidates: Array<{ name: string; skills: string[] }>;
13+ target: number;
14+ mine: boolean;
15+ deadline: number | null;
16+ totalMs: number;
17+ onAction: (a: ActionMsg) => void;
18+}
19+
20+export function CharSelect({ candidates, target, mine, deadline, totalMs, onAction }: Props) {
21+ const [pick, setPick] = useState<string | null>(null);
22+ const [sent, setSent] = useState(false);
23+ if (sent || !mine) return <div className="nm-dialog-wait">等待其他角色选择武将…</div>;
24+ return (
25+ <div className="nm-dialog-mask">
26+ <div className="nm-dialog choose">
27+ <div className="nm-dialog-title">请选择武将</div>
28+ <div className="nm-choose-row">
29+ {candidates.map((c) => {
30+ const meta = getCharacterMeta(c.name);
31+ const fac = meta?.faction ?? '群';
32+ const img = portrait(c.name);
33+ return (
34+ <button key={c.name} className={`nm-choose ${FACTION_KEY[fac] ?? 'qun'}${pick === c.name ? ' selected' : ''}`} onClick={() => setPick(c.name)} onDoubleClick={() => setPick(c.name)}>
35+ <div className="nm-avatar" style={img ? { backgroundImage: `url(${img})` } : undefined} />
36+ <div className="nm-frame" />
37+ <div className={`nm-faction ${FACTION_KEY[fac] ?? 'qun'}`}>{fac}</div>
38+ <div className={`nm-name${c.name.length > 4 ? ' long' : ''}`}>{c.name}</div>
39+ {meta && <Hp hp={meta.maxHealth} max={meta.maxHealth} />}
40+ <div className="nm-choose-skills">
41+ {c.skills.map((s) => (
42+ <span key={s} title={getSkillDescription(s) ?? ''}>
43+ {displaySkillName(s)}
44+ </span>
45+ ))}
46+ </div>
47+ </button>
48+ );
49+ })}
50+ </div>
51+ <Timer deadline={deadline} totalMs={totalMs} />
52+ <div className="nm-control in-dialog">
53+ <button
54+ className="nm-btn ok"
55+ disabled={!pick}
56+ onClick={() => {
57+ if (!pick) return;
58+ setSent(true);
59+ onAction({ skillId: '系统规则', actionType: '选将', ownerId: target, params: { character: pick } });
60+ }}
61+ >
62+ 确定
63+ </button>
64+ </div>
65+ </div>
66+ </div>
67+ );
68+}
+118 −0 src/viewer/noname/Controls.tsx added View file
@@ -0,0 +1,118 @@
1+// The replay's controls in the top bar (step, play, speed, whose view), the live seat switch, and the end of a game as
2+// 无名杀's result dialog.
3+import type { GameView } from '../../../src/engine/types';
4+import type { UseReplayResult, ReplaySpeed } from '../../../src/client/hooks/useReplay';
5+import { ID_SHORT, ID_KEY } from './Seat';
6+import { portrait } from './art';
7+
8+export function ReplayBar({ r }: { r: UseReplayResult }) {
9+ return (
10+ <div className="nm-replay">
11+ <button className="nm-mini" onClick={() => r.goTo(0)} title="回到开局" disabled={r.step <= 0}>
12+ ⏮
13+ </button>
14+ <button className="nm-mini" onClick={r.prev} title="上一步" disabled={r.step <= 0}>
15+ ◀
16+ </button>
17+ <button className="nm-mini play" onClick={r.togglePlay} title={r.playing ? '暂停' : '播放'}>
18+ {r.playing ? '❚❚' : '▶'}
19+ </button>
20+ <button className="nm-mini" onClick={r.next} title="下一步" disabled={r.step >= r.total}>
21+ ▶▏
22+ </button>
23+ <input type="range" min={0} max={r.total} value={r.step} onChange={(e) => r.goTo(Number(e.target.value))} aria-label="进度" />
24+ <span className="nm-step">
25+ {r.step}/{r.total}
26+ </span>
27+ </div>
28+ );
29+}
30+
31+/** The replay's speed and whose view it shows (a seat's, or the spectator's). */
32+export function ReplayView({ r, names }: { r: UseReplayResult; names: string[] }) {
33+ return (
34+ <div className="nm-replay">
35+ <select value={r.speed} onChange={(e) => r.setSpeed(Number(e.target.value) as ReplaySpeed)} title="速度">
36+ {[0.5, 1, 2, 4].map((x) => (
37+ <option key={x} value={x}>
38+ {x}×
39+ </option>
40+ ))}
41+ </select>
42+ <select value={r.seat} onChange={(e) => r.setSeat(Number(e.target.value))} title="视角">
43+ {r.seats.map((s) => (
44+ <option key={s} value={s}>
45+ {s < 0 ? '旁观' : `${s + 1}号位 ${names[s] ?? ''}`}
46+ </option>
47+ ))}
48+ </select>
49+ </div>
50+ );
51+}
52+
53+/** The live seat switch, when this viewer controls more than one seat. */
54+export function SeatSwitch({ seats, seat, view, onPick }: { seats: string[]; seat?: string; view: GameView; onPick: (s: string) => void }) {
55+ if (seats.length < 2) return null;
56+ return (
57+ <div className="nm-replay">
58+ {seats.map((x) => (
59+ <button key={x} className={`nm-mini${x === seat ? ' on' : ''}`} onClick={() => onPick(x)}>
60+ {view.players[Number(x)]?.character || `${Number(x) + 1}号位`}
61+ </button>
62+ ))}
63+ </div>
64+ );
65+}
66+
67+const CAMP: Record<string, string> = { 主公: '主公', 忠臣: '主公', 反贼: '反贼', 内奸: '内奸' };
68+const COUNT: Record<number, [number, number]> = { 2: [0, 1], 3: [0, 1], 4: [1, 1], 5: [1, 2], 6: [1, 3], 7: [2, 3], 8: [2, 4] };
69+
70+/** Who won, from what the view shows at the end: the lord alive means the lord's side; the lord dead, the rebels, unless
71+ * the one left alive is the renegade (every loyalist and rebel is dead and shown). */
72+export function inferWinner(view: GameView): string {
73+ const lord = view.players.find((p) => p.identity === '主公');
74+ if (!lord) return '';
75+ if (lord.alive) return '主公';
76+ const alive = view.players.filter((p) => p.alive);
77+ const [zhong, fan] = COUNT[view.players.length] ?? [1, 2];
78+ const dead = (id: string) => view.players.filter((p) => !p.alive && p.identity === id).length;
79+ return alive.length === 1 && dead('忠臣') === zhong && dead('反贼') === fan ? '内奸' : '反贼';
80+}
81+
82+export function Result({ view, camp, identities, me, labels }: { view: GameView; camp: string; identities?: Record<string, string>; me: number; labels?: string[] }) {
83+ const idOf = (i: number) => identities?.[String(i)] || view.players[i]?.identity || '';
84+ const mine = me >= 0 ? CAMP[idOf(me)] : '';
85+ const title = !camp ? '游戏结束' : mine ? (mine === camp ? '游戏胜利' : '游戏失败') : `${camp === '主公' ? '主公、忠臣' : camp}获胜`;
86+ return (
87+ <div className="nm-dialog-mask result">
88+ <div className={`nm-dialog result ${mine && camp ? (mine === camp ? 'win' : 'lose') : ''}`}>
89+ <div className="nm-result-title">{title}</div>
90+ <table className="nm-result">
91+ <tbody>
92+ {view.players.map((p, i) => {
93+ const id = idOf(i);
94+ const img = portrait(p.character);
95+ return (
96+ <tr key={i} className={`${CAMP[id] === camp ? 'won' : ''}${p.alive ? '' : ' dead'}`}>
97+ <td>
98+ <span className="nm-result-face" style={img ? { backgroundImage: `url(${img})` } : undefined} />
99+ </td>
100+ <td className="nm-result-name">{p.character}</td>
101+ <td>{labels?.[i] ?? (p.name !== p.character ? p.name : '')}</td>
102+ <td>
103+ <span className={`nm-identity inline ${id ? ID_KEY[id] : 'unknown'}`}>
104+ {id ? ID_SHORT[id] : ''}
105+ </span>
106+ {id || '未知'}
107+ </td>
108+ <td>{p.alive ? '存活' : '阵亡'}</td>
109+ <td>{CAMP[id] === camp ? '胜' : id ? '负' : ''}</td>
110+ </tr>
111+ );
112+ })}
113+ </tbody>
114+ </table>
115+ </div>
116+ </div>
117+ );
118+}
+43 −0 src/viewer/noname/Log.tsx added View file
@@ -0,0 +1,43 @@
1+// The game log as 无名杀 writes its history: white lines, generals in blue, cards in yellow, no panel; its newest few
2+// lines, or more when opened.
3+import { useEffect, useMemo, useRef, useState } from 'react';
4+import type { GameView } from '../../../src/engine/types';
5+import art from './art.json';
6+
7+const CARDS = [...Object.keys(art.cards), '火杀', '雷杀'];
8+const esc = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
9+
10+export function Log({ view }: { view: GameView }) {
11+ const [open, setOpen] = useState(false);
12+ const ref = useRef<HTMLDivElement>(null);
13+ const lines = view.log.slice(open ? -80 : -4);
14+ const generals = view.players.map((p) => p.character).filter(Boolean).join('|');
15+ const re = useMemo(() => {
16+ const words = [...generals.split('|').filter(Boolean), ...CARDS].sort((a, b) => b.length - a.length);
17+ return new RegExp(`(${words.map(esc).join('|')})`, 'g');
18+ }, [generals]);
19+ const cards = useMemo(() => new Set(CARDS), []);
20+ useEffect(() => {
21+ if (ref.current) ref.current.scrollTop = ref.current.scrollHeight;
22+ }, [lines.length, open]);
23+ return (
24+ <div className={`nm-log${open ? ' open' : ''}`}>
25+ <button className="nm-log-toggle" onClick={() => setOpen(!open)} title={open ? '收起记录' : '展开记录'}>
26+ 记录
27+ </button>
28+ {lines.length > 0 && (
29+ <div className="nm-log-lines" ref={ref}>
30+ {lines.map((e, i) => {
31+ const p = view.players[e.player];
32+ return (
33+ <div key={view.log.length - lines.length + i} className="nm-log-line">
34+ {p && <span className="who">{p.character || p.name}</span>}
35+ {e.text.split(re).map((t, k) => (k % 2 ? <span key={k} className={cards.has(t) ? 'card' : 'who'}>{t}</span> : t))}
36+ </div>
37+ );
38+ })}
39+ </div>
40+ )}
41+ </div>
42+ );
43+}
+141 −0 src/viewer/noname/Me.tsx added View file
@@ -0,0 +1,141 @@
1+// Your seat along the bottom, as 无名杀's mobile layout: your general's portrait card at the left (name, faction, HP,
2+// identity, judgement area), your equipment beside it as five slots, your hand across the middle, your skills as
3+// buttons at the right. Which skills and equipment can be used now is the upstream's own logic (PlayerCardLarge and
4+// EquipColumn, followed here): their actions, activeWhen and variants, and distribute picking equipment.
5+import type { ReactNode } from 'react';
6+import type { GameView, Json } from '../../../src/engine/types';
7+import type { SkillActionDef } from '../../../src/client/skillActionRegistry';
8+import type { HpChangeNumber } from '../../../src/client/hooks/useAnimationState';
9+import { useGameView } from '../../../src/client/components/GameViewCtx';
10+import { isActiveAction, isFreePlayWindow, skillActionVariants } from '../../../src/client/utils/gameViewHelpers';
11+import { EQUIPMENT_SKILL_NAMES } from '../../../src/client/components/gameViewConstants';
12+import { LORD_SKILLS } from '../../../src/engine/data/character-meta';
13+import { DEFAULT_SKILLS as ENGINE_DEFAULT_SKILLS } from '../../../src/engine/atoms/选将';
14+import { getSkillDescription } from '../../../src/engine/skills/lifecycle';
15+import { useSkillDescReady } from '../../../src/client/hooks/useSkillDescReady';
16+import { displaySkillName } from '../../../src/client/utils/skillDisplay';
17+import { Portrait, Identity, SLOTS, seatState, equipName } from './Seat';
18+import { isRed } from './Card';
19+
20+const DEFAULT_SKILLS = new Set(ENGINE_DEFAULT_SKILLS);
21+type Player = GameView['players'][number];
22+
23+interface Props {
24+ player: Player;
25+ index: number;
26+ isCurrent: boolean;
27+ phase: string;
28+ spectating: boolean;
29+ onSkillAction: (action: SkillActionDef, extraParams?: Record<string, Json>) => void;
30+ onEquipClick: (cardId: string) => void;
31+ distCandidates: Set<string> | null;
32+ distSelected: Set<string>;
33+ isDistributeActive: boolean;
34+ targetable: boolean;
35+ selected: boolean;
36+ onTarget: () => void;
37+ damaged?: number;
38+ healed?: number;
39+ hpChange?: HpChangeNumber;
40+ timer: ReactNode;
41+ hand: ReactNode;
42+}
43+
44+export function Me(props: Props) {
45+ const { view, canOperate, skillActions } = useGameView();
46+ useSkillDescReady();
47+ const { player: p, index, isCurrent, phase, spectating, onSkillAction, onEquipClick, distCandidates, distSelected, isDistributeActive, targetable, selected, onTarget, damaged, healed, hpChange, timer, hand } = props;
48+ const actionCtx = { view, perspectiveIdx: index };
49+
50+ // Skills (PlayerCardLarge): the active ones as buttons, those of the free play window that can't be used now greyed,
51+ // the rest as labels.
52+ const isLord = p.identity === '主公';
53+ const visible = p.skills.filter((s) => !DEFAULT_SKILLS.has(s) && !EQUIPMENT_SKILL_NAMES.has(s) && (isLord || !LORD_SKILLS.has(s)));
54+ const triggerable = skillActions.filter(
55+ (a) =>
56+ a.prompt.type === 'confirm' ||
57+ a.prompt.type === 'chooseOption' ||
58+ a.prompt.type === 'choosePlayer' ||
59+ a.prompt.type === 'selectTarget' ||
60+ (a.prompt.type === 'useCardAndTarget' && !!a.transform) ||
61+ (a.prompt.type === 'useCard' && !!a.transform) ||
62+ a.prompt.type === 'distribute',
63+ );
64+ const isSkillActive = (a: SkillActionDef) => canOperate && isActiveAction(a, actionCtx);
65+ const inFreePlayWindow = canOperate && isFreePlayWindow({ isMyTurn: isCurrent, phase: view.phase, pending: view.pending });
66+ const skills = visible.flatMap((s) => {
67+ const btns = triggerable.filter((a) => a.skillId === s);
68+ const desc = getSkillDescription(s) ?? btns[0]?.prompt.title;
69+ const display = displaySkillName(s);
70+ const variants = btns.flatMap((a) => skillActionVariants(a).map((v) => ({ ...v, action: a, label: v.label || (btns.length > 1 ? a.label || a.actionType : '') })));
71+ const active = variants.filter((v) => isSkillActive(v.action));
72+ if (active.length)
73+ return active.map((v) => (
74+ <button key={v.label ? `${s}:${v.label}` : s} className={`nm-skill on${v.action.style === 'danger' ? ' danger' : ''}`} title={v.description ?? desc} onClick={() => onSkillAction(v.action, v.params)}>
75+ {v.label ? (v.label.startsWith(display) ? v.label : `${display}·${v.label}`) : display}
76+ </button>
77+ ));
78+ if (btns[0] && inFreePlayWindow)
79+ return [
80+ <button key={s} className="nm-skill" disabled title={p.turnUsage?.[`${s}/usedThisTurn`] ? '本回合已发动过(每回合限一次)' : (desc ?? '')}>
81+ {display}
82+ </button>,
83+ ];
84+ return [
85+ <span key={s} className="nm-skill passive" title={desc}>
86+ {display}
87+ </span>,
88+ ];
89+ });
90+
91+ // Equipment (EquipColumn): an equipment skill that can be used now, or a card distribute may pick, is clickable.
92+ const activeEquip = new Map<string, SkillActionDef>();
93+ for (const a of skillActions) if (EQUIPMENT_SKILL_NAMES.has(a.skillId) && canOperate && isActiveAction(a, actionCtx)) activeEquip.set(a.skillId, a);
94+ const equips = SLOTS.map(([slot]) => {
95+ const id = p.equipment[slot];
96+ const c = id ? view.cardMap[id] : undefined;
97+ if (!id) return <div key={slot} className="nm-myequip empty" title={slot} />;
98+ const skill = isDistributeActive ? undefined : activeEquip.get(c?.name ?? '');
99+ const cand = isDistributeActive && !!distCandidates?.has(id);
100+ const desc = c && EQUIPMENT_SKILL_NAMES.has(c.name) ? getSkillDescription(c.name) : c?.description;
101+ return (
102+ <div
103+ key={slot}
104+ className={`nm-myequip${skill ? ' usable' : ''}${cand ? ' candidate' : ''}${distSelected.has(id) ? ' picked' : ''}`}
105+ onClick={skill ? () => onSkillAction(skill) : cand ? () => onEquipClick(id) : undefined}
106+ title={`${c?.name ?? id}(${slot})${desc ? `\n${desc}` : ''}`}
107+ >
108+ <span className="nm-equip-name">{c ? equipName(slot, c.name) : id}</span>
109+ {c && (
110+ <span className={`nm-equip-info${isRed(c.suit) ? ' red' : ''}`}>
111+ {c.suit}
112+ {c.rank}
113+ </span>
114+ )}
115+ </div>
116+ );
117+ });
118+
119+ return (
120+ <div className={`nm-me${spectating ? ' spectating' : ''}`}>
121+ <div
122+ key={damaged ? `d${damaged}` : undefined}
123+ className={`nm-player mine ${seatState(p, { current: isCurrent, selectable: targetable, selected, damaged: !!damaged, healed: !!healed })}`}
124+ data-seat-index={index}
125+ data-player-name={p.name}
126+ onClick={onTarget}
127+ >
128+ <Portrait p={p} view={view} isCurrent={isCurrent} phase={phase} hpChange={hpChange}>
129+ <Identity p={p} mine />
130+ </Portrait>
131+ </div>
132+ <div className="nm-myequips">{equips}</div>
133+ <div className="nm-hand">
134+ {timer}
135+ {hand}
136+ </div>
137+ <div className="nm-skills">{skills}</div>
138+ <div className="nm-me-label">{spectating ? `旁观 · ${p.name}` : p.name}</div>
139+ </div>
140+ );
141+}
+210 −0 src/viewer/noname/Seat.tsx added View file
@@ -0,0 +1,210 @@
1+// Another player's seat, as 无名杀's portrait card: the general's 立绘 filling a framed card in the faction's colour,
2+// the name in vertical brush script, the faction badge, the identity at the top right (主公 shown, others ? until
3+// revealed), HP as 勾玉, the hand count, equipment as text rows along the bottom, the judgement area's tricks as small
4+// marks, 横置 chains, 翻面, dying and dead, the current turn's glow and its phase, and target highlighting.
5+import { useGameView } from '../../../src/client/components/GameViewCtx';
6+import { useCountdownFraction } from '../../../src/client/hooks/useCountdown';
7+import { getCharacterMeta } from '../../../src/engine/data/character-meta';
8+import type { GameView, EquipSlot } from '../../../src/engine/types';
9+import type { HpChangeNumber } from '../../../src/client/hooks/useAnimationState';
10+import type { CSSProperties, ReactNode } from 'react';
11+import { portrait, cardArt, FACTION_KEY } from './art';
12+import { isRed } from './Card';
13+
14+type Player = GameView['players'][number];
15+export const ID_SHORT: Record<string, string> = { 主公: '主', 忠臣: '忠', 反贼: '反', 内奸: '内' };
16+export const ID_KEY: Record<string, string> = { 主公: 'zhu', 忠臣: 'zhong', 反贼: 'fan', 内奸: 'nei' };
17+export const SLOTS: Array<[EquipSlot, string]> = [
18+ ['武器', '武'],
19+ ['防具', '防'],
20+ ['防御马', '+1'],
21+ ['进攻马', '-1'],
22+ ['宝物', '宝'],
23+];
24+const PHASE_SHORT: Record<string, string> = { 准备: '准备', 判定: '判定', 摸牌: '摸牌', 出牌: '出牌', 弃牌: '弃牌', 回合结束: '结束' };
25+
26+export function Timer({ deadline, totalMs }: { deadline: number | null; totalMs?: number }) {
27+ const fill = useCountdownFraction(deadline, totalMs || 15000);
28+ if (deadline == null) return null;
29+ return (
30+ <div className="nm-timer">
31+ <div className="nm-timer-fill" ref={fill} />
32+ </div>
33+ );
34+}
35+
36+/** HP as 无名杀 draws it: one 勾玉 per point, lost ones dark; green, then yellow, then red as it falls; a number past 5. */
37+export function Hp({ hp, max }: { hp: number; max: number }) {
38+ const level = hp > max / 2 ? 'high' : hp > max / 4 && hp > 1 ? 'mid' : 'low';
39+ if (max > 5)
40+ return (
41+ <div className={`nm-hp text ${level}`}>
42+ <i className="nm-jade" />
43+ <span>
44+ {Math.max(hp, 0)}/{max}
45+ </span>
46+ </div>
47+ );
48+ return (
49+ <div className={`nm-hp ${level}`}>
50+ {Array.from({ length: max }, (_, i) => (
51+ <i key={i} className={`nm-jade${i >= Math.max(hp, 0) ? ' lost' : ''}`} />
52+ ))}
53+ </div>
54+ );
55+}
56+
57+export function faction(p: Player): string {
58+ return p.faction ?? (p.character ? getCharacterMeta(p.character)?.faction : undefined) ?? '群';
59+}
60+
61+export const isChained = (p: Player) => p.marks.some((m) => m.id === 'chained');
62+export const isFlipped = (p: Player) => (p.tags ?? []).some((t) => t.endsWith('/翻面'));
63+
64+/** The flags every seat card shows the same way, mine or not. */
65+export function seatState(p: Player, extra: Record<string, boolean | undefined>): string {
66+ const f = FACTION_KEY[faction(p)] ?? 'qun';
67+ const on = { dead: !p.alive, dying: p.alive && p.health <= 0, chained: isChained(p), flipped: isFlipped(p), ...extra };
68+ return `${f} ${Object.entries(on)
69+ .filter(([, v]) => v)
70+ .map(([k]) => k)
71+ .join(' ')}`;
72+}
73+
74+export function Identity({ p, mine }: { p: Player; mine?: boolean }) {
75+ const id = p.identity;
76+ if (!id && !p.identityHidden && !mine) return null;
77+ return <div className={`nm-identity ${id ? ID_KEY[id] : 'unknown'}`} title={id ?? '身份未知'}>{id ? ID_SHORT[id] ?? id[0] : '?'}</div>;
78+}
79+
80+export function Judges({ p, view }: { p: Player; view: GameView }) {
81+ const ids = p.pendingTricks ?? [];
82+ if (!ids.length) return null;
83+ return (
84+ <div className="nm-judges">
85+ {ids.map((id) => {
86+ const c = view.cardMap[id];
87+ return (
88+ <span key={id} className="nm-judge" title={c ? `${c.name} ${c.suit}${c.rank}` : id}>
89+ {c && cardArt(c.name) && <i style={{ backgroundImage: `url(${cardArt(c.name)})` }} />}
90+ <b>{(c?.name ?? '?')[0]}</b>
91+ </span>
92+ );
93+ })}
94+ </div>
95+ );
96+}
97+
98+/** A horse's name as 无名杀 writes it: +1 horses with +, -1 horses with -. */
99+export const equipName = (slot: EquipSlot, name: string) => (slot === '防御马' ? `${name}+` : slot === '进攻马' ? `${name}-` : name);
100+
101+export function Equips({ p, view }: { p: Player; view: GameView }) {
102+ const rows = SLOTS.filter(([slot]) => p.equipment[slot]);
103+ if (!rows.length) return null;
104+ return (
105+ <div className="nm-equips">
106+ {rows.map(([slot, label]) => {
107+ const c = view.cardMap[p.equipment[slot]!];
108+ return (
109+ <div key={slot} className="nm-equip" title={c ? `${c.name}(${slot})${c.description ? `\n${c.description}` : ''}` : slot}>
110+ <span className="nm-equip-slot">{label}</span>
111+ <span className="nm-equip-name">{c ? equipName(slot, c.name) : slot}</span>
112+ {c && (
113+ <span className={`nm-equip-info${isRed(c.suit) ? ' red' : ''}`}>
114+ {c.suit}
115+ {c.rank}
116+ </span>
117+ )}
118+ </div>
119+ );
120+ })}
121+ </div>
122+ );
123+}
124+
125+export function HpFloat({ change }: { change?: HpChangeNumber }) {
126+ if (!change) return null;
127+ return (
128+ <div key={change.version} className={`nm-hpfloat ${change.kind}`}>
129+ {change.kind === 'heal' ? `+${change.amount}` : `-${change.amount}`}
130+ </div>
131+ );
132+}
133+
134+/** The 立绘 and what lies on it, shared by the others' seats and mine. */
135+export function Portrait({ p, view, isCurrent, phase, hpChange, children }: { p: Player; view: GameView; isCurrent: boolean; phase: string; hpChange?: HpChangeNumber; children?: ReactNode }) {
136+ const img = portrait(p.character);
137+ const fac = faction(p);
138+ const name = p.character || '';
139+ return (
140+ <>
141+ <div className="nm-avatar" style={img ? { backgroundImage: `url(${img})` } : undefined}>
142+ {!img && name && <span className="nm-avatar-none">{name}</span>}
143+ </div>
144+ <div className="nm-frame" />
145+ {name && <div className={`nm-faction ${FACTION_KEY[fac] ?? 'qun'}`}>{fac}</div>}
146+ {name && <div className={`nm-name${name.length > 4 ? ' long' : ''}`}>{name}</div>}
147+ {name && <Hp hp={p.health} max={p.maxHealth} />}
148+ <div className="nm-count" title={`手牌 ${p.handCount}`}>
149+ {p.handCount}
150+ </div>
151+ {children}
152+ <Judges p={p} view={view} />
153+ {isChained(p) && <div className="nm-chain" />}
154+ {isFlipped(p) && <div className="nm-flipped">翻面</div>}
155+ {p.alive && p.health <= 0 && <div className="nm-dying">濒死</div>}
156+ {!p.alive && <div className={`nm-dead ${p.identity ? ID_KEY[p.identity] : ''}`}>{p.identity ? <b>{p.identity}</b> : null}阵亡</div>}
157+ {isCurrent && p.alive && <div className="nm-phase-mark">{PHASE_SHORT[phase] ?? phase}</div>}
158+ <HpFloat change={hpChange} />
159+ </>
160+ );
161+}
162+
163+export interface SeatProps {
164+ player: Player;
165+ index: number;
166+ style: CSSProperties;
167+ isCurrent: boolean;
168+ phase: string;
169+ needsTarget: boolean;
170+ targetable: boolean;
171+ selected: boolean;
172+ onClick: () => void;
173+ damaged?: number;
174+ healed?: number;
175+ hpChange?: HpChangeNumber;
176+ deadline: number | null;
177+ totalMs?: number;
178+ distance: number | null;
179+ reason: string | null;
180+ /** Who sits there (a route, a bot, a person), when it is not just the general's name. */
181+ label?: string;
182+}
183+
184+export function Seat(props: SeatProps) {
185+ const { view } = useGameView();
186+ const { player: p, index, style, isCurrent, phase, needsTarget, targetable, selected, onClick, damaged, healed, hpChange, deadline, totalMs, distance, reason, label = p.name } = props;
187+ const clickable = needsTarget && p.alive && targetable;
188+ const cls = seatState(p, { current: isCurrent, selectable: clickable, selected, unselectable: needsTarget && p.alive && !targetable, damaged: !!damaged, healed: !!healed });
189+ return (
190+ <div
191+ key={damaged ? `d${damaged}` : undefined}
192+ className={`nm-seat${needsTarget && clickable ? ' pick' : ''}`}
193+ style={style}
194+ data-seat-index={index}
195+ data-player-name={p.name}
196+ onClick={() => clickable && onClick()}
197+ title={needsTarget && !targetable && reason ? `不可选择:${reason}` : undefined}
198+ >
199+ <div className={`nm-player ${cls}`}>
200+ <Portrait p={p} view={view} isCurrent={isCurrent} phase={phase} hpChange={hpChange}>
201+ <Identity p={p} />
202+ <Equips p={p} view={view} />
203+ {needsTarget && distance != null && p.alive && <div className="nm-distance">距{distance}</div>}
204+ </Portrait>
205+ </div>
206+ {label && label !== p.character && <div className="nm-seat-label">{label}</div>}
207+ <Timer deadline={deadline} totalMs={totalMs} />
208+ </div>
209+ );
210+}
+471 −0 src/viewer/noname/Table.tsx added View file
@@ -0,0 +1,471 @@
1+// The table, drawn as 无名杀 draws an identity game (its mobile layout and woodden theme): the other seats around an
2+// oval, each a portrait card; your seat along the bottom with your hand, equipment, skills and the 确定/取消/结束回合
3+// buttons; the cards just played in the middle; the log on the right. It renders one seat's view (view.viewer, or the
4+// spectator's), and everything it does goes through the upstream's own hooks and action building, as the upstream's
5+// GameView does (src/client/components/GameView.tsx, whose state and handlers this follows line for line): the same
6+// usePlayInteraction, the same prompts and the same messages, so a move made here is the move the upstream table makes.
7+import { useState, useCallback, useRef, useEffect, useMemo, type ReactNode } from 'react';
8+import type { GameView as EngineGameView, Card, Json, ViewEvent } from '../../../src/engine/types';
9+import { getAtomDef } from '../../../src/engine/core/atom';
10+import { viewSlashMax, viewSlashUsed } from '../../../src/engine/rules/action-active';
11+import { viewEffectiveDistance } from '../../../src/engine/rules/viewDistance';
12+import { useCountdownSeconds } from '../../../src/client/hooks/useCountdown';
13+import { AwaitingPrompt } from '../../../src/client/components/AwaitingPrompt';
14+import { HandArea } from '../../../src/client/components/HandArea';
15+import { GameViewProvider, type GameViewCtxValue } from '../../../src/client/components/GameViewCtx';
16+import { findUseActionForCard, hasUseEntry, isActiveAction, canShowCancelSelectionButton, canShowEndTurnButton } from '../../../src/client/utils/gameViewHelpers';
17+import { displaySkillName } from '../../../src/client/utils/skillDisplay';
18+import { useAnimationState } from '../../../src/client/hooks/useAnimationState';
19+import { useCardMoveAnimation } from '../../../src/client/hooks/useCardMoveAnimation';
20+import { useSkillActions } from '../../../src/client/hooks/useSkillActions';
21+import { usePendingState } from '../../../src/client/hooks/usePendingState';
22+import { useCharSelect } from '../../../src/client/hooks/useCharSelect';
23+import { useSeatOrder } from '../../../src/client/hooks/useSeatOrder';
24+import { useHandReorder } from '../../../src/client/hooks/useHandReorder';
25+import { usePlayInteraction } from '../../../src/client/hooks/usePlayInteraction';
26+import { useHotkeys } from '../../../src/client/hooks/useHotkeys';
27+import { useProcessingPicks } from '../../../src/client/hooks/useProcessingPicks';
28+import { useAutoSkipPrefs } from '../../../src/client/hooks/useAutoSkipPrefs';
29+import { useAutoSkip } from '../../../src/client/hooks/useAutoSkip';
30+import type { QueuedEvent } from '../../../src/client/hooks/useEventPlayback';
31+import type { ActionMsg } from '../../../src/client/types';
32+import { Seat, Timer } from './Seat';
33+import { Me } from './Me';
34+import { ActionBar } from './ActionBar';
35+import { CharSelect } from './CharSelect';
36+import { Center, Lines } from './Center';
37+import { Log } from './Log';
38+import { useFx } from './useFx';
39+
40+/** 弃牌超时兜底的保留优先级(as GameView: the engine's own 请求回应 onTimeout order). */
41+const DISCARD_KEEP_PRIORITY: Record<string, number> = { 桃: 0, 杀: 1, 闪: 2, 无懈可击: 3 };
42+const PHASE: Record<string, string> = { 准备: '准备阶段', 判定: '判定阶段', 摸牌: '摸牌阶段', 出牌: '出牌阶段', 弃牌: '弃牌阶段', 回合结束: '结束阶段' };
43+
44+/** Where the others sit, in % of the canvas: on an oval from your left (上家) over the top to your right (下家), as
45+ * 无名杀 seats 2 to 8 players; past five others the oval runs a little below the sides and the cards get smaller. */
46+export function ovalSpot(i: number, k: number): { x: number; y: number; scale: number } {
47+ const start = k === 1 ? 90 : k === 2 ? 150 : k >= 6 ? 200 : k === 5 ? 195 : 180;
48+ const a = k === 1 ? 90 : start - (i * (2 * start - 180)) / (k - 1);
49+ const r = (a * Math.PI) / 180;
50+ return { x: 50 + 41 * Math.cos(r), y: 52 - 33 * Math.sin(r), scale: k <= 4 ? 1 : k === 5 ? 0.9 : k === 6 ? 0.82 : 0.75 };
51+}
52+
53+interface Props {
54+ view: EngineGameView;
55+ onAction: (action: ActionMsg) => void;
56+ readOnly?: boolean;
57+ currentEvent?: QueuedEvent | null;
58+ ingestedEvents?: QueuedEvent[];
59+ /** The top bar's own controls: at the left (the replay's steps, the live seat switch) and at the right. */
60+ top?: ReactNode;
61+ side?: ReactNode;
62+ /** Shown over the table (the end of a game). */
63+ overlay?: ReactNode;
64+ /** Who sits in each seat (the replay's route and bot names), shown under the seats. */
65+ labels?: string[];
66+}
67+
68+export function Table({ view, onAction, readOnly = false, currentEvent, ingestedEvents, top, side, overlay, labels }: Props) {
69+ const perspectiveIdx = view.viewer >= 0 && view.viewer < view.players.length ? view.viewer : 0;
70+ const isSpectating = view.viewer < 0;
71+ const viewRef = useRef(view);
72+ viewRef.current = view;
73+
74+ const { skillActions } = useSkillActions(view, perspectiveIdx);
75+ const pendingState = usePendingState(view, perspectiveIdx, skillActions);
76+ const { pending, pendingTargetIdx, isPerspectiveAwaiting, isDiscardPhase, discardMin, discardMax, skippedBroadcast, markBroadcastSkipped, deadline, deadlineTotalMs, pendingRespondInfo, broadcastKey } = pendingState;
77+ const { prefs: autoSkipPrefs, toggleOptIn: toggleAutoSkip } = useAutoSkipPrefs();
78+ const { isCharSelectPending, charSelect } = useCharSelect(view, perspectiveIdx);
79+ const orderedPlayers = useSeatOrder(view, perspectiveIdx);
80+ const anim = useAnimationState(view, perspectiveIdx);
81+ useCardMoveAnimation(ingestedEvents ?? [], view);
82+ const fx = useFx(ingestedEvents, view);
83+
84+ // 展示 (火攻 and the like): the latest shown card stays until a move, a new show or the engine's 展示结束.
85+ const [revealEvent, setRevealEvent] = useState<ViewEvent | null>(null);
86+ useEffect(() => {
87+ const reveals = (ingestedEvents ?? []).filter((e) => e.event.type === '展示');
88+ if (reveals.length > 0) setRevealEvent(reveals[reveals.length - 1].event);
89+ if ((ingestedEvents ?? []).some((e) => e.event.type === '展示结束')) setRevealEvent(null);
90+ }, [ingestedEvents]);
91+
92+ const handListRef = useRef<HTMLDivElement>(null);
93+ const perspectivePlayer = view.players[perspectiveIdx];
94+ const perspectiveName = perspectivePlayer.name ?? `P${perspectiveIdx}`;
95+ const isMyTurn = view.currentPlayerIndex === perspectiveIdx;
96+ const currentPlayer = view.players[view.currentPlayerIndex];
97+ const currentPlayerName = currentPlayer.name;
98+ const perspectiveHand: Card[] = perspectivePlayer.hand ?? [];
99+ const { orderedHand, handleDragStart, handleDrop } = useHandReorder(perspectiveHand, undefined);
100+ const canOperate = !readOnly;
101+
102+ const send = useCallback(
103+ (skillId: string, actionType: string, params: Record<string, Json>, preceding?: Array<{ skillId: string; actionType: string; params: Record<string, Json> }>) => {
104+ setRevealEvent(null);
105+ onAction({ skillId, actionType, ownerId: perspectiveIdx, params, preceding });
106+ },
107+ [onAction, perspectiveIdx],
108+ );
109+ const processingPicks = useProcessingPicks(view);
110+ useAutoSkip({ view, perspectiveIdx, skillActions, pendingRespondInfo, prefs: autoSkipPrefs, canOperate, isPerspectiveAwaiting, markBroadcastSkipped, broadcastKey, send });
111+ const play = usePlayInteraction(isMyTurn, canOperate, {
112+ view, perspectiveIdx, perspectiveHand, skillActions, pending, isDiscardPhase, discardMin, discardMax, isPerspectiveAwaiting, pendingRespondInfo, broadcastKey, markBroadcastSkipped, pendingTargetIdx, send, handListRef,
113+ });
114+ const {
115+ selectedCardId, selectedCard, selectedTarget, selectedKillTarget, selectedMultiTargets, selectedForDiscard, transformMode, transformWrapperName, activeDistribute, isDistributeActive,
116+ distTargetName, selectedRespondCardId, respondTargetName, respondNeedsTarget, respondTargetReady, playButtonState, playRules, handleCardClick, handlePlayCard, handleTargetClick,
117+ handleSkillAction, isRespondTransformContext, handleRespond, handlePlayRespond, handleEndTurn, isTargetable, skillTargetMode, clearRespondSelection, handleCardDoubleClick,
118+ handleTransformPlay, handleConfirmDiscard, handleDistSubmit, transformSubmit, distSubmit, cancelTransform, cancelSelection, distSelected,
119+ } = play;
120+
121+ const isMyAwaiting = isPerspectiveAwaiting && canOperate;
122+ const broadcastSkipped = pendingTargetIdx < 0 && skippedBroadcast.has(broadcastKey);
123+ const canDiscardClick = isDiscardPhase && isPerspectiveAwaiting && canOperate;
124+ const canPlayHandCard = useCallback(
125+ (card: Card) => {
126+ const useAction = findUseActionForCard(skillActions, card);
127+ return isMyTurn && canOperate && hasUseEntry(card) && (!useAction || isActiveAction(useAction, { view, perspectiveIdx }));
128+ },
129+ [isMyTurn, canOperate, skillActions, view, perspectiveIdx],
130+ );
131+ const isRespondableCard = useCallback((card: Card) => !isDistributeActive && isMyAwaiting && !!pendingRespondInfo?.cardFilter?.(card), [isDistributeActive, isMyAwaiting, pendingRespondInfo]);
132+ const handDisabledReason = useCallback(
133+ (card: Card): string | null => {
134+ if (canPlayHandCard(card)) return null;
135+ if (!isMyTurn || view.phase !== '出牌' || pending) return null;
136+ if (!hasUseEntry(card)) return '仅用于响应,出牌阶段不能主动使用';
137+ const useAction = findUseActionForCard(skillActions, card);
138+ if (useAction && isActiveAction(useAction, { view, perspectiveIdx })) return null;
139+ if (card.name === '杀') {
140+ const max = viewSlashMax(view, perspectiveIdx);
141+ const used = viewSlashUsed(view, perspectiveIdx);
142+ if (Number.isFinite(max) && used >= max) return `本回合杀次数已用完(${used}/${max})`;
143+ return '本回合不能使用杀(次数已尽或被限制)';
144+ }
145+ if (card.name === '桃' && perspectivePlayer.health >= perspectivePlayer.maxHealth) return '体力已满,不需要使用桃';
146+ if (card.name === '酒' && perspectivePlayer.turnUsage?.['酒/usedThisTurn']) return '本回合已使用过酒';
147+ return '当前不满足使用条件(阶段/次数/目标限制)';
148+ },
149+ [canPlayHandCard, isMyTurn, view, pending, skillActions, perspectiveIdx, perspectivePlayer],
150+ );
151+ const countdownSec = useCountdownSeconds(deadline);
152+ const discardFallbackIds = useMemo(() => {
153+ if (!isDiscardPhase || !isPerspectiveAwaiting) return null;
154+ if (countdownSec == null || countdownSec > 5) return null;
155+ if (selectedForDiscard.length >= discardMin) return null;
156+ const sorted = [...perspectiveHand].sort((a, b) => (DISCARD_KEEP_PRIORITY[b.name] ?? 9) - (DISCARD_KEEP_PRIORITY[a.name] ?? 9));
157+ return new Set(sorted.slice(0, discardMin).map((c) => c.id));
158+ }, [isDiscardPhase, isPerspectiveAwaiting, countdownSec, selectedForDiscard.length, discardMin, perspectiveHand]);
159+ const seatTargetInfo = useCallback(
160+ (idx: number): { distance: number | null; reason: string | null } => {
161+ const empty = { distance: null, reason: null };
162+ const player = view.players[idx];
163+ if (!player) return empty;
164+ const distance = viewEffectiveDistance(view.players, perspectiveIdx, idx);
165+ if (!Number.isFinite(distance)) return empty;
166+ if (!player.alive) return { distance, reason: '已阵亡' };
167+ if (isTargetable(idx)) return { distance, reason: null };
168+ if (idx === perspectiveIdx) return { distance, reason: '不能选择自己' };
169+ if (selectedCard?.name === '杀' || isRespondTransformContext) {
170+ const range = view.players[perspectiveIdx]?.distanceVars?.attackRange ?? 1;
171+ if (distance > range) return { distance, reason: `距离 ${distance},超出攻击范围 ${range}` };
172+ }
173+ return { distance, reason: '不满足目标条件' };
174+ },
175+ [view, perspectiveIdx, isTargetable, selectedCard, isRespondTransformContext],
176+ );
177+ const handleEquipCardClick = useCallback(
178+ (cardId: string) => {
179+ const card = viewRef.current.cardMap[cardId];
180+ if (card) handleCardClick(card);
181+ },
182+ [handleCardClick],
183+ );
184+ const isPlayingFlipAnim =
185+ !!currentEvent &&
186+ (() => {
187+ const t = (currentEvent.event as { atomType?: string; type?: string }).atomType ?? currentEvent.event.type;
188+ try {
189+ return getAtomDef(t)?.effect?.animation === 'flip';
190+ } catch {
191+ return false;
192+ }
193+ })();
194+ const showEndTurn = canShowEndTurnButton({ canOperate, isMyTurn, phase: view.phase, pending });
195+ const showCancelSelection = canShowCancelSelectionButton({ selectedCardId, isMyTurn, phase: view.phase, pending });
196+ const isRespondPending = isMyAwaiting && !isDiscardPhase && !broadcastSkipped && (pending?.prompt?.type === 'useCard' || pending?.prompt?.type === 'useCardAndTarget');
197+ const respondCandidateCount = useMemo(() => {
198+ if (!isRespondPending || !pendingRespondInfo?.cardFilter) return null;
199+ return perspectiveHand.filter(pendingRespondInfo.cardFilter).length;
200+ }, [isRespondPending, pendingRespondInfo, perspectiveHand]);
201+
202+ useHotkeys(
203+ readOnly
204+ ? {}
205+ : {
206+ enter: () => {
207+ if (transformMode) {
208+ if (transformSubmit?.canSubmit) handleTransformPlay(transformSubmit.needsTarget ? selectedTarget! : '');
209+ return;
210+ }
211+ if (isRespondPending) {
212+ if (selectedRespondCardId && respondTargetReady) handlePlayRespond();
213+ return;
214+ }
215+ if (isDiscardPhase && isPerspectiveAwaiting) {
216+ if (selectedForDiscard.length >= discardMin && selectedForDiscard.length <= discardMax) handleConfirmDiscard();
217+ return;
218+ }
219+ if (isDistributeActive) {
220+ if (distSubmit?.canSubmit) handleDistSubmit();
221+ return;
222+ }
223+ if (playButtonState?.canPlay) handlePlayCard();
224+ },
225+ escape: () => {
226+ if (transformMode) cancelTransform();
227+ else if (selectedRespondCardId || respondTargetName) clearRespondSelection();
228+ else if (showCancelSelection || skillTargetMode) cancelSelection();
229+ },
230+ space: (e) => {
231+ if (isRespondPending) {
232+ e.preventDefault();
233+ handleRespond();
234+ }
235+ },
236+ e: () => {
237+ if (showEndTurn) handleEndTurn();
238+ },
239+ ...Object.fromEntries(
240+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((n): [string, () => void] => [
241+ String(n),
242+ () => {
243+ const card = perspectiveHand[n === 0 ? 9 : n - 1];
244+ if (!card) return;
245+ const inFreePlay = isMyTurn && view.phase === '出牌' && !pending;
246+ const transformActive = !!transformMode && (isMyTurn || isRespondTransformContext);
247+ if ((inFreePlay && canPlayHandCard(card)) || isRespondableCard(card) || canDiscardClick || transformActive || isDistributeActive) handleCardClick(card);
248+ },
249+ ]),
250+ ),
251+ },
252+ );
253+
254+ const selectedNeedsTarget = (!!playRules && playRules.needsTarget) || (isDistributeActive && !!activeDistribute?.externalTargetSelection) || respondNeedsTarget || skillTargetMode;
255+ const selectedTargetNames =
256+ isDistributeActive && activeDistribute?.externalTargetSelection
257+ ? distTargetName
258+ ? [distTargetName]
259+ : []
260+ : playRules?.hasSlots
261+ ? [selectedTarget, selectedKillTarget].filter((x): x is string => !!x)
262+ : playRules?.multiTarget
263+ ? selectedMultiTargets
264+ : respondNeedsTarget
265+ ? respondTargetName
266+ ? [respondTargetName]
267+ : []
268+ : selectedTarget
269+ ? [selectedTarget]
270+ : [];
271+ const selfTargetable = canOperate && selectedNeedsTarget && isTargetable(perspectiveIdx);
272+
273+ const ctxValue = useMemo<GameViewCtxValue>(
274+ () => ({ view, perspectiveIdx, perspectiveName, isSpectating, canOperate, currentPlayerName, skillActions, send }),
275+ [view, perspectiveIdx, perspectiveName, isSpectating, canOperate, currentPlayerName, skillActions, send],
276+ );
277+
278+ /** A seat's countdown: the pending ask is to it, or to everyone alive (无懈可击). */
279+ const seatDeadline = (idx: number): number | null => {
280+ if (isPlayingFlipAnim || !view.pending) return null;
281+ if (broadcastSkipped && idx === perspectiveIdx && view.pending.target < 0) return null;
282+ if (view.pending.target < 0) return view.players[idx]?.alive ? (view.pending.deadline ?? null) : null;
283+ return view.pending.target === idx ? (view.pending.deadline ?? null) : null;
284+ };
285+ const others = orderedPlayers.slice(1);
286+ const showPrompt = canOperate && isPerspectiveAwaiting && pending && !isDiscardPhase && !isPlayingFlipAnim && pending.atom?.type !== '选将询问' && pending.prompt.type !== 'distribute';
287+ const reveal = revealEvent?.card as { name: string; suit: string; rank: string } | undefined;
288+ const deck = view.zones?.deckCount ?? 0;
289+
290+ return (
291+ <GameViewProvider value={ctxValue}>
292+ <Scaler>
293+ <div className={`nm-arena${isSpectating ? ' spectating' : ''}${readOnly ? ' readonly' : ''}`}>
294+ <div className="nm-topbar">
295+ <div className="nm-pile" data-zone-anchor="deck">
296+ <span>剩余</span>
297+ <b>{deck}</b>
298+ <span>张</span>
299+ </div>
300+ <div className="nm-round">
301+ <span className="nm-discards">弃牌<b>{view.zones?.discardPileCount ?? 0}</b></span>第<b>{view.turn?.round ?? 1}</b>轮 <span className="nm-turn-of">{currentPlayer.character || currentPlayerName}</span>
302+ <span className="nm-phase">{PHASE[view.phase] ?? view.phase}</span>
303+ </div>
304+ <div className="nm-top-slot">{top}</div>
305+ {side && <div className="nm-top-side">{side}</div>}
306+ </div>
307+
308+ {others.map((player, i) => {
309+ const idx = view.players.findIndex((p) => p.name === player.name);
310+ const { x, y, scale } = ovalSpot(i, others.length);
311+ const info = selectedNeedsTarget ? seatTargetInfo(idx) : { distance: null, reason: null };
312+ return (
313+ <Seat
314+ key={player.name}
315+ player={player}
316+ index={idx}
317+ style={{ left: `${x}%`, top: `${y}%`, ['--seat-scale' as string]: scale }}
318+ isCurrent={idx === view.currentPlayerIndex}
319+ phase={view.phase}
320+ needsTarget={selectedNeedsTarget}
321+ targetable={isTargetable(idx)}
322+ selected={selectedTargetNames.includes(player.name)}
323+ onClick={() => handleTargetClick(player.name)}
324+ damaged={anim.damageFlashIndices.get(idx)}
325+ healed={anim.healFlashIndices.get(idx)}
326+ hpChange={anim.hpChangeNumbers.get(idx)}
327+ deadline={seatDeadline(idx)}
328+ totalMs={view.pending?.totalMs}
329+ distance={info.distance}
330+ reason={info.reason}
331+ label={labels?.[idx]}
332+ />
333+ );
334+ })}
335+
336+ <Center items={fx.center} reveal={reveal ? { face: reveal, caption: `${view.players[revealEvent!.player as number]?.character ?? ''} 展示` } : null} />
337+ <Lines lines={fx.lines} words={fx.words} />
338+
339+ <div className="nm-dock">
340+ {showPrompt && (
341+ <AwaitingPrompt
342+ pending={pending}
343+ pendingTargetIdx={pendingTargetIdx}
344+ perspectiveHand={perspectiveHand}
345+ pendingRespondInfo={pendingRespondInfo}
346+ broadcastKey={broadcastKey}
347+ skippedBroadcast={skippedBroadcast}
348+ processingPicks={processingPicks}
349+ autoSkipPrefs={autoSkipPrefs}
350+ onToggleAutoSkip={toggleAutoSkip}
351+ />
352+ )}
353+ {canOperate && isDiscardPhase && isPerspectiveAwaiting && (
354+ <div className="nm-tip">
355+ 请弃置 <b>{discardMin === discardMax ? discardMin : `${discardMin}~${discardMax}`}</b> 张手牌(已选 {selectedForDiscard.length})
356+ </div>
357+ )}
358+ {canOperate && isMyTurn && view.phase === '出牌' && !pending && !selectedCardId && !transformMode && !skillTargetMode && <div className="nm-tip">出牌阶段,请选择要使用的牌</div>}
359+ {canOperate && selectedCardId && selectedNeedsTarget && !selectedTargetNames.length && <div className="nm-tip">请选择目标</div>}
360+ {transformMode && (
361+ <div className="nm-tip">
362+ {displaySkillName(transformMode.skillId)}:选{transformMode.minCards > 1 ? `${transformMode.minCards}张牌` : '一张牌'}当【{transformWrapperName ?? transformMode.wrapperName}】
363+ {transformMode.minCards > 1 ? `(${transformMode.selectedCardIds.length}/${transformMode.maxCards})` : ''}
364+ </div>
365+ )}
366+ {canOperate && (
367+ <ActionBar
368+ play={play}
369+ pending={pending}
370+ isRespondPending={isRespondPending}
371+ respondCandidateCount={respondCandidateCount}
372+ showCancelSelection={showCancelSelection}
373+ showEndTurn={showEndTurn}
374+ isDiscardPhase={isDiscardPhase}
375+ isPerspectiveAwaiting={isPerspectiveAwaiting}
376+ discardMin={discardMin}
377+ discardMax={discardMax}
378+ />
379+ )}
380+ </div>
381+
382+ <Me
383+ player={perspectivePlayer}
384+ index={perspectiveIdx}
385+ isCurrent={isMyTurn}
386+ phase={view.phase}
387+ spectating={isSpectating}
388+ onSkillAction={handleSkillAction}
389+ onEquipClick={handleEquipCardClick}
390+ distCandidates={activeDistribute ? new Set(activeDistribute.cardIds) : null}
391+ distSelected={distSelected}
392+ isDistributeActive={isDistributeActive}
393+ targetable={selfTargetable}
394+ selected={selectedTargetNames.includes(perspectiveName)}
395+ onTarget={() => selfTargetable && handleTargetClick(perspectiveName)}
396+ damaged={anim.damageFlashIndices.get(perspectiveIdx)}
397+ healed={anim.healFlashIndices.get(perspectiveIdx)}
398+ hpChange={anim.hpChangeNumbers.get(perspectiveIdx)}
399+ timer={(isPerspectiveAwaiting || (isMyTurn && view.phase === '出牌')) && !broadcastSkipped && !readOnly && !isPlayingFlipAnim ? <Timer deadline={deadline} totalMs={deadlineTotalMs} /> : null}
400+ hand={
401+ isSpectating ? (
402+ <div className="nm-backs">
403+ {Array.from({ length: Math.min(perspectivePlayer.handCount, 20) }, (_, i) => (
404+ <div key={i} className="nm-card back" />
405+ ))}
406+ </div>
407+ ) : (
408+ <HandArea
409+ play={play}
410+ phase={view.phase}
411+ isSpectating={isSpectating}
412+ perspectiveHand={perspectiveHand}
413+ spectatorHandCount={perspectivePlayer.handCount}
414+ handListRef={handListRef}
415+ orderedHand={orderedHand}
416+ handleDragStart={handleDragStart}
417+ handleDrop={handleDrop}
418+ canPlayHandCard={canPlayHandCard}
419+ isRespondableCard={isRespondableCard}
420+ canDiscardClick={canDiscardClick}
421+ disabledReason={handDisabledReason}
422+ onCardDoubleClick={handleCardDoubleClick}
423+ timeoutFallbackIds={discardFallbackIds}
424+ isMyAwaiting={isMyAwaiting}
425+ isMyTurn={isMyTurn}
426+ />
427+ )
428+ }
429+ />
430+
431+ <Log view={view} />
432+ {isCharSelectPending && charSelect && charSelect.target >= 0 && !readOnly && (
433+ <CharSelect candidates={charSelect.candidates} target={charSelect.target} mine={charSelect.target === perspectiveIdx} deadline={charSelect.pending?.deadline ?? null} totalMs={charSelect.pending?.totalMs ?? 60000} onAction={onAction} />
434+ )}
435+ {overlay}
436+ </div>
437+ </Scaler>
438+ </GameViewProvider>
439+ );
440+}
441+
442+const DESIGN_H = 720;
443+const MIN_W = 1180;
444+
445+/** The canvas is drawn for a 720 px high frame at least 1180 wide and scaled to fit the frame, filling it. */
446+function Scaler({ children }: { children: ReactNode }) {
447+ const ref = useRef<HTMLDivElement>(null);
448+ const [m, setM] = useState({ w: MIN_W, h: DESIGN_H, s: 1 });
449+ useEffect(() => {
450+ const el = ref.current!;
451+ const update = () => {
452+ const W = el.clientWidth;
453+ const H = el.clientHeight;
454+ if (!W || !H) return;
455+ const s = Math.min(H / DESIGN_H, W / MIN_W);
456+ setM({ w: W / s, h: H / s, s });
457+ document.documentElement.style.setProperty('--nm-scale', String(s));
458+ };
459+ update();
460+ const ro = new ResizeObserver(update);
461+ ro.observe(el);
462+ return () => ro.disconnect();
463+ }, []);
464+ return (
465+ <div className="nm-scaler" ref={ref}>
466+ <div className="nm-canvas" style={{ width: m.w, height: m.h, transform: `scale(${m.s})`, ['--gv-scale' as string]: String(m.s) }}>
467+ {children}
468+ </div>
469+ </div>
470+ );
471+}
+213 −0 src/viewer/noname/art.json added View file
@@ -0,0 +1,213 @@
1+{
2+ "source": "libnoname/noname 90b58bb9934edb1712fd187a80c8323b7aeabaf3: apps/core/image/character/<id>.jpg and apps/core/image/card/<id>.png",
3+ "generals": {
4+ "曹操": "caocao",
5+ "司马懿": "simayi",
6+ "夏侯惇": "xiahoudun",
7+ "张辽": "zhangliao",
8+ "许褚": "xuzhu",
9+ "郭嘉": "guojia",
10+ "甄姬": "zhenji",
11+ "夏侯渊": "re_xiahouyuan",
12+ "曹仁": "old_caoren",
13+ "荀彧": "xunyu",
14+ "典韦": "dianwei",
15+ "曹丕": "caopi",
16+ "徐晃": "re_xuhuang",
17+ "张郃": "zhanghe",
18+ "邓艾": "dengai",
19+ "界曹操": "re_caocao",
20+ "界司马懿": "re_simayi",
21+ "界夏侯惇": "re_xiahoudun",
22+ "界张辽": "re_zhangliao",
23+ "界许褚": "re_xuzhu",
24+ "界郭嘉": "re_guojia",
25+ "界甄姬": "re_zhenji",
26+ "界夏侯渊": "ol_xiahouyuan",
27+ "界曹仁": "caoren",
28+ "界荀彧": "ol_xunyu",
29+ "界典韦": "ol_dianwei",
30+ "界曹丕": "re_caopi",
31+ "界徐晃": "ol_xuhuang",
32+ "界张郃": "re_zhanghe",
33+ "界邓艾": "ol_dengai",
34+ "界于禁": "yujin_yujin",
35+ "界张春华": "re_zhangchunhua",
36+ "界曹冲": "re_caochong",
37+ "界曹彰": "re_caozhang",
38+ "界曹植": "dc_caozhi",
39+ "界李典": "re_lidian",
40+ "界王异": "re_wangyi",
41+ "界郭淮": "re_guohuai",
42+ "界郭皇后": "re_guohuanghou",
43+ "毌丘俭": "guanqiujian",
44+ "王基": "wangji",
45+ "蒯越蒯良": "kuailiangkuaiyue",
46+ "郝昭": "haozhao",
47+ "刘备": "liubei",
48+ "界刘备": "re_liubei",
49+ "关羽": "guanyu",
50+ "界关羽": "re_guanyu",
51+ "张飞": "zhangfei",
52+ "界张飞": "re_zhangfei",
53+ "赵云": "zhaoyun",
54+ "界赵云": "re_zhaoyun",
55+ "黄月英": "huangyueying",
56+ "界黄月英": "re_huangyueying",
57+ "马超": "machao",
58+ "界马超": "re_machao",
59+ "界马岱": "re_madai",
60+ "黄忠": "re_huangzhong",
61+ "界黄忠": "ol_huangzhong",
62+ "魏延": "re_weiyan",
63+ "界魏延": "ol_weiyan",
64+ "卧龙诸葛": "sp_zhugeliang",
65+ "界卧龙诸葛": "ol_sp_zhugeliang",
66+ "诸葛亮": "zhugeliang",
67+ "界诸葛亮": "re_zhugeliang",
68+ "庞统": "pangtong",
69+ "界庞统": "ol_pangtong",
70+ "孟获": "menghuo",
71+ "界孟获": "re_menghuo",
72+ "祝融": "zhurong",
73+ "界祝融": "ol_zhurong",
74+ "姜维": "jiangwei",
75+ "界姜维": "ol_jiangwei",
76+ "刘禅": "liushan",
77+ "界刘禅": "ol_liushan",
78+ "界关兴张苞": "re_guanzhang",
79+ "界夏侯氏": "re_xiahoushi",
80+ "界廖化": "re_liaohua",
81+ "界张松": "re_zhangsong",
82+ "界徐庶": "re_xushu",
83+ "界法正": "re_fazheng",
84+ "界简雍": "re_jianyong",
85+ "王平": "wangping",
86+ "诸葛瞻": "zhugezhan",
87+ "陈到": "chendao",
88+ "卧龙诸葛亮": "sp_zhugeliang",
89+ "严颜": "yanyan",
90+ "孙权": "sunquan",
91+ "界孙权": "re_sunquan",
92+ "甘宁": "ganning",
93+ "界甘宁": "re_ganning",
94+ "吕蒙": "lvmeng",
95+ "界吕蒙": "re_lvmeng",
96+ "黄盖": "huanggai",
97+ "界黄盖": "re_huanggai",
98+ "周瑜": "zhouyu",
99+ "界周瑜": "re_zhouyu",
100+ "大乔": "daqiao",
101+ "界大乔": "re_daqiao",
102+ "陆逊": "luxun",
103+ "界陆逊": "re_luxun",
104+ "孙尚香": "sunshangxiang",
105+ "界孙尚香": "re_sunshangxiang",
106+ "小乔": "xiaoqiao",
107+ "界小乔": "ol_xiaoqiao",
108+ "周泰": "old_zhoutai",
109+ "界周泰": "zhoutai",
110+ "太史慈": "taishici",
111+ "界太史慈": "re_taishici",
112+ "鲁肃": "re_lusu",
113+ "界鲁肃": "ol_lusu",
114+ "孙坚": "sunjian",
115+ "界孙坚": "ol_sunjian",
116+ "孙策": "sunce",
117+ "界孙策": "re_sunce",
118+ "张昭张纮": "zhangzhang",
119+ "界张昭张纮": "ol_zhangzhang",
120+ "界凌统": "xin_lingtong",
121+ "界吴国太": "xin_wuguotai",
122+ "界徐盛": "xin_xusheng",
123+ "界程普": "re_chengpu",
124+ "界虞翻": "xin_yufan",
125+ "界韩当": "xin_handang",
126+ "陆抗": "lukang",
127+ "陆绩": "luji",
128+ "张昭张弘": "zhangzhang",
129+ "周妃": "zhoufei",
130+ "孙亮": "sunliang",
131+ "华佗": "huatuo",
132+ "吕布": "lvbu",
133+ "貂蝉": "diaochan",
134+ "界貂蝉": "re_diaochan",
135+ "张角": "sp_zhangjiao",
136+ "于吉": "re_yuji",
137+ "界于吉": "xin_yuji",
138+ "袁绍": "re_yuanshao",
139+ "界袁绍": "ol_yuanshao",
140+ "庞德": "re_pangde",
141+ "界庞德": "ol_pangde",
142+ "颜良文丑": "yanwen",
143+ "界颜良文丑": "ol_yanwen",
144+ "董卓": "dongzhuo",
145+ "界董卓": "ol_dongzhuo",
146+ "贾诩": "jiaxu",
147+ "界贾诩": "re_jiaxu",
148+ "左慈": "zuoci",
149+ "蔡文姬": "caiwenji",
150+ "界蔡文姬": "ol_caiwenji",
151+ "界伏皇后": "re_fuhuanghou",
152+ "界公孙瓒": "re_gongsunzan",
153+ "界刘表": "xin_liubiao",
154+ "界华佗": "re_huatuo",
155+ "界华雄": "re_huaxiong",
156+ "界吕布": "re_lvbu",
157+ "界左慈": "re_zuoci",
158+ "界张角": "re_zhangjiao",
159+ "界李儒": "dc_liru",
160+ "界沮授": "re_jushou",
161+ "界蔡夫人": "re_caifuren",
162+ "界陈宫": "re_chengong",
163+ "界高顺": "xin_gaoshun",
164+ "华雄": "huaxiong",
165+ "袁术": "re_yuanshu",
166+ "卢植": "yl_luzhi",
167+ "张绣": "zhangxiu",
168+ "许攸": "xuyou"
169+ },
170+ "cards": {
171+ "万箭齐发": "wanjian",
172+ "丈八蛇矛": "zhangba",
173+ "乐不思蜀": "lebu",
174+ "五谷丰登": "wugu",
175+ "仁王盾": "renwang",
176+ "借刀杀人": "jiedao",
177+ "八卦阵": "bagua",
178+ "兵粮寸断": "bingliang",
179+ "决斗": "juedou",
180+ "南蛮入侵": "nanman",
181+ "古锭刀": "guding",
182+ "大宛": "dawan",
183+ "寒冰剑": "hanbing",
184+ "方天画戟": "fangtian",
185+ "无中生有": "wuzhong",
186+ "无懈可击": "wuxie",
187+ "朱雀羽扇": "zhuque",
188+ "杀": "sha",
189+ "桃": "tao",
190+ "桃园结义": "taoyuan",
191+ "火攻": "huogong",
192+ "爪黄飞电": "zhuahuang",
193+ "白银狮子": "baiyin",
194+ "的卢": "dilu",
195+ "紫骍": "zixin",
196+ "绝影": "jueying",
197+ "藤甲": "tengjia",
198+ "诸葛连弩": "zhuge",
199+ "贯石斧": "guanshi",
200+ "赤兔": "chitu",
201+ "过河拆桥": "guohe",
202+ "酒": "jiu",
203+ "铁索连环": "tiesuo",
204+ "闪": "shan",
205+ "闪电": "shandian",
206+ "雌雄双股剑": "cixiong",
207+ "青釭剑": "qinggang",
208+ "青龙偃月刀": "qinglong",
209+ "顺手牵羊": "shunshou",
210+ "骅骝": "hualiu",
211+ "麒麟弓": "qilin"
212+ }
213+}
+14 −0 src/viewer/noname/art.ts added View file
@@ -0,0 +1,14 @@
1+// The art pack (viewer/art/, built by src/art.py from 无名杀's files): which picture each general and each card of the
2+// upstream engine gets, as data in art.json (general → 无名杀 character id, card → 无名杀 card id). Anything not in it
3+// falls back to a drawn face: the faction's colour and the name for a general, the name for a card.
4+import art from './art.json';
5+
6+const GENERALS: Record<string, string> = art.generals;
7+const CARDS: Record<string, string> = art.cards;
8+
9+export const portrait = (name?: string): string | null => (name && GENERALS[name] ? `art/general/${GENERALS[name]}.webp` : null);
10+export const cardArt = (name?: string): string | null => (name && CARDS[name] ? `art/card/${CARDS[name]}.webp` : null);
11+export const CARD_BACK = 'art/theme/cardback.webp';
12+
13+/** 魏蜀吴群神 → the class suffix of the faction's frame and badge. */
14+export const FACTION_KEY: Record<string, string> = { 魏: 'wei', 蜀: 'shu', 吴: 'wu', 群: 'qun', 神: 'shen' };
+81 −0 src/viewer/noname/flyCards.ts added View file
@@ -0,0 +1,81 @@
1+// In place of the upstream's flying cards: its useCardMoveAnimation draws and gains with these, between the deck and the
2+// seats, with 无名杀's cards and card back (a discard shows in the middle of the table instead, as a played card). And
3+// in place of its createCardFlyAnimation (a card you play, from your hand): where the card left your hand, so the table
4+// flies it to the middle from there.
5+import { cardArt, CARD_BACK } from './art';
6+import { isRed } from './Card';
7+
8+export interface FlyCardFace {
9+ name: string;
10+ suit: string;
11+ rank: string;
12+}
13+export type AnchorTarget = { kind: 'deck' } | { kind: 'discard' } | { kind: 'seat'; index: number } | { kind: 'offscreen' };
14+
15+const DURATION = 620;
16+
17+function anchor(t: AnchorTarget): { x: number; y: number } {
18+ const sel = t.kind === 'seat' ? `[data-seat-index="${t.index}"]` : t.kind === 'offscreen' ? '' : `[data-zone-anchor="${t.kind}"]`;
19+ const el = sel ? document.querySelector(sel) : null;
20+ const r = el?.getBoundingClientRect();
21+ if (r && r.width) return { x: r.left + r.width / 2, y: r.top + r.height / 2 };
22+ return { x: innerWidth / 2, y: t.kind === 'offscreen' ? -80 : innerHeight * 0.42 };
23+}
24+
25+/** The table's scale (the canvas is drawn at a design size and scaled to the frame): flying cards match its cards. */
26+export const scale = () => Number(getComputedStyle(document.documentElement).getPropertyValue('--nm-scale')) || 1;
27+
28+function face(f: FlyCardFace | null): HTMLElement {
29+ const el = document.createElement('div');
30+ if (!f) {
31+ el.className = 'nm-card back';
32+ el.style.backgroundImage = `url(${CARD_BACK})`;
33+ return el;
34+ }
35+ el.className = `nm-card${isRed(f.suit) ? ' red' : ''}`;
36+ const art = cardArt(f.name);
37+ const a = document.createElement('div');
38+ a.className = art ? 'nm-card-art' : 'nm-card-big';
39+ if (art) a.style.backgroundImage = `url(${art})`;
40+ else a.textContent = f.name.slice(0, 2);
41+ const n = document.createElement('div');
42+ n.className = `nm-card-name${f.name.length > 3 ? ' long' : ''}`;
43+ n.textContent = f.name;
44+ el.append(a, n);
45+ if (f.suit) {
46+ const i = document.createElement('div');
47+ i.className = `nm-card-info${isRed(f.suit) ? ' red' : ''}`;
48+ i.textContent = `${f.suit}${f.rank}`;
49+ el.append(i);
50+ }
51+ return el;
52+}
53+
54+/** Where each card you played last left your hand (by card id), in the frame's pixels. */
55+export const handOrigin = new Map<string, { x: number; y: number }>();
56+
57+export function createCardFlyAnimation(cardEl: HTMLElement, card: { id: string }): void {
58+ const r = cardEl.getBoundingClientRect();
59+ handOrigin.set(card.id, { x: r.left + r.width / 2, y: r.top + r.height / 2 });
60+ if (handOrigin.size > 50) handOrigin.delete(handOrigin.keys().next().value!);
61+}
62+
63+export function flyCards(from: AnchorTarget, to: AnchorTarget, faces: (FlyCardFace | null)[], count?: number): void {
64+ const total = Math.min(count ?? faces.length, 8);
65+ if (total <= 0 || to.kind === 'discard') return;
66+ const a = anchor(from);
67+ const b = anchor(to);
68+ const s = scale();
69+ const box = document.createElement('div');
70+ box.className = 'nm-fly';
71+ box.style.cssText = `left:${a.x}px;top:${a.y}px;--dx:${b.x - a.x}px;--dy:${b.y - a.y}px;--s:${s * 0.8};--n:${total};animation-duration:${DURATION}ms`;
72+ for (let i = 0; i < total; i++) {
73+ const c = face(faces[i] ?? null);
74+ c.style.setProperty('--i', String(i));
75+ box.append(c);
76+ }
77+ document.body.append(box);
78+ const done = () => box.remove();
79+ box.addEventListener('animationend', done);
80+ setTimeout(done, DURATION + 300);
81+}
+8 −0 src/viewer/noname/imageAssets.ts added View file
@@ -0,0 +1,8 @@
1+// In place of the upstream's image lookups (its resource packs): the art pack's portraits and card art. The card back is
2+// null: the upstream draws it in an <object>, which the frame's CSP blocks; its SVG fallback is restyled instead.
3+import { portrait, cardArt } from './art';
4+
5+export const getCharacterImage = (name: string): string | null => portrait(name);
6+export const getCardImage = (card: { name: string }): string | null => cardArt(card.name);
7+export const getEquipCardImage = (name: string): string | null => cardArt(name);
8+export const getCardBackImage = (): string | null => null;
+340 −0 src/viewer/noname/noname.css added View file
@@ -0,0 +1,340 @@
1+/* 无名杀's identity table (its mobile layout over the woodden theme: layout/mobile, layout/newlayout/global.css,
2+ theme/woodden/style.css, theme/style/hp/official.css), drawn for this viewer's markup. Pictures and fonts come from
3+ the art pack (art/art.css); this file is the layout. The canvas is 720 px high; sizes are 无名杀's at that height. */
4+
5+:root {
6+ --card-w: 104px;
7+ --card-h: 120px;
8+ --seat-w: 148px;
9+ --seat-h: 178px;
10+ --me-h: 140px;
11+ --ui: 'PingFang SC', 'STHeiti', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', sans-serif;
12+ --brush: 'nm-xinwei', 'STXinwei', 'KaiTi', serif;
13+ --grass: 'nm-huangcao', 'nm-xinwei', 'STXingkai', serif;
14+ --text-edge: 0 0 2px #000, 0 0 2px #000, 0 0 3px #000;
15+}
16+html, body { margin: 0; height: 100%; overflow: hidden; background: #434b55; color: #fff; font-family: var(--ui); }
17+#root, .nm-root { height: 100%; }
18+.shoal-wait { color: #e8e2d0; font: 18px/1.5 var(--ui); padding: 40px; text-align: center; text-shadow: var(--text-edge); }
19+.nm-root { position: relative; user-select: none; -webkit-user-select: none; }
20+.nm-scaler { position: absolute; inset: 0; overflow: hidden; background: #434b55; }
21+.nm-canvas { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
22+.nm-arena { position: absolute; inset: 0; overflow: hidden; text-shadow: var(--text-edge); }
23+.nm-arena button { font-family: var(--ui); }
24+
25+/* ── top bar: the replay's buttons at the left, round and pile in the middle, the log's at the right ── */
26+.nm-topbar { position: absolute; left: 0; right: 0; top: 0; height: 40px; z-index: 30; pointer-events: none; }
27+.nm-topbar > * { pointer-events: auto; }
28+.nm-round, .nm-pile { position: absolute; top: 9px; font: 15px/20px var(--brush); letter-spacing: .5px; white-space: nowrap; }
29+.nm-pile { left: calc(50% - 4px); transform: translateX(-100%); }
30+.nm-pile b, .nm-round b { font-weight: normal; margin: 0 2px; }
31+.nm-round { left: calc(50% + 4px); }
32+.nm-discards { margin-right: 10px; }
33+.nm-turn-of { margin-left: 8px; color: #ffe9a3; }
34+.nm-phase { margin-left: 4px; color: #ffe9a3; }
35+.nm-top-slot { position: absolute; left: 10px; top: 10px; display: flex; gap: 8px; align-items: flex-start; }
36+.nm-replay, .nm-moves { display: flex; gap: 8px; align-items: center; }
37+.nm-top-side { position: absolute; right: 66px; top: 10px; display: flex; gap: 8px; }
38+.nm-mini, .nm-replay select, .nm-log-toggle, .nm-moves-list button {
39+ height: 27px; min-width: 32px; padding: 0 8px; border: 0; border-radius: 4px; cursor: pointer; color: rgba(77, 60, 51, .8);
40+ font: 15px/27px var(--ui); text-shadow: none; background-size: auto; background-position: center; box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px;
41+}
42+.nm-mini:hover:not(:disabled), .nm-log-toggle:hover { filter: brightness(1.08); }
43+.nm-mini:disabled { opacity: .55; cursor: default; }
44+.nm-mini.on, .nm-mini.play { color: #631515; }
45+.nm-replay select { padding: 0 4px; appearance: none; -webkit-appearance: none; text-align: center; }
46+.nm-replay input[type=range] { width: 120px; accent-color: #9b7a4c; }
47+.nm-step { font: 13px var(--brush); min-width: 64px; text-align: center; }
48+.nm-moves { position: relative; }
49+.nm-moves-list { position: absolute; top: 34px; left: 0; display: flex; flex-direction: column; gap: 5px; max-height: 420px; overflow: auto; padding: 6px; border-radius: 6px; background: rgba(0, 0, 0, .35); }
50+.nm-moves-list button { height: auto; line-height: 1.35; padding: 4px 8px; text-align: left; white-space: nowrap; }
51+
52+/* ── a seat: the portrait card ── */
53+.nm-seat { position: absolute; width: var(--seat-w); height: var(--seat-h); transform: translate(-50%, -50%) scale(var(--seat-scale, 1)); z-index: 4; }
54+.nm-player { position: absolute; inset: 0; border-radius: 8px; background-size: cover; box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px; transition: box-shadow .3s, transform .3s, filter .3s; }
55+.nm-avatar { position: absolute; inset: 3px; border-radius: 6px; background: rgba(0, 0, 0, .25) center 18% / cover no-repeat; overflow: hidden; }
56+.nm-avatar-none { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font: 26px var(--brush); writing-mode: vertical-rl; opacity: .85; }
57+.nm-frame { position: absolute; inset: 3px; border-radius: 6px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25), inset 0 0 8px rgba(0, 0, 0, .35); pointer-events: none; }
58+.nm-player.wei .nm-avatar-none { color: #9fc5ff; }
59+.nm-player.shu .nm-avatar-none { color: #ffb08a; }
60+.nm-player.wu .nm-avatar-none { color: #b2f0a0; }
61+.nm-player.qun .nm-avatar-none { color: #e6e0cf; }
62+
63+/* the name in 新魏, vertical, in the faction's colour as 无名杀 tints it; the faction mark above it */
64+.nm-name { position: absolute; left: 7px; top: 30px; font: 19px/19px var(--brush); writing-mode: vertical-rl; white-space: nowrap; letter-spacing: 1px; z-index: 3;
65+ text-shadow: 0 0 2px #000, 0 0 2px #000, 0 0 4px #000; }
66+.nm-name.long { font-size: 16px; line-height: 16px; letter-spacing: 0; }
67+.nm-faction { position: absolute; left: 6px; top: 7px; width: 20px; height: 20px; font: 17px/20px var(--brush); text-align: center; z-index: 3; text-shadow: 0 0 2px #000, 0 0 3px #000; }
68+.wei .nm-faction, .nm-faction.wei { color: #7ab6ff; }
69+.shu .nm-faction, .nm-faction.shu { color: #ff8e62; }
70+.wu .nm-faction, .nm-faction.wu { color: #8fe36f; }
71+.qun .nm-faction, .nm-faction.qun { color: #e7d9a7; }
72+.shen .nm-faction, .nm-faction.shen { color: #ffd84a; }
73+.wei .nm-name { color: #e8f1ff; }
74+.shu .nm-name { color: #fff0e8; }
75+.wu .nm-name { color: #f0ffe8; }
76+
77+/* HP: a column of 勾玉 at the bottom right; past five, one 勾玉 and the count */
78+.nm-hp { position: absolute; right: 6px; bottom: 8px; display: flex; flex-direction: column-reverse; gap: 2px; z-index: 3; }
79+.nm-jade { display: block; width: 15px; height: 15px; background: center / 100% 100% no-repeat; filter: drop-shadow(0 0 1px rgba(0, 0, 0, .7)); }
80+.nm-jade.lost { filter: grayscale(1) brightness(.7); }
81+.nm-hp.text { flex-direction: row; align-items: center; gap: 2px; font: 17px var(--brush); }
82+.nm-hp.text.mid span { color: #ffe86b; }
83+.nm-hp.text.low span { color: #ff6b5b; }
84+
85+/* hand count: 无名杀's little card at the bottom right corner (newlayout .player .count) */
86+.nm-count { position: absolute; right: -14px; bottom: -14px; width: 28px; height: 28px; background: center / cover no-repeat; z-index: 5;
87+ font: bold 17px/28px var(--brush); text-align: center; color: #fff; text-shadow: 0 0 2px #000, 0 0 2px #000; }
88+
89+/* identity: 主 in red, the rest 猜 (unknown) in blue, in 黄草 with a glow, at the top right corner */
90+.nm-identity { position: absolute; right: -8px; top: -7px; width: 24px; height: 26px; z-index: 6; font: 21px/26px var(--grass); text-align: center; color: #fff;
91+ text-shadow: 0 0 3px #1f6fe0, 0 0 6px #1f6fe0, 0 0 2px #000; }
92+.nm-identity.zhu { text-shadow: 0 0 3px #e0241f, 0 0 7px #e0241f, 0 0 2px #000; }
93+.nm-identity.zhong { text-shadow: 0 0 3px #e0b21f, 0 0 7px #e0b21f, 0 0 2px #000; }
94+.nm-identity.fan { text-shadow: 0 0 3px #3ac53a, 0 0 7px #3ac53a, 0 0 2px #000; }
95+.nm-identity.nei { text-shadow: 0 0 3px #9a3ae0, 0 0 7px #9a3ae0, 0 0 2px #000; }
96+.nm-identity.unknown { font-size: 0; }
97+.nm-identity.unknown::before { content: '猜'; font-size: 21px; }
98+.nm-identity.inline { position: static; display: inline-block; width: 22px; height: 22px; font-size: 18px; line-height: 22px; margin-right: 4px; }
99+.nm-identity.inline.unknown::before { font-size: 18px; }
100+
101+/* equipment: text rows on dark strips across the portrait, suit and rank first; +/- after a horse */
102+.nm-equips { position: absolute; left: 3px; right: 24px; bottom: 8px; display: flex; flex-direction: column; gap: 2px; z-index: 4; pointer-events: auto; }
103+.nm-equip { display: flex; gap: 3px; align-items: center; height: 22px; padding: 0 5px; font: 14px/22px var(--ui); white-space: nowrap; overflow: hidden;
104+ background: linear-gradient(to right, rgba(0, 0, 0, .3), transparent), linear-gradient(135deg, rgba(0, 0, 0, .5), transparent 80%, transparent); }
105+.nm-equip .nm-equip-info { order: -1; font-family: 'nm-suits', var(--ui); font-size: 13px; color: #fff; }
106+.nm-equip .nm-equip-info.red { color: #ff8a80; }
107+.nm-equip .nm-equip-slot { display: none; }
108+
109+/* judgement area: the tricks' little cards just outside the right edge (newlayout .player .judges) */
110+.nm-judges { position: absolute; right: -30px; top: 26px; display: flex; flex-direction: column; gap: 4px; z-index: 5; }
111+.nm-judge { position: relative; width: 24px; height: 24px; border-radius: 4px; background-size: cover; box-shadow: rgba(0, 0, 0, .3) 0 0 0 1px, rgba(0, 0, 0, .45) 0 2px 5px; }
112+.nm-judge > i { position: absolute; inset: 0; background: center / 130% no-repeat; border-radius: 4px; }
113+.nm-judge > b { position: absolute; right: -2px; bottom: -4px; font: normal 13px var(--grass); color: #fff; text-shadow: 0 0 2px #000, 0 0 3px #000; }
114+
115+/* the turn: 无名杀's warm glow round the current seat, and the phase on a small tag */
116+.nm-player.current { box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(255, 203, 0, .95) 0 0 5px 2px, rgba(255, 160, 0, .7) 0 0 16px 4px; }
117+.nm-phase-mark { position: absolute; left: 50%; top: -12px; transform: translateX(-50%); padding: 0 8px; height: 20px; border-radius: 10px; z-index: 6;
118+ font: 13px/20px var(--brush); background: linear-gradient(#b8892f, #7d5916); box-shadow: 0 1px 3px rgba(0, 0, 0, .6); white-space: nowrap; }
119+
120+/* targets: selectable seats glow blue, chosen ones red, the rest dim */
121+.nm-seat.pick { cursor: pointer; }
122+.nm-player.selectable { box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(10, 120, 255, 1) 0 0 5px 2px, rgba(10, 120, 255, .8) 0 0 14px 4px; }
123+.nm-player.selected { box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(255, 0, 0, 1) 0 0 5px 2px, rgba(255, 0, 0, .75) 0 0 14px 4px; transform: scale(1.04); }
124+.nm-player.unselectable { filter: brightness(.55); }
125+.nm-distance { position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%); padding: 0 6px; border-radius: 9px; background: rgba(0, 0, 0, .55); font: 12px/18px var(--ui); z-index: 4; }
126+
127+/* 横置: the iron chain across the middle; 翻面: the card turned dark with 翻面 on it */
128+.nm-chain { position: absolute; left: -2px; right: -2px; top: calc(50% - 6px); height: 12px; z-index: 5; pointer-events: none;
129+ background: repeating-linear-gradient(90deg, #9aa3ad 0 9px, transparent 9px 12px, #6d757e 12px 17px, transparent 17px 20px); border-radius: 3px;
130+ box-shadow: 0 1px 3px rgba(0, 0, 0, .7); animation: nm-chain .4s ease-out; }
131+@keyframes nm-chain { from { transform: translateX(-30px); opacity: 0; } }
132+.nm-flipped { position: absolute; inset: 3px; border-radius: 6px; background: rgba(0, 0, 0, .72); z-index: 4; display: flex; align-items: center; justify-content: center;
133+ font: 40px var(--brush); writing-mode: vertical-rl; color: rgba(255, 255, 255, .85); }
134+
135+/* 横置 as 无名杀 lays it: the seat's card turned on its side, the chain across it (newlayout .player.linked) */
136+.nm-seat .nm-player.chained { transform: rotate(-90deg); }
137+.nm-seat .nm-player.chained.selected { transform: rotate(-90deg) scale(1.04); }
138+.nm-seat .nm-player.chained .nm-judges { transform: rotate(90deg) translateX(10px); }
139+
140+/* dying: a red pulse; dead: grey, tilted, the identity written across in 黄草 */
141+.nm-player.dying .nm-avatar { animation: nm-dying 1s ease-in-out infinite alternate; }
142+@keyframes nm-dying { to { filter: sepia(.6) saturate(3) hue-rotate(-30deg) brightness(.8); } }
143+.nm-dying { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); font: 30px var(--grass); color: #ff3b2f; z-index: 6; text-shadow: 0 0 3px #000, 0 0 8px #600; }
144+.nm-player.dead { transform: rotate(-8deg); filter: grayscale(1) brightness(.85); box-shadow: rgba(0, 0, 0, .3) 0 0 0 1px, rgba(0, 0, 0, .3) 0 3px 8px; }
145+.nm-player.dead .nm-hp, .nm-player.dead .nm-count, .nm-player.dead .nm-equips, .nm-player.dead .nm-judges, .nm-player.dead .nm-identity { display: none; }
146+.nm-dead { position: absolute; inset: 0; z-index: 6; display: flex; flex-direction: column; align-items: center; justify-content: center; font: 22px var(--brush); color: rgba(255, 255, 255, .8); text-shadow: 0 0 3px #000; }
147+.nm-dead b { font: normal 54px/60px var(--grass); color: rgba(30, 30, 30, .85); text-shadow: 0 0 2px #fff, 0 0 6px rgba(255, 255, 255, .8); letter-spacing: 4px; }
148+
149+/* damage: the seat shakes and flashes red, the amount rises in 黄草; healing flashes green */
150+.nm-player.damaged { animation: nm-shake .45s; }
151+.nm-player.damaged .nm-avatar::after { content: ''; position: absolute; inset: 0; background: rgba(255, 0, 0, .55); animation: nm-flash .6s forwards; }
152+.nm-player.healed .nm-avatar::after { content: ''; position: absolute; inset: 0; background: rgba(60, 255, 90, .4); animation: nm-flash .8s forwards; }
153+@keyframes nm-shake { 15%, 55% { transform: translateX(-6px); } 35%, 75% { transform: translateX(6px); } }
154+@keyframes nm-flash { to { opacity: 0; } }
155+.nm-hpfloat { position: absolute; left: 50%; top: 40%; z-index: 8; transform: translate(-50%, -50%); font: 72px var(--grass); pointer-events: none; animation: nm-rise 1.3s ease-out forwards; }
156+.nm-hpfloat.damage { color: #fff; text-shadow: #000 0 0 1px, #e83535 0 0 2px, #e83535 0 0 5px, #e83535 0 0 10px, #e83535 0 0 10px, #e83535 0 0 20px, #e83535 0 0 20px; }
157+.nm-hpfloat.heal { color: #fff; text-shadow: #000 0 0 1px, #397b04 0 0 2px, #397b04 0 0 5px, #397b04 0 0 10px, #397b04 0 0 10px, #397b04 0 0 20px, #397b04 0 0 20px; }
158+@keyframes nm-rise { 0% { opacity: 0; transform: translate(-50%, -20%) scale(1.6); } 15% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, -110%); } }
159+
160+.nm-seat-label { position: absolute; left: 0; right: 0; bottom: -20px; text-align: center; font: 12px/16px var(--ui); color: rgba(255, 255, 255, .7); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
161+.nm-timer { position: absolute; left: 6px; right: 6px; bottom: -8px; height: 4px; border-radius: 2px; background: rgba(0, 0, 0, .4); overflow: hidden; z-index: 7; }
162+.nm-timer-fill { height: 100%; background: linear-gradient(90deg, #ffb31a, #ffe066); box-shadow: 0 0 4px #ffcc33; }
163+
164+/* ── a card: wood face, art, the name boxed and vertical at the top left, suit and rank at the top right ── */
165+.nm-card { position: relative; width: var(--card-w); height: var(--card-h); border-radius: 4px; background-size: cover; color: #3b2a1c; text-shadow: none; overflow: hidden;
166+ box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px; font-family: var(--brush); }
167+.nm-card-fill { position: absolute !important; inset: 0; width: auto; height: auto; }
168+.nm-card-art { position: absolute; left: 0; right: 0; top: 8px; height: 110px; background: center / cover no-repeat; }
169+.nm-card-big { position: absolute; inset: 22px 6px 6px; display: flex; align-items: center; justify-content: center; font: 38px var(--brush); color: rgba(59, 42, 28, .75); }
170+.nm-card-name { position: absolute; left: 6px; top: 7px; padding: 2px 0; width: 19px; border: 1px solid rgba(59, 42, 28, .85); border-radius: 4px; background: rgba(233, 222, 200, .55);
171+ font: 16px/17px var(--brush); writing-mode: vertical-rl; text-align: center; white-space: nowrap; z-index: 2; }
172+.nm-card-name.long { font-size: 14px; line-height: 17px; }
173+.nm-card-info { position: absolute; right: 7px; top: 5px; font: 17px/20px var(--brush); z-index: 2; white-space: nowrap; color: #2b2017; }
174+.nm-card-info .nm-suit, .nm-equip-info, .nm-suit { font-family: 'nm-suits', var(--ui); }
175+.nm-card-info .nm-suit { margin-right: 2px; font-size: 15px; }
176+.nm-card-info.red { color: #b0211a; }
177+.nm-card.fire .nm-card-name { color: #c62a12; border-color: #c62a12; }
178+.nm-card.thunder .nm-card-name { color: #1e4fb4; border-color: #1e4fb4; }
179+.nm-card.fire .nm-card-art { filter: sepia(.3) saturate(1.6) hue-rotate(-15deg); }
180+.nm-card.thunder .nm-card-art { filter: hue-rotate(180deg) saturate(.9); }
181+.nm-card.back { background-size: cover; }
182+.nm-card.back > * { display: none; }
183+
184+/* ── the middle: what was just played, flown in from its seat ── */
185+.nm-center { position: absolute; left: 0; right: 0; top: 296px; height: 150px; z-index: 6; pointer-events: none; }
186+.nm-played-row { display: flex; justify-content: center; gap: 6px; }
187+.nm-played { position: relative; display: flex; flex-direction: column; align-items: center; animation: nm-fade 4.2s forwards; }
188+.nm-played.shown { animation: none; }
189+.nm-played .nm-card { box-shadow: rgba(0, 0, 0, .25) 0 0 0 1px, rgba(0, 0, 0, .5) 0 4px 12px; }
190+.nm-played-caption { margin-top: 3px; max-width: 150px; font: 13px/16px var(--ui); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
191+@keyframes nm-fade { 0%, 82% { opacity: 1; } 100% { opacity: 0; } }
192+.nm-discard { position: absolute; left: 50%; top: 0; width: 1px; height: 1px; }
193+.nm-lines { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 28; pointer-events: none; overflow: visible; }
194+.nm-line line { stroke: rgba(255, 255, 255, .92); stroke-width: 2.5; stroke-linecap: round; filter: drop-shadow(0 0 3px rgba(255, 255, 255, .8)); stroke-dashoffset: var(--len); animation: nm-draw .35s ease-out forwards, nm-fade 1.4s forwards; }
195+.nm-line.sha line { stroke: rgba(255, 236, 214, .95); filter: drop-shadow(0 0 3px rgba(255, 60, 30, .9)); }
196+.nm-line circle { fill: rgba(255, 255, 255, .85); opacity: 0; animation: nm-hit 1.2s .3s forwards; }
197+.nm-line.sha circle { fill: rgba(255, 80, 50, .9); }
198+@keyframes nm-draw { to { stroke-dashoffset: 0; } }
199+@keyframes nm-hit { 0% { opacity: 0; r: 2; } 20% { opacity: 1; r: 9; } 100% { opacity: 0; r: 14; } }
200+
201+/* a basic card's name on its user (cardeffect): 黄草, gold, swelling and fading */
202+.nm-cardeffect { position: absolute; z-index: 29; transform: translate(-50%, -50%); font: 84px/1 var(--grass); color: #ffe27a; pointer-events: none; white-space: nowrap;
203+ text-shadow: 0 0 2px #3a2400, 0 0 3px #3a2400, 0 0 12px rgba(255, 180, 0, .9); animation: nm-effect 1.1s ease-out forwards; }
204+.nm-cardeffect.sha { color: #fff0d0; text-shadow: 0 0 2px #400, 0 0 3px #400, 0 0 14px rgba(255, 40, 0, .95); }
205+@keyframes nm-effect { 0% { opacity: 0; transform: translate(-50%, -50%) scale(.5); } 25% { opacity: 1; transform: translate(-50%, -50%) scale(1.05); } 70% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.15); } }
206+
207+/* a card flying between the deck, seats and the middle */
208+.nm-fly { position: fixed; width: 0; height: 0; z-index: 9998; pointer-events: none; animation-name: nm-fly; animation-timing-function: cubic-bezier(.25, .7, .3, 1); animation-fill-mode: forwards; }
209+.nm-fly > .nm-card { position: absolute; left: calc(var(--card-w) * -.5 + (var(--i) - (var(--n) - 1) / 2) * 28px); top: calc(var(--card-h) * -.5); transform: scale(var(--s)); }
210+@keyframes nm-fly { 0% { opacity: 0; transform: translate(0, 0) scale(.7); } 15% { opacity: 1; transform: translate(0, 0) scale(1); } 85% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.9); } }
211+
212+/* ── prompts and the 确定 / 取消 / 结束回合 buttons above your hand ── */
213+.nm-dock { position: absolute; left: 0; right: 0; bottom: calc(var(--me-h) + 8px); z-index: 20; display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: none; }
214+.nm-dock > * { pointer-events: auto; }
215+.nm-tip, .nm-promptDesc { font: 20px/26px var(--ui); text-align: center; max-width: 760px; }
216+.nm-tip b { font-weight: normal; color: #ffe08a; }
217+.nm-promptBoxAwaiting, .nm-promptBox { display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 900px; }
218+.nm-promptTitle, .nm-promptDescInline, .nm-autoSkipToggle, .nm-slashCountBadge { display: none !important; }
219+.nm-promptDesc span { opacity: .9; }
220+.nm-waitingHint { font: 16px var(--ui); opacity: .8; }
221+.nm-promptActions, .nm-promptActionsWrap { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; max-width: 900px; }
222+.nm-promptDescFull { width: 100%; text-align: center; font: 14px var(--ui); opacity: .85; }
223+.nm-control { display: flex; gap: 10px; justify-content: center; align-items: center; min-height: 30px; }
224+.nm-btn, .nm-promptBtn, .nm-promptBtnPrimary, .nm-promptBtnDisabled, .nm-chooseOptionCard {
225+ height: 30px; min-width: 54px; padding: 0 9px; border: 0; border-radius: 4px; cursor: pointer; background-size: auto; background-position: center; color: rgba(77, 60, 51, .8); text-shadow: none;
226+ font: 19px/30px var(--ui); box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px; white-space: nowrap; transition: filter .15s, opacity .15s; }
227+.nm-btn:hover:not(:disabled), .nm-promptBtn:hover, .nm-promptBtnPrimary:hover, .nm-chooseOptionCard:hover { filter: brightness(1.08); }
228+.nm-btn.ok, .nm-promptBtnPrimary { color: rgba(77, 60, 51, .95); }
229+.nm-btn:disabled, .nm-promptBtnDisabled { opacity: .5; cursor: default; }
230+.nm-btn.end { position: absolute; left: 174px; }
231+.nm-chooseOptionCard { height: auto; padding: 6px 10px; display: flex; flex-direction: column; line-height: 1.3; border: 0 !important; background-color: transparent !important; }
232+.nm-chooseOptionCardName { font: 18px var(--brush); }
233+.nm-chooseOptionCardSkills { font-size: 12px; }
234+.nm-pickHandRow { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
235+.nm-pickHandCard { position: relative; width: 62px; height: 72px; border: 0; border-radius: 4px; padding: 0; cursor: pointer; background-size: cover; box-shadow: rgba(0, 0, 0, .3) 0 0 0 1px, rgba(0, 0, 0, .5) 0 3px 8px; }
236+.nm-pickHandCard > *:not(.nm-pickHandIndex) { opacity: 0; }
237+.nm-pickHandIndex { position: absolute; right: 3px; bottom: 2px; font: 14px var(--brush); color: #fff; text-shadow: var(--text-edge); }
238+.nm-pickedByTag { margin-left: 6px; font-size: 12px; opacity: .8; }
239+
240+/* ── your strip: portrait at the left, the hand, your equipment at the right ── */
241+.nm-me { position: absolute; left: 0; right: 0; bottom: 0; height: var(--me-h); background-size: 100% 100%; z-index: 10;
242+ box-shadow: rgba(0, 0, 0, .25) 0 -1px 0, rgba(0, 0, 0, .3) 0 -2px 10px; }
243+.nm-me .nm-player.mine { left: 0; top: 0; bottom: 0; right: auto; width: 120px; border-radius: 0; box-shadow: none; background: none; }
244+.nm-me .nm-player.mine .nm-avatar { inset: 0; border-radius: 0; }
245+.nm-me .nm-player.mine .nm-frame { inset: 0; border-radius: 0; box-shadow: inset -1px 0 0 rgba(0, 0, 0, .3); }
246+.nm-me .nm-player.mine .nm-count { right: auto; left: 4px; bottom: 6px; transform: rotate(-8deg); }
247+.nm-me .nm-player.mine .nm-identity { right: -10px; top: -9px; }
248+.nm-me .nm-player.mine .nm-judges { right: auto; left: 4px; top: -28px; flex-direction: row; }
249+.nm-me .nm-player.mine .nm-phase-mark { top: -24px; }
250+.nm-me .nm-player.mine.current { box-shadow: rgba(255, 203, 0, .95) 0 0 4px 2px; z-index: 2; }
251+.nm-me .nm-player.mine.dead { transform: none; }
252+.nm-me.spectating .nm-player.mine { filter: none; }
253+.nm-me-label { position: absolute; left: 0; width: 120px; bottom: -1px; display: none; }
254+
255+.nm-myequips { position: absolute; right: 0; top: 0; bottom: 0; width: 120px; display: flex; flex-direction: column; box-shadow: -1px 0 0 rgba(0, 0, 0, .25), -2px 0 8px rgba(0, 0, 0, .15); }
256+.nm-myequip { flex: 1; display: flex; align-items: center; gap: 5px; padding: 0 6px; background-size: cover; color: rgba(77, 60, 51, .9); text-shadow: none; font: 15px var(--ui);
257+ border-bottom: 1px solid rgba(77, 60, 51, .3); white-space: nowrap; overflow: hidden; }
258+.nm-myequip .nm-equip-slot { width: 18px; font: 12px var(--brush); color: rgba(77, 60, 51, .55); }
259+.nm-myequip.empty .nm-equip-slot { color: rgba(77, 60, 51, .3); }
260+.nm-myequip .nm-equip-info { order: -1; font-size: 14px; color: rgba(77, 60, 51, .9); }
261+.nm-myequip .nm-equip-info.red { color: #b0211a; }
262+.nm-myequip.usable, .nm-myequip.candidate { cursor: pointer; box-shadow: inset 0 0 0 2px rgba(10, 120, 255, .8); }
263+.nm-myequip.picked { box-shadow: inset 0 0 0 2px rgba(255, 0, 0, .8); }
264+
265+.nm-skills { position: absolute; right: 128px; bottom: calc(var(--me-h) + 8px); display: flex; flex-direction: row-reverse; gap: 8px; z-index: 21; }
266+.nm-skill { height: 30px; padding: 0 10px; border: 0; border-radius: 4px; cursor: pointer; font: 19px/30px var(--brush); color: rgba(77, 60, 51, .9); text-shadow: none;
267+ background-size: auto; background-position: center; box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px; }
268+.nm-skill.on { color: #6b1a0c; box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(255, 196, 0, .9) 0 0 6px 1px, rgba(0, 0, 0, .45) 0 3px 10px; }
269+.nm-skill:disabled { opacity: .5; cursor: default; }
270+.nm-skill.passive { display: none; }
271+
272+.nm-hand { position: absolute; left: 128px; right: 128px; top: 10px; bottom: 0; }
273+.nm-hand > .nm-timer { left: 0; right: auto; width: 280px; top: -6px; bottom: auto; }
274+.nm-handColumn { position: absolute; inset: 0; }
275+.nm-handHeader, .nm-handTitle, .nm-phaseStrip, .nm-phaseStripBadge, .nm-debugHint, .nm-distHint { display: none; }
276+.nm-handList { position: absolute; inset: 0; display: flex; align-items: flex-start; padding-left: 6px; }
277+.nm-handList > div { flex: 0 1 112px; min-width: 20px; position: relative; }
278+.nm-handList > div:last-of-type { flex: 0 0 auto; }
279+.nm-handCard { position: relative; width: var(--card-w); height: var(--card-h); border-radius: 4px; cursor: default; transition: transform .2s, opacity .2s, filter .2s; --fan-angle: 0deg !important;
280+ box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px; }
281+.nm-handCard:hover:hover { transform: translateY(-6px) !important; box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .5) 0 6px 14px !important; filter: none !important; }
282+.nm-handCardPlayable, .nm-handCardRespondable, .nm-handCardDiscardable, .nm-handCardTransform, .nm-handCardDistributeCandidate { cursor: pointer; }
283+.nm-handCardDisabled, .nm-handCardTransformDisabled { opacity: 1; }
284+.nm-arena:not(.readonly) .nm-handCardDisabled .nm-card::after, .nm-handCardTransformDisabled .nm-card::after { content: ''; position: absolute; inset: 0; background: rgba(240, 236, 228, .52); }
285+.nm-handCard.nm-handCardSelected, .nm-handCard.nm-handCardRespondSelected, .nm-handCard.nm-discardCardSelected, .nm-handCard.nm-handCardDistributeSelected,
286+.nm-handCard.nm-handCardSelected:hover:hover, .nm-handCard.nm-handCardRespondSelected:hover:hover, .nm-handCard.nm-discardCardSelected:hover:hover, .nm-handCard.nm-handCardDistributeSelected:hover:hover { transform: translateY(-20px) !important;
287+ box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(255, 0, 0, 1) 0 0 4px 2px, rgba(255, 0, 0, .6) 0 0 12px 3px !important; }
288+.nm-handCardDistributeAllocated { opacity: .6; }
289+.nm-handCardTimeoutFallback { box-shadow: rgba(255, 170, 0, .9) 0 0 5px 2px !important; }
290+.nm-handCardMeta { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; padding: 2px 0; background: rgba(0, 0, 0, .55); text-align: center; color: #fff; text-shadow: var(--text-edge); }
291+.nm-handCardMeta .nm-cardName { font: 16px var(--brush); }
292+.nm-cardOrigin { font-size: 11px; opacity: .85; }
293+.nm-backs { position: absolute; inset: 0; display: flex; padding-left: 6px; }
294+.nm-backs > .nm-card { flex: 0 0 auto; margin-right: -40px; }
295+.nm-emptyHand { padding: 46px 20px; font: 15px var(--ui); color: rgba(77, 60, 51, .6); text-shadow: none; white-space: nowrap; }
296+.nm-distExternalWrap { position: absolute; left: 0; bottom: calc(100% + 60px); display: flex; flex-direction: column; gap: 6px; }
297+.nm-distExternalLabel { font: 15px var(--ui); }
298+.nm-distExternalList { display: flex; gap: 6px; }
299+.nm-distExternalCard { position: relative; width: 64px; height: 80px; border-radius: 4px; padding: 6px; background: rgba(233, 222, 200, .9); color: #3b2a1c; text-shadow: none; cursor: pointer; font: 15px var(--brush); }
300+.nm-handCardDistributeCandidate { box-shadow: rgba(10, 120, 255, .9) 0 0 4px 2px !important; }
301+
302+/* ── the log, at the right under the top bar ── */
303+.nm-log { position: absolute; right: 10px; top: 10px; width: 236px; z-index: 25; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
304+.nm-log-lines { width: 100%; max-height: 220px; overflow-y: auto; padding: 2px 4px; box-sizing: border-box; font: 13px/18px var(--ui); text-align: left;
305+ scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .3) transparent; }
306+.nm-log.open .nm-log-lines { border-radius: 6px; background: rgba(30, 36, 44, .55); padding: 4px 8px; }
307+.nm-log-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
308+.nm-log-line .who { color: #8ec5ff; }
309+.nm-log-line .card { color: #ffe45c; }
310+
311+/* ── dialogs: choosing a general, the result ── */
312+.nm-dialog-mask { position: absolute; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, .15); }
313+.nm-dialog { max-width: 1040px; box-sizing: border-box; padding: 14px 18px 16px; border-radius: 6px; background: rgba(40, 46, 56, .72); box-shadow: rgba(0, 0, 0, .3) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 16px;
314+ display: flex; flex-direction: column; align-items: center; gap: 12px; }
315+.nm-dialog-title { font: 21px var(--ui); }
316+.nm-dialog-wait { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -50%); z-index: 50; font: 20px var(--ui); }
317+.nm-choose-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; max-width: 980px; }
318+.nm-choose { position: relative; width: 104px; height: 130px; padding: 0; border: 0; border-radius: 8px; cursor: pointer; background-size: cover; color: #fff; text-shadow: var(--text-edge);
319+ box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(0, 0, 0, .45) 0 3px 10px; transition: transform .15s, box-shadow .15s; }
320+.nm-choose:hover { transform: translateY(-3px); }
321+.nm-choose.selected { box-shadow: rgba(0, 0, 0, .2) 0 0 0 1px, rgba(255, 0, 0, 1) 0 0 5px 2px, rgba(255, 0, 0, .7) 0 0 14px 4px; }
322+.nm-choose .nm-faction { left: auto; right: 6px; }
323+.nm-choose .nm-name { top: 8px; }
324+.nm-choose .nm-hp { bottom: 28px; }
325+.nm-choose .nm-jade { width: 13px; height: 13px; }
326+.nm-choose-skills { position: absolute; left: 3px; right: 3px; bottom: 3px; padding: 2px 0; border-radius: 0 0 6px 6px; background: rgba(0, 0, 0, .55); font: 13px/17px var(--brush); display: flex; justify-content: center; gap: 6px; flex-wrap: wrap; }
327+.nm-dialog .nm-timer { position: relative; left: 0; right: 0; bottom: 0; width: 100%; }
328+.nm-control.in-dialog { margin-top: 2px; }
329+.nm-dialog.result { min-width: 560px; }
330+.nm-result-title { font: 44px var(--grass); letter-spacing: 6px; color: #ffe9a3; text-shadow: 0 0 3px #000, 0 0 12px #c08000; }
331+.nm-dialog.result.lose .nm-result-title { color: #d9d9d9; text-shadow: 0 0 3px #000, 0 0 12px #444; }
332+table.nm-result { border-collapse: collapse; font: 15px var(--ui); }
333+.nm-result td { padding: 4px 12px; border-bottom: 1px solid rgba(255, 255, 255, .12); white-space: nowrap; }
334+.nm-result tr.won td { color: #ffe9a3; }
335+.nm-result tr.dead td { opacity: .7; }
336+.nm-result-name { font: 19px var(--brush); }
337+.nm-result-face { display: block; width: 34px; height: 34px; border-radius: 4px; background: #333 center 18% / cover; }
338+
339+/* the upstream's tooltips (skill and card descriptions) as 无名杀's: dark, small */
340+[role='tooltip'] { font-family: var(--ui) !important; }
+64 −0 src/viewer/noname/styles.ts added View file
@@ -0,0 +1,64 @@
1+// In place of the upstream's style sheet (gameViewStyles) for the upstream components this table keeps (its prompts,
2+// action buttons and hand): the same class names, mapped to this folder's 无名杀 classes in noname.css. Names not
3+// listed keep the upstream's own styles.
4+export * from '../../../src/client/components/gameViewStyles/index';
5+export const actionBar = 'nm-actionBar';
6+export const autoSkipToggle = 'nm-autoSkipToggle';
7+export const btnDisabled = 'nm-btnDisabled';
8+export const cancelBtn = 'nm-cancelBtn';
9+export const cardName = 'nm-cardName';
10+export const cardOrigin = 'nm-cardOrigin';
11+export const cardSuit = 'nm-cardSuit';
12+export const chooseOptionCard = 'nm-chooseOptionCard';
13+export const chooseOptionCardName = 'nm-chooseOptionCardName';
14+export const chooseOptionCardSkills = 'nm-chooseOptionCardSkills';
15+export const debugHint = 'nm-debugHint';
16+export const discardCardSelected = 'nm-discardCardSelected';
17+export const distExternalCard = 'nm-distExternalCard';
18+export const distExternalLabel = 'nm-distExternalLabel';
19+export const distExternalList = 'nm-distExternalList';
20+export const distExternalWrap = 'nm-distExternalWrap';
21+export const distHint = 'nm-distHint';
22+export const emptyHand = 'nm-emptyHand';
23+export const endTurnBtn = 'nm-endTurnBtn';
24+export const handCard = 'nm-handCard';
25+export const handCardDisabled = 'nm-handCardDisabled';
26+export const handCardDiscardable = 'nm-handCardDiscardable';
27+export const handCardDistributeAllocated = 'nm-handCardDistributeAllocated';
28+export const handCardDistributeCandidate = 'nm-handCardDistributeCandidate';
29+export const handCardDistributeSelected = 'nm-handCardDistributeSelected';
30+export const handCardMeta = 'nm-handCardMeta';
31+export const handCardPlayable = 'nm-handCardPlayable';
32+export const handCardRespondSelected = 'nm-handCardRespondSelected';
33+export const handCardRespondable = 'nm-handCardRespondable';
34+export const handCardSelected = 'nm-handCardSelected';
35+export const handCardTimeoutFallback = 'nm-handCardTimeoutFallback';
36+export const handCardTransform = 'nm-handCardTransform';
37+export const handCardTransformDisabled = 'nm-handCardTransformDisabled';
38+export const handColumn = 'nm-handColumn';
39+export const handHeader = 'nm-handHeader';
40+export const handList = 'nm-handList';
41+export const handTitle = 'nm-handTitle';
42+export const keyHint = 'nm-keyHint';
43+export const phaseStrip = 'nm-phaseStrip';
44+export const phaseStripBadge = 'nm-phaseStripBadge';
45+export const pickHandCard = 'nm-pickHandCard';
46+export const pickHandIndex = 'nm-pickHandIndex';
47+export const pickHandRow = 'nm-pickHandRow';
48+export const pickedByTag = 'nm-pickedByTag';
49+export const playBtn = 'nm-playBtn';
50+export const promptActions = 'nm-promptActions';
51+export const promptActionsWrap = 'nm-promptActionsWrap';
52+export const promptBox = 'nm-promptBox';
53+export const promptBoxAwaiting = 'nm-promptBoxAwaiting';
54+export const promptBtn = 'nm-promptBtn';
55+export const promptBtnDisabled = 'nm-promptBtnDisabled';
56+export const promptBtnPrimary = 'nm-promptBtnPrimary';
57+export const promptDesc = 'nm-promptDesc';
58+export const promptDescFull = 'nm-promptDescFull';
59+export const promptDescInline = 'nm-promptDescInline';
60+export const promptTitle = 'nm-promptTitle';
61+export const slashCountBadge = 'nm-slashCountBadge';
62+export const targetHint = 'nm-targetHint';
63+export const transformHint = 'nm-transformHint';
64+export const waitingHint = 'nm-waitingHint';
+127 −0 src/viewer/noname/useFx.ts added View file
@@ -0,0 +1,127 @@
1+// What the table shows of each engine event beyond the state itself, as 无名杀 does: a card played, discarded, judged
2+// or shown flies from its seat to the centre and stays there a moment with a caption (谁 → 谁), and a line runs from
3+// the user to each target; a basic card's name flashes on its user. Fed by the same event batches as the upstream's play history (usePlayHistory).
4+import { useEffect, useRef, useState } from 'react';
5+import type { GameView, ViewEvent } from '../../../src/engine/types';
6+import type { QueuedEvent } from '../../../src/client/hooks/useEventPlayback';
7+import type { Face } from './Card';
8+
9+export interface CenterCard {
10+ id: string;
11+ face: Face;
12+ caption: string;
13+ from: number | null;
14+ cardId?: string;
15+ at: number;
16+}
17+/** A basic card's name flashing large on its user, as 无名杀's cardeffect. */
18+export interface Word {
19+ id: string;
20+ seat: number;
21+ text: string;
22+ at: number;
23+}
24+export interface Line {
25+ id: string;
26+ from: number;
27+ to: number;
28+ kind: 'sha' | 'trick';
29+ at: number;
30+}
31+
32+const KEEP_MS = 4200;
33+const LINE_MS = 1400;
34+const WORD_MS = 1100;
35+const WORDS: Record<string, string> = { 杀: 'sha', 火杀: 'sha', 雷杀: 'sha', 闪: 'shan', 桃: 'tao', 酒: 'jiu' };
36+const MAX_CENTER = 7;
37+let n = 0;
38+const id = () => `fx${++n}`;
39+
40+export function useFx(ingested: readonly QueuedEvent[] | undefined, view: GameView) {
41+ const [center, setCenter] = useState<CenterCard[]>([]);
42+ const [lines, setLines] = useState<Line[]>([]);
43+ const [words, setWords] = useState<Word[]>([]);
44+ const last = useRef(-1);
45+ const viewRef = useRef(view);
46+ viewRef.current = view;
47+
48+ useEffect(() => {
49+ const batch = ingested ?? [];
50+ if (!batch.length) return;
51+ // A batch from before the last one is a jump back (a replay seek): start the table's effects over.
52+ if (batch.every((e) => e.seq <= last.current)) {
53+ last.current = Math.min(...batch.map((e) => e.seq)) - 1;
54+ setCenter([]);
55+ setLines([]);
56+ setWords([]);
57+ }
58+ const fresh = batch.filter((e) => e.seq > last.current);
59+ if (!fresh.length) return;
60+ last.current = Math.max(...fresh.map((e) => e.seq));
61+ const v = viewRef.current;
62+ const name = (i: unknown) => v.players[i as number]?.character || v.players[i as number]?.name || '';
63+ const now = Date.now();
64+ const add: CenterCard[] = [];
65+ const newLines: Line[] = [];
66+ const newWords: Word[] = [];
67+ const captions = new Map<string, string>();
68+ for (const { event } of fresh) {
69+ const e = event as ViewEvent & Record<string, unknown>;
70+ const card = e.card as { name?: string; suit?: string; rank?: string } | null | undefined;
71+ const full = typeof e.cardId === 'string' ? v.cardMap[e.cardId] : undefined;
72+ const face = (c: { name?: string; suit?: string; rank?: string } | undefined, cid?: string): Face | null => {
73+ const f = cid ? v.cardMap[cid] : undefined;
74+ const nm = c?.name ?? f?.name;
75+ return nm ? { name: nm, suit: c?.suit ?? f?.suit, rank: c?.rank ?? f?.rank, damageType: f?.damageType } : null;
76+ };
77+ if (e.type === '打出' || e.type === '弃牌' || e.type === '展示') {
78+ const f = face(card ?? undefined, e.cardId as string | undefined);
79+ const verb = e.type === '打出' ? '' : e.type === '弃牌' ? ' 弃置' : ' 展示';
80+ if (f) add.push({ id: id(), face: f, caption: `${name(e.player)}${verb}`, from: e.player as number, cardId: e.cardId as string, at: now });
81+ const label = f && (f.damageType === '火焰' ? '火杀' : f.damageType === '雷电' ? '雷杀' : f.name);
82+ if (e.type === '打出' && label && WORDS[label]) newWords.push({ id: id(), seat: e.player as number, text: label, at: now });
83+ } else if (e.type === '弃置') {
84+ const ids = (e.cardIds as string[] | undefined) ?? [];
85+ const names = (e.cardNames as string[] | undefined) ?? [];
86+ for (let i = 0; i < Math.max(ids.length, names.length); i++) {
87+ const f = face(names[i] ? { name: names[i], ...pick(v.cardMap[ids[i]]) } : undefined, ids[i]);
88+ if (f) add.push({ id: id(), face: f, caption: `${name(e.player)} 弃置`, from: e.player as number, cardId: ids[i], at: now });
89+ }
90+ } else if (e.type === '判定') {
91+ const f = face(card ?? undefined, e.cardId as string | undefined);
92+ if (f) add.push({ id: id(), face: f, caption: `${name(e.player)} ${(e.judgeType as string) ?? ''}判定`, from: null, cardId: e.cardId as string, at: now });
93+ } else if (e.type === '指定目标' && typeof e.source === 'number' && typeof e.target === 'number') {
94+ const cardName = (e.cardName as string) ?? full?.name;
95+ if (e.source !== e.target) newLines.push({ id: id(), from: e.source, to: e.target, kind: cardName === '杀' ? 'sha' : 'trick', at: now });
96+ if (typeof e.cardId === 'string') {
97+ const prev = captions.get(e.cardId);
98+ captions.set(e.cardId, prev ? `${prev}、${name(e.target)}` : `${name(e.source)} → ${name(e.target)}`);
99+ }
100+ }
101+ }
102+ if (add.length || captions.size)
103+ setCenter((prev) => {
104+ let next = [...prev.filter((c) => now - c.at < KEEP_MS), ...add];
105+ if (captions.size) next = next.map((c) => (c.cardId && captions.has(c.cardId) ? { ...c, caption: captions.get(c.cardId)! } : c));
106+ return next.slice(-MAX_CENTER);
107+ });
108+ if (newLines.length) setLines((prev) => [...prev.filter((l) => now - l.at < LINE_MS), ...newLines]);
109+ if (newWords.length) setWords((prev) => [...prev.filter((w) => now - w.at < WORD_MS), ...newWords]);
110+ }, [ingested]);
111+
112+ // expire
113+ useEffect(() => {
114+ if (!center.length && !lines.length && !words.length) return;
115+ const t = setInterval(() => {
116+ const now = Date.now();
117+ setCenter((p) => (p.some((c) => now - c.at >= KEEP_MS) ? p.filter((c) => now - c.at < KEEP_MS) : p));
118+ setLines((p) => (p.some((l) => now - l.at >= LINE_MS) ? p.filter((l) => now - l.at < LINE_MS) : p));
119+ setWords((p) => (p.some((w) => now - w.at >= WORD_MS) ? p.filter((w) => now - w.at < WORD_MS) : p));
120+ }, 300);
121+ return () => clearInterval(t);
122+ }, [center.length, lines.length, words.length]);
123+
124+ return { center, lines, words };
125+}
126+
127+const pick = (c?: { suit?: string; rank?: string }) => (c ? { suit: c.suit, rank: c.rank } : {});
+25 −0 src/viewer/storage.ts added View file
@@ -0,0 +1,25 @@
1+// In Shoal the viewer runs in a frame with scripts only (no same origin), where touching localStorage or
2+// sessionStorage throws. The upstream UI reads both (onboarding, the identity reveal, sound settings), some of it
3+// without a try, so the page gets in-memory stand-ins before any of it loads.
4+for (const name of ['localStorage', 'sessionStorage'] as const) {
5+ try {
6+ void window[name].length;
7+ } catch {
8+ const data = new Map<string, string>();
9+ const memory: Storage = {
10+ get length() {
11+ return data.size;
12+ },
13+ clear: () => data.clear(),
14+ getItem: (k) => data.get(k) ?? null,
15+ key: (i) => [...data.keys()][i] ?? null,
16+ removeItem: (k) => void data.delete(k),
17+ setItem: (k, v) => void data.set(k, String(v)),
18+ };
19+ try {
20+ Object.defineProperty(window, name, { value: memory, configurable: true });
21+ } catch {
22+ // nothing more to do: the upstream code that guards its storage keeps working
23+ }
24+ }
25+}
+19 −0 src/vite.engine.config.ts added View file
@@ -0,0 +1,19 @@
1+// The engine bundle: one ES module for Node 20+, with every skill module the engine imports lazily inlined
2+// (codeSplitting: false, as the upstream's vite.mcp.config.ts does for its MCP server).
3+import { defineConfig } from 'vite';
4+
5+export default defineConfig({
6+ publicDir: false,
7+ build: {
8+ lib: { entry: 'shoal/sgs.ts', formats: ['es'], fileName: () => 'sgs.mjs' },
9+ outDir: 'dist/shoal-engine',
10+ emptyOutDir: true,
11+ minify: false,
12+ sourcemap: false,
13+ target: 'node20',
14+ rollupOptions: {
15+ external: [/^node:/],
16+ output: { codeSplitting: false },
17+ },
18+ },
19+});
+53 −0 src/vite.viewer.config.ts added View file
@@ -0,0 +1,53 @@
1+// The viewer: the upstream's React UI (its Vite, React and Linaria setup from vite.config.ts) with this folder's entry,
2+// as static files with relative paths and no network: one script, one stylesheet, no CDN, no fonts to fetch. The art
3+// pack (viewer/art/, built by src/art.py) is plain files beside them, linked from index.html.
4+//
5+// The look is 无名杀's (viewer/noname/): this folder's own table over the upstream's hooks and action building. When the
6+// upstream's own components (its prompts, action bar and hand) import these modules, they get this folder's instead:
7+// the image lookups (the art pack), the flying cards and the card face (drawn as 无名杀's; a card you play leaves your
8+// hand for the middle of the table), and the style sheet (the same class names, restyled).
9+import path from 'node:path';
10+import { defineConfig, type Plugin } from 'vite';
11+import react from '@vitejs/plugin-react';
12+import wyw from '@wyw-in-js/vite';
13+
14+const NONAME = path.resolve('shoal/viewer/noname');
15+const SWAPS: Record<string, string> = {
16+ 'src/client/assets/imageAssets': 'imageAssets.ts',
17+ 'src/client/utils/cardMoveAnimation': 'flyCards.ts',
18+ 'src/client/utils/cardFlyAnimation': 'flyCards.ts',
19+ 'src/client/components/CardFace': 'CardFace.tsx',
20+ 'src/client/components/gameViewStyles/index': 'styles.ts',
21+};
22+
23+function swap(): Plugin {
24+ return {
25+ name: 'shoal-noname-swap',
26+ enforce: 'pre',
27+ async resolveId(source, importer, opts) {
28+ if (!importer || importer.startsWith(NONAME)) return null;
29+ const r = await this.resolve(source, importer, { ...opts, skipSelf: true });
30+ const id = r?.id.replace(/\.tsx?$/, '');
31+ const hit = id && Object.keys(SWAPS).find((k) => id.endsWith(k));
32+ return hit ? path.join(NONAME, SWAPS[hit]) : null;
33+ },
34+ };
35+}
36+
37+export default defineConfig({
38+ root: 'shoal/viewer',
39+ base: './',
40+ publicDir: false,
41+ plugins: [
42+ swap(),
43+ react({ exclude: ['node_modules/**'] }),
44+ wyw({ sourceMap: false, displayName: false, exclude: ['node_modules/**'], evaluate: true, babelOptions: { presets: ['@babel/preset-typescript'] } }),
45+ ],
46+ build: {
47+ outDir: '../../dist/shoal-viewer',
48+ emptyOutDir: true,
49+ target: 'es2022',
50+ cssMinify: 'esbuild',
51+ rollupOptions: { output: { codeSplitting: false, entryFileNames: 'viewer.js', assetFileNames: 'viewer[extname]' } },
52+ },
53+});
+36 −0 viewer/NOTICE added View file
@@ -0,0 +1,36 @@
1+viewer.js and viewer.css are built (src/build.mjs) from wmzy/sanguosha, https://github.com/wmzy/sanguosha, commit
2+8f4b693b654a6365d143a80003877219f6e08b22 (2026-09-28): its engine, replay player and the logic of its React table (its
3+hooks, prompts, action building and general selection), with this project's entry and table drawing, src/viewer/ (MIT, but for its stylesheet, below).
4+
5+The drawing follows 无名杀 (noname), https://github.com/libnoname/noname, commit 90b58bb9934edb1712fd187a80c8323b7aeabaf3,
6+GPL-3.0: viewer.css reproduces the layout and woodden theme of its stylesheets (layout/mobile, layout/newlayout,
7+layout/default, theme/woodden, theme/style/hp), so treat it as covering GPL-3.0 material. The pictures and fonts it uses
8+are the art pack in art/, taken from 无名杀, with its own NOTICE (art/NOTICE): its 立绘 and card art are mostly the
9+commercial 三国杀 art of 游卡桌游, NOT CLEARED FOR PUBLICATION.
10+
11+Also bundled, each under the MIT licence: React, React DOM and scheduler (Copyright (c) Meta Platforms, Inc. and
12+affiliates) and @linaria/core (Copyright (c) 2017 Callstack).
13+
14+The upstream's licence:
15+
16+MIT License
17+
18+Copyright (c) 2025 三国杀项目作者
19+
20+Permission is hereby granted, free of charge, to any person obtaining a copy
21+of this software and associated documentation files (the "Software"), to deal
22+in the Software without restriction, including without limitation the rights
23+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24+copies of the Software, and to permit persons to whom the Software is
25+furnished to do so, subject to the following conditions:
26+
27+The above copyright notice and this permission notice shall be included in all
28+copies or substantial portions of the Software.
29+
30+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+SOFTWARE.
+26 −0 viewer/art/NOTICE added View file
@@ -0,0 +1,26 @@
1+The art pack: everything in this folder (viewer/art/) except art.css and this NOTICE, which are this project's.
2+
3+NOT CLEARED FOR PUBLICATION. The portraits and card art below are, for the most part, the commercial 三国杀 (Sanguosha)
4+art of 游卡桌游 (Yoka Games), as 无名杀 redistributes it. This pack is here so the viewer can look like 无名杀 while the
5+licence of that art is being sorted out; the user is coordinating it. Do not publish, release or deploy this folder (or
6+a build that includes it) until that is settled. It is kept in its own folder so it can be replaced as a whole, e.g. by
7+art the project owns or has a licence for: the viewer falls back to drawn faces for anything missing.
8+
9+Source: 无名杀 (noname), https://github.com/libnoname/noname, commit 90b58bb9934edb1712fd187a80c8323b7aeabaf3, licensed
10+under the GNU General Public License v3.0 (https://www.gnu.org/licenses/gpl-3.0.html). Its project asks that copies keep
11+the source link above and are not used commercially. Taken from apps/core/ and converted by src/art.py (resized,
12+recompressed to WebP, fonts cut down to the characters the viewer uses):
13+
14+ general/<id>.webp image/character/<id>.jpg generals' portraits (立绘), mapped in src/viewer/noname/art.json
15+ card/<id>.webp image/card/<id>.png card art
16+ theme/grid.png, wood.webp, wood.png, wood2.jpg, wood2.png theme/woodden/ (the woodden theme)
17+ theme/hp1-4.png theme/style/hp/image/glass1-4.png (勾玉)
18+ theme/handcard.png image/card/handcard.png (the hand count's card)
19+ theme/cardback.webp theme/style/cardback/image/official.png (the 三国杀 card back, with the Yoka Games mark)
20+ font/xinwei.woff2, font/huangcao.woff2, font/suits.woff2 font/ (subset)
21+
22+Provenance, as far as 无名杀 records it: most 立绘 and the card art come from 游卡桌游's 三国杀 (its standard, 界限突破,
23+手杀 and 十周年 editions) and are © 游卡桌游 and their artists; the card back is 三国杀's official one. 无名杀 does not
24+hold or grant a licence to that art, and the GPL on its code does not cover it. The woodden theme pieces and the 勾玉
25+images are 无名杀's own (GPL-3.0). The fonts are 华文新魏 (xinwei, STXinwei, © Changzhou SinoType), 黄草 (huangcao) and
26+无名杀's suit symbols, redistributed by 无名杀; their licences for redistribution are not stated there either.
+22 −0 viewer/art/art.css added View file
@@ -0,0 +1,22 @@
1+/* The art pack's hookups: 无名杀's fonts and woodden theme pieces (theme/, font/), its portraits and card art (general/,
2+ card/, named in src/viewer/noname/art.json). Replacing this folder replaces the look; noname.css draws the layout. */
3+@font-face { font-family: 'nm-xinwei'; src: url(font/xinwei.woff2) format('woff2'); font-display: block; }
4+@font-face { font-family: 'nm-huangcao'; src: url(font/huangcao.woff2) format('woff2'); font-display: block; }
5+@font-face { font-family: 'nm-suits'; src: url(font/suits.woff2) format('woff2'); }
6+
7+/* woodden (theme/woodden/style.css): the grid over a slate gradient; wood.jpg for seats, cards and your equipment rows,
8+ wood2.jpg for buttons (its .control and top bar), wood.png for your strip (#mebg) */
9+.nm-arena { background: url(theme/grid.png), linear-gradient(#6c7989, #434b55); }
10+.nm-player, .nm-card, .nm-myequip, .nm-choose, .nm-chooseOptionCard { background-image: url(theme/wood.webp); }
11+.nm-mini, .nm-btn, .nm-skill, .nm-replay select, .nm-moves-list button, .nm-log-toggle, .nm-promptBtn, .nm-promptBtnPrimary, .nm-promptBtnDisabled {
12+ background-image: url(theme/wood2.jpg); }
13+.nm-me { background-image: url(theme/wood.png); }
14+.nm-count { background-image: url(theme/handcard.png); }
15+.nm-judge { background-image: url(theme/wood.webp); }
16+.nm-card.back, .nm-pickHandCard { background-image: url(theme/cardback.webp); }
17+
18+/* the glass 勾玉 (theme/style/hp/glass.css): green, yellow, red as HP falls; grey for each one lost */
19+.nm-jade { background-image: url(theme/hp1.png); }
20+.nm-hp.mid .nm-jade { background-image: url(theme/hp2.png); }
21+.nm-hp.low .nm-jade { background-image: url(theme/hp3.png); }
22+.nm-hp .nm-jade.lost { background-image: url(theme/hp4.png); }
+0 −0 viewer/art/card/bagua.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/baiyin.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/bingliang.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/chitu.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/cixiong.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/dawan.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/dilu.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/fangtian.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/guanshi.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/guding.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/guohe.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/hanbing.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/hualiu.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/huogong.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/jiedao.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/jiu.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/juedou.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/jueying.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/lebu.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/nanman.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/qilin.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/qinggang.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/qinglong.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/renwang.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/sha.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/shan.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/shandian.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/shunshou.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/tao.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/taoyuan.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/tengjia.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/tiesuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/wanjian.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/wugu.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/wuxie.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/wuzhong.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/zhangba.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/zhuahuang.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/zhuge.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/zhuque.webp added View file
Binary file not shown.
+0 −0 viewer/art/card/zixin.webp added View file
Binary file not shown.
+0 −0 viewer/art/font/huangcao.woff2 added View file
Binary file not shown.
+0 −0 viewer/art/font/suits.woff2 added View file
Binary file not shown.
+0 −0 viewer/art/font/xinwei.woff2 added View file
Binary file not shown.
+0 −0 viewer/art/general/caiwenji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/caocao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/caopi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/caoren.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/chendao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/daqiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/dc_caozhi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/dc_liru.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/dengai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/dianwei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/diaochan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/dongzhuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ganning.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/guanqiujian.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/guanyu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/guojia.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/haozhao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/huanggai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/huangyueying.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/huatuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/huaxiong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/jiangwei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/jiaxu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/kuailiangkuaiyue.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/liubei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/liushan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/luji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/lukang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/luxun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/lvbu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/lvmeng.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/machao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/menghuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_caiwenji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_dengai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_dianwei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_dongzhuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_huangzhong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_jiangwei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_liushan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_lusu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_pangde.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_pangtong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_sp_zhugeliang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_sunjian.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_weiyan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_xiahouyuan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_xiaoqiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_xuhuang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_xunyu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_yanwen.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_yuanshao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_zhangzhang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/ol_zhurong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/old_caoren.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/old_zhoutai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/pangtong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_caifuren.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_caocao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_caochong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_caopi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_caozhang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_chengong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_chengpu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_daqiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_diaochan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_fazheng.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_fuhuanghou.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_ganning.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_gongsunzan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_guanyu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_guanzhang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_guohuai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_guohuanghou.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_guojia.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_huanggai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_huangyueying.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_huangzhong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_huatuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_huaxiong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_jianyong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_jiaxu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_jushou.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_liaohua.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_lidian.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_liubei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_lusu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_luxun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_lvbu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_lvmeng.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_machao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_madai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_menghuo.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_pangde.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_simayi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_sunce.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_sunquan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_sunshangxiang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_taishici.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_wangyi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_weiyan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_xiahoudun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_xiahoushi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_xiahouyuan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_xuhuang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_xushu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_xuzhu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_yuanshao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_yuanshu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_yuji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhangchunhua.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhangfei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhanghe.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhangjiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhangliao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhangsong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhaoyun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhenji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhouyu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zhugeliang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/re_zuoci.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/simayi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sp_zhangjiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sp_zhugeliang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sunce.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sunjian.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sunliang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sunquan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/sunshangxiang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/taishici.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/wangji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/wangping.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xiahoudun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xiaoqiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_gaoshun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_handang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_lingtong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_liubiao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_wuguotai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_xusheng.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_yufan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xin_yuji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xunyu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xuyou.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/xuzhu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/yanwen.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/yanyan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/yl_luzhi.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/yujin_yujin.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhangfei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhanghe.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhangliao.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhangxiu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhangzhang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhaoyun.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhenji.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhoufei.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhoutai.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhouyu.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhugeliang.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhugezhan.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zhurong.webp added View file
Binary file not shown.
+0 −0 viewer/art/general/zuoci.webp added View file
Binary file not shown.
+0 −0 viewer/art/theme/cardback.webp added View file
Binary file not shown.
+0 −0 viewer/art/theme/grid.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/handcard.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/hp1.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/hp2.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/hp3.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/hp4.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/wood.png added View file
Binary file not shown.
+0 −0 viewer/art/theme/wood.webp added View file
Binary file not shown.
+0 −0 viewer/art/theme/wood2.jpg added View file
Binary file not shown.
+0 −0 viewer/art/theme/wood2.png added View file
Binary file not shown.
+19 −0 viewer/bridge.js added View file
@@ -0,0 +1,19 @@
1+// The page around a game's viewer hands it the replay (Shoal's public/app.js): the viewer runs in a frame with scripts
2+// only, says it is ready, and gets {shoal: 'replay', name, text}. Opened by itself, it reads ?replay=<file> instead,
3+// so a replay can be watched from a clone: python3 -m http.server, then viewer/index.html?replay=../replays/x.json
4+// A live room (docs/games.md §8.4) opens the viewer as index.html?live. shoalLive(fn) says {shoal: 'ready', live: true}
5+// and calls fn(batch) for each {shoal: 'live', room, you, messages}: you lists the seats this viewer controls, the first
6+// batch holds all the history it may see, and each message is the room's (§8.3) plus its sequence number n: {n, to,
7+// version, obs, legal} asks a seat to act, {n, to, obs} tells one seat, {n, event} is public, {n, end} ends the room.
8+// shoalAct(seat, version, action) plays for a seat in you, answering the request with that version.
9+window.shoalReplay = start => {
10+ addEventListener('message', e => { if (e.data && e.data.shoal === 'replay') start(e.data.text, e.data.name) })
11+ const local = new URLSearchParams(location.search).get('replay')
12+ if (local) fetch(local).then(r => r.text()).then(t => start(t, local))
13+ else if (parent !== window) parent.postMessage({ shoal: 'ready' }, '*')
14+}
15+window.shoalLive = fn => {
16+ addEventListener('message', e => { if (e.data && e.data.shoal === 'live') fn(e.data) })
17+ if (parent !== window) parent.postMessage({ shoal: 'ready', live: true }, '*')
18+}
19+window.shoalAct = (seat, version, action) => parent.postMessage({ shoal: 'act', seat, version, action }, '*')
+14 −0 viewer/index.html added View file
@@ -0,0 +1,14 @@
1+<!doctype html>
2+<html lang="zh-CN">
3+ <head>
4+ <meta charset="UTF-8" />
5+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+ <title>三国杀</title>
7+ <script src="./bridge.js"></script>
8+ <script type="module" crossorigin src="./viewer.js"></script>
9+ <link rel="stylesheet" crossorigin href="./viewer.css">
10+ </head>
11+ <body>
12+ <div id="root"></div>
13+ </body>
14+</html>
+1 −0 viewer/viewer.css added View file
@@ -0,0 +1 @@
1+@keyframes flyToCenter{0%{opacity:1;transform:translate(0) scale(1) rotate(0)}40%{opacity:1;transform:translate(var(--fly-dx, 0),calc(var(--fly-dy, 0) - 30px)) scale(1.1) rotate(-3deg)}to{opacity:0;transform:translate(var(--fly-dx, 0),var(--fly-dy, 0)) scale(.6) rotate(5deg)}}@keyframes damageFlash{0%{color:inherit;transform:scale(1);text-shadow:none}15%{color:#f22;transform:scale(1.5);text-shadow:0 0 12px rgba(255,34,34,.8)}40%{color:#f44;transform:scale(1.25);text-shadow:0 0 8px rgba(255,68,68,.5)}to{color:inherit;transform:scale(1);text-shadow:none}}@keyframes damageShake{0%,to{transform:translate(0)}10%{transform:translate(-6px)}20%{transform:translate(6px)}30%{transform:translate(-5px)}40%{transform:translate(5px)}50%{transform:translate(-3px)}60%{transform:translate(3px)}70%{transform:translate(-2px)}80%{transform:translate(2px)}90%{transform:translate(-1px)}}@keyframes damageOverlay{0%{opacity:0;background:#f000}20%{opacity:1;background:#ff000026}to{opacity:0;background:#f000}}@keyframes healFlash{0%{color:inherit;transform:scale(1);text-shadow:none}15%{color:#2d5;transform:scale(1.5);text-shadow:0 0 12px rgba(34,221,85,.8)}40%{color:#4e6;transform:scale(1.25);text-shadow:0 0 8px rgba(68,238,102,.5)}to{color:inherit;transform:scale(1);text-shadow:none}}@keyframes healOverlay{0%{opacity:0;background:#0f50}20%{opacity:1;background:#00ff552e}to{opacity:0;background:#0f50}}@keyframes hpFloatUp{0%{opacity:0;transform:translate(-50%) scale(.6)}15%{opacity:1;transform:translate(-50%,-8px) scale(1.2)}30%{transform:translate(-50%,-12px) scale(1)}75%{opacity:1}to{opacity:0;transform:translate(-50%,-52px) scale(1)}}@keyframes phaseIn{0%{opacity:0;transform:translateY(8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes newTurnGlow{0%{box-shadow:0 0 #ffd70000}30%{box-shadow:0 0 20px #ffd70080}to{box-shadow:0 0 #ffd70000}}@keyframes chainPulse{0%,to{box-shadow:0 0 10px #96b4c866,inset 0 0 8px #96b4c81f}50%{box-shadow:0 0 18px #b4cddca6,inset 0 0 12px #96b4c833}}@keyframes seatTargetPulse{0%,to{box-shadow:0 0 0 1px #0009,0 0 10px 2px #e74c3c80}50%{box-shadow:0 0 0 1px #0009,0 0 22px 5px #e74c3cd9}}@keyframes activeSeatPulse{0%,to{outline-color:#ffd700f2}50%{outline-color:#ffd70073}}@keyframes endTurnBreath{0%,to{box-shadow:inset 0 1px #fff3,0 3px 12px #c4362666,0 0 14px #e74c3c38}50%{box-shadow:inset 0 1px #fff3,0 3px 12px #c4362680,0 0 26px #e74c3c73}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes identityCardFlip{0%{transform:rotateY(180deg) scale(.5);opacity:0}60%{transform:rotateY(-20deg) scale(1.05);opacity:1}80%{transform:rotateY(5deg) scale(.98);opacity:1}to{transform:rotateY(0) scale(1);opacity:1}}@keyframes overlayFadeIn{0%{opacity:0}to{opacity:1}}@keyframes overlayFadeOut{0%{opacity:1}to{opacity:0}}@keyframes cardJudgePendingIn{0%{opacity:0;transform:translateY(-12px) scale(.85)}15%{opacity:1;transform:translateY(0) scale(1)}72%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(-8px) scale(.95)}}@keyframes cardFlipIn{0%{opacity:0;transform:translateY(-24px) scale(.6) rotateY(180deg)}15%{opacity:1;transform:translateY(-8px) scale(.85) rotateY(130deg)}30%{opacity:1;transform:translateY(0) scale(1.06) rotateY(-10deg)}38%{opacity:1;transform:translateY(0) scale(.99) rotateY(3deg)}45%{opacity:1;transform:translateY(0) scale(1) rotateY(0)}72%{opacity:1;transform:translateY(0) scale(1) rotateY(0)}to{opacity:0;transform:translateY(-20px) scale(.95) rotateY(0)}}@keyframes revealCardIn{0%{opacity:0;transform:translateY(-24px) scale(.6) rotateY(180deg)}25%{opacity:1;transform:translateY(-8px) scale(.9) rotateY(120deg)}50%{opacity:1;transform:translateY(0) scale(1.05) rotateY(-8deg)}65%{opacity:1;transform:translateY(0) scale(.99) rotateY(2deg)}80%,to{opacity:1;transform:translateY(0) scale(1) rotateY(0)}}@keyframes bannerIn{0%{opacity:0;transform:translate(-50%,calc(-50% - 16px)) scale(.9)}60%{opacity:1;transform:translate(-50%,calc(-50% + 2px)) scale(1.04)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}@keyframes playHistoryIn{0%{opacity:0;transform:translateY(8px) scale(.92)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes flyCardMove{0%{opacity:0;transform:translate(0) scale(.6)}12%{opacity:1;transform:translate(0) scale(1)}82%{opacity:1;transform:translate(var(--fly-dx, 0),var(--fly-dy, 0)) scale(1)}to{opacity:0;transform:translate(var(--fly-dx, 0),var(--fly-dy, 0)) scale(.8)}}@keyframes arrowPulse{0%,to{opacity:.85}50%{opacity:1}}@keyframes fade{0%{opacity:1}to{opacity:0}}@keyframes shake{0%,to{transform:translate(0)}20%{transform:translate(-6px)}40%{transform:translate(6px)}60%{transform:translate(-4px)}80%{transform:translate(4px)}}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.08)}}@keyframes slide{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes highlight{0%,to{box-shadow:0 0 #ffc80000}50%{box-shadow:0 0 12px 4px #ffc800b3}}@keyframes flash{0%{opacity:0}30%{opacity:.8}to{opacity:0}}@keyframes countdownUrgentPulse{0%,to{opacity:1}50%{opacity:.55}}:root{--card-w: 104px;--card-h: 120px;--seat-w: 148px;--seat-h: 178px;--me-h: 140px;--ui: "PingFang SC", "STHeiti", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif;--brush: "nm-xinwei", "STXinwei", "KaiTi", serif;--grass: "nm-huangcao", "nm-xinwei", "STXingkai", serif;--text-edge: 0 0 2px #000, 0 0 2px #000, 0 0 3px #000}html,body{margin:0;height:100%;overflow:hidden;background:#434b55;color:#fff;font-family:var(--ui)}#root,.nm-root{height:100%}.shoal-wait{color:#e8e2d0;font:18px/1.5 var(--ui);padding:40px;text-align:center;text-shadow:var(--text-edge)}.nm-root{position:relative;user-select:none;-webkit-user-select:none}.nm-scaler{position:absolute;inset:0;overflow:hidden;background:#434b55}.nm-canvas{position:absolute;left:0;top:0;transform-origin:0 0}.nm-arena{position:absolute;inset:0;overflow:hidden;text-shadow:var(--text-edge)}.nm-arena button{font-family:var(--ui)}.nm-topbar{position:absolute;left:0;right:0;top:0;height:40px;z-index:30;pointer-events:none}.nm-topbar>*{pointer-events:auto}.nm-round,.nm-pile{position:absolute;top:9px;font:15px/20px var(--brush);letter-spacing:.5px;white-space:nowrap}.nm-pile{left:calc(50% - 4px);transform:translate(-100%)}.nm-pile b,.nm-round b{font-weight:400;margin:0 2px}.nm-round{left:calc(50% + 4px)}.nm-discards{margin-right:10px}.nm-turn-of{margin-left:8px;color:#ffe9a3}.nm-phase{margin-left:4px;color:#ffe9a3}.nm-top-slot{position:absolute;left:10px;top:10px;display:flex;gap:8px;align-items:flex-start}.nm-replay,.nm-moves{display:flex;gap:8px;align-items:center}.nm-top-side{position:absolute;right:66px;top:10px;display:flex;gap:8px}.nm-mini,.nm-replay select,.nm-log-toggle,.nm-moves-list button{height:27px;min-width:32px;padding:0 8px;border:0;border-radius:4px;cursor:pointer;color:#4d3c33cc;font:15px/27px var(--ui);text-shadow:none;background-size:auto;background-position:center;box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px}.nm-mini:hover:not(:disabled),.nm-log-toggle:hover{filter:brightness(1.08)}.nm-mini:disabled{opacity:.55;cursor:default}.nm-mini.on,.nm-mini.play{color:#631515}.nm-replay select{padding:0 4px;appearance:none;-webkit-appearance:none;text-align:center}.nm-replay input[type=range]{width:120px;accent-color:#9b7a4c}.nm-step{font:13px var(--brush);min-width:64px;text-align:center}.nm-moves{position:relative}.nm-moves-list{position:absolute;top:34px;left:0;display:flex;flex-direction:column;gap:5px;max-height:420px;overflow:auto;padding:6px;border-radius:6px;background:#00000059}.nm-moves-list button{height:auto;line-height:1.35;padding:4px 8px;text-align:left;white-space:nowrap}.nm-seat{position:absolute;width:var(--seat-w);height:var(--seat-h);transform:translate(-50%,-50%) scale(var(--seat-scale, 1));z-index:4}.nm-player{position:absolute;inset:0;border-radius:8px;background-size:cover;box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px;transition:box-shadow .3s,transform .3s,filter .3s}.nm-avatar{position:absolute;inset:3px;border-radius:6px;background:#00000040 center 18% / cover no-repeat;overflow:hidden}.nm-avatar-none{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font:26px var(--brush);writing-mode:vertical-rl;opacity:.85}.nm-frame{position:absolute;inset:3px;border-radius:6px;box-shadow:inset 0 0 0 1px #ffffff40,inset 0 0 8px #00000059;pointer-events:none}.nm-player.wei .nm-avatar-none{color:#9fc5ff}.nm-player.shu .nm-avatar-none{color:#ffb08a}.nm-player.wu .nm-avatar-none{color:#b2f0a0}.nm-player.qun .nm-avatar-none{color:#e6e0cf}.nm-name{position:absolute;left:7px;top:30px;font:19px/19px var(--brush);writing-mode:vertical-rl;white-space:nowrap;letter-spacing:1px;z-index:3;text-shadow:0 0 2px #000,0 0 2px #000,0 0 4px #000}.nm-name.long{font-size:16px;line-height:16px;letter-spacing:0}.nm-faction{position:absolute;left:6px;top:7px;width:20px;height:20px;font:17px/20px var(--brush);text-align:center;z-index:3;text-shadow:0 0 2px #000,0 0 3px #000}.wei .nm-faction,.nm-faction.wei{color:#7ab6ff}.shu .nm-faction,.nm-faction.shu{color:#ff8e62}.wu .nm-faction,.nm-faction.wu{color:#8fe36f}.qun .nm-faction,.nm-faction.qun{color:#e7d9a7}.shen .nm-faction,.nm-faction.shen{color:#ffd84a}.wei .nm-name{color:#e8f1ff}.shu .nm-name{color:#fff0e8}.wu .nm-name{color:#f0ffe8}.nm-hp{position:absolute;right:6px;bottom:8px;display:flex;flex-direction:column-reverse;gap:2px;z-index:3}.nm-jade{display:block;width:15px;height:15px;background:center / 100% 100% no-repeat;filter:drop-shadow(0 0 1px rgba(0,0,0,.7))}.nm-jade.lost{filter:grayscale(1) brightness(.7)}.nm-hp.text{flex-direction:row;align-items:center;gap:2px;font:17px var(--brush)}.nm-hp.text.mid span{color:#ffe86b}.nm-hp.text.low span{color:#ff6b5b}.nm-count{position:absolute;right:-14px;bottom:-14px;width:28px;height:28px;background:center / cover no-repeat;z-index:5;font:bold 17px/28px var(--brush);text-align:center;color:#fff;text-shadow:0 0 2px #000,0 0 2px #000}.nm-identity{position:absolute;right:-8px;top:-7px;width:24px;height:26px;z-index:6;font:21px/26px var(--grass);text-align:center;color:#fff;text-shadow:0 0 3px #1f6fe0,0 0 6px #1f6fe0,0 0 2px #000}.nm-identity.zhu{text-shadow:0 0 3px #e0241f,0 0 7px #e0241f,0 0 2px #000}.nm-identity.zhong{text-shadow:0 0 3px #e0b21f,0 0 7px #e0b21f,0 0 2px #000}.nm-identity.fan{text-shadow:0 0 3px #3ac53a,0 0 7px #3ac53a,0 0 2px #000}.nm-identity.nei{text-shadow:0 0 3px #9a3ae0,0 0 7px #9a3ae0,0 0 2px #000}.nm-identity.unknown{font-size:0}.nm-identity.unknown:before{content:"猜";font-size:21px}.nm-identity.inline{position:static;display:inline-block;width:22px;height:22px;font-size:18px;line-height:22px;margin-right:4px}.nm-identity.inline.unknown:before{font-size:18px}.nm-equips{position:absolute;left:3px;right:24px;bottom:8px;display:flex;flex-direction:column;gap:2px;z-index:4;pointer-events:auto}.nm-equip{display:flex;gap:3px;align-items:center;height:22px;padding:0 5px;font:14px/22px var(--ui);white-space:nowrap;overflow:hidden;background:linear-gradient(to right,rgba(0,0,0,.3),transparent),linear-gradient(135deg,rgba(0,0,0,.5),transparent 80%,transparent)}.nm-equip .nm-equip-info{order:-1;font-family:"nm-suits",var(--ui);font-size:13px;color:#fff}.nm-equip .nm-equip-info.red{color:#ff8a80}.nm-equip .nm-equip-slot{display:none}.nm-judges{position:absolute;right:-30px;top:26px;display:flex;flex-direction:column;gap:4px;z-index:5}.nm-judge{position:relative;width:24px;height:24px;border-radius:4px;background-size:cover;box-shadow:#0000004d 0 0 0 1px,#00000073 0 2px 5px}.nm-judge>i{position:absolute;inset:0;background:center / 130% no-repeat;border-radius:4px}.nm-judge>b{position:absolute;right:-2px;bottom:-4px;font:normal 13px var(--grass);color:#fff;text-shadow:0 0 2px #000,0 0 3px #000}.nm-player.current{box-shadow:#0003 0 0 0 1px,#ffcb00f2 0 0 5px 2px,#ffa000b3 0 0 16px 4px}.nm-phase-mark{position:absolute;left:50%;top:-12px;transform:translate(-50%);padding:0 8px;height:20px;border-radius:10px;z-index:6;font:13px/20px var(--brush);background:linear-gradient(#b8892f,#7d5916);box-shadow:0 1px 3px #0009;white-space:nowrap}.nm-seat.pick{cursor:pointer}.nm-player.selectable{box-shadow:#0003 0 0 0 1px,#0a78ff 0 0 5px 2px,#0a78ffcc 0 0 14px 4px}.nm-player.selected{box-shadow:#0003 0 0 0 1px,red 0 0 5px 2px,#ff0000bf 0 0 14px 4px;transform:scale(1.04)}.nm-player.unselectable{filter:brightness(.55)}.nm-distance{position:absolute;left:50%;bottom:6px;transform:translate(-50%);padding:0 6px;border-radius:9px;background:#0000008c;font:12px/18px var(--ui);z-index:4}.nm-chain{position:absolute;left:-2px;right:-2px;top:calc(50% - 6px);height:12px;z-index:5;pointer-events:none;background:repeating-linear-gradient(90deg,#9aa3ad 0 9px,transparent 9px 12px,#6d757e 12px 17px,transparent 17px 20px);border-radius:3px;box-shadow:0 1px 3px #000000b3;animation:nm-chain .4s ease-out}@keyframes nm-chain{0%{transform:translate(-30px);opacity:0}}.nm-flipped{position:absolute;inset:3px;border-radius:6px;background:#000000b8;z-index:4;display:flex;align-items:center;justify-content:center;font:40px var(--brush);writing-mode:vertical-rl;color:#ffffffd9}.nm-seat .nm-player.chained{transform:rotate(-90deg)}.nm-seat .nm-player.chained.selected{transform:rotate(-90deg) scale(1.04)}.nm-seat .nm-player.chained .nm-judges{transform:rotate(90deg) translate(10px)}.nm-player.dying .nm-avatar{animation:nm-dying 1s ease-in-out infinite alternate}@keyframes nm-dying{to{filter:sepia(.6) saturate(3) hue-rotate(-30deg) brightness(.8)}}.nm-dying{position:absolute;left:50%;top:42%;transform:translate(-50%,-50%);font:30px var(--grass);color:#ff3b2f;z-index:6;text-shadow:0 0 3px #000,0 0 8px #600}.nm-player.dead{transform:rotate(-8deg);filter:grayscale(1) brightness(.85);box-shadow:#0000004d 0 0 0 1px,#0000004d 0 3px 8px}.nm-player.dead .nm-hp,.nm-player.dead .nm-count,.nm-player.dead .nm-equips,.nm-player.dead .nm-judges,.nm-player.dead .nm-identity{display:none}.nm-dead{position:absolute;inset:0;z-index:6;display:flex;flex-direction:column;align-items:center;justify-content:center;font:22px var(--brush);color:#fffc;text-shadow:0 0 3px #000}.nm-dead b{font:normal 54px/60px var(--grass);color:#1e1e1ed9;text-shadow:0 0 2px #fff,0 0 6px rgba(255,255,255,.8);letter-spacing:4px}.nm-player.damaged{animation:nm-shake .45s}.nm-player.damaged .nm-avatar:after{content:"";position:absolute;inset:0;background:#ff00008c;animation:nm-flash .6s forwards}.nm-player.healed .nm-avatar:after{content:"";position:absolute;inset:0;background:#3cff5a66;animation:nm-flash .8s forwards}@keyframes nm-shake{15%,55%{transform:translate(-6px)}35%,75%{transform:translate(6px)}}@keyframes nm-flash{to{opacity:0}}.nm-hpfloat{position:absolute;left:50%;top:40%;z-index:8;transform:translate(-50%,-50%);font:72px var(--grass);pointer-events:none;animation:nm-rise 1.3s ease-out forwards}.nm-hpfloat.damage{color:#fff;text-shadow:#000 0 0 1px,#e83535 0 0 2px,#e83535 0 0 5px,#e83535 0 0 10px,#e83535 0 0 10px,#e83535 0 0 20px,#e83535 0 0 20px}.nm-hpfloat.heal{color:#fff;text-shadow:#000 0 0 1px,#397b04 0 0 2px,#397b04 0 0 5px,#397b04 0 0 10px,#397b04 0 0 10px,#397b04 0 0 20px,#397b04 0 0 20px}@keyframes nm-rise{0%{opacity:0;transform:translate(-50%,-20%) scale(1.6)}15%{opacity:1;transform:translate(-50%,-50%) scale(1)}80%{opacity:1}to{opacity:0;transform:translate(-50%,-110%)}}.nm-seat-label{position:absolute;left:0;right:0;bottom:-20px;text-align:center;font:12px/16px var(--ui);color:#ffffffb3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nm-timer{position:absolute;left:6px;right:6px;bottom:-8px;height:4px;border-radius:2px;background:#0006;overflow:hidden;z-index:7}.nm-timer-fill{height:100%;background:linear-gradient(90deg,#ffb31a,#ffe066);box-shadow:0 0 4px #fc3}.nm-card{position:relative;width:var(--card-w);height:var(--card-h);border-radius:4px;background-size:cover;color:#3b2a1c;text-shadow:none;overflow:hidden;box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px;font-family:var(--brush)}.nm-card-fill{position:absolute!important;inset:0;width:auto;height:auto}.nm-card-art{position:absolute;left:0;right:0;top:8px;height:110px;background:center / cover no-repeat}.nm-card-big{position:absolute;inset:22px 6px 6px;display:flex;align-items:center;justify-content:center;font:38px var(--brush);color:#3b2a1cbf}.nm-card-name{position:absolute;left:6px;top:7px;padding:2px 0;width:19px;border:1px solid rgba(59,42,28,.85);border-radius:4px;background:#e9dec88c;font:16px/17px var(--brush);writing-mode:vertical-rl;text-align:center;white-space:nowrap;z-index:2}.nm-card-name.long{font-size:14px;line-height:17px}.nm-card-info{position:absolute;right:7px;top:5px;font:17px/20px var(--brush);z-index:2;white-space:nowrap;color:#2b2017}.nm-card-info .nm-suit,.nm-equip-info,.nm-suit{font-family:"nm-suits",var(--ui)}.nm-card-info .nm-suit{margin-right:2px;font-size:15px}.nm-card-info.red{color:#b0211a}.nm-card.fire .nm-card-name{color:#c62a12;border-color:#c62a12}.nm-card.thunder .nm-card-name{color:#1e4fb4;border-color:#1e4fb4}.nm-card.fire .nm-card-art{filter:sepia(.3) saturate(1.6) hue-rotate(-15deg)}.nm-card.thunder .nm-card-art{filter:hue-rotate(180deg) saturate(.9)}.nm-card.back{background-size:cover}.nm-card.back>*{display:none}.nm-center{position:absolute;left:0;right:0;top:296px;height:150px;z-index:6;pointer-events:none}.nm-played-row{display:flex;justify-content:center;gap:6px}.nm-played{position:relative;display:flex;flex-direction:column;align-items:center;animation:nm-fade 4.2s forwards}.nm-played.shown{animation:none}.nm-played .nm-card{box-shadow:#00000040 0 0 0 1px,#00000080 0 4px 12px}.nm-played-caption{margin-top:3px;max-width:150px;font:13px/16px var(--ui);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@keyframes nm-fade{0%,82%{opacity:1}to{opacity:0}}.nm-discard{position:absolute;left:50%;top:0;width:1px;height:1px}.nm-lines{position:absolute;inset:0;width:100%;height:100%;z-index:28;pointer-events:none;overflow:visible}.nm-line line{stroke:#ffffffeb;stroke-width:2.5;stroke-linecap:round;filter:drop-shadow(0 0 3px rgba(255,255,255,.8));stroke-dashoffset:var(--len);animation:nm-draw .35s ease-out forwards,nm-fade 1.4s forwards}.nm-line.sha line{stroke:#ffecd6f2;filter:drop-shadow(0 0 3px rgba(255,60,30,.9))}.nm-line circle{fill:#ffffffd9;opacity:0;animation:nm-hit 1.2s .3s forwards}.nm-line.sha circle{fill:#ff5032e6}@keyframes nm-draw{to{stroke-dashoffset:0}}@keyframes nm-hit{0%{opacity:0;r:2}20%{opacity:1;r:9}to{opacity:0;r:14}}.nm-cardeffect{position:absolute;z-index:29;transform:translate(-50%,-50%);font:84px/1 var(--grass);color:#ffe27a;pointer-events:none;white-space:nowrap;text-shadow:0 0 2px #3a2400,0 0 3px #3a2400,0 0 12px rgba(255,180,0,.9);animation:nm-effect 1.1s ease-out forwards}.nm-cardeffect.sha{color:#fff0d0;text-shadow:0 0 2px #400,0 0 3px #400,0 0 14px rgba(255,40,0,.95)}@keyframes nm-effect{0%{opacity:0;transform:translate(-50%,-50%) scale(.5)}25%{opacity:1;transform:translate(-50%,-50%) scale(1.05)}70%{opacity:1}to{opacity:0;transform:translate(-50%,-50%) scale(1.15)}}.nm-fly{position:fixed;width:0;height:0;z-index:9998;pointer-events:none;animation-name:nm-fly;animation-timing-function:cubic-bezier(.25,.7,.3,1);animation-fill-mode:forwards}.nm-fly>.nm-card{position:absolute;left:calc(var(--card-w) * -.5 + (var(--i) - (var(--n) - 1) / 2) * 28px);top:calc(var(--card-h) * -.5);transform:scale(var(--s))}@keyframes nm-fly{0%{opacity:0;transform:translate(0) scale(.7)}15%{opacity:1;transform:translate(0) scale(1)}85%{opacity:1}to{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.9)}}.nm-dock{position:absolute;left:0;right:0;bottom:calc(var(--me-h) + 8px);z-index:20;display:flex;flex-direction:column;align-items:center;gap:10px;pointer-events:none}.nm-dock>*{pointer-events:auto}.nm-tip,.nm-promptDesc{font:20px/26px var(--ui);text-align:center;max-width:760px}.nm-tip b{font-weight:400;color:#ffe08a}.nm-promptBoxAwaiting,.nm-promptBox{display:flex;flex-direction:column;align-items:center;gap:10px;max-width:900px}.nm-promptTitle,.nm-promptDescInline,.nm-autoSkipToggle,.nm-slashCountBadge{display:none!important}.nm-promptDesc span{opacity:.9}.nm-waitingHint{font:16px var(--ui);opacity:.8}.nm-promptActions,.nm-promptActionsWrap{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:8px;max-width:900px}.nm-promptDescFull{width:100%;text-align:center;font:14px var(--ui);opacity:.85}.nm-control{display:flex;gap:10px;justify-content:center;align-items:center;min-height:30px}.nm-btn,.nm-promptBtn,.nm-promptBtnPrimary,.nm-promptBtnDisabled,.nm-chooseOptionCard{height:30px;min-width:54px;padding:0 9px;border:0;border-radius:4px;cursor:pointer;background-size:auto;background-position:center;color:#4d3c33cc;text-shadow:none;font:19px/30px var(--ui);box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px;white-space:nowrap;transition:filter .15s,opacity .15s}.nm-btn:hover:not(:disabled),.nm-promptBtn:hover,.nm-promptBtnPrimary:hover,.nm-chooseOptionCard:hover{filter:brightness(1.08)}.nm-btn.ok,.nm-promptBtnPrimary{color:#4d3c33f2}.nm-btn:disabled,.nm-promptBtnDisabled{opacity:.5;cursor:default}.nm-btn.end{position:absolute;left:174px}.nm-chooseOptionCard{height:auto;padding:6px 10px;display:flex;flex-direction:column;line-height:1.3;border:0!important;background-color:transparent!important}.nm-chooseOptionCardName{font:18px var(--brush)}.nm-chooseOptionCardSkills{font-size:12px}.nm-pickHandRow{display:flex;gap:6px;flex-wrap:wrap;justify-content:center}.nm-pickHandCard{position:relative;width:62px;height:72px;border:0;border-radius:4px;padding:0;cursor:pointer;background-size:cover;box-shadow:#0000004d 0 0 0 1px,#00000080 0 3px 8px}.nm-pickHandCard>*:not(.nm-pickHandIndex){opacity:0}.nm-pickHandIndex{position:absolute;right:3px;bottom:2px;font:14px var(--brush);color:#fff;text-shadow:var(--text-edge)}.nm-pickedByTag{margin-left:6px;font-size:12px;opacity:.8}.nm-me{position:absolute;left:0;right:0;bottom:0;height:var(--me-h);background-size:100% 100%;z-index:10;box-shadow:#00000040 0 -1px,#0000004d 0 -2px 10px}.nm-me .nm-player.mine{inset:0 auto 0 0;width:120px;border-radius:0;box-shadow:none;background:none}.nm-me .nm-player.mine .nm-avatar{inset:0;border-radius:0}.nm-me .nm-player.mine .nm-frame{inset:0;border-radius:0;box-shadow:inset -1px 0 #0000004d}.nm-me .nm-player.mine .nm-count{right:auto;left:4px;bottom:6px;transform:rotate(-8deg)}.nm-me .nm-player.mine .nm-identity{right:-10px;top:-9px}.nm-me .nm-player.mine .nm-judges{right:auto;left:4px;top:-28px;flex-direction:row}.nm-me .nm-player.mine .nm-phase-mark{top:-24px}.nm-me .nm-player.mine.current{box-shadow:#ffcb00f2 0 0 4px 2px;z-index:2}.nm-me .nm-player.mine.dead{transform:none}.nm-me.spectating .nm-player.mine{filter:none}.nm-me-label{position:absolute;left:0;width:120px;bottom:-1px;display:none}.nm-myequips{position:absolute;right:0;top:0;bottom:0;width:120px;display:flex;flex-direction:column;box-shadow:-1px 0 #00000040,-2px 0 8px #00000026}.nm-myequip{flex:1;display:flex;align-items:center;gap:5px;padding:0 6px;background-size:cover;color:#4d3c33e6;text-shadow:none;font:15px var(--ui);border-bottom:1px solid rgba(77,60,51,.3);white-space:nowrap;overflow:hidden}.nm-myequip .nm-equip-slot{width:18px;font:12px var(--brush);color:#4d3c338c}.nm-myequip.empty .nm-equip-slot{color:#4d3c334d}.nm-myequip .nm-equip-info{order:-1;font-size:14px;color:#4d3c33e6}.nm-myequip .nm-equip-info.red{color:#b0211a}.nm-myequip.usable,.nm-myequip.candidate{cursor:pointer;box-shadow:inset 0 0 0 2px #0a78ffcc}.nm-myequip.picked{box-shadow:inset 0 0 0 2px #f00c}.nm-skills{position:absolute;right:128px;bottom:calc(var(--me-h) + 8px);display:flex;flex-direction:row-reverse;gap:8px;z-index:21}.nm-skill{height:30px;padding:0 10px;border:0;border-radius:4px;cursor:pointer;font:19px/30px var(--brush);color:#4d3c33e6;text-shadow:none;background-size:auto;background-position:center;box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px}.nm-skill.on{color:#6b1a0c;box-shadow:#0003 0 0 0 1px,#ffc400e6 0 0 6px 1px,#00000073 0 3px 10px}.nm-skill:disabled{opacity:.5;cursor:default}.nm-skill.passive{display:none}.nm-hand{position:absolute;inset:10px 128px 0}.nm-hand>.nm-timer{inset:-6px auto auto 0;width:280px}.nm-handColumn{position:absolute;inset:0}.nm-handHeader,.nm-handTitle,.nm-phaseStrip,.nm-phaseStripBadge,.nm-debugHint,.nm-distHint{display:none}.nm-handList{position:absolute;inset:0;display:flex;align-items:flex-start;padding-left:6px}.nm-handList>div{flex:0 1 112px;min-width:20px;position:relative}.nm-handList>div:last-of-type{flex:0 0 auto}.nm-handCard{position:relative;width:var(--card-w);height:var(--card-h);border-radius:4px;cursor:default;transition:transform .2s,opacity .2s,filter .2s;--fan-angle: 0deg !important;box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px}.nm-handCard:hover:hover{transform:translateY(-6px)!important;box-shadow:#0003 0 0 0 1px,#00000080 0 6px 14px!important;filter:none!important}.nm-handCardPlayable,.nm-handCardRespondable,.nm-handCardDiscardable,.nm-handCardTransform,.nm-handCardDistributeCandidate{cursor:pointer}.nm-handCardDisabled,.nm-handCardTransformDisabled{opacity:1}.nm-arena:not(.readonly) .nm-handCardDisabled .nm-card:after,.nm-handCardTransformDisabled .nm-card:after{content:"";position:absolute;inset:0;background:#f0ece485}.nm-handCard.nm-handCardSelected,.nm-handCard.nm-handCardRespondSelected,.nm-handCard.nm-discardCardSelected,.nm-handCard.nm-handCardDistributeSelected,.nm-handCard.nm-handCardSelected:hover:hover,.nm-handCard.nm-handCardRespondSelected:hover:hover,.nm-handCard.nm-discardCardSelected:hover:hover,.nm-handCard.nm-handCardDistributeSelected:hover:hover{transform:translateY(-20px)!important;box-shadow:#0003 0 0 0 1px,red 0 0 4px 2px,#f009 0 0 12px 3px!important}.nm-handCardDistributeAllocated{opacity:.6}.nm-handCardTimeoutFallback{box-shadow:#ffaa00e6 0 0 5px 2px!important}.nm-handCardMeta{position:absolute;left:0;right:0;bottom:0;z-index:3;padding:2px 0;background:#0000008c;text-align:center;color:#fff;text-shadow:var(--text-edge)}.nm-handCardMeta .nm-cardName{font:16px var(--brush)}.nm-cardOrigin{font-size:11px;opacity:.85}.nm-backs{position:absolute;inset:0;display:flex;padding-left:6px}.nm-backs>.nm-card{flex:0 0 auto;margin-right:-40px}.nm-emptyHand{padding:46px 20px;font:15px var(--ui);color:#4d3c3399;text-shadow:none;white-space:nowrap}.nm-distExternalWrap{position:absolute;left:0;bottom:calc(100% + 60px);display:flex;flex-direction:column;gap:6px}.nm-distExternalLabel{font:15px var(--ui)}.nm-distExternalList{display:flex;gap:6px}.nm-distExternalCard{position:relative;width:64px;height:80px;border-radius:4px;padding:6px;background:#e9dec8e6;color:#3b2a1c;text-shadow:none;cursor:pointer;font:15px var(--brush)}.nm-handCardDistributeCandidate{box-shadow:#0a78ffe6 0 0 4px 2px!important}.nm-log{position:absolute;right:10px;top:10px;width:236px;z-index:25;display:flex;flex-direction:column;align-items:flex-end;gap:6px}.nm-log-lines{width:100%;max-height:220px;overflow-y:auto;padding:2px 4px;box-sizing:border-box;font:13px/18px var(--ui);text-align:left;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.nm-log.open .nm-log-lines{border-radius:6px;background:#1e242c8c;padding:4px 8px}.nm-log-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nm-log-line .who{color:#8ec5ff}.nm-log-line .card{color:#ffe45c}.nm-dialog-mask{position:absolute;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#00000026}.nm-dialog{max-width:1040px;box-sizing:border-box;padding:14px 18px 16px;border-radius:6px;background:#282e38b8;box-shadow:#0000004d 0 0 0 1px,#00000073 0 3px 16px;display:flex;flex-direction:column;align-items:center;gap:12px}.nm-dialog-title{font:21px var(--ui)}.nm-dialog-wait{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);z-index:50;font:20px var(--ui)}.nm-choose-row{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;max-width:980px}.nm-choose{position:relative;width:104px;height:130px;padding:0;border:0;border-radius:8px;cursor:pointer;background-size:cover;color:#fff;text-shadow:var(--text-edge);box-shadow:#0003 0 0 0 1px,#00000073 0 3px 10px;transition:transform .15s,box-shadow .15s}.nm-choose:hover{transform:translateY(-3px)}.nm-choose.selected{box-shadow:#0003 0 0 0 1px,red 0 0 5px 2px,#ff0000b3 0 0 14px 4px}.nm-choose .nm-faction{left:auto;right:6px}.nm-choose .nm-name{top:8px}.nm-choose .nm-hp{bottom:28px}.nm-choose .nm-jade{width:13px;height:13px}.nm-choose-skills{position:absolute;left:3px;right:3px;bottom:3px;padding:2px 0;border-radius:0 0 6px 6px;background:#0000008c;font:13px/17px var(--brush);display:flex;justify-content:center;gap:6px;flex-wrap:wrap}.nm-dialog .nm-timer{position:relative;left:0;right:0;bottom:0;width:100%}.nm-control.in-dialog{margin-top:2px}.nm-dialog.result{min-width:560px}.nm-result-title{font:44px var(--grass);letter-spacing:6px;color:#ffe9a3;text-shadow:0 0 3px #000,0 0 12px #c08000}.nm-dialog.result.lose .nm-result-title{color:#d9d9d9;text-shadow:0 0 3px #000,0 0 12px #444}table.nm-result{border-collapse:collapse;font:15px var(--ui)}.nm-result td{padding:4px 12px;border-bottom:1px solid rgba(255,255,255,.12);white-space:nowrap}.nm-result tr.won td{color:#ffe9a3}.nm-result tr.dead td{opacity:.7}.nm-result-name{font:19px var(--brush)}.nm-result-face{display:block;width:34px;height:34px;border-radius:4px;background:#333 center 18% / cover}[role=tooltip]{font-family:var(--ui)!important}.pindiq{font-family:Noto Sans SC,PingFang SC,sans-serif;background-color:#1a1a2e;color:#eee;height:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:hidden;--hero-card-h:200px}.h1fj10rw{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;padding:6px 12px;background:linear-gradient(#0a0a12b8,#06060ca8);border-bottom:1px solid rgba(196,162,84,.3);box-shadow:0 1px #ffe8aa0a}.b1srmvi3{border:1px solid rgba(255,255,255,.16);border-radius:999px;padding:3px 12px;cursor:pointer;background:#ffffff08;color:#cfcabb;font-size:12px;line-height:1.5;-webkit-transition:all .15s;transition:all .15s}.b1srmvi3:hover{border-color:#d9b45ca6;color:#ecd9a8;background:#d9b45c14}.h1vhoy77{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:10px;font-size:13px}.rreharb{background:#14223ed9;border:1px solid rgba(90,130,190,.3);border-radius:999px;padding:2px 10px;font-size:11px;color:#8fa8c8}.p14u2chb{background:linear-gradient(#d6761ae6,#b45c10e6);border-radius:999px;padding:2px 10px;font-size:11px;color:#fff;font-weight:700;box-shadow:inset 0 1px #ffdca040}.c1iesxt0{color:#f0d78a;font-size:12px;letter-spacing:.5px}.hwdcipj{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:6px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.p1m01srd{border:1px solid rgba(82,150,220,.55);border-radius:999px;padding:3px 12px;cursor:pointer;background:#3478c81f;color:#7db8e8;font-size:12px;line-height:1.5;-webkit-transition:all .15s;transition:all .15s}.p1m01srd:hover{border-color:#78b4f0cc;background:#3478c838}.g54tgz6{border:1px solid rgba(255,255,255,.16);border-radius:999px;padding:3px 12px;cursor:pointer;background:#ffffff08;color:#b7b2a4;font-size:12px;line-height:1.5;-webkit-transition:all .15s;transition:all .15s}.g54tgz6:hover{border-color:#d9b45ca6;color:#ecd9a8;background:#d9b45c14}.txsypp3{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px}.tan3r9k{border:1px solid rgba(255,255,255,.16);border-radius:999px;padding:3px 9px;cursor:pointer;background:#ffffff08;color:#cfcabb;font-size:14px;line-height:1;-webkit-transition:all .15s;transition:all .15s}.tan3r9k:hover{border-color:#d9b45ca6;color:#ecd9a8;background:#d9b45c14}.pmjrgps{position:absolute;top:calc(100% + 6px);right:0;z-index:1000;box-shadow:0 8px 24px #00000080}.m1dzrar7{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;min-height:0;overflow:hidden}.bsxuigg{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;position:relative;background:radial-gradient(ellipse 62% 55% at 50% 44%,rgba(112,86,44,.22),transparent 68%),radial-gradient(ellipse 90% 80% at 50% 50%,transparent 55%,rgba(4,5,12,.55) 100%);min-width:0;overflow:hidden}.bsxuigg:before{content:"";position:absolute;inset:10px 14px;pointer-events:none;--orn:rgba(206, 172, 92, .22);background:linear-gradient(var(--orn),var(--orn)) left 0 top 0/30px 1px,linear-gradient(var(--orn),var(--orn)) left 0 top 0/1px 30px,linear-gradient(var(--orn),var(--orn)) right 0 top 0/30px 1px,linear-gradient(var(--orn),var(--orn)) right 0 top 0/1px 30px,linear-gradient(var(--orn),var(--orn)) left 0 bottom 0/30px 1px,linear-gradient(var(--orn),var(--orn)) left 0 bottom 0/1px 30px,linear-gradient(var(--orn),var(--orn)) right 0 bottom 0/30px 1px,linear-gradient(var(--orn),var(--orn)) right 0 bottom 0/1px 30px;background-repeat:no-repeat}.c1vpyoko{position:absolute;top:48%;left:50%;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);z-index:10000;width:min(560px,92%);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:6px;pointer-events:none}.c1vpyoko>*{pointer-events:auto}.zixkj8o{position:absolute;left:12px;bottom:10px;z-index:6;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;gap:4px;pointer-events:none}.b1s99k60{position:absolute;top:48%;left:50%;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:min(500px,42%);aspect-ratio:1;border-radius:50%;background:radial-gradient(circle,rgba(241,196,15,.055) 0%,transparent 56%),repeating-conic-gradient(rgba(255,228,158,.014) 0deg 3deg,transparent 3deg 7.5deg),radial-gradient(circle,transparent 63.6%,rgba(241,196,15,.11) 64%,rgba(241,196,15,.11) 64.7%,transparent 65.1%),radial-gradient(circle,transparent 67.4%,rgba(241,196,15,.055) 67.8%,rgba(241,196,15,.055) 68.2%,transparent 68.6%);pointer-events:none;z-index:0}.c1yc37co{text-align:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;max-width:100%}.s1w07sod{position:absolute;left:50%;bottom:6px;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translate(-50%);z-index:6;width:min(560px,92%);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:6px;pointer-events:none}.s1w07sod>*{pointer-events:auto}.r97hga2{-webkit-flex:0 0 250px;-ms-flex:0 0 250px;flex:0 0 250px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;background:#0009;border-left:1px solid #534629;min-height:0;overflow:hidden}.b1adl8i0{-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;height:var(--hero-card-h);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:stretch;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;gap:10px;padding:8px 12px 10px;border-top:1px solid #534629;background:#00000080;position:relative;overflow:hidden}.h1kclk5m{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:4px;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;height:100%}.p1qwaiyr{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.pqp6eo{background:#c0392b;color:#fff;font-size:11px;font-weight:700;padding:3px 8px;border-radius:2px 8px 8px 2px;letter-spacing:1px;box-shadow:0 1px 4px #00000059}.s3og69t{position:absolute;inset:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.s16lno82{position:relative;width:100%;max-width:1760px;margin:0 auto;height:100%;overflow:visible}.s1kyaluv{position:absolute;left:var(--seat-left, 0);top:var(--seat-top, 0);-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translate(-50%);width:calc(var(--hero-card-h) * 15 / 19);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:3px;z-index:2}.ml4g12j{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:7px;font-size:12px;color:#cbbd93;background:linear-gradient(#221c10d9,#16120ad9);border:1px solid rgba(200,164,78,.32);border-radius:999px;padding:4px 14px;letter-spacing:.5px;box-shadow:inset 0 1px #ffebb412,0 2px 10px #00000073}.z1oy3h4e{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;width:20px;height:26px;font-size:15px;line-height:1;color:#d8c48a;background:linear-gradient(160deg,#3a2f52,#241d38);border:1px solid rgba(200,164,78,.5);border-radius:3px;box-shadow:0 1px 3px #00000080}.z138bqby{color:#f0dfae;font-weight:700;font-variant-numeric:tabular-nums}.s18htd8h{cursor:pointer}.s18htd8h:hover{outline:2px solid #e74c3c}.s1nac25o{outline:3px solid #e74c3c;box-shadow:0 0 12px #e74c3c66}.p56tufy{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:6px;margin:6px auto;padding:6px 12px;background:#e77e2224;border:1px dashed #e67e22;border-radius:8px;max-width:480px;font-size:12px;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-shadow:0 2px 12px #e67e2233}.p10atxx5{color:#e67e22;font-weight:700}.p5kb27d{display:inline-block;padding:1px 6px;border-radius:4px;border:1px solid var(--suit-color, #ccc);color:var(--suit-color, #ccc);background:#e67e2214;font-weight:700}.pfctbre{color:#f1c40f;font-size:10px;margin-right:4px;font-weight:400}.p12dbusz{margin-right:2px}.p3c5hb8{font-size:10px;opacity:.85}.dbt4o7h{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:7px;margin-top:2px;font-size:12px;color:#c9a49b;background:linear-gradient(#221410d9,#180e0ad9);border:1px solid rgba(231,76,60,.35);border-radius:999px;padding:3px 12px;letter-spacing:.5px;box-shadow:inset 0 1px #ffc8b40d,0 2px 10px #00000073}.d150nr5e{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;width:20px;height:26px;font-size:13px;line-height:1;color:#e8a08f;background:linear-gradient(160deg,#4a2622,#301815);border:1px solid rgba(231,76,60,.5);border-radius:3px;box-shadow:0 1px 3px #00000080}.d3c76mr{color:#f2c4b8;font-weight:700;font-variant-numeric:tabular-nums}.h6bmnq1{-webkit-animation:damageFlash .6s ease-out both;animation:damageFlash .6s ease-out both}.s1mjab4v{-webkit-animation:damageShake .5s ease-out both;animation:damageShake .5s ease-out both}.s17g1cwh{position:relative}.s17g1cwh:after{content:"";position:absolute;inset:0;border-radius:8px;pointer-events:none;-webkit-animation:damageOverlay .6s ease-out both;animation:damageOverlay .6s ease-out both}.h1oz38jg{-webkit-animation:healFlash .6s ease-out both;animation:healFlash .6s ease-out both}.hpoovxc{position:absolute;left:50%;top:32%;z-index:6;font-size:34px;font-weight:700;pointer-events:none;-webkit-animation:hpFloatUp 1s ease-out both;animation:hpFloatUp 1s ease-out both}.hppi5b6{color:#ff4d4f;text-shadow:0 0 8px rgba(255,34,34,.7),0 1px 3px rgba(0,0,0,.9)}.hrbqvpp{color:#52c41a;text-shadow:0 0 8px rgba(82,196,26,.7),0 1px 3px rgba(0,0,0,.9)}.s1nmp558{position:relative}.s1nmp558:after{content:"";position:absolute;inset:0;border-radius:8px;pointer-events:none;-webkit-animation:healOverlay .6s ease-out both;animation:healOverlay .6s ease-out both}.p1sxzls7{-webkit-animation:phaseIn .35s ease-out both;animation:phaseIn .35s ease-out both}.tod7xpl{-webkit-animation:newTurnGlow .8s ease-out both;animation:newTurnGlow .8s ease-out both}.hf4xos5{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:8px}.h1qltubh{font-size:14px;color:#aaa;font-weight:700}.d1ty0ksj{color:#666;font-weight:400;font-size:12px}.e12p8fqm{position:absolute;inset:0;z-index:7;pointer-events:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.e1v9e4oj{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:2px;perspective:800px;-webkit-animation:cardFlipIn var(--flip-duration, 1.8s) cubic-bezier(.22,.61,.36,1) both;animation:cardFlipIn var(--flip-duration, 1.8s) cubic-bezier(.22,.61,.36,1) both}.e1eoue1w{font-size:11px;font-weight:700;color:#b78bff;background:#9b59b633;padding:1px 8px;border-radius:8px;border:1px solid rgba(155,89,182,.4)}.ekgv2dp{font-size:12px;font-weight:700;color:#6fc3ff;background:#3498db2e;padding:1px 10px;border-radius:8px;border:1px solid rgba(52,152,219,.4)}.r4dw9vt{position:absolute;top:8px;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translate(-50%);z-index:30;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;pointer-events:none}.egfa8r5{position:absolute;top:8px;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translate(-50%);z-index:31;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;pointer-events:none}.e11h4zky{top:196px}.ekedyv6{padding:1px 8px;border-radius:10px;border:1px solid rgba(230,126,34,.6);background:#0000008c;color:#f5b041;font-size:12px;font-weight:700;white-space:nowrap}.e1qjo0as{pointer-events:auto;padding:1px 7px;border-radius:10px;border:1px solid rgba(230,126,34,.6);background:#0000008c;color:#f5b041;font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap}.e1qjo0as:hover{background:#e67e2259}.r5it0k6{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:2px;perspective:800px;-webkit-animation:revealCardIn var(--flip-duration, .7s) cubic-bezier(.22,.61,.36,1) both;animation:revealCardIn var(--flip-duration, .7s) cubic-bezier(.22,.61,.36,1) both}.e1772k5b{position:relative;box-sizing:border-box;min-width:90px;width:120px;height:160px;padding:0;border-radius:8px;background:linear-gradient(135deg,#2a2a3e,#1a1a2e);border:2px solid #c9a227;box-shadow:0 4px 20px #c9a22766;text-align:center;transform-style:preserve-3d;overflow:hidden}.e182lzb8{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top;z-index:0}.e10k4l9z{position:absolute;left:0;right:0;bottom:0;z-index:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:16px 12px 8px;background:linear-gradient(to top,#000000d9,#0000008c 60%,#0000)}.e3d9jpb{font-size:16px;font-weight:700;line-height:1.3;color:var(--suit-color, #ccc)}.e7ftlsv{font-size:13px;font-weight:700;margin-top:2px;color:var(--suit-color, #ccc)}.j10sg1mi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:14px;perspective:800px}.jlegnt{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;-webkit-animation:cardJudgePendingIn var(--flip-duration, 1.8s) ease-out both;animation:cardJudgePendingIn var(--flip-duration, 1.8s) ease-out both}.j168kvzn{position:relative;box-sizing:border-box;width:80px;height:120px;border-radius:8px;background:linear-gradient(135deg,#2a2a3e,#1a1a2e);border:2px solid #b78bff;box-shadow:0 2px 12px #9b59b666;overflow:hidden}.j12zlj6{font-size:13px;font-weight:700;color:#c9a227;text-shadow:0 1px 4px rgba(0,0,0,.8);white-space:nowrap}.c1k9h9zu{border:1px solid #555;border-radius:4px;padding:2px 8px;cursor:pointer;background:transparent;color:#aaa;font-size:11px}.hlbstba{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:flex-end;-webkit-box-align:flex-end;-ms-flex-align:flex-end;align-items:flex-end;gap:0;margin-bottom:8px;min-height:142px;padding:8px 0 0}.hu9rwba{position:relative;box-sizing:border-box;border:2px solid rgba(126,104,66,.85);border-radius:9px;padding:0;cursor:pointer;background:linear-gradient(180deg,#1e140ff2,#140c08f2);min-width:92px;width:92px;height:134px;text-align:center;-webkit-transition:all .2s;transition:all .2s;-webkit-transform:rotate(var(--fan-angle, 0deg));-moz-transform:rotate(var(--fan-angle, 0deg));-ms-transform:rotate(var(--fan-angle, 0deg));transform:rotate(var(--fan-angle, 0deg));transform-origin:bottom center;z-index:var(--card-z, 0);box-shadow:-1px 2px 6px #00000059,inset 0 1px #ffe8aa12;margin-left:-18px;overflow:hidden}.hu9rwba:first-of-type{margin-left:0}.hu9rwba:hover{z-index:100!important;margin-bottom:8px;box-shadow:0 6px 18px #0000008c,0 0 14px #d9b45c40;border-color:#d9b45c}.h15hev3f{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top;z-index:0}.h1k2a0x7{position:absolute;left:0;right:0;bottom:0;z-index:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:1px;padding:14px 4px 6px;background:linear-gradient(to top,#000000d1,#0000008c 60%,#0000)}.h1h2jqd0{border:2px solid #3498db;background:#3498db2e;margin-bottom:8px;box-shadow:0 4px 12px #3498db4d}.h1emi3hr{opacity:.4;cursor:default}.h38z6ef{border:2px dashed #e67e22;box-shadow:0 0 10px #e67e228c;-webkit-animation:fallbackBlink-h38z6ef 1s ease-in-out infinite;animation:fallbackBlink-h38z6ef 1s ease-in-out infinite}@-webkit-keyframes fallbackBlink-h38z6ef{0%,to{box-shadow:0 0 4px #e67e224d}50%{box-shadow:0 0 14px #e67e22b3}}@keyframes fallbackBlink-h38z6ef{0%,to{box-shadow:0 0 4px #e67e224d}50%{box-shadow:0 0 14px #e67e22b3}}.h5xnkoo{border:2px solid #ffd700;box-shadow:0 0 10px #ffd70066;background:#ffd70014}.h15xavli{border-color:#a86fd6;box-shadow:0 0 8px #a86fd659;-webkit-animation:discardPulse-h15xavli 1.8s ease-in-out infinite;animation:discardPulse-h15xavli 1.8s ease-in-out infinite}.h15xavli>:first-child{-webkit-filter:brightness(1.12);filter:brightness(1.12)}@-webkit-keyframes discardPulse-h15xavli{0%,to{box-shadow:0 0 5px #a86fd640}50%{box-shadow:0 0 14px #a86fd68c}}@keyframes discardPulse-h15xavli{0%,to{box-shadow:0 0 5px #a86fd640}50%{box-shadow:0 0 14px #a86fd68c}}.hfynt8g{border-color:#93a3ae;box-shadow:-1px 2px 6px #0000004d,0 0 5px #ffffff1a}.h1jr7ru9{border:3px solid #2ecc71;box-shadow:0 0 14px #2ecc7199;background:#2ecc7138;margin-bottom:8px}.h83znjd{border:2px solid #f1c40f;box-shadow:0 0 10px #f1c40f80;background:#f1c40f14;cursor:pointer}.h83znjd:hover{background:#f1c40f2e}.h1vjswjw{opacity:.3;cursor:not-allowed}.h1uwuuik{border:2px solid #f1c40f;box-shadow:0 0 10px #f1c40f66;cursor:pointer}.h1uwuuik:hover{background:#f1c40f26}.h18kbocv{border:2px solid #2ecc71;box-shadow:0 0 12px #2ecc7180;background:#2ecc7126;margin-bottom:8px}.h1mz6xnm{opacity:.4;cursor:default;border-color:#888}.dzvgbv4{opacity:.5;border:2px solid #e74c3c;border-radius:6px;background:#e74c3c2e}.c1qldmck{font-weight:700;font-size:16px;letter-spacing:1px;color:var(--suit-color, #ccc)}.cc3cfv{font-size:13px;color:var(--suit-color, #ccc)}.c43y6yv{font-size:10px;opacity:.7;font-style:italic;color:var(--suit-color, #ccc)}.e11ckrkq{color:#555;font-size:13px;padding:12px}.dukp8wa{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;margin:4px 0;padding:6px 8px;border:1px dashed rgba(241,196,15,.3);border-radius:6px;background:#f1c40f0a}.d1h6g1y8{color:#f1c40f;font-size:12px;font-weight:700;letter-spacing:.5px}.d3d179f{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:flex-end;-webkit-box-align:flex-end;-ms-flex-align:flex-end;align-items:flex-end;gap:4px;min-height:80px}.do5v5wq{border:2px solid #555;border-radius:8px;padding:6px 10px;cursor:pointer;background:linear-gradient(180deg,#1e140ff2,#140c08f2);min-width:64px;width:72px;text-align:center;-webkit-transition:all .2s;transition:all .2s}.do5v5wq:hover{border-color:#888;-webkit-transform:translateY(-2px);-moz-transform:translateY(-2px);-ms-transform:translateY(-2px);transform:translateY(-2px)}.a19geho8{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:10px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding:6px 10px;background:#00000059;border-radius:8px;border:1px solid rgba(83,70,41,.6)}.a19geho8:empty{display:none}.p16row33{border:none;border-radius:8px;padding:8px 22px;cursor:pointer;background:linear-gradient(#2ecc71f2,#1e9655f2);color:#fff;font-weight:700;font-size:14px;letter-spacing:1px;box-shadow:inset 0 1px #ffffff38,0 3px 10px #00000059;-webkit-transition:all .15s;transition:all .15s}.p16row33:hover{-webkit-filter:brightness(1.08);filter:brightness(1.08);-webkit-transform:translateY(-1px);-moz-transform:translateY(-1px);-ms-transform:translateY(-1px);transform:translateY(-1px)}.p16row33:active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-filter:brightness(.95);filter:brightness(.95)}.e1e90bnf{border:none;border-radius:8px;padding:8px 22px;cursor:pointer;background:linear-gradient(#f0523cf5,#c43626f5);color:#fff;font-weight:700;font-size:14px;letter-spacing:2px;box-shadow:inset 0 1px #fff3,0 3px 12px #c4362666,0 0 18px #e74c3c40;-webkit-transition:all .15s;transition:all .15s;-webkit-animation:endTurnBreath 2.4s ease-in-out infinite;animation:endTurnBreath 2.4s ease-in-out infinite}.e1e90bnf:hover{-webkit-filter:brightness(1.08);filter:brightness(1.08);-webkit-transform:translateY(-1px);-moz-transform:translateY(-1px);-ms-transform:translateY(-1px);transform:translateY(-1px)}.e1e90bnf:active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-filter:brightness(.95);filter:brightness(.95);-webkit-animation:none;animation:none}.tmc7gk0{font-size:13px;color:gold;width:100%;text-align:center}.srdo86e{border:1px solid #8a7448;border-radius:3px;padding:2px 7px;cursor:pointer;background:linear-gradient(#3a3020f2,#262016f2);color:#e8d9a8;font-size:10px;font-weight:700;margin-right:3px;text-shadow:0 1px 2px rgba(0,0,0,.6);box-shadow:inset 0 1px #ffebb412;-webkit-transition:border-color .15s,box-shadow .15s;transition:border-color .15s,box-shadow .15s}.srdo86e:hover{border-color:#d4a048;box-shadow:0 0 8px #d4a04866,inset 0 1px #ffebb412}.sgsbapn{cursor:not-allowed;border-color:#565043;background:linear-gradient(#2a261ef2,#1e1b15f2);color:#6f6a58}.sgsbapn:hover{border-color:#565043;box-shadow:none}.e1tjfzk4{cursor:pointer;border-color:#f39c12;background:#f39c1233;box-shadow:0 0 8px #f39c1280}.e1tjfzk4:hover{background:#f39c1257}.elkxz39{cursor:pointer;border-color:#f1c40f;background:#f1c40f24;box-shadow:0 0 8px #f1c40f66}.elkxz39:hover{background:#f1c40f3d}.e19gak72{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);-ms-transform:translateX(8px);transform:translate(8px);border-color:#2ecc71;color:#2ecc71;background:#2ecc7129;box-shadow:0 0 10px #2ecc718c}.e15eqpa{margin-left:auto;font-size:11px}.e1qnjdzb{-webkit-flex:0 0 156px;-ms-flex:0 0 156px;flex:0 0 156px;border:1px solid rgba(196,162,84,.28);border-radius:12px;background:linear-gradient(#100e0ac7,#0a0906d1);box-shadow:0 4px 16px #00000059,inset 0 1px #ffe8aa0d;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:hidden;-webkit-align-self:stretch;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.e11vkpix{font-size:11px;color:#e8c47a;font-weight:700;padding:8px 12px 6px;letter-spacing:2px;border-bottom:1px solid rgba(196,162,84,.18)}.e1og88kj{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;padding:8px 10px;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;min-height:0;overflow-y:auto}.e1i06fes{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:4px}.e1i06fes>*{-webkit-flex:1 1 0;-ms-flex:1 1 0;flex:1 1 0;min-width:0}.ekdr9j5{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;font-size:12px;color:#f39c12;padding:2px 4px;border-radius:4px;background:#f39c120f;border:1px solid rgba(243,156,18,.15);overflow:hidden;height:48px;box-sizing:border-box}.eq4uw25{font-size:13px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.etzebf1{width:32px;height:44px;object-fit:cover;object-position:center top;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;border-radius:3px;display:block}.e12u2cdb{opacity:.4;border:1px dashed rgba(243,156,18,.22);background:transparent}.etwbc2z{color:#777;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.e8z6wu5{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.p1thfas{position:relative;box-sizing:border-box;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;aspect-ratio:15/19;border:1px solid #8a7448;border-radius:6px;background:#14110c;box-shadow:0 0 0 1px #0009,0 6px 18px #00000073;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-self:stretch;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.p1xpvk32{border-color:#d4a048;box-shadow:0 0 0 1px #0009,0 0 16px #ffcd5c73,0 0 32px #6ebe6438}.p10icgrd{padding:5px 8px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:2px;background:linear-gradient(#14100ae6,#0d0a07bd);border-bottom:1px solid rgba(138,116,72,.5)}.p1d5s6ni{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;min-width:0}.p1khsely{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:700;font-size:13px;color:#fffffff0;text-shadow:0 1px 2px rgba(0,0,0,.7)}.p1x8jp48{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:3px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.pswwb2l{background:#3498dbeb;border-radius:3px;padding:1px 4px;font-size:9px;color:#fff;font-weight:700;line-height:1.5}.p1lbgodb{background:#d4a017;border-radius:3px;padding:1px 4px;font-size:9px;color:#241a04;font-weight:700;line-height:1.5}.pkzpqy1{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:linear-gradient(135deg,#6b8294,#9bb3c4);border:1px solid #b9cdd9;border-radius:3px;padding:1px 4px;font-size:10px;color:#fff;font-weight:700;line-height:1.5}.p9d8g64{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;min-width:22px;text-align:center;padding:1px 4px;border-radius:3px;font-size:9px;font-weight:700;line-height:1.5;text-shadow:0 1px 1px rgba(0,0,0,.5);box-shadow:inset 0 1px #ffffff1f}.phcc0b4{background:#d4a017;color:#3a2400}.pldrrsf{background:#3f6fb5;color:#fff}.puht0pu{background:#b03a30;color:#fff}.pr1a3oh{background:#8e5aa8;color:#fff}.pp1rl6m{position:absolute;left:0;top:32px;bottom:4px;z-index:3;width:30px;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:6px;padding:5px 0 8px;background:linear-gradient(to bottom,#0000009e,#0000006b 60%,#00000014)}.p3kqkdy{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;min-height:0;overflow:hidden;-webkit-writing-mode:vertical-rl;-ms-writing-mode:tb-rl;writing-mode:vertical-rl;-webkit-text-orientation:upright;-moz-text-orientation:upright;-ms-text-orientation:upright;text-orientation:upright;font-weight:700;font-size:13px;letter-spacing:3px;color:#f3e6c2;text-shadow:1px 0 2px rgba(0,0,0,.9),-1px 0 2px rgba(0,0,0,.9),0 1px 2px rgba(0,0,0,.9),0 -1px 2px rgba(0,0,0,.9)}.p1wz1rgz{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;display:inline-block;line-height:1;font-size:17px;font-weight:900;color:#ff5f52;text-shadow:0 1px 2px rgba(0,0,0,.85),0 0 6px rgba(255,60,40,.45)}.p1ejniuw{position:absolute;right:-5px;top:50%;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:5;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;pointer-events:none}.p1n3qnkb{box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;border-radius:50% 50% 50% 0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg);background:linear-gradient(135deg,#7ec850 8%,#3e8f2e 92%);border:1px solid rgba(46,94,28,.9);box-shadow:inset 0 2px 2px #ffffff59,inset 0 -1px 2px #00000040,0 0 6px #7ec85073}.pgmfqz5{box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;border-radius:50% 50% 50% 0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg);background:linear-gradient(135deg,#e8c84a 8%,#b8862a 92%);border:1px solid rgba(122,88,20,.9);box-shadow:inset 0 2px 2px #ffffff59,inset 0 -1px 2px #00000040,0 0 6px #e8c84a73}.p1hiai0v{box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;border-radius:50% 50% 50% 0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg);background:linear-gradient(135deg,#e85d4a 8%,#a8281a 92%);border:1px solid rgba(122,30,20,.9);box-shadow:inset 0 2px 2px #ffffff59,inset 0 -1px 2px #00000040,0 0 6px #e85d4a80}.pishhnh{box-sizing:border-box;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;border-radius:50% 50% 50% 0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg);background:#00000038;border:1px solid #444;box-shadow:inset 0 1px 2px #0000008c}.p1s40zvi{position:absolute;top:46%;left:50%;z-index:4;-webkit-transform:translate(-50%,-50%) rotate(-12deg);-moz-transform:translate(-50%,-50%) rotate(-12deg);-ms-transform:translate(-50%,-50%) rotate(-12deg);transform:translate(-50%,-50%) rotate(-12deg);padding:2px 8px 2px 14px;border:3px solid rgba(200,40,34,.85);border-radius:8px;background:#14060459;color:#e23830eb;font-size:34px;font-weight:900;letter-spacing:6px;text-shadow:0 0 10px rgba(180,30,24,.6);pointer-events:none}.p1enw04k{position:absolute;inset:0;z-index:0;overflow:hidden;border-radius:5px;background:var(--faction-color, rgba(0, 0, 0, .45))}.pku4xon{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top;-webkit-transition:filter .3s;transition:filter .3s}.p8bnm2b{-webkit-filter:grayscale(1) brightness(.6);filter:grayscale(1) brightness(.6)}.p1jox6y0{-webkit-animation:chainPulse 1.8s ease-in-out infinite;animation:chainPulse 1.8s ease-in-out infinite}.ps92vk6{position:absolute;inset:0;z-index:2;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:hidden;border-radius:5px}.pex9fzp{margin-top:auto;margin-left:30px;padding:5px 12px 6px 2px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:3px;background:linear-gradient(to top,#0a0805e6,#0a0805c7 72%,#0a080500)}.pkuwqf9{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:3px}.p1yixnwl{display:inline-block;background:#0a0806ad;border:1px solid rgba(138,116,72,.42);border-radius:3px;padding:1px 6px;font-size:10px;color:#e8c47a;text-shadow:0 1px 2px rgba(0,0,0,.6)}.p1hrsjqx{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:3px;font-size:10px}.p8gflkc{color:#c9a2ff;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.7)}.p1mveq84{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:2px;padding:1px 6px;border-radius:3px;border:1px solid #8e6cc8;color:var(--suit-color, #ccc);background:#181022c7;font-weight:700;text-shadow:0 1px 2px rgba(0,0,0,.65)}.p1lj96g9{-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:3px;padding:1px 6px;border-radius:3px;background:#0000008c;border:1px solid rgba(138,116,72,.5);color:#e8c47a;font-size:10px;font-weight:700;line-height:1.4;text-shadow:0 1px 2px rgba(0,0,0,.6)}.p1215ahs{padding:6px 12px 8px;border-top:1px solid rgba(255,255,255,.06);background:#f39c120d}.pxis11d{font-size:11px;color:#f39c12;font-weight:700;margin-bottom:4px;letter-spacing:1px}.p1yq43hq{position:relative;border:1px solid #8a7448;border-radius:8px;padding:10px 14px 12px;background:linear-gradient(#241d14f2,#171209f2);box-shadow:inset 0 0 0 1px #0009,0 4px 16px #00000073;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);width:min(720px,92%);margin:0 auto;box-sizing:border-box}.p1yq43hq:after{content:"";position:absolute;left:10px;right:10px;bottom:3px;height:2px;border-radius:1px;background:linear-gradient(90deg,transparent,rgba(232,196,122,.55) 18%,rgba(240,215,138,.85) 50%,rgba(232,196,122,.55) 82%,transparent);pointer-events:none}.p1ap4fqq{position:relative;border:1px solid #8a7448;border-radius:8px;padding:10px 14px 12px;background:linear-gradient(#241d14f2,#171209f2);box-shadow:inset 0 0 0 1px #0009,0 4px 16px #00000073;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);width:min(720px,92%);margin:0 auto;box-sizing:border-box}.p1ap4fqq:after{content:"";position:absolute;left:10px;right:10px;bottom:3px;height:2px;border-radius:1px;background:linear-gradient(90deg,transparent,rgba(232,196,122,.55) 18%,rgba(240,215,138,.85) 50%,rgba(232,196,122,.55) 82%,transparent);pointer-events:none}.p1gjtu2r{color:#f0d78a;font-weight:700;font-size:15px;margin-bottom:4px;letter-spacing:2px;text-shadow:0 1px 2px rgba(0,0,0,.8)}.p1gjtu2r:before{content:"◆";font-size:10px;margin-right:6px;color:#c4a254;text-shadow:none}.saa4pvc{display:inline-block;vertical-align:middle;margin-left:8px;padding:1px 6px;border-radius:3px;border:1px solid rgba(230,126,34,.6);background:#00000040;color:#f5b041;font-size:12px;font-weight:400}.p1wsv0bb{font-size:13px;color:#d8cba8;margin-bottom:6px}.p1ps5km3{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:10px;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.p1mvk097{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:6px 10px;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.padfn32{font-size:12px;color:#cbbd93;width:100%;margin-bottom:0}.p1nqfvfb{font-size:13px;color:#d8cba8;margin-bottom:0;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.p1n7196g{border:1px solid #6a5a3e;border-radius:4px;padding:7px 22px;cursor:pointer;background:linear-gradient(#3a352c,#2a251d);color:#e8d9a8;font-size:13px;line-height:1.4;box-shadow:inset 0 1px #ffebb40f,0 2px 6px #0006;-webkit-transition:border-color .15s,filter .15s;transition:border-color .15s,filter .15s}.p1n7196g:hover{border-color:#d4a048;-webkit-filter:brightness(1.12);filter:brightness(1.12)}.p1n7196g:disabled{opacity:.55;cursor:not-allowed;color:#8a8068;-webkit-filter:none;filter:none}.pwz81mi{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:6px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.p1gsyn3o{position:relative;width:44px;height:62px;padding:0;border:1.5px solid #a8842a;border-radius:5px;overflow:hidden;cursor:pointer;background:#f5e6c8;-webkit-transition:-webkit-transform .12s,box-shadow .12s,border-color .12s;transition:transform .12s,box-shadow .12s,border-color .12s}.p1gsyn3o:hover{-webkit-transform:translateY(-3px);-moz-transform:translateY(-3px);-ms-transform:translateY(-3px);transform:translateY(-3px);box-shadow:0 4px 10px #00000080;border-color:gold;z-index:1}.pe9ye2q{position:absolute;top:2px;left:2px;min-width:14px;height:14px;padding:0 3px;border-radius:7px;background:#000000a6;color:gold;font-size:10px;font-weight:700;line-height:14px;text-align:center;pointer-events:none}.pr369d4{border:1px solid #d4a048;border-radius:4px;padding:7px 22px;cursor:pointer;background:linear-gradient(#a03028,#7a2018);color:#f5e6c8;font-size:13px;font-weight:700;letter-spacing:1px;line-height:1.4;text-shadow:0 1px 2px rgba(60,10,6,.8);box-shadow:inset 0 1px #ffdca02e,0 2px 8px #7a201873;-webkit-transition:filter .15s,border-color .15s;transition:filter .15s,border-color .15s}.pr369d4:hover{border-color:#f0c060;-webkit-filter:brightness(1.15);filter:brightness(1.15)}.pr369d4:active{-webkit-filter:brightness(.95);filter:brightness(.95)}.p13z9rp1{border:1px solid #55503f;border-radius:4px;padding:7px 22px;cursor:not-allowed;background:linear-gradient(#332f28,#26221b);color:#6f6a58;font-size:13px;line-height:1.4;opacity:.6;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:2px}.pf0r8yt{font-size:10px;color:#e74c3c;font-weight:400;-webkit-text-decoration:line-through;text-decoration:line-through}.kglgt13{display:inline-block;margin-left:5px;padding:0 4px;border-radius:3px;border:1px solid rgba(255,255,255,.28);font-size:10px;line-height:1.5;opacity:.62;vertical-align:1px}.cn370x3{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;border:2px solid #888;border-radius:8px;padding:10px 16px;cursor:pointer;font-size:13px;-webkit-transition:-webkit-transform .1s;transition:transform .1s}.cn370x3:hover{-webkit-transform:scale(1.03);-moz-transform:scale(1.03);-ms-transform:scale(1.03);transform:scale(1.03)}.crtlnoh{font-weight:700;font-size:15px}.c1ykgg9y{font-size:12px;color:#888}.w47nkj7{text-align:center;color:#888;font-size:13px;margin-bottom:12px}.ag5iinz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;font-size:12px;color:#aaa;cursor:pointer;margin-bottom:8px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ag5iinz input{cursor:pointer}.at10j8q{border-color:#5ebe7899!important;color:#86e0a0!important;background:#5ebe781a!important}.at10j8q:hover{border-color:#82dc9bcc!important;background:#5ebe782e!important}.tc6lv6t{color:#f1c40f;margin-left:8px}.drmm49j{color:#1abc9c;margin-left:8px}.dufbdzd{background:#555}.s1bg0p9g{border-color:#e74c3c}.s1d9ubhv{border-color:#f39c12}.bp2tha5{opacity:.4;cursor:not-allowed}.s1mk2ain{padding:8px 12px}.j16wuf3w{padding:0 12px 8px}.d1sznoxz{position:fixed;left:0;right:0;bottom:0;z-index:9400;border:1px solid #333;border-radius:8px 8px 0 0;background:#0a0a0ed9}.dr0292y{padding:8px 12px;cursor:pointer;color:#888;font-size:12px}.d1oxzsoi{padding:8px 12px;font-size:12px;color:#aaa;font-family:monospace}.db29mtm{border:none;border-top:1px solid #333;margin:8px 0}.duul7v9{margin-bottom:4px}.d1v5m6vj{-webkit-text-decoration:line-through;text-decoration:line-through;opacity:.5}.l1fmtknq{margin-top:12px;border:1px solid #333;border-radius:8px;background:#0003}.lspnznh{padding:8px 12px;cursor:pointer;color:#888;font-size:12px}.ldfe6wv{padding:8px 12px;font-size:12px;color:#aaa;max-height:200px;overflow-y:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.l1f8elat{color:#555;font-style:italic;text-align:center}.l1cr3gli{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:8px;padding:2px 0;border-bottom:1px solid rgba(255,255,255,.05)}.lxa24eg{color:#666;min-width:40px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.l1nnk0nu{color:#3498db;font-weight:700;min-width:40px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.l1x00hgh{color:#ccc}.c11c5jur{position:fixed;inset:0;z-index:9998;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;background:#000000e6;color:#f1c40f;font-size:18px;gap:12px}.c1raad4w{font-size:13px;color:#aaa}.c1f6oldp{width:300px;margin-top:8px}.c8iitzx{margin-top:16px;padding:8px 18px;font-size:14px;font-weight:700;color:#fff;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;cursor:pointer}.s1733xwn{position:relative;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;padding:0;border-radius:12px;box-shadow:0 4px 24px #ffd70040,0 4px 16px #0006;border:2px solid rgba(255,215,0,.6);min-width:220px;width:220px;height:300px;overflow:hidden;background:var(--faction-color, #8e44ad)}.skfk9ns{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--faction-color, rgba(0, 0, 0, .35));box-shadow:inset 0 0 0 1px #ffffff1a}.sa9bstq{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top}.s1ql5fy{position:relative;z-index:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;padding:40px 18px 18px;margin-top:auto;width:100%;background:linear-gradient(to top,#000000d9,#0000008c 60%,#0000)}.s1cc5s9a{font-size:12px;color:#ffffffb3;letter-spacing:2px}.svic53r{font-size:28px;font-weight:700;color:#fff;text-shadow:0 1px 4px rgba(0,0,0,.4)}.s1kr1ugg{font-size:13px;color:#fffc;background:#00000040;border-radius:6px;padding:3px 10px}.seqs477{font-size:12px;color:#ffffffbf;text-align:center}.s5mnr1a{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:4px;margin-top:2px}.s4sphds{display:inline-block;width:14px;height:14px;border-radius:50%;background:#e74c3c;box-shadow:0 0 4px #e74c3c80}.sn3n7dv{background:#5ebe781a;color:#86e0a0;border:1px solid rgba(94,190,120,.55);padding:3px 12px;border-radius:999px;cursor:pointer;font-size:12px;line-height:1.5;-webkit-transition:all .15s;transition:all .15s}.sn3n7dv:hover{background:#5ebe782e;border-color:#82dc9bcc}.sn3n7dv:disabled{opacity:.5;cursor:wait}.swzxucy{position:fixed;top:50px;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translate(-50%);background:#1f3d1f;color:#7ee787;padding:10px 20px;border-radius:6px;border:1px solid #4a8a4a;font-size:13px;z-index:9999;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:10px}.c1i0tb5b{background:#2d4a2d;color:#7ee787;border:1px solid #4a8a4a;padding:2px 10px;border-radius:4px;cursor:pointer;font-size:12px;white-space:nowrap}.c1i0tb5b:hover{background:#3d5a3d}.c1cxq0y7{background:#1a3d1a;border-color:#2a6a2a;cursor:default}.s1anw4ff{position:fixed;top:50px;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translate(-50%);background:#3d1f1f;color:#ff7b72;padding:10px 20px;border-radius:6px;border:1px solid #8a4a4a;font-size:13px;z-index:9999}.bw4u80p{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}.bn4ntvc{position:absolute;inset:0;width:100%;height:100%;display:block}.c1sgrnfw{position:fixed;z-index:99999;background:#000000f2;color:#f0e6d3;padding:8px 14px;border-radius:8px;font-size:12px;line-height:1.6;word-break:break-word;max-width:300px;min-width:140px;box-shadow:0 4px 16px #0009;border:1px solid rgba(255,215,0,.2);pointer-events:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.cpua85b{font-weight:700;font-size:13px}.c1xbhg54{display:block}.c17nl2uc{font-size:11px;opacity:.7;font-style:italic}.c1gq2t9n{display:block;margin-top:3px;font-size:12px;color:#f0a35e}.c1vhr7s6{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.h13senao:hover:hover{margin-bottom:0;-webkit-transform:rotate(var(--fan-angle, 0deg)) translateY(-10px) scale(1.04);-moz-transform:rotate(var(--fan-angle, 0deg)) translateY(-10px) scale(1.04);-ms-transform:rotate(var(--fan-angle, 0deg)) translateY(-10px) scale(1.04);transform:rotate(var(--fan-angle, 0deg)) translateY(-10px) scale(1.04);box-shadow:0 12px 26px #000000a6,0 0 16px #d9b45c4d;border-color:#e6c06a;-webkit-filter:brightness(1.08);filter:brightness(1.08)}
+10 −0 viewer/viewer.js added View file
@@ -0,0 +1,10 @@
1+var e=Object.defineProperty,t=(e,t)=>()=>(e&&(t=e(e=0)),t),n=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),r=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();for(let e of[`localStorage`,`sessionStorage`])try{window[e].length}catch{let t=new Map,n={get length(){return t.size},clear:()=>t.clear(),getItem:e=>t.get(e)??null,key:e=>[...t.keys()][e]??null,removeItem:e=>void t.delete(e),setItem:(e,n)=>void t.set(e,String(n))};try{Object.defineProperty(window,e,{value:n,configurable:!0})}catch{}}var i=n((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function ee(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var b=ee.prototype=new y;b.constructor=ee,g(b,v.prototype),b.isPureReactComponent=!0;var x=Array.isArray;function S(){}var C={H:null,A:null,T:null,S:null},w=Object.prototype.hasOwnProperty;function te(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function ne(e,t){return te(e.type,t,e.props)}function T(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function re(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ie=/\/+/g;function ae(e,t){return typeof e==`object`&&e&&e.key!=null?re(``+e.key):t.toString(36)}function E(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(S,S):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function oe(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,oe(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ae(e,0):a,x(o)?(i=``,c!=null&&(i=c.replace(ie,`$&/`)+`/`),oe(o,r,i,``,function(e){return e})):o!=null&&(T(o)&&(o=ne(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ie,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(x(e))for(var u=0;u<e.length;u++)a=e[u],s=l+ae(a,u),c+=oe(a,r,i,s,o);else if(u=m(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+ae(a,u++),c+=oe(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return oe(E(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function se(e,t,n){if(e==null)return e;var r=[],i=0;return oe(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function ce(e){if(e._status===-1){var t=e._result;t=t(),t.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=t)}if(e._status===1)return e._result.default;throw e._result}var D=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)},O={map:se,forEach:function(e,t,n){se(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return se(e,function(){t++}),t},toArray:function(e){return se(e,function(e){return e})||[]},only:function(e){if(!T(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}};e.Activity=f,e.Children=O,e.Component=v,e.Fragment=r,e.Profiler=a,e.PureComponent=ee,e.StrictMode=i,e.Suspense=l,e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=C,e.__COMPILER_RUNTIME={__proto__:null,c:function(e){return C.H.useMemoCache(e)}},e.cache=function(e){return function(){return e.apply(null,arguments)}},e.cacheSignal=function(){return null},e.cloneElement=function(e,t,n){if(e==null)throw Error(`The argument must be a React element, but you passed `+e+`.`);var r=g({},e.props),i=e.key;if(t!=null)for(a in t.key!==void 0&&(i=``+t.key),t)!w.call(t,a)||a===`key`||a===`__self`||a===`__source`||a===`ref`&&t.ref===void 0||(r[a]=t[a]);var a=arguments.length-2;if(a===1)r.children=n;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return te(e.type,i,r)},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null},e.Provider=e,e.Consumer={$$typeof:o,_context:e},e},e.createElement=function(e,t,n){var r,i={},a=null;if(t!=null)for(r in t.key!==void 0&&(a=``+t.key),t)w.call(t,r)&&r!==`key`&&r!==`__self`&&r!==`__source`&&(i[r]=t[r]);var o=arguments.length-2;if(o===1)i.children=n;else if(1<o){for(var s=Array(o),c=0;c<o;c++)s[c]=arguments[c+2];i.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps,o)i[r]===void 0&&(i[r]=o[r]);return te(e,a,i)},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=T,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:ce}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=function(e){var t=C.T,n={};C.T=n;try{var r=e(),i=C.S;i!==null&&i(n,r),typeof r==`object`&&r&&typeof r.then==`function`&&r.then(S,D)}catch(e){D(e)}finally{t!==null&&n.types!==null&&(t.types=n.types),C.T=t}},e.unstable_useCacheRefresh=function(){return C.H.useCacheRefresh()},e.use=function(e){return C.H.use(e)},e.useActionState=function(e,t,n){return C.H.useActionState(e,t,n)},e.useCallback=function(e,t){return C.H.useCallback(e,t)},e.useContext=function(e){return C.H.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e,t){return C.H.useDeferredValue(e,t)},e.useEffect=function(e,t){return C.H.useEffect(e,t)},e.useEffectEvent=function(e){return C.H.useEffectEvent(e)},e.useId=function(){return C.H.useId()},e.useImperativeHandle=function(e,t,n){return C.H.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return C.H.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return C.H.useLayoutEffect(e,t)},e.useMemo=function(e,t){return C.H.useMemo(e,t)},e.useOptimistic=function(e,t){return C.H.useOptimistic(e,t)},e.useReducer=function(e,t,n){return C.H.useReducer(e,t,n)},e.useRef=function(e){return C.H.useRef(e)},e.useState=function(e){return C.H.useState(e)},e.useSyncExternalStore=function(e,t,n){return C.H.useSyncExternalStore(e,t,n)},e.useTransition=function(){return C.H.useTransition()},e.version=`19.2.6`})),a=n(((e,t)=>{t.exports=i()})),o=n((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function ee(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function b(e){if(h=!1,ee(e),!m)if(n(c)!==null)m=!0,x||(x=!0,T());else{var t=n(l);t!==null&&ae(b,t.startTime-e)}}var x=!1,S=-1,C=5,w=-1;function te(){return g?!0:!(e.unstable_now()-w<C)}function ne(){if(g=!1,x){var t=e.unstable_now();w=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(S),S=-1),p=!0;var a=f;try{b:{for(ee(t),d=n(c);d!==null&&!(d.expirationTime>t&&te());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,ee(t),i=!0;break b}d===n(c)&&r(c),ee(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ae(b,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?T():x=!1}}}var T;if(typeof y==`function`)T=function(){y(ne)};else if(typeof MessageChannel<`u`){var re=new MessageChannel,ie=re.port2;re.port1.onmessage=ne,T=function(){ie.postMessage(null)}}else T=function(){_(ne,0)};function ae(t,n){S=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):C=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(S),S=-1):h=!0,ae(b,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,x||(x=!0,T()))),r},e.unstable_shouldYield=te,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),s=n(((e,t)=>{t.exports=o()})),c=n((e=>{var t=a();function n(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function r(){}var i={d:{f:r,r:function(){throw Error(n(522))},D:r,C:r,L:r,m:r,X:r,S:r,M:r},p:0,findDOMNode:null},o=Symbol.for(`react.portal`);function s(e,t,n){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:o,key:r==null?null:``+r,children:e,containerInfo:t,implementation:n}}var c=t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function l(e,t){if(e===`font`)return``;if(typeof t==`string`)return t===`use-credentials`?t:``}e.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=i,e.createPortal=function(e,t){var r=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)throw Error(n(299));return s(e,t,null,r)},e.flushSync=function(e){var t=c.T,n=i.p;try{if(c.T=null,i.p=2,e)return e()}finally{c.T=t,i.p=n,i.d.f()}},e.preconnect=function(e,t){typeof e==`string`&&(t?(t=t.crossOrigin,t=typeof t==`string`?t===`use-credentials`?t:``:void 0):t=null,i.d.C(e,t))},e.prefetchDNS=function(e){typeof e==`string`&&i.d.D(e)},e.preinit=function(e,t){if(typeof e==`string`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin),a=typeof t.integrity==`string`?t.integrity:void 0,o=typeof t.fetchPriority==`string`?t.fetchPriority:void 0;n===`style`?i.d.S(e,typeof t.precedence==`string`?t.precedence:void 0,{crossOrigin:r,integrity:a,fetchPriority:o}):n===`script`&&i.d.X(e,{crossOrigin:r,integrity:a,fetchPriority:o,nonce:typeof t.nonce==`string`?t.nonce:void 0})}},e.preinitModule=function(e,t){if(typeof e==`string`)if(typeof t==`object`&&t){if(t.as==null||t.as===`script`){var n=l(t.as,t.crossOrigin);i.d.M(e,{crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0})}}else t??i.d.M(e)},e.preload=function(e,t){if(typeof e==`string`&&typeof t==`object`&&t&&typeof t.as==`string`){var n=t.as,r=l(n,t.crossOrigin);i.d.L(e,n,{crossOrigin:r,integrity:typeof t.integrity==`string`?t.integrity:void 0,nonce:typeof t.nonce==`string`?t.nonce:void 0,type:typeof t.type==`string`?t.type:void 0,fetchPriority:typeof t.fetchPriority==`string`?t.fetchPriority:void 0,referrerPolicy:typeof t.referrerPolicy==`string`?t.referrerPolicy:void 0,imageSrcSet:typeof t.imageSrcSet==`string`?t.imageSrcSet:void 0,imageSizes:typeof t.imageSizes==`string`?t.imageSizes:void 0,media:typeof t.media==`string`?t.media:void 0})}},e.preloadModule=function(e,t){if(typeof e==`string`)if(t){var n=l(t.as,t.crossOrigin);i.d.m(e,{as:typeof t.as==`string`&&t.as!==`script`?t.as:void 0,crossOrigin:n,integrity:typeof t.integrity==`string`?t.integrity:void 0})}else i.d.m(e)},e.requestFormReset=function(e){i.d.r(e)},e.unstable_batchedUpdates=function(e,t){return e(t)},e.useFormState=function(e,t,n){return c.H.useFormState(e,t,n)},e.useFormStatus=function(){return c.H.useHostTransitionStatus()},e.version=`19.2.6`})),l=n(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=c()})),u=n((e=>{var t=s(),n=a(),r=l();function i(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function o(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function c(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function u(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function d(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function f(e){if(c(e)!==e)throw Error(i(188))}function p(e){var t=e.alternate;if(!t){if(t=c(e),t===null)throw Error(i(188));return t===e?e:null}for(var n=e,r=t;;){var a=n.return;if(a===null)break;var o=a.alternate;if(o===null){if(r=a.return,r!==null){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return f(a),e;if(o===r)return f(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var s=!1,l=a.child;l;){if(l===n){s=!0,n=a,r=o;break}if(l===r){s=!0,r=a,n=o;break}l=l.sibling}if(!s){for(l=o.child;l;){if(l===n){s=!0,n=o,r=a;break}if(l===r){s=!0,r=o,n=a;break}l=l.sibling}if(!s)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(n.tag!==3)throw Error(i(188));return n.stateNode.current===n?e:t}function m(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=m(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),ee=Symbol.for(`react.strict_mode`),b=Symbol.for(`react.profiler`),x=Symbol.for(`react.consumer`),S=Symbol.for(`react.context`),C=Symbol.for(`react.forward_ref`),w=Symbol.for(`react.suspense`),te=Symbol.for(`react.suspense_list`),ne=Symbol.for(`react.memo`),T=Symbol.for(`react.lazy`),re=Symbol.for(`react.activity`),ie=Symbol.for(`react.memo_cache_sentinel`),ae=Symbol.iterator;function E(e){return typeof e!=`object`||!e?null:(e=ae&&e[ae]||e[`@@iterator`],typeof e==`function`?e:null)}var oe=Symbol.for(`react.client.reference`);function se(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===oe?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case b:return`Profiler`;case ee:return`StrictMode`;case w:return`Suspense`;case te:return`SuspenseList`;case re:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case S:return e.displayName||`Context`;case x:return(e._context.displayName||`Context`)+`.Consumer`;case C:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case ne:return t=e.displayName||null,t===null?se(e.type)||`Memo`:t;case T:t=e._payload,e=e._init;try{return se(e(t))}catch{}}return null}var ce=Array.isArray,D=n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,O=r.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,k={pending:!1,data:null,method:null,action:null},le=[],ue=-1;function de(e){return{current:e}}function A(e){0>ue||(e.current=le[ue],le[ue]=null,ue--)}function j(e,t){ue++,le[ue]=e.current,e.current=t}var M=de(null),N=de(null),fe=de(null),pe=de(null);function me(e,t){switch(j(fe,t),j(N,e),j(M,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?qd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=qd(t),e=Jd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}A(M),j(M,e)}function he(){A(M),A(N),A(fe)}function ge(e){e.memoizedState!==null&&j(pe,e);var t=M.current,n=Jd(t,e.type);t!==n&&(j(N,e),j(M,n))}function P(e){N.current===e&&(A(M),A(N)),pe.current===e&&(A(pe),rp._currentValue=k)}var _e,F;function ve(e){if(_e===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);_e=t&&t[1]||``,F=-1<e.stack.indexOf(`
2+ at`)?` (<anonymous>)`:-1<e.stack.indexOf(`@`)?`@unknown:0:0`:``}return`
3+`+_e+e+F}var ye=!1;function be(e,t){if(!e||ye)return``;ye=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){r=e}(n=e())&&typeof n.catch==`function`&&n.catch(function(){})}}catch(e){if(e&&r&&typeof e.stack==`string`)return[e.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`;var i=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`);i&&i.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,"name",{value:`DetermineComponentFrameRoot`});var a=r.DetermineComponentFrameRoot(),o=a[0],s=a[1];if(o&&s){var c=o.split(`
4+`),l=s.split(`
5+`);for(i=r=0;r<c.length&&!c[r].includes(`DetermineComponentFrameRoot`);)r++;for(;i<l.length&&!l[i].includes(`DetermineComponentFrameRoot`);)i++;if(r===c.length||i===l.length)for(r=c.length-1,i=l.length-1;1<=r&&0<=i&&c[r]!==l[i];)i--;for(;1<=r&&0<=i;r--,i--)if(c[r]!==l[i]){if(r!==1||i!==1)do if(r--,i--,0>i||c[r]!==l[i]){var u=`
6+`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(`<anonymous>`)&&(u=u.replace(`<anonymous>`,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{ye=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?ve(n):``}function xe(e,t){switch(e.tag){case 26:case 27:case 5:return ve(e.type);case 16:return ve(`Lazy`);case 13:return e.child!==t&&t!==null?ve(`Suspense Fallback`):ve(`Suspense`);case 19:return ve(`SuspenseList`);case 0:case 15:return be(e.type,!1);case 11:return be(e.type.render,!1);case 1:return be(e.type,!0);case 31:return ve(`Activity`);default:return``}}function Se(e){try{var t=``,n=null;do t+=xe(e,n),n=e,e=e.return;while(e);return t}catch(e){return`
7+Error generating stack: `+e.message+`
8+`+e.stack}}var Ce=Object.prototype.hasOwnProperty,we=t.unstable_scheduleCallback,Te=t.unstable_cancelCallback,Ee=t.unstable_shouldYield,De=t.unstable_requestPaint,Oe=t.unstable_now,ke=t.unstable_getCurrentPriorityLevel,Ae=t.unstable_ImmediatePriority,je=t.unstable_UserBlockingPriority,Me=t.unstable_NormalPriority,Ne=t.unstable_LowPriority,Pe=t.unstable_IdlePriority,Fe=t.log,Ie=t.unstable_setDisableYieldValue,Le=null,Re=null;function ze(e){if(typeof Fe==`function`&&Ie(e),Re&&typeof Re.setStrictMode==`function`)try{Re.setStrictMode(Le,e)}catch{}}var Be=Math.clz32?Math.clz32:Ue,Ve=Math.log,He=Math.LN2;function Ue(e){return e>>>=0,e===0?32:31-(Ve(e)/He|0)|0}var We=256,Ge=262144,I=4194304;function L(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Ke(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=L(n))):i=L(o):i=L(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=L(n))):i=L(o)):i=L(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function R(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function qe(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Je(){var e=I;return I<<=1,!(I&62914560)&&(I=4194304),e}function Ye(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function z(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Xe(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0<n;){var u=31-Be(n),d=1<<u;s[u]=0,c[u]=-1;var f=l[u];if(f!==null)for(l[u]=null,u=0;u<f.length;u++){var p=f[u];p!==null&&(p.lane&=-536870913)}n&=~d}r!==0&&Ze(e,r,0),a!==0&&i===0&&e.tag!==0&&(e.suspendedLanes|=a&~(o&~t))}function Ze(e,t,n){e.pendingLanes|=t,e.suspendedLanes&=~t;var r=31-Be(t);e.entangledLanes|=t,e.entanglements[r]=e.entanglements[r]|1073741824|n&261930}function Qe(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-Be(n),i=1<<r;i&t|e[r]&t&&(e[r]|=t),n&=~i}}function B(e,t){var n=t&-t;return n=n&42?1:$e(n),(n&(e.suspendedLanes|t))===0?n:0}function $e(e){switch(e){case 2:e=1;break;case 8:e=4;break;case 32:e=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:e=128;break;case 268435456:e=134217728;break;default:e=0}return e}function V(e){return e&=-e,2<e?8<e?e&134217727?32:268435456:8:2}function et(){var e=O.p;return e===0?(e=window.event,e===void 0?32:yp(e.type)):e}function tt(e,t){var n=O.p;try{return O.p=e,t()}finally{O.p=n}}var nt=Math.random().toString(36).slice(2),rt=`__reactFiber$`+nt,it=`__reactProps$`+nt,at=`__reactContainer$`+nt,ot=`__reactEvents$`+nt,st=`__reactListeners$`+nt,ct=`__reactHandles$`+nt,lt=`__reactResources$`+nt,ut=`__reactMarker$`+nt;function dt(e){delete e[rt],delete e[it],delete e[ot],delete e[st],delete e[ct]}function ft(e){var t=e[rt];if(t)return t;for(var n=e.parentNode;n;){if(t=n[at]||n[rt]){if(n=t.alternate,t.child!==null||n!==null&&n.child!==null)for(e=_f(e);e!==null;){if(n=e[rt])return n;e=_f(e)}return t}e=n,n=e.parentNode}return null}function pt(e){if(e=e[rt]||e[at]){var t=e.tag;if(t===5||t===6||t===13||t===31||t===26||t===27||t===3)return e}return null}function mt(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e.stateNode;throw Error(i(33))}function ht(e){var t=e[lt];return t||=e[lt]={hoistableStyles:new Map,hoistableScripts:new Map},t}function gt(e){e[ut]=!0}var _t=new Set,vt={};function yt(e,t){bt(e,t),bt(e+`Capture`,t)}function bt(e,t){for(vt[e]=t,e=0;e<t.length;e++)_t.add(t[e])}var xt=RegExp(`^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$`),St={},Ct={};function wt(e){return Ce.call(Ct,e)?!0:Ce.call(St,e)?!1:xt.test(e)?Ct[e]=!0:(St[e]=!0,!1)}function Tt(e,t,n){if(wt(t))if(n===null)e.removeAttribute(t);else{switch(typeof n){case`undefined`:case`function`:case`symbol`:e.removeAttribute(t);return;case`boolean`:var r=t.toLowerCase().slice(0,5);if(r!==`data-`&&r!==`aria-`){e.removeAttribute(t);return}}e.setAttribute(t,``+n)}}function Et(e,t,n){if(n===null)e.removeAttribute(t);else{switch(typeof n){case`undefined`:case`function`:case`symbol`:case`boolean`:e.removeAttribute(t);return}e.setAttribute(t,``+n)}}function Dt(e,t,n,r){if(r===null)e.removeAttribute(n);else{switch(typeof r){case`undefined`:case`function`:case`symbol`:case`boolean`:e.removeAttribute(n);return}e.setAttributeNS(t,n,``+r)}}function Ot(e){switch(typeof e){case`bigint`:case`boolean`:case`number`:case`string`:case`undefined`:return e;case`object`:return e;default:return``}}function kt(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()===`input`&&(t===`checkbox`||t===`radio`)}function At(e,t,n){var r=Object.getOwnPropertyDescriptor(e.constructor.prototype,t);if(!e.hasOwnProperty(t)&&r!==void 0&&typeof r.get==`function`&&typeof r.set==`function`){var i=r.get,a=r.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(e){n=``+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:r.enumerable}),{getValue:function(){return n},setValue:function(e){n=``+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function jt(e){if(!e._valueTracker){var t=kt(e)?`checked`:`value`;e._valueTracker=At(e,t,``+e[t])}}function Mt(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r=``;return e&&(r=kt(e)?e.checked?`true`:`false`:e.value),e=r,e===n?!1:(t.setValue(e),!0)}function Nt(e){if(e||=typeof document<`u`?document:void 0,e===void 0)return null;try{return e.activeElement||e.body}catch{return e.body}}var Pt=/[\n"\\]/g;function Ft(e){return e.replace(Pt,function(e){return`\\`+e.charCodeAt(0).toString(16)+` `})}function It(e,t,n,r,i,a,o,s){e.name=``,o!=null&&typeof o!=`function`&&typeof o!=`symbol`&&typeof o!=`boolean`?e.type=o:e.removeAttribute(`type`),t==null?o!==`submit`&&o!==`reset`||e.removeAttribute(`value`):o===`number`?(t===0&&e.value===``||e.value!=t)&&(e.value=``+Ot(t)):e.value!==``+Ot(t)&&(e.value=``+Ot(t)),t==null?n==null?r!=null&&e.removeAttribute(`value`):Rt(e,o,Ot(n)):Rt(e,o,Ot(t)),i==null&&a!=null&&(e.defaultChecked=!!a),i!=null&&(e.checked=i&&typeof i!=`function`&&typeof i!=`symbol`),s!=null&&typeof s!=`function`&&typeof s!=`symbol`&&typeof s!=`boolean`?e.name=``+Ot(s):e.removeAttribute(`name`)}function Lt(e,t,n,r,i,a,o,s){if(a!=null&&typeof a!=`function`&&typeof a!=`symbol`&&typeof a!=`boolean`&&(e.type=a),t!=null||n!=null){if(!(a!==`submit`&&a!==`reset`||t!=null)){jt(e);return}n=n==null?``:``+Ot(n),t=t==null?n:``+Ot(t),s||t===e.value||(e.value=t),e.defaultValue=t}r??=i,r=typeof r!=`function`&&typeof r!=`symbol`&&!!r,e.checked=s?e.checked:!!r,e.defaultChecked=!!r,o!=null&&typeof o!=`function`&&typeof o!=`symbol`&&typeof o!=`boolean`&&(e.name=o),jt(e)}function Rt(e,t,n){t===`number`&&Nt(e.ownerDocument)===e||e.defaultValue===``+n||(e.defaultValue=``+n)}function zt(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i<n.length;i++)t[`$`+n[i]]=!0;for(n=0;n<e.length;n++)i=t.hasOwnProperty(`$`+e[n].value),e[n].selected!==i&&(e[n].selected=i),i&&r&&(e[n].defaultSelected=!0)}else{for(n=``+Ot(n),t=null,i=0;i<e.length;i++){if(e[i].value===n){e[i].selected=!0,r&&(e[i].defaultSelected=!0);return}t!==null||e[i].disabled||(t=e[i])}t!==null&&(t.selected=!0)}}function Bt(e,t,n){if(t!=null&&(t=``+Ot(t),t!==e.value&&(e.value=t),n==null)){e.defaultValue!==t&&(e.defaultValue=t);return}e.defaultValue=n==null?``:``+Ot(n)}function Vt(e,t,n,r){if(t==null){if(r!=null){if(n!=null)throw Error(i(92));if(ce(r)){if(1<r.length)throw Error(i(93));r=r[0]}n=r}n??=``,t=n}n=Ot(t),e.defaultValue=n,r=e.textContent,r===n&&r!==``&&r!==null&&(e.value=r),jt(e)}function Ht(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Ut=new Set(`animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp`.split(` `));function Wt(e,t,n){var r=t.indexOf(`--`)===0;n==null||typeof n==`boolean`||n===``?r?e.setProperty(t,``):t===`float`?e.cssFloat=``:e[t]=``:r?e.setProperty(t,n):typeof n!=`number`||n===0||Ut.has(t)?t===`float`?e.cssFloat=n:e[t]=(``+n).trim():e[t]=n+`px`}function Gt(e,t,n){if(t!=null&&typeof t!=`object`)throw Error(i(62));if(e=e.style,n!=null){for(var r in n)!n.hasOwnProperty(r)||t!=null&&t.hasOwnProperty(r)||(r.indexOf(`--`)===0?e.setProperty(r,``):r===`float`?e.cssFloat=``:e[r]=``);for(var a in t)r=t[a],t.hasOwnProperty(a)&&n[a]!==r&&Wt(e,a,r)}else for(var o in t)t.hasOwnProperty(o)&&Wt(e,o,t[o])}function Kt(e){if(e.indexOf(`-`)===-1)return!1;switch(e){case`annotation-xml`:case`color-profile`:case`font-face`:case`font-face-src`:case`font-face-uri`:case`font-face-format`:case`font-face-name`:case`missing-glyph`:return!1;default:return!0}}var qt=new Map([[`acceptCharset`,`accept-charset`],[`htmlFor`,`for`],[`httpEquiv`,`http-equiv`],[`crossOrigin`,`crossorigin`],[`accentHeight`,`accent-height`],[`alignmentBaseline`,`alignment-baseline`],[`arabicForm`,`arabic-form`],[`baselineShift`,`baseline-shift`],[`capHeight`,`cap-height`],[`clipPath`,`clip-path`],[`clipRule`,`clip-rule`],[`colorInterpolation`,`color-interpolation`],[`colorInterpolationFilters`,`color-interpolation-filters`],[`colorProfile`,`color-profile`],[`colorRendering`,`color-rendering`],[`dominantBaseline`,`dominant-baseline`],[`enableBackground`,`enable-background`],[`fillOpacity`,`fill-opacity`],[`fillRule`,`fill-rule`],[`floodColor`,`flood-color`],[`floodOpacity`,`flood-opacity`],[`fontFamily`,`font-family`],[`fontSize`,`font-size`],[`fontSizeAdjust`,`font-size-adjust`],[`fontStretch`,`font-stretch`],[`fontStyle`,`font-style`],[`fontVariant`,`font-variant`],[`fontWeight`,`font-weight`],[`glyphName`,`glyph-name`],[`glyphOrientationHorizontal`,`glyph-orientation-horizontal`],[`glyphOrientationVertical`,`glyph-orientation-vertical`],[`horizAdvX`,`horiz-adv-x`],[`horizOriginX`,`horiz-origin-x`],[`imageRendering`,`image-rendering`],[`letterSpacing`,`letter-spacing`],[`lightingColor`,`lighting-color`],[`markerEnd`,`marker-end`],[`markerMid`,`marker-mid`],[`markerStart`,`marker-start`],[`overlinePosition`,`overline-position`],[`overlineThickness`,`overline-thickness`],[`paintOrder`,`paint-order`],[`panose-1`,`panose-1`],[`pointerEvents`,`pointer-events`],[`renderingIntent`,`rendering-intent`],[`shapeRendering`,`shape-rendering`],[`stopColor`,`stop-color`],[`stopOpacity`,`stop-opacity`],[`strikethroughPosition`,`strikethrough-position`],[`strikethroughThickness`,`strikethrough-thickness`],[`strokeDasharray`,`stroke-dasharray`],[`strokeDashoffset`,`stroke-dashoffset`],[`strokeLinecap`,`stroke-linecap`],[`strokeLinejoin`,`stroke-linejoin`],[`strokeMiterlimit`,`stroke-miterlimit`],[`strokeOpacity`,`stroke-opacity`],[`strokeWidth`,`stroke-width`],[`textAnchor`,`text-anchor`],[`textDecoration`,`text-decoration`],[`textRendering`,`text-rendering`],[`transformOrigin`,`transform-origin`],[`underlinePosition`,`underline-position`],[`underlineThickness`,`underline-thickness`],[`unicodeBidi`,`unicode-bidi`],[`unicodeRange`,`unicode-range`],[`unitsPerEm`,`units-per-em`],[`vAlphabetic`,`v-alphabetic`],[`vHanging`,`v-hanging`],[`vIdeographic`,`v-ideographic`],[`vMathematical`,`v-mathematical`],[`vectorEffect`,`vector-effect`],[`vertAdvY`,`vert-adv-y`],[`vertOriginX`,`vert-origin-x`],[`vertOriginY`,`vert-origin-y`],[`wordSpacing`,`word-spacing`],[`writingMode`,`writing-mode`],[`xmlnsXlink`,`xmlns:xlink`],[`xHeight`,`x-height`]]),Jt=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;function Yt(e){return Jt.test(``+e)?`javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')`:e}function Xt(){}var Zt=null;function Qt(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var $t=null,en=null;function tn(e){var t=pt(e);if(t&&(e=t.stateNode)){var n=e[it]||null;a:switch(e=t.stateNode,t.type){case`input`:if(It(e,n.value,n.defaultValue,n.defaultValue,n.checked,n.defaultChecked,n.type,n.name),t=n.name,n.type===`radio`&&t!=null){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll(`input[name="`+Ft(``+t)+`"][type="radio"]`),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=r[it]||null;if(!a)throw Error(i(90));It(r,a.value,a.defaultValue,a.defaultValue,a.checked,a.defaultChecked,a.type,a.name)}}for(t=0;t<n.length;t++)r=n[t],r.form===e.form&&Mt(r)}break a;case`textarea`:Bt(e,n.value,n.defaultValue);break a;case`select`:t=n.value,t!=null&&zt(e,!!n.multiple,t,!1)}}}var nn=!1;function rn(e,t,n){if(nn)return e(t,n);nn=!0;try{return e(t)}finally{if(nn=!1,($t!==null||en!==null)&&(wu(),$t&&(t=$t,e=en,en=$t=null,tn(t),e)))for(t=0;t<e.length;t++)tn(e[t])}}function an(e,t){var n=e.stateNode;if(n===null)return null;var r=n[it]||null;if(r===null)return null;n=r[t];a:switch(t){case`onClick`:case`onClickCapture`:case`onDoubleClick`:case`onDoubleClickCapture`:case`onMouseDown`:case`onMouseDownCapture`:case`onMouseMove`:case`onMouseMoveCapture`:case`onMouseUp`:case`onMouseUpCapture`:case`onMouseEnter`:(r=!r.disabled)||(e=e.type,r=!(e===`button`||e===`input`||e===`select`||e===`textarea`)),e=!r;break a;default:e=!1}if(e)return null;if(n&&typeof n!=`function`)throw Error(i(231,t,typeof n));return n}var on=!(typeof window>`u`||window.document===void 0||window.document.createElement===void 0),sn=!1;if(on)try{var cn={};Object.defineProperty(cn,"passive",{get:function(){sn=!0}}),window.addEventListener(`test`,cn,cn),window.removeEventListener(`test`,cn,cn)}catch{sn=!1}var ln=null,un=null,dn=null;function fn(){if(dn)return dn;var e,t=un,n=t.length,r,i=`value`in ln?ln.value:ln.textContent,a=i.length;for(e=0;e<n&&t[e]===i[e];e++);var o=n-e;for(r=1;r<=o&&t[n-r]===i[a-r];r++);return dn=i.slice(e,1<r?1-r:void 0)}function pn(e){var t=e.keyCode;return`charCode`in e?(e=e.charCode,e===0&&t===13&&(e=13)):e=t,e===10&&(e=13),32<=e||e===13?e:0}function mn(){return!0}function hn(){return!1}function gn(e){function t(t,n,r,i,a){for(var o in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=i,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(o)&&(t=e[o],this[o]=t?t(i):i[o]);return this.isDefaultPrevented=(i.defaultPrevented==null?!1===i.returnValue:i.defaultPrevented)?mn:hn,this.isPropagationStopped=hn,this}return h(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():typeof e.returnValue!=`unknown`&&(e.returnValue=!1),this.isDefaultPrevented=mn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():typeof e.cancelBubble!=`unknown`&&(e.cancelBubble=!0),this.isPropagationStopped=mn)},persist:function(){},isPersistent:mn}),t}var _n={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},vn=gn(_n),yn=h({},_n,{view:0,detail:0}),bn=gn(yn),xn,Sn,Cn,wn=h({},yn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Pn,button:0,buttons:0,relatedTarget:function(e){return e.relatedTarget===void 0?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return`movementX`in e?e.movementX:(e!==Cn&&(Cn&&e.type===`mousemove`?(xn=e.screenX-Cn.screenX,Sn=e.screenY-Cn.screenY):Sn=xn=0,Cn=e),xn)},movementY:function(e){return`movementY`in e?e.movementY:Sn}}),Tn=gn(wn),En=gn(h({},wn,{dataTransfer:0})),Dn=gn(h({},yn,{relatedTarget:0})),On=gn(h({},_n,{animationName:0,elapsedTime:0,pseudoElement:0})),kn=gn(h({},_n,{clipboardData:function(e){return`clipboardData`in e?e.clipboardData:window.clipboardData}})),An=gn(h({},_n,{data:0})),eee={Esc:`Escape`,Spacebar:` `,Left:`ArrowLeft`,Up:`ArrowUp`,Right:`ArrowRight`,Down:`ArrowDown`,Del:`Delete`,Win:`OS`,Menu:`ContextMenu`,Apps:`ContextMenu`,Scroll:`ScrollLock`,MozPrintableKey:`Unidentified`},jn={8:`Backspace`,9:`Tab`,12:`Clear`,13:`Enter`,16:`Shift`,17:`Control`,18:`Alt`,19:`Pause`,20:`CapsLock`,27:`Escape`,32:` `,33:`PageUp`,34:`PageDown`,35:`End`,36:`Home`,37:`ArrowLeft`,38:`ArrowUp`,39:`ArrowRight`,40:`ArrowDown`,45:`Insert`,46:`Delete`,112:`F1`,113:`F2`,114:`F3`,115:`F4`,116:`F5`,117:`F6`,118:`F7`,119:`F8`,120:`F9`,121:`F10`,122:`F11`,123:`F12`,144:`NumLock`,145:`ScrollLock`,224:`Meta`},Mn={Alt:`altKey`,Control:`ctrlKey`,Meta:`metaKey`,Shift:`shiftKey`};function Nn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):(e=Mn[e])?!!t[e]:!1}function Pn(){return Nn}var Fn=gn(h({},yn,{key:function(e){if(e.key){var t=eee[e.key]||e.key;if(t!==`Unidentified`)return t}return e.type===`keypress`?(e=pn(e),e===13?`Enter`:String.fromCharCode(e)):e.type===`keydown`||e.type===`keyup`?jn[e.keyCode]||`Unidentified`:``},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Pn,charCode:function(e){return e.type===`keypress`?pn(e):0},keyCode:function(e){return e.type===`keydown`||e.type===`keyup`?e.keyCode:0},which:function(e){return e.type===`keypress`?pn(e):e.type===`keydown`||e.type===`keyup`?e.keyCode:0}})),In=gn(h({},wn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Ln=gn(h({},yn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Pn})),Rn=gn(h({},_n,{propertyName:0,elapsedTime:0,pseudoElement:0})),zn=gn(h({},wn,{deltaX:function(e){return`deltaX`in e?e.deltaX:`wheelDeltaX`in e?-e.wheelDeltaX:0},deltaY:function(e){return`deltaY`in e?e.deltaY:`wheelDeltaY`in e?-e.wheelDeltaY:`wheelDelta`in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0})),Bn=gn(h({},_n,{newState:0,oldState:0})),Vn=[9,13,27,32],Hn=on&&`CompositionEvent`in window,Un=null;on&&`documentMode`in document&&(Un=document.documentMode);var Wn=on&&`TextEvent`in window&&!Un,Gn=on&&(!Hn||Un&&8<Un&&11>=Un),Kn=` `,qn=!1;function Jn(e,t){switch(e){case`keyup`:return Vn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Yn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Xn=!1;function Zn(e,t){switch(e){case`compositionend`:return Yn(t);case`keypress`:return t.which===32?(qn=!0,Kn):null;case`textInput`:return e=t.data,e===Kn&&qn?null:e;default:return null}}function Qn(e,t){if(Xn)return e===`compositionend`||!Hn&&Jn(e,t)?(e=fn(),dn=un=ln=null,Xn=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case`compositionend`:return Gn&&t.locale!==`ko`?null:t.data;default:return null}}var $n={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function er(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t===`input`?!!$n[e.type]:t===`textarea`}function tr(e,t,n,r){$t?en?en.push(r):en=[r]:$t=r,t=jd(t,`onChange`),0<t.length&&(n=new vn(`onChange`,`change`,null,n,r),e.push({event:n,listeners:t}))}var nr=null,rr=null;function ir(e){wd(e,0)}function ar(e){if(Mt(mt(e)))return e}function or(e,t){if(e===`change`)return t}var sr=!1;if(on){var cr;if(on){var lr=`oninput`in document;if(!lr){var ur=document.createElement(`div`);ur.setAttribute(`oninput`,`return;`),lr=typeof ur.oninput==`function`}cr=lr}else cr=!1;sr=cr&&(!document.documentMode||9<document.documentMode)}function dr(){nr&&(nr.detachEvent(`onpropertychange`,fr),rr=nr=null)}function fr(e){if(e.propertyName===`value`&&ar(rr)){var t=[];tr(t,rr,e,Qt(e)),rn(ir,t)}}function pr(e,t,n){e===`focusin`?(dr(),nr=t,rr=n,nr.attachEvent(`onpropertychange`,fr)):e===`focusout`&&dr()}function mr(e){if(e===`selectionchange`||e===`keyup`||e===`keydown`)return ar(rr)}function hr(e,t){if(e===`click`)return ar(t)}function gr(e,t){if(e===`input`||e===`change`)return ar(t)}function _r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var vr=typeof Object.is==`function`?Object.is:_r;function yr(e,t){if(vr(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var i=n[r];if(!Ce.call(t,i)||!vr(e[i],t[i]))return!1}return!0}function br(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function xr(e,t){var n=br(e);e=0;for(var r;n;){if(n.nodeType===3){if(r=e+n.textContent.length,e<=t&&r>=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=br(n)}}function Sr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Sr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Cr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Nt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Nt(e.document)}return t}function wr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Tr=on&&`documentMode`in document&&11>=document.documentMode,Er=null,Dr=null,Or=null,kr=!1;function Ar(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;kr||Er==null||Er!==Nt(r)||(r=Er,`selectionStart`in r&&wr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Or&&yr(Or,r)||(Or=r,r=jd(Dr,`onSelect`),0<r.length&&(t=new vn(`onSelect`,`select`,null,t,n),e.push({event:t,listeners:r}),t.target=Er)))}function jr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n[`Webkit`+e]=`webkit`+t,n[`Moz`+e]=`moz`+t,n}var Mr={animationend:jr(`Animation`,`AnimationEnd`),animationiteration:jr(`Animation`,`AnimationIteration`),animationstart:jr(`Animation`,`AnimationStart`),transitionrun:jr(`Transition`,`TransitionRun`),transitionstart:jr(`Transition`,`TransitionStart`),transitioncancel:jr(`Transition`,`TransitionCancel`),transitionend:jr(`Transition`,`TransitionEnd`)},Nr={},Pr={};on&&(Pr=document.createElement(`div`).style,`AnimationEvent`in window||(delete Mr.animationend.animation,delete Mr.animationiteration.animation,delete Mr.animationstart.animation),`TransitionEvent`in window||delete Mr.transitionend.transition);function Fr(e){if(Nr[e])return Nr[e];if(!Mr[e])return e;var t=Mr[e],n;for(n in t)if(t.hasOwnProperty(n)&&n in Pr)return Nr[e]=t[n];return e}var Ir=Fr(`animationend`),Lr=Fr(`animationiteration`),Rr=Fr(`animationstart`),zr=Fr(`transitionrun`),Br=Fr(`transitionstart`),Vr=Fr(`transitioncancel`),Hr=Fr(`transitionend`),Ur=new Map,Wr=`abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel`.split(` `);Wr.push(`scrollEnd`);function Gr(e,t){Ur.set(e,t),yt(t,[e])}var Kr=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)},qr=[],Jr=0,Yr=0;function Xr(){for(var e=Jr,t=Yr=Jr=0;t<e;){var n=qr[t];qr[t++]=null;var r=qr[t];qr[t++]=null;var i=qr[t];qr[t++]=null;var a=qr[t];if(qr[t++]=null,r!==null&&i!==null){var o=r.pending;o===null?i.next=i:(i.next=o.next,o.next=i),r.pending=i}a!==0&&ei(n,i,a)}}function Zr(e,t,n,r){qr[Jr++]=e,qr[Jr++]=t,qr[Jr++]=n,qr[Jr++]=r,Yr|=r,e.lanes|=r,e=e.alternate,e!==null&&(e.lanes|=r)}function Qr(e,t,n,r){return Zr(e,t,n,r),ti(e)}function $r(e,t){return Zr(e,null,null,t),ti(e)}function ei(e,t,n){e.lanes|=n;var r=e.alternate;r!==null&&(r.lanes|=n);for(var i=!1,a=e.return;a!==null;)a.childLanes|=n,r=a.alternate,r!==null&&(r.childLanes|=n),a.tag===22&&(e=a.stateNode,e===null||e._visibility&1||(i=!0)),e=a,a=a.return;return e.tag===3?(a=e.stateNode,i&&t!==null&&(i=31-Be(n),e=a.hiddenUpdates,r=e[i],r===null?e[i]=[t]:r.push(t),t.lane=n|536870912),a):null}function ti(e){if(50<hu)throw hu=0,gu=null,Error(i(185));for(var t=e.return;t!==null;)e=t,t=e.return;return e.tag===3?e.stateNode:null}var ni={};function ri(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.refCleanup=this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ii(e,t,n,r){return new ri(e,t,n,r)}function ai(e){return e=e.prototype,!(!e||!e.isReactComponent)}function oi(e,t){var n=e.alternate;return n===null?(n=ii(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&65011712,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n.refCleanup=e.refCleanup,n}function si(e,t){e.flags&=65011714;var n=e.alternate;return n===null?(e.childLanes=0,e.lanes=t,e.child=null,e.subtreeFlags=0,e.memoizedProps=null,e.memoizedState=null,e.updateQueue=null,e.dependencies=null,e.stateNode=null):(e.childLanes=n.childLanes,e.lanes=n.lanes,e.child=n.child,e.subtreeFlags=0,e.deletions=null,e.memoizedProps=n.memoizedProps,e.memoizedState=n.memoizedState,e.updateQueue=n.updateQueue,e.type=n.type,t=n.dependencies,e.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext}),e}function ci(e,t,n,r,a,o){var s=0;if(r=e,typeof e==`function`)ai(e)&&(s=1);else if(typeof e==`string`)s=Jf(e,n,M.current)?26:e===`html`||e===`head`||e===`body`?27:5;else a:switch(e){case re:return e=ii(31,n,t,a),e.elementType=re,e.lanes=o,e;case y:return li(n.children,a,o,t);case ee:s=8,a|=24;break;case b:return e=ii(12,n,t,a|2),e.elementType=b,e.lanes=o,e;case w:return e=ii(13,n,t,a),e.elementType=w,e.lanes=o,e;case te:return e=ii(19,n,t,a),e.elementType=te,e.lanes=o,e;default:if(typeof e==`object`&&e)switch(e.$$typeof){case S:s=10;break a;case x:s=9;break a;case C:s=11;break a;case ne:s=14;break a;case T:s=16,r=null;break a}s=29,n=Error(i(130,e===null?`null`:typeof e,``)),r=null}return t=ii(s,n,t,a),t.elementType=e,t.type=r,t.lanes=o,t}function li(e,t,n,r){return e=ii(7,e,r,t),e.lanes=n,e}function ui(e,t,n){return e=ii(6,e,null,t),e.lanes=n,e}function di(e){var t=ii(18,null,null,0);return t.stateNode=e,t}function fi(e,t,n){return t=ii(4,e.children===null?[]:e.children,e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}var pi=new WeakMap;function mi(e,t){if(typeof e==`object`&&e){var n=pi.get(e);return n===void 0?(t={value:e,source:t,stack:Se(t)},pi.set(e,t),t):n}return{value:e,source:t,stack:Se(t)}}var hi=[],gi=0,_i=null,vi=0,yi=[],bi=0,xi=null,Si=1,Ci=``;function wi(e,t){hi[gi++]=vi,hi[gi++]=_i,_i=e,vi=t}function Ti(e,t,n){yi[bi++]=Si,yi[bi++]=Ci,yi[bi++]=xi,xi=e;var r=Si;e=Ci;var i=32-Be(r)-1;r&=~(1<<i),n+=1;var a=32-Be(t)+i;if(30<a){var o=i-i%5;a=(r&(1<<o)-1).toString(32),r>>=o,i-=o,Si=1<<32-Be(t)+i|n<<i|r,Ci=a+e}else Si=1<<a|n<<i|r,Ci=e}function Ei(e){e.return!==null&&(wi(e,1),Ti(e,1,0))}function Di(e){for(;e===_i;)_i=hi[--gi],hi[gi]=null,vi=hi[--gi],hi[gi]=null;for(;e===xi;)xi=yi[--bi],yi[bi]=null,Ci=yi[--bi],yi[bi]=null,Si=yi[--bi],yi[bi]=null}function Oi(e,t){yi[bi++]=Si,yi[bi++]=Ci,yi[bi++]=xi,Si=t.id,Ci=t.overflow,xi=e}var ki=null,Ai=null,ji=!1,Mi=null,Ni=!1,Pi=Error(i(519));function Fi(e){throw Vi(mi(Error(i(418,1<arguments.length&&arguments[1]!==void 0&&arguments[1]?`text`:`HTML`,``)),e)),Pi}function Ii(e){var t=e.stateNode,n=e.type,r=e.memoizedProps;switch(t[rt]=e,t[it]=r,n){case`dialog`:G(`cancel`,t),G(`close`,t);break;case`iframe`:case`object`:case`embed`:G(`load`,t);break;case`video`:case`audio`:for(n=0;n<Sd.length;n++)G(Sd[n],t);break;case`source`:G(`error`,t);break;case`img`:case`image`:case`link`:G(`error`,t),G(`load`,t);break;case`details`:G(`toggle`,t);break;case`input`:G(`invalid`,t),Lt(t,r.value,r.defaultValue,r.checked,r.defaultChecked,r.type,r.name,!0);break;case`select`:G(`invalid`,t);break;case`textarea`:G(`invalid`,t),Vt(t,r.value,r.defaultValue,r.children)}n=r.children,typeof n!=`string`&&typeof n!=`number`&&typeof n!=`bigint`||t.textContent===``+n||!0===r.suppressHydrationWarning||Ld(t.textContent,n)?(r.popover!=null&&(G(`beforetoggle`,t),G(`toggle`,t)),r.onScroll!=null&&G(`scroll`,t),r.onScrollEnd!=null&&G(`scrollend`,t),r.onClick!=null&&(t.onclick=Xt),t=!0):t=!1,t||Fi(e,!0)}function Li(e){for(ki=e.return;ki;)switch(ki.tag){case 5:case 31:case 13:Ni=!1;return;case 27:case 3:Ni=!0;return;default:ki=ki.return}}function Ri(e){if(e!==ki)return!1;if(!ji)return Li(e),ji=!0,!1;var t=e.tag,n;if((n=t!==3&&t!==27)&&((n=t===5)&&(n=e.type,n=!(n!==`form`&&n!==`button`)||Yd(e.type,e.memoizedProps)),n=!n),n&&Ai&&Fi(e),Li(e),t===13){if(e=e.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(317));Ai=gf(e)}else if(t===31){if(e=e.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(317));Ai=gf(e)}else t===27?(t=Ai,rf(e.type)?(e=hf,hf=null,Ai=e):Ai=t):Ai=ki?mf(e.stateNode.nextSibling):null;return!0}function zi(){Ai=ki=null,ji=!1}function Bi(){var e=Mi;return e!==null&&(tu===null?tu=e:tu.push.apply(tu,e),Mi=null),e}function Vi(e){Mi===null?Mi=[e]:Mi.push(e)}var Hi=de(null),Ui=null,Wi=null;function Gi(e,t,n){j(Hi,t._currentValue),t._currentValue=n}function Ki(e){e._currentValue=Hi.current,A(Hi)}function qi(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)===t?r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t):(e.childLanes|=t,r!==null&&(r.childLanes|=t)),e===n)break;e=e.return}}function Ji(e,t,n,r){var a=e.child;for(a!==null&&(a.return=e);a!==null;){var o=a.dependencies;if(o!==null){var s=a.child;o=o.firstContext;a:for(;o!==null;){var c=o;o=a;for(var l=0;l<t.length;l++)if(c.context===t[l]){o.lanes|=n,c=o.alternate,c!==null&&(c.lanes|=n),qi(o.return,n,e),r||(s=null);break a}o=c.next}}else if(a.tag===18){if(s=a.return,s===null)throw Error(i(341));s.lanes|=n,o=s.alternate,o!==null&&(o.lanes|=n),qi(s,n,e),s=null}else s=a.child;if(s!==null)s.return=a;else for(s=a;s!==null;){if(s===e){s=null;break}if(a=s.sibling,a!==null){a.return=s.return,s=a;break}s=s.return}a=s}}function Yi(e,t,n,r){e=null;for(var a=t,o=!1;a!==null;){if(!o){if(a.flags&524288)o=!0;else if(a.flags&262144)break}if(a.tag===10){var s=a.alternate;if(s===null)throw Error(i(387));if(s=s.memoizedProps,s!==null){var c=a.type;vr(a.pendingProps.value,s.value)||(e===null?e=[c]:e.push(c))}}else if(a===pe.current){if(s=a.alternate,s===null)throw Error(i(387));s.memoizedState.memoizedState!==a.memoizedState.memoizedState&&(e===null?e=[rp]:e.push(rp))}a=a.return}e!==null&&Ji(t,e,n,r),t.flags|=262144}function Xi(e){for(e=e.firstContext;e!==null;){if(!vr(e.context._currentValue,e.memoizedValue))return!0;e=e.next}return!1}function Zi(e){Ui=e,Wi=null,e=e.dependencies,e!==null&&(e.firstContext=null)}function Qi(e){return ea(Ui,e)}function $i(e,t){return Ui===null&&Zi(e),ea(e,t)}function ea(e,t){var n=t._currentValue;if(t={context:t,memoizedValue:n,next:null},Wi===null){if(e===null)throw Error(i(308));Wi=t,e.dependencies={lanes:0,firstContext:t},e.flags|=524288}else Wi=Wi.next=t;return n}var ta=typeof AbortController<`u`?AbortController:function(){var e=[],t=this.signal={aborted:!1,addEventListener:function(t,n){e.push(n)}};this.abort=function(){t.aborted=!0,e.forEach(function(e){return e()})}},na=t.unstable_scheduleCallback,ra=t.unstable_NormalPriority,ia={$$typeof:S,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function aa(){return{controller:new ta,data:new Map,refCount:0}}function oa(e){e.refCount--,e.refCount===0&&na(ra,function(){e.controller.abort()})}var sa=null,ca=0,la=0,ua=null;function da(e,t){if(sa===null){var n=sa=[];ca=0,la=gd(),ua={status:`pending`,value:void 0,then:function(e){n.push(e)}}}return ca++,t.then(fa,fa),t}function fa(){if(--ca===0&&sa!==null){ua!==null&&(ua.status=`fulfilled`);var e=sa;sa=null,la=0,ua=null;for(var t=0;t<e.length;t++)(0,e[t])()}}function pa(e,t){var n=[],r={status:`pending`,value:null,reason:null,then:function(e){n.push(e)}};return e.then(function(){r.status=`fulfilled`,r.value=t;for(var e=0;e<n.length;e++)(0,n[e])(t)},function(e){for(r.status=`rejected`,r.reason=e,e=0;e<n.length;e++)(0,n[e])(void 0)}),r}var ma=D.S;D.S=function(e,t){iu=Oe(),typeof t==`object`&&t&&typeof t.then==`function`&&da(e,t),ma!==null&&ma(e,t)};var ha=de(null);function ga(){var e=ha.current;return e===null?Vl.pooledCache:e}function _a(e,t){t===null?j(ha,ha.current):j(ha,t.pool)}function va(){var e=ga();return e===null?null:{parent:ia._currentValue,pool:e}}var ya=Error(i(460)),ba=Error(i(474)),xa=Error(i(542)),Sa={then:function(){}};function Ca(e){return e=e.status,e===`fulfilled`||e===`rejected`}function wa(e,t,n){switch(n=e[n],n===void 0?e.push(t):n!==t&&(t.then(Xt,Xt),t=n),t.status){case`fulfilled`:return t.value;case`rejected`:throw e=t.reason,Oa(e),e;default:if(typeof t.status==`string`)t.then(Xt,Xt);else{if(e=Vl,e!==null&&100<e.shellSuspendCounter)throw Error(i(482));e=t,e.status=`pending`,e.then(function(e){if(t.status===`pending`){var n=t;n.status=`fulfilled`,n.value=e}},function(e){if(t.status===`pending`){var n=t;n.status=`rejected`,n.reason=e}})}switch(t.status){case`fulfilled`:return t.value;case`rejected`:throw e=t.reason,Oa(e),e}throw Ea=t,ya}}function Ta(e){try{var t=e._init;return t(e._payload)}catch(e){throw typeof e==`object`&&e&&typeof e.then==`function`?(Ea=e,ya):e}}var Ea=null;function Da(){if(Ea===null)throw Error(i(459));var e=Ea;return Ea=null,e}function Oa(e){if(e===ya||e===xa)throw Error(i(483))}var ka=null,Aa=0;function ja(e){var t=Aa;return Aa+=1,ka===null&&(ka=[]),wa(ka,e,t)}function Ma(e,t){t=t.props.ref,e.ref=t===void 0?null:t}function Na(e,t){throw t.$$typeof===g?Error(i(525)):(e=Object.prototype.toString.call(t),Error(i(31,e===`[object Object]`?`object with keys {`+Object.keys(t).join(`, `)+`}`:e)))}function Pa(e){function t(t,n){if(e){var r=t.deletions;r===null?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;r!==null;)t(n,r),r=r.sibling;return null}function r(e){for(var t=new Map;e!==null;)e.key===null?t.set(e.index,e):t.set(e.key,e),e=e.sibling;return t}function a(e,t){return e=oi(e,t),e.index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?(r=t.alternate,r===null?(t.flags|=67108866,n):(r=r.index,r<n?(t.flags|=67108866,n):r)):(t.flags|=1048576,n)}function s(t){return e&&t.alternate===null&&(t.flags|=67108866),t}function c(e,t,n,r){return t===null||t.tag!==6?(t=ui(n,e.mode,r),t.return=e,t):(t=a(t,n),t.return=e,t)}function l(e,t,n,r){var i=n.type;return i===y?d(e,t,n.props.children,r,n.key):t!==null&&(t.elementType===i||typeof i==`object`&&i&&i.$$typeof===T&&Ta(i)===t.type)?(t=a(t,n.props),Ma(t,n),t.return=e,t):(t=ci(n.type,n.key,n.props,null,e.mode,r),Ma(t,n),t.return=e,t)}function u(e,t,n,r){return t===null||t.tag!==4||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?(t=fi(n,e.mode,r),t.return=e,t):(t=a(t,n.children||[]),t.return=e,t)}function d(e,t,n,r,i){return t===null||t.tag!==7?(t=li(n,e.mode,r,i),t.return=e,t):(t=a(t,n),t.return=e,t)}function f(e,t,n){if(typeof t==`string`&&t!==``||typeof t==`number`||typeof t==`bigint`)return t=ui(``+t,e.mode,n),t.return=e,t;if(typeof t==`object`&&t){switch(t.$$typeof){case _:return n=ci(t.type,t.key,t.props,null,e.mode,n),Ma(n,t),n.return=e,n;case v:return t=fi(t,e.mode,n),t.return=e,t;case T:return t=Ta(t),f(e,t,n)}if(ce(t)||E(t))return t=li(t,e.mode,n,null),t.return=e,t;if(typeof t.then==`function`)return f(e,ja(t),n);if(t.$$typeof===S)return f(e,$i(e,t),n);Na(e,t)}return null}function p(e,t,n,r){var i=t===null?null:t.key;if(typeof n==`string`&&n!==``||typeof n==`number`||typeof n==`bigint`)return i===null?c(e,t,``+n,r):null;if(typeof n==`object`&&n){switch(n.$$typeof){case _:return n.key===i?l(e,t,n,r):null;case v:return n.key===i?u(e,t,n,r):null;case T:return n=Ta(n),p(e,t,n,r)}if(ce(n)||E(n))return i===null?d(e,t,n,r,null):null;if(typeof n.then==`function`)return p(e,t,ja(n),r);if(n.$$typeof===S)return p(e,t,$i(e,n),r);Na(e,n)}return null}function m(e,t,n,r,i){if(typeof r==`string`&&r!==``||typeof r==`number`||typeof r==`bigint`)return e=e.get(n)||null,c(t,e,``+r,i);if(typeof r==`object`&&r){switch(r.$$typeof){case _:return e=e.get(r.key===null?n:r.key)||null,l(t,e,r,i);case v:return e=e.get(r.key===null?n:r.key)||null,u(t,e,r,i);case T:return r=Ta(r),m(e,t,n,r,i)}if(ce(r)||E(r))return e=e.get(n)||null,d(t,e,r,i,null);if(typeof r.then==`function`)return m(e,t,n,ja(r),i);if(r.$$typeof===S)return m(e,t,n,$i(t,r),i);Na(t,r)}return null}function h(i,a,s,c){for(var l=null,u=null,d=a,h=a=0,g=null;d!==null&&h<s.length;h++){d.index>h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),ji&&wi(i,h),l;if(d===null){for(;h<s.length;h++)d=f(i,s[h],c),d!==null&&(a=o(d,a,h),u===null?l=d:u.sibling=d,u=d);return ji&&wi(i,h),l}for(d=r(d);h<s.length;h++)g=m(d,i,h,s[h],c),g!==null&&(e&&g.alternate!==null&&d.delete(g.key===null?h:g.key),a=o(g,a,h),u===null?l=g:u.sibling=g,u=g);return e&&d.forEach(function(e){return t(i,e)}),ji&&wi(i,h),l}function g(a,s,c,l){if(c==null)throw Error(i(151));for(var u=null,d=null,h=s,g=s=0,_=null,v=c.next();h!==null&&!v.done;g++,v=c.next()){h.index>g?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),ji&&wi(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return ji&&wi(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),ji&&wi(a,g),u}function ee(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===T&&Ta(l)===r.type){n(e,r.sibling),c=a(r,o.props),Ma(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=li(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=ci(o.type,o.key,o.props,null,e.mode,c),Ma(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=fi(o,e.mode,c),c.return=e,e=c}return s(e);case T:return o=Ta(o),ee(e,r,o,c)}if(ce(o))return h(e,r,o,c);if(E(o)){if(l=E(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return ee(e,r,ja(o),c);if(o.$$typeof===S)return ee(e,r,$i(e,o),c);Na(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=ui(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Aa=0;var i=ee(e,t,n,r);return ka=null,i}catch(t){if(t===ya||t===xa)throw t;var a=ii(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Fa=Pa(!0),Ia=Pa(!1),La=!1;function Ra(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function za(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ba(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Va(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Bl&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ti(e),ei(e,null,n),t}return Zr(e,r,t,n),ti(e)}function Ha(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}function Ua(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Wa=!1;function Ga(){if(Wa){var e=ua;if(e!==null)throw e}}function Ka(e,t,n,r){Wa=!1;var i=e.updateQueue;La=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Hl&f)===f:(r&f)===f){f!==0&&f===la&&(Wa=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:La=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Yl|=o,e.lanes=o,e.memoizedState=d}}function qa(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Ja(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;e<n.length;e++)qa(n[e],t)}var Ya=de(null),Xa=de(0);function Za(e,t){e=Jl,j(Xa,e),j(Ya,t),Jl=e|t.baseLanes}function Qa(){j(Xa,Jl),j(Ya,Ya.current)}function $a(){Jl=Xa.current,A(Ya),A(Xa)}var eo=de(null),to=null;function no(e){var t=e.alternate;j(so,so.current&1),j(eo,e),to===null&&(t===null||Ya.current!==null||t.memoizedState!==null)&&(to=e)}function ro(e){j(so,so.current),j(eo,e),to===null&&(to=e)}function io(e){e.tag===22?(j(so,so.current),j(eo,e),to===null&&(to=e)):ao(e)}function ao(){j(so,so.current),j(eo,eo.current)}function oo(e){A(eo),to===e&&(to=null),A(so)}var so=de(0);function co(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||df(n)||ff(n)))return t}else if(t.tag===19&&(t.memoizedProps.revealOrder===`forwards`||t.memoizedProps.revealOrder===`backwards`||t.memoizedProps.revealOrder===`unstable_legacy-backwards`||t.memoizedProps.revealOrder===`together`)){if(t.flags&128)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var lo=0,H=null,uo=null,fo=null,po=!1,mo=!1,ho=!1,go=0,_o=0,vo=null,yo=0;function bo(){throw Error(i(321))}function xo(e,t){if(t===null)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!vr(e[n],t[n]))return!1;return!0}function So(e,t,n,r,i,a){return lo=a,H=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,D.H=e===null||e.memoizedState===null?zs:Bs,ho=!1,a=n(r,i),ho=!1,mo&&(a=wo(t,n,r,i)),Co(e),a}function Co(e){D.H=Rs;var t=uo!==null&&uo.next!==null;if(lo=0,fo=uo=H=null,po=!1,_o=0,vo=null,t)throw Error(i(300));e===null||nc||(e=e.dependencies,e!==null&&Xi(e)&&(nc=!0))}function wo(e,t,n,r){H=e;var a=0;do{if(mo&&(vo=null),_o=0,mo=!1,25<=a)throw Error(i(301));if(a+=1,fo=uo=null,e.updateQueue!=null){var o=e.updateQueue;o.lastEffect=null,o.events=null,o.stores=null,o.memoCache!=null&&(o.memoCache.index=0)}D.H=Vs,o=t(n,r)}while(mo);return o}function To(){var e=D.H,t=e.useState()[0];return t=typeof t.then==`function`?Mo(t):t,e=e.useState()[0],(uo===null?null:uo.memoizedState)!==e&&(H.flags|=1024),t}function Eo(){var e=go!==0;return go=0,e}function Do(e,t,n){t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~n}function Oo(e){if(po){for(e=e.memoizedState;e!==null;){var t=e.queue;t!==null&&(t.pending=null),e=e.next}po=!1}lo=0,fo=uo=H=null,mo=!1,_o=go=0,vo=null}function ko(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return fo===null?H.memoizedState=fo=e:fo=fo.next=e,fo}function Ao(){if(uo===null){var e=H.alternate;e=e===null?null:e.memoizedState}else e=uo.next;var t=fo===null?H.memoizedState:fo.next;if(t!==null)fo=t,uo=e;else{if(e===null)throw H.alternate===null?Error(i(467)):Error(i(310));uo=e,e={memoizedState:uo.memoizedState,baseState:uo.baseState,baseQueue:uo.baseQueue,queue:uo.queue,next:null},fo===null?H.memoizedState=fo=e:fo=fo.next=e}return fo}function jo(){return{lastEffect:null,events:null,stores:null,memoCache:null}}function Mo(e){var t=_o;return _o+=1,vo===null&&(vo=[]),e=wa(vo,e,t),t=H,(fo===null?t.memoizedState:fo.next)===null&&(t=t.alternate,D.H=t===null||t.memoizedState===null?zs:Bs),e}function No(e){if(typeof e==`object`&&e){if(typeof e.then==`function`)return Mo(e);if(e.$$typeof===S)return Qi(e)}throw Error(i(438,String(e)))}function Po(e){var t=null,n=H.updateQueue;if(n!==null&&(t=n.memoCache),t==null){var r=H.alternate;r!==null&&(r=r.updateQueue,r!==null&&(r=r.memoCache,r!=null&&(t={data:r.data.map(function(e){return e.slice()}),index:0})))}if(t??={data:[],index:0},n===null&&(n=jo(),H.updateQueue=n),n.memoCache=t,n=t.data[t.index],n===void 0)for(n=t.data[t.index]=Array(e),r=0;r<e;r++)n[r]=ie;return t.index++,n}function Fo(e,t){return typeof t==`function`?t(e):t}function Io(e){return Lo(Ao(),uo,e)}function Lo(e,t,n){var r=e.queue;if(r===null)throw Error(i(311));r.lastRenderedReducer=n;var a=e.baseQueue,o=r.pending;if(o!==null){if(a!==null){var s=a.next;a.next=o.next,o.next=s}t.baseQueue=a=o,r.pending=null}if(o=e.baseState,a===null)e.memoizedState=o;else{t=a.next;var c=s=null,l=null,u=t,d=!1;do{var f=u.lane&-536870913;if(f===u.lane?(lo&f)===f:(Hl&f)===f){var p=u.revertLane;if(p===0)l!==null&&(l=l.next={lane:0,revertLane:0,gesture:null,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),f===la&&(d=!0);else if((lo&p)===p){u=u.next,p===la&&(d=!0);continue}else f={lane:0,revertLane:u.revertLane,gesture:null,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null},l===null?(c=l=f,s=o):l=l.next=f,H.lanes|=p,Yl|=p;f=u.action,ho&&n(o,f),o=u.hasEagerState?u.eagerState:n(o,f)}else p={lane:f,revertLane:u.revertLane,gesture:u.gesture,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null},l===null?(c=l=p,s=o):l=l.next=p,H.lanes|=f,Yl|=f;u=u.next}while(u!==null&&u!==t);if(l===null?s=o:l.next=c,!vr(o,e.memoizedState)&&(nc=!0,d&&(n=ua,n!==null)))throw n;e.memoizedState=o,e.baseState=s,e.baseQueue=l,r.lastRenderedState=o}return a===null&&(r.lanes=0),[e.memoizedState,r.dispatch]}function Ro(e){var t=Ao(),n=t.queue;if(n===null)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(a!==null){n.pending=null;var s=a=a.next;do o=e(o,s.action),s=s.next;while(s!==a);vr(o,t.memoizedState)||(nc=!0),t.memoizedState=o,t.baseQueue===null&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function zo(e,t,n){var r=H,a=Ao(),o=ji;if(o){if(n===void 0)throw Error(i(407));n=n()}else n=t();var s=!vr((uo||a).memoizedState,n);if(s&&(a.memoizedState=n,nc=!0),a=a.queue,us(Ho.bind(null,r,a,e),[e]),a.getSnapshot!==t||s||fo!==null&&fo.memoizedState.tag&1){if(r.flags|=2048,as(9,{destroy:void 0},Vo.bind(null,r,a,n,t),null),Vl===null)throw Error(i(349));o||lo&127||Bo(r,t,n)}return n}function Bo(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},t=H.updateQueue,t===null?(t=jo(),H.updateQueue=t,t.stores=[e]):(n=t.stores,n===null?t.stores=[e]:n.push(e))}function Vo(e,t,n,r){t.value=n,t.getSnapshot=r,Uo(t)&&Wo(e)}function Ho(e,t,n){return n(function(){Uo(t)&&Wo(e)})}function Uo(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!vr(e,n)}catch{return!0}}function Wo(e){var t=$r(e,2);t!==null&&yu(t,e,2)}function Go(e){var t=ko();if(typeof e==`function`){var n=e;if(e=n(),ho){ze(!0);try{n()}finally{ze(!1)}}}return t.memoizedState=t.baseState=e,t.queue={pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:e},t}function Ko(e,t,n,r){return e.baseState=n,Lo(e,uo,typeof r==`function`?r:Fo)}function qo(e,t,n,r,a){if(Fs(e))throw Error(i(485));if(e=t.action,e!==null){var o={payload:a,action:e,next:null,isTransition:!0,status:`pending`,value:null,reason:null,listeners:[],then:function(e){o.listeners.push(e)}};D.T===null?o.isTransition=!1:n(!0),r(o),n=t.pending,n===null?(o.next=t.pending=o,Jo(t,o)):(o.next=n.next,t.pending=n.next=o)}}function Jo(e,t){var n=t.action,r=t.payload,i=e.state;if(t.isTransition){var a=D.T,o={};D.T=o;try{var s=n(i,r),c=D.S;c!==null&&c(o,s),Yo(e,t,s)}catch(n){Zo(e,t,n)}finally{a!==null&&o.types!==null&&(a.types=o.types),D.T=a}}else try{a=n(i,r),Yo(e,t,a)}catch(n){Zo(e,t,n)}}function Yo(e,t,n){typeof n==`object`&&n&&typeof n.then==`function`?n.then(function(n){Xo(e,t,n)},function(n){return Zo(e,t,n)}):Xo(e,t,n)}function Xo(e,t,n){t.status=`fulfilled`,t.value=n,Qo(t),e.state=n,t=e.pending,t!==null&&(n=t.next,n===t?e.pending=null:(n=n.next,t.next=n,Jo(e,n)))}function Zo(e,t,n){var r=e.pending;if(e.pending=null,r!==null){r=r.next;do t.status=`rejected`,t.reason=n,Qo(t),t=t.next;while(t!==r)}e.action=null}function Qo(e){e=e.listeners;for(var t=0;t<e.length;t++)(0,e[t])()}function $o(e,t){return t}function es(e,t){if(ji){var n=Vl.formState;if(n!==null){a:{var r=H;if(ji){if(Ai){b:{for(var i=Ai,a=Ni;i.nodeType!==8;){if(!a){i=null;break b}if(i=mf(i.nextSibling),i===null){i=null;break b}}a=i.data,i=a===`F!`||a===`F`?i:null}if(i){Ai=mf(i.nextSibling),r=i.data===`F!`;break a}}Fi(r)}r=!1}r&&(t=n[0])}}return n=ko(),n.memoizedState=n.baseState=t,r={pending:null,lanes:0,dispatch:null,lastRenderedReducer:$o,lastRenderedState:t},n.queue=r,n=Ms.bind(null,H,r),r.dispatch=n,r=Go(!1),a=Ps.bind(null,H,!1,r.queue),r=ko(),i={state:t,dispatch:null,action:e,pending:null},r.queue=i,n=qo.bind(null,H,i,a,n),i.dispatch=n,r.memoizedState=e,[t,n,!1]}function ts(e){return ns(Ao(),uo,e)}function ns(e,t,n){if(t=Lo(e,t,$o)[0],e=Io(Fo)[0],typeof t==`object`&&t&&typeof t.then==`function`)try{var r=Mo(t)}catch(e){throw e===ya?xa:e}else r=t;t=Ao();var i=t.queue,a=i.dispatch;return n!==t.memoizedState&&(H.flags|=2048,as(9,{destroy:void 0},rs.bind(null,i,n),null)),[r,a,e]}function rs(e,t){e.action=t}function is(e){var t=Ao(),n=uo;if(n!==null)return ns(t,n,e);Ao(),t=t.memoizedState,n=Ao();var r=n.queue.dispatch;return n.memoizedState=e,[t,r,!1]}function as(e,t,n,r){return e={tag:e,create:n,deps:r,inst:t,next:null},t=H.updateQueue,t===null&&(t=jo(),H.updateQueue=t),n=t.lastEffect,n===null?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function os(){return Ao().memoizedState}function ss(e,t,n,r){var i=ko();H.flags|=e,i.memoizedState=as(1|t,{destroy:void 0},n,r===void 0?null:r)}function cs(e,t,n,r){var i=Ao();r=r===void 0?null:r;var a=i.memoizedState.inst;uo!==null&&r!==null&&xo(r,uo.memoizedState.deps)?i.memoizedState=as(t,a,n,r):(H.flags|=e,i.memoizedState=as(1|t,a,n,r))}function ls(e,t){ss(8390656,8,e,t)}function us(e,t){cs(2048,8,e,t)}function ds(e){H.flags|=4;var t=H.updateQueue;if(t===null)t=jo(),H.updateQueue=t,t.events=[e];else{var n=t.events;n===null?t.events=[e]:n.push(e)}}function fs(e){var t=Ao().memoizedState;return ds({ref:t,nextImpl:e}),function(){if(Bl&2)throw Error(i(440));return t.impl.apply(void 0,arguments)}}function ps(e,t){return cs(4,2,e,t)}function ms(e,t){return cs(4,4,e,t)}function hs(e,t){if(typeof t==`function`){e=e();var n=t(e);return function(){typeof n==`function`?n():t(null)}}if(t!=null)return e=e(),t.current=e,function(){t.current=null}}function gs(e,t,n){n=n==null?null:n.concat([e]),cs(4,4,hs.bind(null,t,e),n)}function _s(){}function vs(e,t){var n=Ao();t=t===void 0?null:t;var r=n.memoizedState;return t!==null&&xo(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function ys(e,t){var n=Ao();t=t===void 0?null:t;var r=n.memoizedState;if(t!==null&&xo(t,r[1]))return r[0];if(r=e(),ho){ze(!0);try{e()}finally{ze(!1)}}return n.memoizedState=[r,t],r}function bs(e,t,n){return n===void 0||lo&1073741824&&!(Hl&261930)?e.memoizedState=t:(e.memoizedState=n,e=vu(),H.lanes|=e,Yl|=e,n)}function xs(e,t,n,r){return vr(n,t)?n:Ya.current===null?!(lo&42)||lo&1073741824&&!(Hl&261930)?(nc=!0,e.memoizedState=n):(e=vu(),H.lanes|=e,Yl|=e,t):(e=bs(e,n,r),vr(e,t)||(nc=!0),e)}function Ss(e,t,n,r,i){var a=O.p;O.p=a!==0&&8>a?a:8;var o=D.T,s={};D.T=s,Ps(e,!1,t,n);try{var c=i(),l=D.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Ns(e,t,pa(c,r),_u(e)):Ns(e,t,r,_u(e))}catch(n){Ns(e,t,{then:function(){},status:`rejected`,reason:n},_u())}finally{O.p=a,o!==null&&s.types!==null&&(o.types=s.types),D.T=o}}function Cs(){}function ws(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Ts(e).queue;Ss(e,a,t,k,n===null?Cs:function(){return Es(e),n(r)})}function Ts(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:k,baseState:k,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:k},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Es(e){var t=Ts(e);t.next===null&&(t=e.alternate.memoizedState),Ns(e,t.next.queue,{},_u())}function Ds(){return Qi(rp)}function Os(){return Ao().memoizedState}function ks(){return Ao().memoizedState}function As(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=_u();e=Ba(n);var r=Va(t,e,n);r!==null&&(yu(r,t,n),Ha(r,t,n)),t={cache:aa()},e.payload=t;return}t=t.return}}function js(e,t,n){var r=_u();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Fs(e)?Is(t,n):(n=Qr(e,t,n,r),n!==null&&(yu(n,e,r),Ls(n,t,r)))}function Ms(e,t,n){Ns(e,t,n,_u())}function Ns(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Fs(e))Is(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,vr(s,o))return Zr(e,t,i,0),Vl===null&&Xr(),!1}catch{}if(n=Qr(e,t,i,r),n!==null)return yu(n,e,r),Ls(n,t,r),!0}return!1}function Ps(e,t,n,r){if(r={lane:2,revertLane:gd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Fs(e)){if(t)throw Error(i(479))}else t=Qr(e,n,r,2),t!==null&&yu(t,e,2)}function Fs(e){var t=e.alternate;return e===H||t!==null&&t===H}function Is(e,t){mo=po=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ls(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}var Rs={readContext:Qi,use:No,useCallback:bo,useContext:bo,useEffect:bo,useImperativeHandle:bo,useLayoutEffect:bo,useInsertionEffect:bo,useMemo:bo,useReducer:bo,useRef:bo,useState:bo,useDebugValue:bo,useDeferredValue:bo,useTransition:bo,useSyncExternalStore:bo,useId:bo,useHostTransitionStatus:bo,useFormState:bo,useActionState:bo,useOptimistic:bo,useMemoCache:bo,useCacheRefresh:bo};Rs.useEffectEvent=bo;var zs={readContext:Qi,use:No,useCallback:function(e,t){return ko().memoizedState=[e,t===void 0?null:t],e},useContext:Qi,useEffect:ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ss(4194308,4,hs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ss(4194308,4,e,t)},useInsertionEffect:function(e,t){ss(4,2,e,t)},useMemo:function(e,t){var n=ko();t=t===void 0?null:t;var r=e();if(ho){ze(!0);try{e()}finally{ze(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=ko();if(n!==void 0){var i=n(t);if(ho){ze(!0);try{n(t)}finally{ze(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=js.bind(null,H,e),[r.memoizedState,e]},useRef:function(e){var t=ko();return e={current:e},t.memoizedState=e},useState:function(e){e=Go(e);var t=e.queue,n=Ms.bind(null,H,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:_s,useDeferredValue:function(e,t){return bs(ko(),e,t)},useTransition:function(){var e=Go(!1);return e=Ss.bind(null,H,e.queue,!0,!1),ko().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=H,a=ko();if(ji){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Vl===null)throw Error(i(349));Hl&127||Bo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ls(Ho.bind(null,r,o,e),[e]),r.flags|=2048,as(9,{destroy:void 0},Vo.bind(null,r,o,n,t),null),n},useId:function(){var e=ko(),t=Vl.identifierPrefix;if(ji){var n=Ci,r=Si;n=(r&~(1<<32-Be(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=go++,0<n&&(t+=`H`+n.toString(32)),t+=`_`}else n=yo++,t=`_`+t+`r_`+n.toString(32)+`_`;return e.memoizedState=t},useHostTransitionStatus:Ds,useFormState:es,useActionState:es,useOptimistic:function(e){var t=ko();t.memoizedState=t.baseState=e;var n={pending:null,lanes:0,dispatch:null,lastRenderedReducer:null,lastRenderedState:null};return t.queue=n,t=Ps.bind(null,H,!0,n),n.dispatch=t,[e,t]},useMemoCache:Po,useCacheRefresh:function(){return ko().memoizedState=As.bind(null,H)},useEffectEvent:function(e){var t=ko(),n={impl:e};return t.memoizedState=n,function(){if(Bl&2)throw Error(i(440));return n.impl.apply(void 0,arguments)}}},Bs={readContext:Qi,use:No,useCallback:vs,useContext:Qi,useEffect:us,useImperativeHandle:gs,useInsertionEffect:ps,useLayoutEffect:ms,useMemo:ys,useReducer:Io,useRef:os,useState:function(){return Io(Fo)},useDebugValue:_s,useDeferredValue:function(e,t){return xs(Ao(),uo.memoizedState,e,t)},useTransition:function(){var e=Io(Fo)[0],t=Ao().memoizedState;return[typeof e==`boolean`?e:Mo(e),t]},useSyncExternalStore:zo,useId:Os,useHostTransitionStatus:Ds,useFormState:ts,useActionState:ts,useOptimistic:function(e,t){return Ko(Ao(),uo,e,t)},useMemoCache:Po,useCacheRefresh:ks};Bs.useEffectEvent=fs;var Vs={readContext:Qi,use:No,useCallback:vs,useContext:Qi,useEffect:us,useImperativeHandle:gs,useInsertionEffect:ps,useLayoutEffect:ms,useMemo:ys,useReducer:Ro,useRef:os,useState:function(){return Ro(Fo)},useDebugValue:_s,useDeferredValue:function(e,t){var n=Ao();return uo===null?bs(n,e,t):xs(n,uo.memoizedState,e,t)},useTransition:function(){var e=Ro(Fo)[0],t=Ao().memoizedState;return[typeof e==`boolean`?e:Mo(e),t]},useSyncExternalStore:zo,useId:Os,useHostTransitionStatus:Ds,useFormState:is,useActionState:is,useOptimistic:function(e,t){var n=Ao();return uo===null?(n.baseState=e,[e,n.queue.dispatch]):Ko(n,uo,e,t)},useMemoCache:Po,useCacheRefresh:ks};Vs.useEffectEvent=fs;function Hs(e,t,n,r){t=e.memoizedState,n=n(r,t),n=n==null?t:h({},t,n),e.memoizedState=n,e.lanes===0&&(e.updateQueue.baseState=n)}var Us={enqueueSetState:function(e,t,n){e=e._reactInternals;var r=_u(),i=Ba(r);i.payload=t,n!=null&&(i.callback=n),t=Va(e,i,r),t!==null&&(yu(t,e,r),Ha(t,e,r))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=_u(),i=Ba(r);i.tag=1,i.payload=t,n!=null&&(i.callback=n),t=Va(e,i,r),t!==null&&(yu(t,e,r),Ha(t,e,r))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=_u(),r=Ba(n);r.tag=2,t!=null&&(r.callback=t),t=Va(e,r,n),t!==null&&(yu(t,e,n),Ha(t,e,n))}};function Ws(e,t,n,r,i,a,o){return e=e.stateNode,typeof e.shouldComponentUpdate==`function`?e.shouldComponentUpdate(r,a,o):t.prototype&&t.prototype.isPureReactComponent?!yr(n,r)||!yr(i,a):!0}function Gs(e,t,n,r){e=t.state,typeof t.componentWillReceiveProps==`function`&&t.componentWillReceiveProps(n,r),typeof t.UNSAFE_componentWillReceiveProps==`function`&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&Us.enqueueReplaceState(t,t.state,null)}function Ks(e,t){var n=t;if(`ref`in t)for(var r in n={},t)r!==`ref`&&(n[r]=t[r]);if(e=e.defaultProps)for(var i in n===t&&(n=h({},n)),e)n[i]===void 0&&(n[i]=e[i]);return n}function qs(e){Kr(e)}function tee(e){console.error(e)}function Js(e){Kr(e)}function Ys(e,t){try{var n=e.onUncaughtError;n(t.value,{componentStack:t.stack})}catch(e){setTimeout(function(){throw e})}}function Xs(e,t,n){try{var r=e.onCaughtError;r(n.value,{componentStack:n.stack,errorBoundary:t.tag===1?t.stateNode:null})}catch(e){setTimeout(function(){throw e})}}function Zs(e,t,n){return n=Ba(n),n.tag=3,n.payload={element:null},n.callback=function(){Ys(e,t)},n}function Qs(e){return e=Ba(e),e.tag=3,e}function $s(e,t,n,r){var i=n.type.getDerivedStateFromError;if(typeof i==`function`){var a=r.value;e.payload=function(){return i(a)},e.callback=function(){Xs(t,n,r)}}var o=n.stateNode;o!==null&&typeof o.componentDidCatch==`function`&&(e.callback=function(){Xs(t,n,r),typeof i!=`function`&&(su===null?su=new Set([this]):su.add(this));var e=r.stack;this.componentDidCatch(r.value,{componentStack:e===null?``:e})})}function ec(e,t,n,r,a){if(n.flags|=32768,typeof r==`object`&&r&&typeof r.then==`function`){if(t=n.alternate,t!==null&&Yi(t,n,a,!0),n=eo.current,n!==null){switch(n.tag){case 31:case 13:return to===null?ju():n.alternate===null&&W===0&&(W=3),n.flags&=-257,n.flags|=65536,n.lanes=a,r===Sa?n.flags|=16384:(t=n.updateQueue,t===null?n.updateQueue=new Set([r]):t.add(r),Xu(e,r,a)),!1;case 22:return n.flags|=65536,r===Sa?n.flags|=16384:(t=n.updateQueue,t===null?(t={transitions:null,markerInstances:null,retryQueue:new Set([r])},n.updateQueue=t):(n=t.retryQueue,n===null?t.retryQueue=new Set([r]):n.add(r)),Xu(e,r,a)),!1}throw Error(i(435,n.tag))}return Xu(e,r,a),ju(),!1}if(ji)return t=eo.current,t===null?(r!==Pi&&(t=Error(i(423),{cause:r}),Vi(mi(t,n))),e=e.current.alternate,e.flags|=65536,a&=-a,e.lanes|=a,r=mi(r,n),a=Zs(e.stateNode,r,a),Ua(e,a),W!==4&&(W=2)):(!(t.flags&65536)&&(t.flags|=256),t.flags|=65536,t.lanes=a,r!==Pi&&(e=Error(i(422),{cause:r}),Vi(mi(e,n)))),!1;var o=Error(i(520),{cause:r});if(o=mi(o,n),eu===null?eu=[o]:eu.push(o),W!==4&&(W=2),t===null)return!0;r=mi(r,n),n=t;do{switch(n.tag){case 3:return n.flags|=65536,e=a&-a,n.lanes|=e,e=Zs(n.stateNode,r,e),Ua(n,e),!1;case 1:if(t=n.type,o=n.stateNode,!(n.flags&128)&&(typeof t.getDerivedStateFromError==`function`||o!==null&&typeof o.componentDidCatch==`function`&&(su===null||!su.has(o))))return n.flags|=65536,a&=-a,n.lanes|=a,a=Qs(a),$s(a,e,n,r),Ua(n,a),!1}n=n.return}while(n!==null);return!1}var tc=Error(i(461)),nc=!1;function rc(e,t,n,r){t.child=e===null?Ia(t,null,n,r):Fa(t,e.child,n,r)}function ic(e,t,n,r,i){n=n.render;var a=t.ref;if(`ref`in r){var o={};for(var s in r)s!==`ref`&&(o[s]=r[s])}else o=r;return Zi(t),r=So(e,t,n,o,a,i),s=Eo(),e!==null&&!nc?(Do(e,t,i),Oc(e,t,i)):(ji&&s&&Ei(t),t.flags|=1,rc(e,t,r,i),t.child)}function ac(e,t,n,r,i){if(e===null){var a=n.type;return typeof a==`function`&&!ai(a)&&a.defaultProps===void 0&&n.compare===null?(t.tag=15,t.type=a,oc(e,t,a,r,i)):(e=ci(n.type,null,r,t,t.mode,i),e.ref=t.ref,e.return=t,t.child=e)}if(a=e.child,!kc(e,i)){var o=a.memoizedProps;if(n=n.compare,n=n===null?yr:n,n(o,r)&&e.ref===t.ref)return Oc(e,t,i)}return t.flags|=1,e=oi(a,r),e.ref=t.ref,e.return=t,t.child=e}function oc(e,t,n,r,i){if(e!==null){var a=e.memoizedProps;if(yr(a,r)&&e.ref===t.ref)if(nc=!1,t.pendingProps=r=a,kc(e,i))e.flags&131072&&(nc=!0);else return t.lanes=e.lanes,Oc(e,t,i)}return mc(e,t,n,r,i)}function sc(e,t,n,r){var i=r.children,a=e===null?null:e.memoizedState;if(e===null&&t.stateNode===null&&(t.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),r.mode===`hidden`){if(t.flags&128){if(a=a===null?n:a.baseLanes|n,e!==null){for(r=t.child=e.child,i=0;r!==null;)i=i|r.lanes|r.childLanes,r=r.sibling;r=i&~a}else r=0,t.child=null;return lc(e,t,a,n,r)}if(n&536870912)t.memoizedState={baseLanes:0,cachePool:null},e!==null&&_a(t,a===null?null:a.cachePool),a===null?Qa():Za(t,a),io(t);else return r=t.lanes=536870912,lc(e,t,a===null?n:a.baseLanes|n,n,r)}else a===null?(e!==null&&_a(t,null),Qa(),ao(t)):(_a(t,a.cachePool),Za(t,a),ao(t),t.memoizedState=null);return rc(e,t,i,n),t.child}function cc(e,t){return e!==null&&e.tag===22||t.stateNode!==null||(t.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),t.sibling}function lc(e,t,n,r,i){var a=ga();return a=a===null?null:{parent:ia._currentValue,pool:a},t.memoizedState={baseLanes:n,cachePool:a},e!==null&&_a(t,null),Qa(),io(t),e!==null&&Yi(e,t,r,!0),t.childLanes=i,null}function uc(e,t){return t=Cc({mode:t.mode,children:t.children},e.mode),t.ref=e.ref,e.child=t,t.return=e,t}function dc(e,t,n){return Fa(t,e.child,null,n),e=uc(t,t.pendingProps),e.flags|=2,oo(t),t.memoizedState=null,e}function fc(e,t,n){var r=t.pendingProps,a=(t.flags&128)!=0;if(t.flags&=-129,e===null){if(ji){if(r.mode===`hidden`)return e=uc(t,r),t.lanes=536870912,cc(null,e);if(ro(t),(e=Ai)?(e=uf(e,Ni),e=e!==null&&e.data===`&`?e:null,e!==null&&(t.memoizedState={dehydrated:e,treeContext:xi===null?null:{id:Si,overflow:Ci},retryLane:536870912,hydrationErrors:null},n=di(e),n.return=t,t.child=n,ki=t,Ai=null)):e=null,e===null)throw Fi(t);return t.lanes=536870912,null}return uc(t,r)}var o=e.memoizedState;if(o!==null){var s=o.dehydrated;if(ro(t),a)if(t.flags&256)t.flags&=-257,t=dc(e,t,n);else if(t.memoizedState!==null)t.child=e.child,t.flags|=128,t=null;else throw Error(i(558));else if(nc||Yi(e,t,n,!1),a=(n&e.childLanes)!==0,nc||a){if(r=Vl,r!==null&&(s=B(r,n),s!==0&&s!==o.retryLane))throw o.retryLane=s,$r(e,s),yu(r,e,s),tc;ju(),t=dc(e,t,n)}else e=o.treeContext,Ai=mf(s.nextSibling),ki=t,ji=!0,Mi=null,Ni=!1,e!==null&&Oi(t,e),t=uc(t,r),t.flags|=4096;return t}return e=oi(e.child,{mode:r.mode,children:r.children}),e.ref=t.ref,t.child=e,e.return=t,e}function pc(e,t){var n=t.ref;if(n===null)e!==null&&e.ref!==null&&(t.flags|=4194816);else{if(typeof n!=`function`&&typeof n!=`object`)throw Error(i(284));(e===null||e.ref!==n)&&(t.flags|=4194816)}}function mc(e,t,n,r,i){return Zi(t),n=So(e,t,n,r,void 0,i),r=Eo(),e!==null&&!nc?(Do(e,t,i),Oc(e,t,i)):(ji&&r&&Ei(t),t.flags|=1,rc(e,t,n,i),t.child)}function hc(e,t,n,r,i,a){return Zi(t),t.updateQueue=null,n=wo(t,r,n,i),Co(e),r=Eo(),e!==null&&!nc?(Do(e,t,a),Oc(e,t,a)):(ji&&r&&Ei(t),t.flags|=1,rc(e,t,n,a),t.child)}function gc(e,t,n,r,i){if(Zi(t),t.stateNode===null){var a=ni,o=n.contextType;typeof o==`object`&&o&&(a=Qi(o)),a=new n(r,a),t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,a.updater=Us,t.stateNode=a,a._reactInternals=t,a=t.stateNode,a.props=r,a.state=t.memoizedState,a.refs={},Ra(t),o=n.contextType,a.context=typeof o==`object`&&o?Qi(o):ni,a.state=t.memoizedState,o=n.getDerivedStateFromProps,typeof o==`function`&&(Hs(t,n,o,r),a.state=t.memoizedState),typeof n.getDerivedStateFromProps==`function`||typeof a.getSnapshotBeforeUpdate==`function`||typeof a.UNSAFE_componentWillMount!=`function`&&typeof a.componentWillMount!=`function`||(o=a.state,typeof a.componentWillMount==`function`&&a.componentWillMount(),typeof a.UNSAFE_componentWillMount==`function`&&a.UNSAFE_componentWillMount(),o!==a.state&&Us.enqueueReplaceState(a,a.state,null),Ka(t,r,a,i),Ga(),a.state=t.memoizedState),typeof a.componentDidMount==`function`&&(t.flags|=4194308),r=!0}else if(e===null){a=t.stateNode;var s=t.memoizedProps,c=Ks(n,s);a.props=c;var l=a.context,u=n.contextType;o=ni,typeof u==`object`&&u&&(o=Qi(u));var d=n.getDerivedStateFromProps;u=typeof d==`function`||typeof a.getSnapshotBeforeUpdate==`function`,s=t.pendingProps!==s,u||typeof a.UNSAFE_componentWillReceiveProps!=`function`&&typeof a.componentWillReceiveProps!=`function`||(s||l!==o)&&Gs(t,a,r,o),La=!1;var f=t.memoizedState;a.state=f,Ka(t,r,a,i),Ga(),l=t.memoizedState,s||f!==l||La?(typeof d==`function`&&(Hs(t,n,d,r),l=t.memoizedState),(c=La||Ws(t,n,c,r,f,l,o))?(u||typeof a.UNSAFE_componentWillMount!=`function`&&typeof a.componentWillMount!=`function`||(typeof a.componentWillMount==`function`&&a.componentWillMount(),typeof a.UNSAFE_componentWillMount==`function`&&a.UNSAFE_componentWillMount()),typeof a.componentDidMount==`function`&&(t.flags|=4194308)):(typeof a.componentDidMount==`function`&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=l),a.props=r,a.state=l,a.context=o,r=c):(typeof a.componentDidMount==`function`&&(t.flags|=4194308),r=!1)}else{a=t.stateNode,za(e,t),o=t.memoizedProps,u=Ks(n,o),a.props=u,d=t.pendingProps,f=a.context,l=n.contextType,c=ni,typeof l==`object`&&l&&(c=Qi(l)),s=n.getDerivedStateFromProps,(l=typeof s==`function`||typeof a.getSnapshotBeforeUpdate==`function`)||typeof a.UNSAFE_componentWillReceiveProps!=`function`&&typeof a.componentWillReceiveProps!=`function`||(o!==d||f!==c)&&Gs(t,a,r,c),La=!1,f=t.memoizedState,a.state=f,Ka(t,r,a,i),Ga();var p=t.memoizedState;o!==d||f!==p||La||e!==null&&e.dependencies!==null&&Xi(e.dependencies)?(typeof s==`function`&&(Hs(t,n,s,r),p=t.memoizedState),(u=La||Ws(t,n,u,r,f,p,c)||e!==null&&e.dependencies!==null&&Xi(e.dependencies))?(l||typeof a.UNSAFE_componentWillUpdate!=`function`&&typeof a.componentWillUpdate!=`function`||(typeof a.componentWillUpdate==`function`&&a.componentWillUpdate(r,p,c),typeof a.UNSAFE_componentWillUpdate==`function`&&a.UNSAFE_componentWillUpdate(r,p,c)),typeof a.componentDidUpdate==`function`&&(t.flags|=4),typeof a.getSnapshotBeforeUpdate==`function`&&(t.flags|=1024)):(typeof a.componentDidUpdate!=`function`||o===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!=`function`||o===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=p),a.props=r,a.state=p,a.context=c,r=u):(typeof a.componentDidUpdate!=`function`||o===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!=`function`||o===e.memoizedProps&&f===e.memoizedState||(t.flags|=1024),r=!1)}return a=r,pc(e,t),r=(t.flags&128)!=0,a||r?(a=t.stateNode,n=r&&typeof n.getDerivedStateFromError!=`function`?null:a.render(),t.flags|=1,e!==null&&r?(t.child=Fa(t,e.child,null,i),t.child=Fa(t,null,n,i)):rc(e,t,n,i),t.memoizedState=a.state,e=t.child):e=Oc(e,t,i),e}function _c(e,t,n,r){return zi(),t.flags|=256,rc(e,t,n,r),t.child}var vc={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function yc(e){return{baseLanes:e,cachePool:va()}}function bc(e,t,n){return e=e===null?0:e.childLanes&~n,t&&(e|=Ql),e}function xc(e,t,n){var r=t.pendingProps,a=!1,o=(t.flags&128)!=0,s;if((s=o)||(s=e!==null&&e.memoizedState===null?!1:(so.current&2)!=0),s&&(a=!0,t.flags&=-129),s=(t.flags&32)!=0,t.flags&=-33,e===null){if(ji){if(a?no(t):ao(t),(e=Ai)?(e=uf(e,Ni),e=e!==null&&e.data!==`&`?e:null,e!==null&&(t.memoizedState={dehydrated:e,treeContext:xi===null?null:{id:Si,overflow:Ci},retryLane:536870912,hydrationErrors:null},n=di(e),n.return=t,t.child=n,ki=t,Ai=null)):e=null,e===null)throw Fi(t);return ff(e)?t.lanes=32:t.lanes=536870912,null}var c=r.children;return r=r.fallback,a?(ao(t),a=t.mode,c=Cc({mode:`hidden`,children:c},a),r=li(r,a,n,null),c.return=t,r.return=t,c.sibling=r,t.child=c,r=t.child,r.memoizedState=yc(n),r.childLanes=bc(e,s,n),t.memoizedState=vc,cc(null,r)):(no(t),Sc(t,c))}var l=e.memoizedState;if(l!==null&&(c=l.dehydrated,c!==null)){if(o)t.flags&256?(no(t),t.flags&=-257,t=wc(e,t,n)):t.memoizedState===null?(ao(t),c=r.fallback,a=t.mode,r=Cc({mode:`visible`,children:r.children},a),c=li(c,a,n,null),c.flags|=2,r.return=t,c.return=t,r.sibling=c,t.child=r,Fa(t,e.child,null,n),r=t.child,r.memoizedState=yc(n),r.childLanes=bc(e,s,n),t.memoizedState=vc,t=cc(null,r)):(ao(t),t.child=e.child,t.flags|=128,t=null);else if(no(t),ff(c)){if(s=c.nextSibling&&c.nextSibling.dataset,s)var u=s.dgst;s=u,r=Error(i(419)),r.stack=``,r.digest=s,Vi({value:r,source:null,stack:null}),t=wc(e,t,n)}else if(nc||Yi(e,t,n,!1),s=(n&e.childLanes)!==0,nc||s){if(s=Vl,s!==null&&(r=B(s,n),r!==0&&r!==l.retryLane))throw l.retryLane=r,$r(e,r),yu(s,e,r),tc;df(c)||ju(),t=wc(e,t,n)}else df(c)?(t.flags|=192,t.child=e.child,t=null):(e=l.treeContext,Ai=mf(c.nextSibling),ki=t,ji=!0,Mi=null,Ni=!1,e!==null&&Oi(t,e),t=Sc(t,r.children),t.flags|=4096);return t}return a?(ao(t),c=r.fallback,a=t.mode,l=e.child,u=l.sibling,r=oi(l,{mode:`hidden`,children:r.children}),r.subtreeFlags=l.subtreeFlags&65011712,u===null?(c=li(c,a,n,null),c.flags|=2):c=oi(u,c),c.return=t,r.return=t,r.sibling=c,t.child=r,cc(null,r),r=t.child,c=e.child.memoizedState,c===null?c=yc(n):(a=c.cachePool,a===null?a=va():(l=ia._currentValue,a=a.parent===l?a:{parent:l,pool:l}),c={baseLanes:c.baseLanes|n,cachePool:a}),r.memoizedState=c,r.childLanes=bc(e,s,n),t.memoizedState=vc,cc(e.child,r)):(no(t),n=e.child,e=n.sibling,n=oi(n,{mode:`visible`,children:r.children}),n.return=t,n.sibling=null,e!==null&&(s=t.deletions,s===null?(t.deletions=[e],t.flags|=16):s.push(e)),t.child=n,t.memoizedState=null,n)}function Sc(e,t){return t=Cc({mode:`visible`,children:t},e.mode),t.return=e,e.child=t}function Cc(e,t){return e=ii(22,e,null,t),e.lanes=0,e}function wc(e,t,n){return Fa(t,e.child,null,n),e=Sc(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function Tc(e,t,n){e.lanes|=t;var r=e.alternate;r!==null&&(r.lanes|=t),qi(e.return,t,n)}function Ec(e,t,n,r,i,a){var o=e.memoizedState;o===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:i,treeForkCount:a}:(o.isBackwards=t,o.rendering=null,o.renderingStartTime=0,o.last=r,o.tail=n,o.tailMode=i,o.treeForkCount=a)}function Dc(e,t,n){var r=t.pendingProps,i=r.revealOrder,a=r.tail;r=r.children;var o=so.current,s=(o&2)!=0;if(s?(o=o&1|2,t.flags|=128):o&=1,j(so,o),rc(e,t,r,n),r=ji?vi:0,!s&&e!==null&&e.flags&128)a:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Tc(e,n,t);else if(e.tag===19)Tc(e,n,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break a;for(;e.sibling===null;){if(e.return===null||e.return===t)break a;e=e.return}e.sibling.return=e.return,e=e.sibling}switch(i){case`forwards`:for(n=t.child,i=null;n!==null;)e=n.alternate,e!==null&&co(e)===null&&(i=n),n=n.sibling;n=i,n===null?(i=t.child,t.child=null):(i=n.sibling,n.sibling=null),Ec(t,!1,i,n,a,r);break;case`backwards`:case`unstable_legacy-backwards`:for(n=null,i=t.child,t.child=null;i!==null;){if(e=i.alternate,e!==null&&co(e)===null){t.child=i;break}e=i.sibling,i.sibling=n,n=i,i=e}Ec(t,!0,n,null,a,r);break;case`together`:Ec(t,!1,null,null,void 0,r);break;default:t.memoizedState=null}return t.child}function Oc(e,t,n){if(e!==null&&(t.dependencies=e.dependencies),Yl|=t.lanes,(n&t.childLanes)===0)if(e!==null){if(Yi(e,t,n,!1),(n&t.childLanes)===0)return null}else return null;if(e!==null&&t.child!==e.child)throw Error(i(153));if(t.child!==null){for(e=t.child,n=oi(e,e.pendingProps),t.child=n,n.return=t;e.sibling!==null;)e=e.sibling,n=n.sibling=oi(e,e.pendingProps),n.return=t;n.sibling=null}return t.child}function kc(e,t){return(e.lanes&t)===0?(e=e.dependencies,!!(e!==null&&Xi(e))):!0}function Ac(e,t,n){switch(t.tag){case 3:me(t,t.stateNode.containerInfo),Gi(t,ia,e.memoizedState.cache),zi();break;case 27:case 5:ge(t);break;case 4:me(t,t.stateNode.containerInfo);break;case 10:Gi(t,t.type,t.memoizedProps.value);break;case 31:if(t.memoizedState!==null)return t.flags|=128,ro(t),null;break;case 13:var r=t.memoizedState;if(r!==null)return r.dehydrated===null?(n&t.child.childLanes)===0?(no(t),e=Oc(e,t,n),e===null?null:e.sibling):xc(e,t,n):(no(t),t.flags|=128,null);no(t);break;case 19:var i=(e.flags&128)!=0;if(r=(n&t.childLanes)!==0,r||=(Yi(e,t,n,!1),(n&t.childLanes)!==0),i){if(r)return Dc(e,t,n);t.flags|=128}if(i=t.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),j(so,so.current),r)break;return null;case 22:return t.lanes=0,sc(e,t,n,t.pendingProps);case 24:Gi(t,ia,e.memoizedState.cache)}return Oc(e,t,n)}function jc(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps)nc=!0;else{if(!kc(e,n)&&!(t.flags&128))return nc=!1,Ac(e,t,n);nc=!!(e.flags&131072)}else nc=!1,ji&&t.flags&1048576&&Ti(t,vi,t.index);switch(t.lanes=0,t.tag){case 16:a:{var r=t.pendingProps;if(e=Ta(t.elementType),t.type=e,typeof e==`function`)ai(e)?(r=Ks(e,r),t.tag=1,t=gc(null,t,e,r,n)):(t.tag=0,t=mc(null,t,e,r,n));else{if(e!=null){var a=e.$$typeof;if(a===C){t.tag=11,t=ic(null,t,e,r,n);break a}else if(a===ne){t.tag=14,t=ac(null,t,e,r,n);break a}}throw t=se(e)||e,Error(i(306,t,``))}}return t;case 0:return mc(e,t,t.type,t.pendingProps,n);case 1:return r=t.type,a=Ks(r,t.pendingProps),gc(e,t,r,a,n);case 3:a:{if(me(t,t.stateNode.containerInfo),e===null)throw Error(i(387));r=t.pendingProps;var o=t.memoizedState;a=o.element,za(e,t),Ka(t,r,null,n);var s=t.memoizedState;if(r=s.cache,Gi(t,ia,r),r!==o.cache&&Ji(t,[ia],n,!0),Ga(),r=s.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:s.cache},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){t=_c(e,t,r,n);break a}else if(r!==a){a=mi(Error(i(424)),t),Vi(a),t=_c(e,t,r,n);break a}else{switch(e=t.stateNode.containerInfo,e.nodeType){case 9:e=e.body;break;default:e=e.nodeName===`HTML`?e.ownerDocument.body:e}for(Ai=mf(e.firstChild),ki=t,ji=!0,Mi=null,Ni=!0,n=Ia(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling}else{if(zi(),r===a){t=Oc(e,t,n);break a}rc(e,t,r,n)}t=t.child}return t;case 26:return pc(e,t),e===null?(n=Pf(t.type,null,t.pendingProps,null))?t.memoizedState=n:ji||(n=t.type,e=t.pendingProps,r=Kd(fe.current).createElement(n),r[rt]=t,r[it]=e,Bd(r,n,e),gt(r),t.stateNode=r):t.memoizedState=Pf(t.type,e.memoizedProps,t.pendingProps,e.memoizedState),null;case 27:return ge(t),e===null&&ji&&(r=t.stateNode=vf(t.type,t.pendingProps,fe.current),ki=t,Ni=!0,a=Ai,rf(t.type)?(hf=a,Ai=mf(r.firstChild)):Ai=a),rc(e,t,t.pendingProps.children,n),pc(e,t),e===null&&(t.flags|=4194304),t.child;case 5:return e===null&&ji&&((a=r=Ai)&&(r=cf(r,t.type,t.pendingProps,Ni),r===null?a=!1:(t.stateNode=r,ki=t,Ai=mf(r.firstChild),Ni=!1,a=!0)),a||Fi(t)),ge(t),a=t.type,o=t.pendingProps,s=e===null?null:e.memoizedProps,r=o.children,Yd(a,o)?r=null:s!==null&&Yd(a,s)&&(t.flags|=32),t.memoizedState!==null&&(a=So(e,t,To,null,null,n),rp._currentValue=a),pc(e,t),rc(e,t,r,n),t.child;case 6:return e===null&&ji&&((e=n=Ai)&&(n=lf(n,t.pendingProps,Ni),n===null?e=!1:(t.stateNode=n,ki=t,Ai=null,e=!0)),e||Fi(t)),null;case 13:return xc(e,t,n);case 4:return me(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Fa(t,null,r,n):rc(e,t,r,n),t.child;case 11:return ic(e,t,t.type,t.pendingProps,n);case 7:return rc(e,t,t.pendingProps,n),t.child;case 8:return rc(e,t,t.pendingProps.children,n),t.child;case 12:return rc(e,t,t.pendingProps.children,n),t.child;case 10:return r=t.pendingProps,Gi(t,t.type,r.value),rc(e,t,r.children,n),t.child;case 9:return a=t.type._context,r=t.pendingProps.children,Zi(t),a=Qi(a),r=r(a),t.flags|=1,rc(e,t,r,n),t.child;case 14:return ac(e,t,t.type,t.pendingProps,n);case 15:return oc(e,t,t.type,t.pendingProps,n);case 19:return Dc(e,t,n);case 31:return fc(e,t,n);case 22:return sc(e,t,n,t.pendingProps);case 24:return Zi(t),r=Qi(ia),e===null?(a=ga(),a===null&&(a=Vl,o=aa(),a.pooledCache=o,o.refCount++,o!==null&&(a.pooledCacheLanes|=n),a=o),t.memoizedState={parent:r,cache:a},Ra(t),Gi(t,ia,a)):((e.lanes&n)!==0&&(za(e,t),Ka(t,null,null,n),Ga()),a=e.memoizedState,o=t.memoizedState,a.parent===r?(r=o.cache,Gi(t,ia,r),r!==a.cache&&Ji(t,[ia],n,!0)):(a={parent:r,cache:r},t.memoizedState=a,t.lanes===0&&(t.memoizedState=t.updateQueue.baseState=a),Gi(t,ia,r))),rc(e,t,t.pendingProps.children,n),t.child;case 29:throw t.pendingProps}throw Error(i(156,t.tag))}function Mc(e){e.flags|=4}function Nc(e,t,n,r,i){if((t=(e.mode&32)!=0)&&(t=!1),t){if(e.flags|=16777216,(i&335544128)===i)if(e.stateNode.complete)e.flags|=8192;else if(Ou())e.flags|=8192;else throw Ea=Sa,ba}else e.flags&=-16777217}function Pc(e,t){if(t.type!==`stylesheet`||t.state.loading&4)e.flags&=-16777217;else if(e.flags|=16777216,!Yf(t))if(Ou())e.flags|=8192;else throw Ea=Sa,ba}function Fc(e,t){t!==null&&(e.flags|=4),e.flags&16384&&(t=e.tag===22?536870912:Je(),e.lanes|=t,$l|=t)}function Ic(e,t){if(!ji)switch(e.tailMode){case`hidden`:t=e.tail;for(var n=null;t!==null;)t.alternate!==null&&(n=t),t=t.sibling;n===null?e.tail=null:n.sibling=null;break;case`collapsed`:n=e.tail;for(var r=null;n!==null;)n.alternate!==null&&(r=n),n=n.sibling;r===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Lc(e){var t=e.alternate!==null&&e.alternate.child===e.child,n=0,r=0;if(t)for(var i=e.child;i!==null;)n|=i.lanes|i.childLanes,r|=i.subtreeFlags&65011712,r|=i.flags&65011712,i.return=e,i=i.sibling;else for(i=e.child;i!==null;)n|=i.lanes|i.childLanes,r|=i.subtreeFlags,r|=i.flags,i.return=e,i=i.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function Rc(e,t,n){var r=t.pendingProps;switch(Di(t),t.tag){case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Lc(t),null;case 1:return Lc(t),null;case 3:return n=t.stateNode,r=null,e!==null&&(r=e.memoizedState.cache),t.memoizedState.cache!==r&&(t.flags|=2048),Ki(ia),he(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(e===null||e.child===null)&&(Ri(t)?Mc(t):e===null||e.memoizedState.isDehydrated&&!(t.flags&256)||(t.flags|=1024,Bi())),Lc(t),null;case 26:var a=t.type,o=t.memoizedState;return e===null?(Mc(t),o===null?(Lc(t),Nc(t,a,null,r,n)):(Lc(t),Pc(t,o))):o?o===e.memoizedState?(Lc(t),t.flags&=-16777217):(Mc(t),Lc(t),Pc(t,o)):(e=e.memoizedProps,e!==r&&Mc(t),Lc(t),Nc(t,a,e,r,n)),null;case 27:if(P(t),n=fe.current,a=t.type,e!==null&&t.stateNode!=null)e.memoizedProps!==r&&Mc(t);else{if(!r){if(t.stateNode===null)throw Error(i(166));return Lc(t),null}e=M.current,Ri(t)?Ii(t,e):(e=vf(a,r,n),t.stateNode=e,Mc(t))}return Lc(t),null;case 5:if(P(t),a=t.type,e!==null&&t.stateNode!=null)e.memoizedProps!==r&&Mc(t);else{if(!r){if(t.stateNode===null)throw Error(i(166));return Lc(t),null}if(o=M.current,Ri(t))Ii(t,o);else{var s=Kd(fe.current);switch(o){case 1:o=s.createElementNS(`http://www.w3.org/2000/svg`,a);break;case 2:o=s.createElementNS(`http://www.w3.org/1998/Math/MathML`,a);break;default:switch(a){case`svg`:o=s.createElementNS(`http://www.w3.org/2000/svg`,a);break;case`math`:o=s.createElementNS(`http://www.w3.org/1998/Math/MathML`,a);break;case`script`:o=s.createElement(`div`),o.innerHTML=`<script><\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[rt]=t,o[it]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Bd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Mc(t)}}return Lc(t),Nc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Mc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=fe.current,Ri(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=ki,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[rt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Ld(e.nodeValue,n)),e||Fi(t,!0)}else e=Kd(e).createTextNode(r),e[rt]=t,t.stateNode=e}return Lc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Ri(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[rt]=t}else zi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Lc(t),e=!1}else n=Bi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(oo(t),t):(oo(t),null);if(t.flags&128)throw Error(i(558))}return Lc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Ri(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[rt]=t}else zi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Lc(t),a=!1}else a=Bi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(oo(t),t):(oo(t),null)}return oo(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Fc(t,t.updateQueue),Lc(t),null);case 4:return he(),e===null&&Dd(t.stateNode.containerInfo),Lc(t),null;case 10:return Ki(t.type),Lc(t),null;case 19:if(A(so),r=t.memoizedState,r===null)return Lc(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Ic(r,!1);else{if(W!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=co(e),o!==null){for(t.flags|=128,Ic(r,!1),e=o.updateQueue,t.updateQueue=e,Fc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)si(n,e),n=n.sibling;return j(so,so.current&1|2),ji&&wi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Oe()>au&&(t.flags|=128,a=!0,Ic(r,!1),t.lanes=4194304)}else{if(!a)if(e=co(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Fc(t,e),Ic(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!ji)return Lc(t),null}else 2*Oe()-r.renderingStartTime>au&&n!==536870912&&(t.flags|=128,a=!0,Ic(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Lc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Oe(),e.sibling=null,n=so.current,j(so,a?n&1|2:n&1),ji&&wi(t,r.treeForkCount),e);case 22:case 23:return oo(t),$a(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Lc(t),t.subtreeFlags&6&&(t.flags|=8192)):Lc(t),n=t.updateQueue,n!==null&&Fc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&A(ha),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Ki(ia),Lc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function zc(e,t){switch(Di(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ki(ia),he(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return P(t),null;case 31:if(t.memoizedState!==null){if(oo(t),t.alternate===null)throw Error(i(340));zi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(oo(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));zi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return A(so),null;case 4:return he(),null;case 10:return Ki(t.type),null;case 22:case 23:return oo(t),$a(),e!==null&&A(ha),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Ki(ia),null;case 25:return null;default:return null}}function Bc(e,t){switch(Di(t),t.tag){case 3:Ki(ia),he();break;case 26:case 27:case 5:P(t);break;case 4:he();break;case 31:t.memoizedState!==null&&oo(t);break;case 13:oo(t);break;case 19:A(so);break;case 10:Ki(t.type);break;case 22:case 23:oo(t),$a(),e!==null&&A(ha);break;case 24:Ki(ia)}}function Vc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Yu(t,t.return,e)}}function Hc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Yu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Yu(t,t.return,e)}}function Uc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ja(t,n)}catch(t){Yu(e,e.return,t)}}}function Wc(e,t,n){n.props=Ks(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Yu(e,t,n)}}function Gc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Yu(e,t,n)}}function Kc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Yu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Yu(e,t,n)}else n.current=null}function qc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Yu(e,e.return,t)}}function Jc(e,t,n){try{var r=e.stateNode;Vd(r,e.type,n,t),r[it]=t}catch(t){Yu(e,e.return,t)}}function Yc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&rf(e.type)||e.tag===4}function Xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Yc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&rf(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Xt));else if(r!==4&&(r===27&&rf(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&rf(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Bd(t,r,n),t[rt]=e,t[it]=n}catch(t){Yu(e,e.return,t)}}var el=!1,tl=!1,nl=!1,rl=typeof WeakSet==`function`?WeakSet:Set,il=null;function al(e,t){if(e=e.containerInfo,Wd=fp,e=Cr(e),wr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(Gd={focusedElem:e,selectionRange:n},fp=!1,il=t;il!==null;)if(t=il,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,il=e;else for(;il!==null;){switch(t=il,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n<e.length;n++)a=e[n],a.ref.impl=a.nextImpl;break;case 11:case 15:break;case 1:if(e&1024&&o!==null){e=void 0,n=t,a=o.memoizedProps,o=o.memoizedState,r=n.stateNode;try{var h=Ks(n.type,a);e=r.getSnapshotBeforeUpdate(h,o),r.__reactInternalSnapshotBeforeUpdate=e}catch(e){Yu(n,n.return,e)}}break;case 3:if(e&1024){if(e=t.stateNode.containerInfo,n=e.nodeType,n===9)sf(e);else if(n===1)switch(e.nodeName){case`HEAD`:case`HTML`:case`BODY`:sf(e);break;default:e.textContent=``}}break;case 5:case 26:case 27:case 6:case 4:case 17:break;default:if(e&1024)throw Error(i(163))}if(e=t.sibling,e!==null){e.return=t.return,il=e;break}il=t.return}}function ol(e,t,n){var r=n.flags;switch(n.tag){case 0:case 11:case 15:xl(e,n),r&4&&Vc(5,n);break;case 1:if(xl(e,n),r&4)if(e=n.stateNode,t===null)try{e.componentDidMount()}catch(e){Yu(n,n.return,e)}else{var i=Ks(n.type,t.memoizedProps);t=t.memoizedState;try{e.componentDidUpdate(i,t,e.__reactInternalSnapshotBeforeUpdate)}catch(e){Yu(n,n.return,e)}}r&64&&Uc(n),r&512&&Gc(n,n.return);break;case 3:if(xl(e,n),r&64&&(e=n.updateQueue,e!==null)){if(t=null,n.child!==null)switch(n.child.tag){case 27:case 5:t=n.child.stateNode;break;case 1:t=n.child.stateNode}try{Ja(e,t)}catch(e){Yu(n,n.return,e)}}break;case 27:t===null&&r&4&&$c(n);case 26:case 5:xl(e,n),t===null&&r&4&&qc(n),r&512&&Gc(n,n.return);break;case 12:xl(e,n);break;case 31:xl(e,n),r&4&&fl(e,n);break;case 13:xl(e,n),r&4&&pl(e,n),r&64&&(e=n.memoizedState,e!==null&&(e=e.dehydrated,e!==null&&(n=$u.bind(null,n),pf(e,n))));break;case 22:if(r=n.memoizedState!==null||el,!r){t=t!==null&&t.memoizedState!==null||tl,i=el;var a=tl;el=r,(tl=t)&&!a?Cl(e,n,(n.subtreeFlags&8772)!=0):xl(e,n),el=i,tl=a}break;case 30:break;default:xl(e,n)}}function sl(e){var t=e.alternate;t!==null&&(e.alternate=null,sl(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&dt(t)),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}var cl=null,ll=!1;function ul(e,t,n){for(n=n.child;n!==null;)dl(e,t,n),n=n.sibling}function dl(e,t,n){if(Re&&typeof Re.onCommitFiberUnmount==`function`)try{Re.onCommitFiberUnmount(Le,n)}catch{}switch(n.tag){case 26:tl||Kc(n,t),ul(e,t,n),n.memoizedState?n.memoizedState.count--:n.stateNode&&(n=n.stateNode,n.parentNode.removeChild(n));break;case 27:tl||Kc(n,t);var r=cl,i=ll;rf(n.type)&&(cl=n.stateNode,ll=!1),ul(e,t,n),yf(n.stateNode),cl=r,ll=i;break;case 5:tl||Kc(n,t);case 6:if(r=cl,i=ll,cl=null,ul(e,t,n),cl=r,ll=i,cl!==null)if(ll)try{(cl.nodeType===9?cl.body:cl.nodeName===`HTML`?cl.ownerDocument.body:cl).removeChild(n.stateNode)}catch(e){Yu(n,t,e)}else try{cl.removeChild(n.stateNode)}catch(e){Yu(n,t,e)}break;case 18:cl!==null&&(ll?(e=cl,af(e.nodeType===9?e.body:e.nodeName===`HTML`?e.ownerDocument.body:e,n.stateNode),Rp(e)):af(cl,n.stateNode));break;case 4:r=cl,i=ll,cl=n.stateNode.containerInfo,ll=!0,ul(e,t,n),cl=r,ll=i;break;case 0:case 11:case 14:case 15:Hc(2,n,t),tl||Hc(4,n,t),ul(e,t,n);break;case 1:tl||(Kc(n,t),r=n.stateNode,typeof r.componentWillUnmount==`function`&&Wc(n,t,r)),ul(e,t,n);break;case 21:ul(e,t,n);break;case 22:tl=(r=tl)||n.memoizedState!==null,ul(e,t,n),tl=r;break;default:ul(e,t,n)}}function fl(e,t){if(t.memoizedState===null&&(e=t.alternate,e!==null&&(e=e.memoizedState,e!==null))){e=e.dehydrated;try{Rp(e)}catch(e){Yu(t,t.return,e)}}}function pl(e,t){if(t.memoizedState===null&&(e=t.alternate,e!==null&&(e=e.memoizedState,e!==null&&(e=e.dehydrated,e!==null))))try{Rp(e)}catch(e){Yu(t,t.return,e)}}function ml(e){switch(e.tag){case 31:case 13:case 19:var t=e.stateNode;return t===null&&(t=e.stateNode=new rl),t;case 22:return e=e.stateNode,t=e._retryCache,t===null&&(t=e._retryCache=new rl),t;default:throw Error(i(435,e.tag))}}function hl(e,t){var n=ml(e);t.forEach(function(t){if(!n.has(t)){n.add(t);var r=ed.bind(null,e,t);t.then(r,r)}})}function gl(e,t){var n=t.deletions;if(n!==null)for(var r=0;r<n.length;r++){var a=n[r],o=e,s=t,c=s;a:for(;c!==null;){switch(c.tag){case 27:if(rf(c.type)){cl=c.stateNode,ll=!1;break a}break;case 5:cl=c.stateNode,ll=!1;break a;case 3:case 4:cl=c.stateNode.containerInfo,ll=!0;break a}c=c.return}if(cl===null)throw Error(i(160));dl(o,s,a),cl=null,ll=!1,o=a.alternate,o!==null&&(o.return=null),a.return=null}if(t.subtreeFlags&13886)for(t=t.child;t!==null;)vl(t,e),t=t.sibling}var _l=null;function vl(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:gl(t,e),yl(e),r&4&&(Hc(3,e,e.return),Vc(3,e),Hc(5,e,e.return));break;case 1:gl(t,e),yl(e),r&512&&(tl||n===null||Kc(n,n.return)),r&64&&el&&(e=e.updateQueue,e!==null&&(r=e.callbacks,r!==null&&(n=e.shared.hiddenCallbacks,e.shared.hiddenCallbacks=n===null?r:n.concat(r))));break;case 26:var a=_l;if(gl(t,e),yl(e),r&512&&(tl||n===null||Kc(n,n.return)),r&4){var o=n===null?null:n.memoizedState;if(r=e.memoizedState,n===null)if(r===null)if(e.stateNode===null){a:{r=e.type,n=e.memoizedProps,a=a.ownerDocument||a;b:switch(r){case`title`:o=a.getElementsByTagName(`title`)[0],(!o||o[ut]||o[rt]||o.namespaceURI===`http://www.w3.org/2000/svg`||o.hasAttribute(`itemprop`))&&(o=a.createElement(r),a.head.insertBefore(o,a.querySelector(`head > title`))),Bd(o,r,n),o[rt]=e,gt(o),r=o;break a;case`link`:var s=Kf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;c<s.length;c++)if(o=s[c],o.getAttribute(`href`)===(n.href==null||n.href===``?null:n.href)&&o.getAttribute(`rel`)===(n.rel==null?null:n.rel)&&o.getAttribute(`title`)===(n.title==null?null:n.title)&&o.getAttribute(`crossorigin`)===(n.crossOrigin==null?null:n.crossOrigin)){s.splice(c,1);break b}}o=a.createElement(r),Bd(o,r,n),a.head.appendChild(o);break;case`meta`:if(s=Kf(`meta`,`content`,a).get(r+(n.content||``))){for(c=0;c<s.length;c++)if(o=s[c],o.getAttribute(`content`)===(n.content==null?null:``+n.content)&&o.getAttribute(`name`)===(n.name==null?null:n.name)&&o.getAttribute(`property`)===(n.property==null?null:n.property)&&o.getAttribute(`http-equiv`)===(n.httpEquiv==null?null:n.httpEquiv)&&o.getAttribute(`charset`)===(n.charSet==null?null:n.charSet)){s.splice(c,1);break b}}o=a.createElement(r),Bd(o,r,n),a.head.appendChild(o);break;default:throw Error(i(468,r))}o[rt]=e,gt(o),r=o}e.stateNode=r}else qf(a,e.type,e.stateNode);else e.stateNode=Vf(a,r,e.memoizedProps);else o===r?r===null&&e.stateNode!==null&&Jc(e,e.memoizedProps,n.memoizedProps):(o===null?n.stateNode!==null&&(n=n.stateNode,n.parentNode.removeChild(n)):o.count--,r===null?qf(a,e.type,e.stateNode):Vf(a,r,e.memoizedProps))}break;case 27:gl(t,e),yl(e),r&512&&(tl||n===null||Kc(n,n.return)),n!==null&&r&4&&Jc(e,e.memoizedProps,n.memoizedProps);break;case 5:if(gl(t,e),yl(e),r&512&&(tl||n===null||Kc(n,n.return)),e.flags&32){a=e.stateNode;try{Ht(a,``)}catch(t){Yu(e,e.return,t)}}r&4&&e.stateNode!=null&&(a=e.memoizedProps,Jc(e,a,n===null?a:n.memoizedProps)),r&1024&&(nl=!0);break;case 6:if(gl(t,e),yl(e),r&4){if(e.stateNode===null)throw Error(i(162));r=e.memoizedProps,n=e.stateNode;try{n.nodeValue=r}catch(t){Yu(e,e.return,t)}}break;case 3:if(Gf=null,a=_l,_l=Sf(t.containerInfo),gl(t,e),_l=a,yl(e),r&4&&n!==null&&n.memoizedState.isDehydrated)try{Rp(t.containerInfo)}catch(t){Yu(e,e.return,t)}nl&&(nl=!1,bl(e));break;case 4:r=_l,_l=Sf(e.stateNode.containerInfo),gl(t,e),yl(e),_l=r;break;case 12:gl(t,e),yl(e);break;case 31:gl(t,e),yl(e),r&4&&(r=e.updateQueue,r!==null&&(e.updateQueue=null,hl(e,r)));break;case 13:gl(t,e),yl(e),e.child.flags&8192&&e.memoizedState!==null!=(n!==null&&n.memoizedState!==null)&&(ru=Oe()),r&4&&(r=e.updateQueue,r!==null&&(e.updateQueue=null,hl(e,r)));break;case 22:a=e.memoizedState!==null;var l=n!==null&&n.memoizedState!==null,u=el,d=tl;if(el=u||a,tl=d||l,gl(t,e),tl=d,el=u,yl(e),r&8192)a:for(t=e.stateNode,t._visibility=a?t._visibility&-2:t._visibility|1,a&&(n===null||l||el||tl||Sl(e)),n=null,t=e;;){if(t.tag===5||t.tag===26){if(n===null){l=n=t;try{if(o=l.stateNode,a)s=o.style,typeof s.setProperty==`function`?s.setProperty(`display`,`none`,`important`):s.display=`none`;else{c=l.stateNode;var f=l.memoizedProps.style,p=f!=null&&f.hasOwnProperty(`display`)?f.display:null;c.style.display=p==null||typeof p==`boolean`?``:(``+p).trim()}}catch(e){Yu(l,l.return,e)}}}else if(t.tag===6){if(n===null){l=t;try{l.stateNode.nodeValue=a?``:l.memoizedProps}catch(e){Yu(l,l.return,e)}}}else if(t.tag===18){if(n===null){l=t;try{var m=l.stateNode;a?of(m,!0):of(l.stateNode,!1)}catch(e){Yu(l,l.return,e)}}}else if((t.tag!==22&&t.tag!==23||t.memoizedState===null||t===e)&&t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break a;for(;t.sibling===null;){if(t.return===null||t.return===e)break a;n===t&&(n=null),t=t.return}n===t&&(n=null),t.sibling.return=t.return,t=t.sibling}r&4&&(r=e.updateQueue,r!==null&&(n=r.retryQueue,n!==null&&(r.retryQueue=null,hl(e,n))));break;case 19:gl(t,e),yl(e),r&4&&(r=e.updateQueue,r!==null&&(e.updateQueue=null,hl(e,r)));break;case 30:break;case 21:break;default:gl(t,e),yl(e)}}function yl(e){var t=e.flags;if(t&2){try{for(var n,r=e.return;r!==null;){if(Yc(r)){n=r;break}r=r.return}if(n==null)throw Error(i(160));switch(n.tag){case 27:var a=n.stateNode;Qc(e,Xc(e),a);break;case 5:var o=n.stateNode;n.flags&32&&(Ht(o,``),n.flags&=-33),Qc(e,Xc(e),o);break;case 3:case 4:var s=n.stateNode.containerInfo;Zc(e,Xc(e),s);break;default:throw Error(i(161))}}catch(t){Yu(e,e.return,t)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function bl(e){if(e.subtreeFlags&1024)for(e=e.child;e!==null;){var t=e;bl(t),t.tag===5&&t.flags&1024&&t.stateNode.reset(),e=e.sibling}}function xl(e,t){if(t.subtreeFlags&8772)for(t=t.child;t!==null;)ol(e,t.alternate,t),t=t.sibling}function Sl(e){for(e=e.child;e!==null;){var t=e;switch(t.tag){case 0:case 11:case 14:case 15:Hc(4,t,t.return),Sl(t);break;case 1:Kc(t,t.return);var n=t.stateNode;typeof n.componentWillUnmount==`function`&&Wc(t,t.return,n),Sl(t);break;case 27:yf(t.stateNode);case 26:case 5:Kc(t,t.return),Sl(t);break;case 22:t.memoizedState===null&&Sl(t);break;case 30:Sl(t);break;default:Sl(t)}e=e.sibling}}function Cl(e,t,n){for(n&&=(t.subtreeFlags&8772)!=0,t=t.child;t!==null;){var r=t.alternate,i=e,a=t,o=a.flags;switch(a.tag){case 0:case 11:case 15:Cl(i,a,n),Vc(4,a);break;case 1:if(Cl(i,a,n),r=a,i=r.stateNode,typeof i.componentDidMount==`function`)try{i.componentDidMount()}catch(e){Yu(r,r.return,e)}if(r=a,i=r.updateQueue,i!==null){var s=r.stateNode;try{var c=i.shared.hiddenCallbacks;if(c!==null)for(i.shared.hiddenCallbacks=null,i=0;i<c.length;i++)qa(c[i],s)}catch(e){Yu(r,r.return,e)}}n&&o&64&&Uc(a),Gc(a,a.return);break;case 27:$c(a);case 26:case 5:Cl(i,a,n),n&&r===null&&o&4&&qc(a),Gc(a,a.return);break;case 12:Cl(i,a,n);break;case 31:Cl(i,a,n),n&&o&4&&fl(i,a);break;case 13:Cl(i,a,n),n&&o&4&&pl(i,a);break;case 22:a.memoizedState===null&&Cl(i,a,n),Gc(a,a.return);break;case 30:break;default:Cl(i,a,n)}t=t.sibling}}function wl(e,t){var n=null;e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),e=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(e=t.memoizedState.cachePool.pool),e!==n&&(e!=null&&e.refCount++,n!=null&&oa(n))}function Tl(e,t){e=null,t.alternate!==null&&(e=t.alternate.memoizedState.cache),t=t.memoizedState.cache,t!==e&&(t.refCount++,e!=null&&oa(e))}function El(e,t,n,r){if(t.subtreeFlags&10256)for(t=t.child;t!==null;)Dl(e,t,n,r),t=t.sibling}function Dl(e,t,n,r){var i=t.flags;switch(t.tag){case 0:case 11:case 15:El(e,t,n,r),i&2048&&Vc(9,t);break;case 1:El(e,t,n,r);break;case 3:El(e,t,n,r),i&2048&&(e=null,t.alternate!==null&&(e=t.alternate.memoizedState.cache),t=t.memoizedState.cache,t!==e&&(t.refCount++,e!=null&&oa(e)));break;case 12:if(i&2048){El(e,t,n,r),e=t.stateNode;try{var a=t.memoizedProps,o=a.id,s=a.onPostCommit;typeof s==`function`&&s(o,t.alternate===null?`mount`:`update`,e.passiveEffectDuration,-0)}catch(e){Yu(t,t.return,e)}}else El(e,t,n,r);break;case 31:El(e,t,n,r);break;case 13:El(e,t,n,r);break;case 23:break;case 22:a=t.stateNode,o=t.alternate,t.memoizedState===null?a._visibility&2?El(e,t,n,r):(a._visibility|=2,Ol(e,t,n,r,(t.subtreeFlags&10256)!=0||!1)):a._visibility&2?El(e,t,n,r):kl(e,t),i&2048&&wl(o,t);break;case 24:El(e,t,n,r),i&2048&&Tl(t.alternate,t);break;default:El(e,t,n,r)}}function Ol(e,t,n,r,i){for(i&&=(t.subtreeFlags&10256)!=0||!1,t=t.child;t!==null;){var a=e,o=t,s=n,c=r,l=o.flags;switch(o.tag){case 0:case 11:case 15:Ol(a,o,s,c,i),Vc(8,o);break;case 23:break;case 22:var u=o.stateNode;o.memoizedState===null?(u._visibility|=2,Ol(a,o,s,c,i)):u._visibility&2?Ol(a,o,s,c,i):kl(a,o),i&&l&2048&&wl(o.alternate,o);break;case 24:Ol(a,o,s,c,i),i&&l&2048&&Tl(o.alternate,o);break;default:Ol(a,o,s,c,i)}t=t.sibling}}function kl(e,t){if(t.subtreeFlags&10256)for(t=t.child;t!==null;){var n=e,r=t,i=r.flags;switch(r.tag){case 22:kl(n,r),i&2048&&wl(r.alternate,r);break;case 24:kl(n,r),i&2048&&Tl(r.alternate,r);break;default:kl(n,r)}t=t.sibling}}var Al=8192;function jl(e,t,n){if(e.subtreeFlags&Al)for(e=e.child;e!==null;)Ml(e,t,n),e=e.sibling}function Ml(e,t,n){switch(e.tag){case 26:jl(e,t,n),e.flags&Al&&e.memoizedState!==null&&Xf(n,_l,e.memoizedState,e.memoizedProps);break;case 5:jl(e,t,n);break;case 3:case 4:var r=_l;_l=Sf(e.stateNode.containerInfo),jl(e,t,n),_l=r;break;case 22:e.memoizedState===null&&(r=e.alternate,r!==null&&r.memoizedState!==null?(r=Al,Al=16777216,jl(e,t,n),Al=r):jl(e,t,n));break;default:jl(e,t,n)}}function Nl(e){var t=e.alternate;if(t!==null&&(e=t.child,e!==null)){t.child=null;do t=e.sibling,e.sibling=null,e=t;while(e!==null)}}function Pl(e){var t=e.deletions;if(e.flags&16){if(t!==null)for(var n=0;n<t.length;n++){var r=t[n];il=r,Ll(r,e)}Nl(e)}if(e.subtreeFlags&10256)for(e=e.child;e!==null;)Fl(e),e=e.sibling}function Fl(e){switch(e.tag){case 0:case 11:case 15:Pl(e),e.flags&2048&&Hc(9,e,e.return);break;case 3:Pl(e);break;case 12:Pl(e);break;case 22:var t=e.stateNode;e.memoizedState!==null&&t._visibility&2&&(e.return===null||e.return.tag!==13)?(t._visibility&=-3,Il(e)):Pl(e);break;default:Pl(e)}}function Il(e){var t=e.deletions;if(e.flags&16){if(t!==null)for(var n=0;n<t.length;n++){var r=t[n];il=r,Ll(r,e)}Nl(e)}for(e=e.child;e!==null;){switch(t=e,t.tag){case 0:case 11:case 15:Hc(8,t,t.return),Il(t);break;case 22:n=t.stateNode,n._visibility&2&&(n._visibility&=-3,Il(t));break;default:Il(t)}e=e.sibling}}function Ll(e,t){for(;il!==null;){var n=il;switch(n.tag){case 0:case 11:case 15:Hc(8,n,t);break;case 23:case 22:if(n.memoizedState!==null&&n.memoizedState.cachePool!==null){var r=n.memoizedState.cachePool.pool;r!=null&&r.refCount++}break;case 24:oa(n.memoizedState.cache)}if(r=n.child,r!==null)r.return=n,il=r;else a:for(n=e;il!==null;){r=il;var i=r.sibling,a=r.return;if(sl(r),r===n){il=null;break a}if(i!==null){i.return=a,il=i;break a}il=a}}}var Rl={getCacheForType:function(e){var t=Qi(ia),n=t.data.get(e);return n===void 0&&(n=e(),t.data.set(e,n)),n},cacheSignal:function(){return Qi(ia).controller.signal}},zl=typeof WeakMap==`function`?WeakMap:Map,Bl=0,Vl=null,U=null,Hl=0,Ul=0,Wl=null,Gl=!1,Kl=!1,ql=!1,Jl=0,W=0,Yl=0,Xl=0,Zl=0,Ql=0,$l=0,eu=null,tu=null,nu=!1,ru=0,iu=0,au=1/0,ou=null,su=null,cu=0,lu=null,uu=null,du=0,fu=0,pu=null,mu=null,hu=0,gu=null;function _u(){return Bl&2&&Hl!==0?Hl&-Hl:D.T===null?et():gd()}function vu(){if(Ql===0)if(!(Hl&536870912)||ji){var e=Ge;Ge<<=1,!(Ge&3932160)&&(Ge=262144),Ql=e}else Ql=536870912;return e=eo.current,e!==null&&(e.flags|=32),Ql}function yu(e,t,n){(e===Vl&&(Ul===2||Ul===9)||e.cancelPendingCommit!==null)&&(Eu(e,0),Cu(e,Hl,Ql,!1)),z(e,n),(!(Bl&2)||e!==Vl)&&(e===Vl&&(!(Bl&2)&&(Xl|=n),W===4&&Cu(e,Hl,Ql,!1)),cd(e))}function bu(e,t,n){if(Bl&6)throw Error(i(327));var r=!n&&(t&127)==0&&(t&e.expiredLanes)===0||R(e,t),a=r?Pu(e,t):Mu(e,t,!0),o=r;do{if(a===0){Kl&&!r&&Cu(e,t,0,!1);break}else{if(n=e.current.alternate,o&&!Su(n)){a=Mu(e,t,!1),o=!1;continue}if(a===2){if(o=t,e.errorRecoveryDisabledLanes&o)var s=0;else s=e.pendingLanes&-536870913,s=s===0?s&536870912?536870912:0:s;if(s!==0){t=s;a:{var c=e;a=eu;var l=c.current.memoizedState.isDehydrated;if(l&&(Eu(c,s).flags|=256),s=Mu(c,s,!1),s!==2){if(ql&&!l){c.errorRecoveryDisabledLanes|=o,Xl|=o,a=4;break a}o=tu,tu=a,o!==null&&(tu===null?tu=o:tu.push.apply(tu,o))}a=s}if(o=!1,a!==2)continue}}if(a===1){Eu(e,0),Cu(e,t,0,!0);break}a:{switch(r=e,o=a,o){case 0:case 1:throw Error(i(345));case 4:if((t&4194048)!==t)break;case 6:Cu(r,t,Ql,!Gl);break a;case 2:tu=null;break;case 3:case 5:break;default:throw Error(i(329))}if((t&62914560)===t&&(a=ru+300-Oe(),10<a)){if(Cu(r,t,Ql,!Gl),Ke(r,0,!0)!==0)break a;du=t,r.timeoutHandle=Qd(xu.bind(null,r,n,tu,ou,nu,t,Ql,Xl,$l,Gl,o,`Throttled`,-0,0),a);break a}xu(r,n,tu,ou,nu,t,Ql,Xl,$l,Gl,o,null,-0,0)}}break}while(1);cd(e)}function xu(e,t,n,r,i,a,o,s,c,l,u,d,f,p){if(e.timeoutHandle=-1,d=t.subtreeFlags,d&8192||(d&16785408)==16785408){d={stylesheets:null,count:0,imgCount:0,imgBytes:0,suspenseyImages:[],waitingForImages:!0,waitingForViewTransition:!1,unsuspend:Xt},Ml(t,a,d);var m=(a&62914560)===a?ru-Oe():(a&4194048)===a?iu-Oe():0;if(m=Qf(d,m),m!==null){du=a,e.cancelPendingCommit=m(Vu.bind(null,e,t,a,n,r,i,o,s,c,u,d,null,f,p)),Cu(e,a,o,!l);return}}Vu(e,t,a,n,r,i,o,s,c)}function Su(e){for(var t=e;;){var n=t.tag;if((n===0||n===11||n===15)&&t.flags&16384&&(n=t.updateQueue,n!==null&&(n=n.stores,n!==null)))for(var r=0;r<n.length;r++){var i=n[r],a=i.getSnapshot;i=i.value;try{if(!vr(a(),i))return!1}catch{return!1}}if(n=t.child,t.subtreeFlags&16384&&n!==null)n.return=t,t=n;else{if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function Cu(e,t,n,r){t&=~Zl,t&=~Xl,e.suspendedLanes|=t,e.pingedLanes&=~t,r&&(e.warmLanes|=t),r=e.expirationTimes;for(var i=t;0<i;){var a=31-Be(i),o=1<<a;r[a]=-1,i&=~o}n!==0&&Ze(e,n,t)}function wu(){return Bl&6?!0:(ld(0,!1),!1)}function Tu(){if(U!==null){if(Ul===0)var e=U.return;else e=U,Wi=Ui=null,Oo(e),ka=null,Aa=0,e=U;for(;e!==null;)Bc(e.alternate,e),e=e.return;U=null}}function Eu(e,t){var n=e.timeoutHandle;n!==-1&&(e.timeoutHandle=-1,$d(n)),n=e.cancelPendingCommit,n!==null&&(e.cancelPendingCommit=null,n()),du=0,Tu(),Vl=e,U=n=oi(e.current,null),Hl=t,Ul=0,Wl=null,Gl=!1,Kl=R(e,t),ql=!1,$l=Ql=Zl=Xl=Yl=W=0,tu=eu=null,nu=!1,t&8&&(t|=t&32);var r=e.entangledLanes;if(r!==0)for(e=e.entanglements,r&=t;0<r;){var i=31-Be(r),a=1<<i;t|=e[i],r&=~a}return Jl=t,Xr(),n}function Du(e,t){H=null,D.H=Rs,t===ya||t===xa?(t=Da(),Ul=3):t===ba?(t=Da(),Ul=4):Ul=t===tc?8:typeof t==`object`&&t&&typeof t.then==`function`?6:1,Wl=t,U===null&&(W=1,Ys(e,mi(t,e.current)))}function Ou(){var e=eo.current;return e===null?!0:(Hl&4194048)===Hl?to===null:(Hl&62914560)===Hl||Hl&536870912?e===to:!1}function ku(){var e=D.H;return D.H=Rs,e===null?Rs:e}function Au(){var e=D.A;return D.A=Rl,e}function ju(){W=4,Gl||(Hl&4194048)!==Hl&&eo.current!==null||(Kl=!0),!(Yl&134217727)&&!(Xl&134217727)||Vl===null||Cu(Vl,Hl,Ql,!1)}function Mu(e,t,n){var r=Bl;Bl|=2;var i=ku(),a=Au();(Vl!==e||Hl!==t)&&(ou=null,Eu(e,t)),t=!1;var o=W;a:do try{if(Ul!==0&&U!==null){var s=U,c=Wl;switch(Ul){case 8:Tu(),o=6;break a;case 3:case 2:case 9:case 6:eo.current===null&&(t=!0);var l=Ul;if(Ul=0,Wl=null,Ru(e,s,c,l),n&&Kl){o=0;break a}break;default:l=Ul,Ul=0,Wl=null,Ru(e,s,c,l)}}Nu(),o=W;break}catch(t){Du(e,t)}while(1);return t&&e.shellSuspendCounter++,Wi=Ui=null,Bl=r,D.H=i,D.A=a,U===null&&(Vl=null,Hl=0,Xr()),o}function Nu(){for(;U!==null;)Iu(U)}function Pu(e,t){var n=Bl;Bl|=2;var r=ku(),a=Au();Vl!==e||Hl!==t?(ou=null,au=Oe()+500,Eu(e,t)):Kl=R(e,t);a:do try{if(Ul!==0&&U!==null){t=U;var o=Wl;b:switch(Ul){case 1:Ul=0,Wl=null,Ru(e,t,o,1);break;case 2:case 9:if(Ca(o)){Ul=0,Wl=null,Lu(t);break}t=function(){Ul!==2&&Ul!==9||Vl!==e||(Ul=7),cd(e)},o.then(t,t);break a;case 3:Ul=7;break a;case 4:Ul=5;break a;case 7:Ca(o)?(Ul=0,Wl=null,Lu(t)):(Ul=0,Wl=null,Ru(e,t,o,7));break;case 5:var s=null;switch(U.tag){case 26:s=U.memoizedState;case 5:case 27:var c=U;if(s?Yf(s):c.stateNode.complete){Ul=0,Wl=null;var l=c.sibling;if(l!==null)U=l;else{var u=c.return;u===null?U=null:(U=u,zu(u))}break b}}Ul=0,Wl=null,Ru(e,t,o,5);break;case 6:Ul=0,Wl=null,Ru(e,t,o,6);break;case 8:Tu(),W=6;break a;default:throw Error(i(462))}}Fu();break}catch(t){Du(e,t)}while(1);return Wi=Ui=null,D.H=r,D.A=a,Bl=n,U===null?(Vl=null,Hl=0,Xr(),W):0}function Fu(){for(;U!==null&&!Ee();)Iu(U)}function Iu(e){var t=jc(e.alternate,e,Jl);e.memoizedProps=e.pendingProps,t===null?zu(e):U=t}function Lu(e){var t=e,n=t.alternate;switch(t.tag){case 15:case 0:t=hc(n,t,t.pendingProps,t.type,void 0,Hl);break;case 11:t=hc(n,t,t.pendingProps,t.type.render,t.ref,Hl);break;case 5:Oo(t);default:Bc(n,t),t=U=si(t,Jl),t=jc(n,t,Jl)}e.memoizedProps=e.pendingProps,t===null?zu(e):U=t}function Ru(e,t,n,r){Wi=Ui=null,Oo(t),ka=null,Aa=0;var i=t.return;try{if(ec(e,i,t,n,Hl)){W=1,Ys(e,mi(n,e.current)),U=null;return}}catch(t){if(i!==null)throw U=i,t;W=1,Ys(e,mi(n,e.current)),U=null;return}t.flags&32768?(ji||r===1?e=!0:Kl||Hl&536870912?e=!1:(Gl=e=!0,(r===2||r===9||r===3||r===6)&&(r=eo.current,r!==null&&r.tag===13&&(r.flags|=16384))),Bu(t,e)):zu(t)}function zu(e){var t=e;do{if(t.flags&32768){Bu(t,Gl);return}e=t.return;var n=Rc(t.alternate,t,Jl);if(n!==null){U=n;return}if(t=t.sibling,t!==null){U=t;return}U=t=e}while(t!==null);W===0&&(W=5)}function Bu(e,t){do{var n=zc(e.alternate,e);if(n!==null){n.flags&=32767,U=n;return}if(n=e.return,n!==null&&(n.flags|=32768,n.subtreeFlags=0,n.deletions=null),!t&&(e=e.sibling,e!==null)){U=e;return}U=e=n}while(e!==null);W=6,U=null}function Vu(e,t,n,r,a,o,s,c,l){e.cancelPendingCommit=null;do Ku();while(cu!==0);if(Bl&6)throw Error(i(327));if(t!==null){if(t===e.current)throw Error(i(177));if(o=t.lanes|t.childLanes,o|=Yr,Xe(e,n,o,s,c,l),e===Vl&&(U=Vl=null,Hl=0),uu=t,lu=e,du=n,fu=o,pu=a,mu=r,t.subtreeFlags&10256||t.flags&10256?(e.callbackNode=null,e.callbackPriority=0,td(Me,function(){return qu(),null})):(e.callbackNode=null,e.callbackPriority=0),r=(t.flags&13878)!=0,t.subtreeFlags&13878||r){r=D.T,D.T=null,a=O.p,O.p=2,s=Bl,Bl|=4;try{al(e,t,n)}finally{Bl=s,O.p=a,D.T=r}}cu=1,Hu(),Uu(),Wu()}}function Hu(){if(cu===1){cu=0;var e=lu,t=uu,n=(t.flags&13878)!=0;if(t.subtreeFlags&13878||n){n=D.T,D.T=null;var r=O.p;O.p=2;var i=Bl;Bl|=4;try{vl(t,e);var a=Gd,o=Cr(e.containerInfo),s=a.focusedElem,c=a.selectionRange;if(o!==s&&s&&s.ownerDocument&&Sr(s.ownerDocument.documentElement,s)){if(c!==null&&wr(s)){var l=c.start,u=c.end;if(u===void 0&&(u=l),`selectionStart`in s)s.selectionStart=l,s.selectionEnd=Math.min(u,s.value.length);else{var d=s.ownerDocument||document,f=d&&d.defaultView||window;if(f.getSelection){var p=f.getSelection(),m=s.textContent.length,h=Math.min(c.start,m),g=c.end===void 0?h:Math.min(c.end,m);!p.extend&&h>g&&(o=g,g=h,h=o);var _=xr(s,h),v=xr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;s<d.length;s++){var ee=d[s];ee.element.scrollLeft=ee.left,ee.element.scrollTop=ee.top}}fp=!!Wd,Gd=Wd=null}finally{Bl=i,O.p=r,D.T=n}}e.current=t,cu=2}}function Uu(){if(cu===2){cu=0;var e=lu,t=uu,n=(t.flags&8772)!=0;if(t.subtreeFlags&8772||n){n=D.T,D.T=null;var r=O.p;O.p=2;var i=Bl;Bl|=4;try{ol(e,t.alternate,t)}finally{Bl=i,O.p=r,D.T=n}}cu=3}}function Wu(){if(cu===4||cu===3){cu=0,De();var e=lu,t=uu,n=du,r=mu;t.subtreeFlags&10256||t.flags&10256?cu=5:(cu=0,uu=lu=null,Gu(e,e.pendingLanes));var i=e.pendingLanes;if(i===0&&(su=null),V(n),t=t.stateNode,Re&&typeof Re.onCommitFiberRoot==`function`)try{Re.onCommitFiberRoot(Le,t,void 0,(t.current.flags&128)==128)}catch{}if(r!==null){t=D.T,i=O.p,O.p=2,D.T=null;try{for(var a=e.onRecoverableError,o=0;o<r.length;o++){var s=r[o];a(s.value,{componentStack:s.stack})}}finally{D.T=t,O.p=i}}du&3&&Ku(),cd(e),i=e.pendingLanes,n&261930&&i&42?e===gu?hu++:(hu=0,gu=e):hu=0,ld(0,!1)}}function Gu(e,t){(e.pooledCacheLanes&=t)===0&&(t=e.pooledCache,t!=null&&(e.pooledCache=null,oa(t)))}function Ku(){return Hu(),Uu(),Wu(),qu()}function qu(){if(cu!==5)return!1;var e=lu,t=fu;fu=0;var n=V(du),r=D.T,a=O.p;try{O.p=32>n?32:n,D.T=null,n=pu,pu=null;var o=lu,s=du;if(cu=0,uu=lu=null,du=0,Bl&6)throw Error(i(331));var c=Bl;if(Bl|=4,Fl(o.current),Dl(o,o.current,s,n),Bl=c,ld(0,!1),Re&&typeof Re.onPostCommitFiberRoot==`function`)try{Re.onPostCommitFiberRoot(Le,o)}catch{}return!0}finally{O.p=a,D.T=r,Gu(e,t)}}function Ju(e,t,n){t=mi(n,t),t=Zs(e.stateNode,t,2),e=Va(e,t,2),e!==null&&(z(e,2),cd(e))}function Yu(e,t,n){if(e.tag===3)Ju(e,e,n);else for(;t!==null;){if(t.tag===3){Ju(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(su===null||!su.has(r))){e=mi(n,e),n=Qs(2),r=Va(t,n,2),r!==null&&($s(n,r,t,e),z(r,2),cd(r));break}}t=t.return}}function Xu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new zl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(ql=!0,i.add(n),e=Zu.bind(null,e,t,n),t.then(e,e))}function Zu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Vl===e&&(Hl&n)===n&&(W===4||W===3&&(Hl&62914560)===Hl&&300>Oe()-ru?!(Bl&2)&&Eu(e,0):Zl|=n,$l===Hl&&($l=0)),cd(e)}function Qu(e,t){t===0&&(t=Je()),e=$r(e,t),e!==null&&(z(e,t),cd(e))}function $u(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Qu(e,n)}function ed(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Qu(e,n)}function td(e,t){return we(e,t)}var nd=null,rd=null,id=!1,ad=!1,od=!1,sd=0;function cd(e){e!==rd&&e.next===null&&(rd===null?nd=rd=e:rd=rd.next=e),ad=!0,id||(id=!0,hd())}function ld(e,t){if(!od&&ad){od=!0;do for(var n=!1,r=nd;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Be(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,md(r,a))}else a=Hl,a=Ke(r,r===Vl?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||R(r,a)||(n=!0,md(r,a));r=r.next}while(n);od=!1}}function ud(){dd()}function dd(){ad=id=!1;var e=0;sd!==0&&Zd()&&(e=sd);for(var t=Oe(),n=null,r=nd;r!==null;){var i=r.next,a=fd(r,t);a===0?(r.next=null,n===null?nd=i:n.next=i,i===null&&(rd=n)):(n=r,(e!==0||a&3)&&(ad=!0)),r=i}cu!==0&&cu!==5||ld(e,!1),sd!==0&&(sd=0)}function fd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0<a;){var o=31-Be(a),s=1<<o,c=i[o];c===-1?((s&n)===0||(s&r)!==0)&&(i[o]=qe(s,t)):c<=t&&(e.expiredLanes|=s),a&=~s}if(t=Vl,n=Hl,n=Ke(e,e===t?n:0,e.cancelPendingCommit!==null||e.timeoutHandle!==-1),r=e.callbackNode,n===0||e===t&&(Ul===2||Ul===9)||e.cancelPendingCommit!==null)return r!==null&&r!==null&&Te(r),e.callbackNode=null,e.callbackPriority=0;if(!(n&3)||R(e,n)){if(t=n&-n,t===e.callbackPriority)return t;switch(r!==null&&Te(r),V(n)){case 2:case 8:n=je;break;case 32:n=Me;break;case 268435456:n=Pe;break;default:n=Me}return r=pd.bind(null,e),n=we(n,r),e.callbackPriority=t,e.callbackNode=n,t}return r!==null&&r!==null&&Te(r),e.callbackPriority=2,e.callbackNode=null,2}function pd(e,t){if(cu!==0&&cu!==5)return e.callbackNode=null,e.callbackPriority=0,null;var n=e.callbackNode;if(Ku()&&e.callbackNode!==n)return null;var r=Hl;return r=Ke(e,e===Vl?r:0,e.cancelPendingCommit!==null||e.timeoutHandle!==-1),r===0?null:(bu(e,r,t),fd(e,Oe()),e.callbackNode!=null&&e.callbackNode===n?pd.bind(null,e):null)}function md(e,t){if(Ku())return null;bu(e,t,!0)}function hd(){tf(function(){Bl&6?we(Ae,ud):dd()})}function gd(){if(sd===0){var e=la;e===0&&(e=We,We<<=1,!(We&261888)&&(We=256)),sd=e}return sd}function _d(e){return e==null||typeof e==`symbol`||typeof e==`boolean`?null:typeof e==`function`?e:Yt(``+e)}function vd(e,t){var n=t.ownerDocument.createElement(`input`);return n.name=t.name,n.value=t.value,e.id&&n.setAttribute(`form`,e.id),t.parentNode.insertBefore(n,t),e=new FormData(e),n.parentNode.removeChild(n),e}function yd(e,t,n,r,i){if(t===`submit`&&n&&n.stateNode===i){var a=_d((i[it]||null).action),o=r.submitter;o&&(t=(t=o[it]||null)?_d(t.formAction):o.getAttribute(`formAction`),t!==null&&(a=t,o=null));var s=new vn(`action`,`action`,null,r,i);e.push({event:s,listeners:[{instance:null,listener:function(){if(r.defaultPrevented){if(sd!==0){var e=o?vd(i,o):new FormData(i);ws(n,{pending:!0,data:e,method:i.method,action:a},null,e)}}else typeof a==`function`&&(s.preventDefault(),e=o?vd(i,o):new FormData(i),ws(n,{pending:!0,data:e,method:i.method,action:a},a,e))},currentTarget:i}]})}}for(var bd=0;bd<Wr.length;bd++){var xd=Wr[bd];Gr(xd.toLowerCase(),`on`+(xd[0].toUpperCase()+xd.slice(1)))}Gr(Ir,`onAnimationEnd`),Gr(Lr,`onAnimationIteration`),Gr(Rr,`onAnimationStart`),Gr(`dblclick`,`onDoubleClick`),Gr(`focusin`,`onFocus`),Gr(`focusout`,`onBlur`),Gr(zr,`onTransitionRun`),Gr(Br,`onTransitionStart`),Gr(Vr,`onTransitionCancel`),Gr(Hr,`onTransitionEnd`),bt(`onMouseEnter`,[`mouseout`,`mouseover`]),bt(`onMouseLeave`,[`mouseout`,`mouseover`]),bt(`onPointerEnter`,[`pointerout`,`pointerover`]),bt(`onPointerLeave`,[`pointerout`,`pointerover`]),yt(`onChange`,`change click focusin focusout input keydown keyup selectionchange`.split(` `)),yt(`onSelect`,`focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange`.split(` `)),yt(`onBeforeInput`,[`compositionend`,`keypress`,`textInput`,`paste`]),yt(`onCompositionEnd`,`compositionend focusout keydown keypress keyup mousedown`.split(` `)),yt(`onCompositionStart`,`compositionstart focusout keydown keypress keyup mousedown`.split(` `)),yt(`onCompositionUpdate`,`compositionupdate focusout keydown keypress keyup mousedown`.split(` `));var Sd=`abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting`.split(` `),Cd=new Set(`beforetoggle cancel close invalid load scroll scrollend toggle`.split(` `).concat(Sd));function wd(e,t){t=(t&4)!=0;for(var n=0;n<e.length;n++){var r=e[n],i=r.event;r=r.listeners;a:{var a=void 0;if(t)for(var o=r.length-1;0<=o;o--){var s=r[o],c=s.instance,l=s.currentTarget;if(s=s.listener,c!==a&&i.isPropagationStopped())break a;a=s,i.currentTarget=l;try{a(i)}catch(e){Kr(e)}i.currentTarget=null,a=c}else for(o=0;o<r.length;o++){if(s=r[o],c=s.instance,l=s.currentTarget,s=s.listener,c!==a&&i.isPropagationStopped())break a;a=s,i.currentTarget=l;try{a(i)}catch(e){Kr(e)}i.currentTarget=null,a=c}}}}function G(e,t){var n=t[ot];n===void 0&&(n=t[ot]=new Set);var r=e+`__bubble`;n.has(r)||(Od(t,e,2,!1),n.add(r))}function Td(e,t,n){var r=0;t&&(r|=4),Od(n,e,r,t)}var Ed=`_reactListening`+Math.random().toString(36).slice(2);function Dd(e){if(!e[Ed]){e[Ed]=!0,_t.forEach(function(t){t!==`selectionchange`&&(Cd.has(t)||Td(t,!1,e),Td(t,!0,e))});var t=e.nodeType===9?e:e.ownerDocument;t===null||t[Ed]||(t[Ed]=!0,Td(`selectionchange`,!1,t))}}function Od(e,t,n,r){switch(yp(t)){case 2:var i=pp;break;case 8:i=mp;break;default:i=hp}n=i.bind(null,t,n,e),i=void 0,!sn||t!==`touchstart`&&t!==`touchmove`&&t!==`wheel`||(i=!0),r?i===void 0?e.addEventListener(t,n,!0):e.addEventListener(t,n,{capture:!0,passive:i}):i===void 0?e.addEventListener(t,n,!1):e.addEventListener(t,n,{passive:i})}function kd(e,t,n,r,i){var a=r;if(!(t&1)&&!(t&2)&&r!==null)a:for(;;){if(r===null)return;var o=r.tag;if(o===3||o===4){var s=r.stateNode.containerInfo;if(s===i)break;if(o===4)for(o=r.return;o!==null;){var l=o.tag;if((l===3||l===4)&&o.stateNode.containerInfo===i)return;o=o.return}for(;s!==null;){if(o=ft(s),o===null)return;if(l=o.tag,l===5||l===6||l===26||l===27){r=a=o;continue a}s=s.parentNode}}r=r.return}rn(function(){var r=a,i=Qt(n),o=[];a:{var s=Ur.get(e);if(s!==void 0){var l=vn,u=e;switch(e){case`keypress`:if(pn(n)===0)break a;case`keydown`:case`keyup`:l=Fn;break;case`focusin`:u=`focus`,l=Dn;break;case`focusout`:u=`blur`,l=Dn;break;case`beforeblur`:case`afterblur`:l=Dn;break;case`click`:if(n.button===2)break a;case`auxclick`:case`dblclick`:case`mousedown`:case`mousemove`:case`mouseup`:case`mouseout`:case`mouseover`:case`contextmenu`:l=Tn;break;case`drag`:case`dragend`:case`dragenter`:case`dragexit`:case`dragleave`:case`dragover`:case`dragstart`:case`drop`:l=En;break;case`touchcancel`:case`touchend`:case`touchmove`:case`touchstart`:l=Ln;break;case Ir:case Lr:case Rr:l=On;break;case Hr:l=Rn;break;case`scroll`:case`scrollend`:l=bn;break;case`wheel`:l=zn;break;case`copy`:case`cut`:case`paste`:l=kn;break;case`gotpointercapture`:case`lostpointercapture`:case`pointercancel`:case`pointerdown`:case`pointermove`:case`pointerout`:case`pointerover`:case`pointerup`:l=In;break;case`toggle`:case`beforetoggle`:l=Bn}var d=(t&4)!=0,f=!d&&(e===`scroll`||e===`scrollend`),p=d?s===null?null:s+`Capture`:s;d=[];for(var m=r,h;m!==null;){var g=m;if(h=g.stateNode,g=g.tag,g!==5&&g!==26&&g!==27||h===null||p===null||(g=an(m,p),g!=null&&d.push(Ad(m,g,h))),f)break;m=m.return}0<d.length&&(s=new l(s,u,null,n,i),o.push({event:s,listeners:d}))}}if(!(t&7)){a:{if(s=e===`mouseover`||e===`pointerover`,l=e===`mouseout`||e===`pointerout`,s&&n!==Zt&&(u=n.relatedTarget||n.fromElement)&&(ft(u)||u[at]))break a;if((l||s)&&(s=i.window===i?i:(s=i.ownerDocument)?s.defaultView||s.parentWindow:window,l?(u=n.relatedTarget||n.toElement,l=r,u=u?ft(u):null,u!==null&&(f=c(u),d=u.tag,u!==f||d!==5&&d!==27&&d!==6)&&(u=null)):(l=null,u=r),l!==u)){if(d=Tn,g=`onMouseLeave`,p=`onMouseEnter`,m=`mouse`,(e===`pointerout`||e===`pointerover`)&&(d=In,g=`onPointerLeave`,p=`onPointerEnter`,m=`pointer`),f=l==null?s:mt(l),h=u==null?s:mt(u),s=new d(g,m+`leave`,l,n,i),s.target=f,s.relatedTarget=h,g=null,ft(i)===r&&(d=new d(p,m+`enter`,u,n,i),d.target=h,d.relatedTarget=f,g=d),f=g,l&&u)b:{for(d=Md,p=l,m=u,h=0,g=p;g;g=d(g))h++;g=0;for(var _=m;_;_=d(_))g++;for(;0<h-g;)p=d(p),h--;for(;0<g-h;)m=d(m),g--;for(;h--;){if(p===m||m!==null&&p===m.alternate){d=p;break b}p=d(p),m=d(m)}d=null}else d=null;l!==null&&Nd(o,s,l,d,!1),u!==null&&f!==null&&Nd(o,f,u,d,!0)}}a:{if(s=r?mt(r):window,l=s.nodeName&&s.nodeName.toLowerCase(),l===`select`||l===`input`&&s.type===`file`)var v=or;else if(er(s))if(sr)v=gr;else{v=mr;var y=pr}else l=s.nodeName,!l||l.toLowerCase()!==`input`||s.type!==`checkbox`&&s.type!==`radio`?r&&Kt(r.elementType)&&(v=or):v=hr;if(v&&=v(e,r)){tr(o,v,n,i);break a}y&&y(e,s,r),e===`focusout`&&r&&s.type===`number`&&r.memoizedProps.value!=null&&Rt(s,`number`,s.value)}switch(y=r?mt(r):window,e){case`focusin`:(er(y)||y.contentEditable===`true`)&&(Er=y,Dr=r,Or=null);break;case`focusout`:Or=Dr=Er=null;break;case`mousedown`:kr=!0;break;case`contextmenu`:case`mouseup`:case`dragend`:kr=!1,Ar(o,n,i);break;case`selectionchange`:if(Tr)break;case`keydown`:case`keyup`:Ar(o,n,i)}var ee;if(Hn)b:{switch(e){case`compositionstart`:var b=`onCompositionStart`;break b;case`compositionend`:b=`onCompositionEnd`;break b;case`compositionupdate`:b=`onCompositionUpdate`;break b}b=void 0}else Xn?Jn(e,n)&&(b=`onCompositionEnd`):e===`keydown`&&n.keyCode===229&&(b=`onCompositionStart`);b&&(Gn&&n.locale!==`ko`&&(Xn||b!==`onCompositionStart`?b===`onCompositionEnd`&&Xn&&(ee=fn()):(ln=i,un=`value`in ln?ln.value:ln.textContent,Xn=!0)),y=jd(r,b),0<y.length&&(b=new An(b,e,null,n,i),o.push({event:b,listeners:y}),ee?b.data=ee:(ee=Yn(n),ee!==null&&(b.data=ee)))),(ee=Wn?Zn(e,n):Qn(e,n))&&(b=jd(r,`onBeforeInput`),0<b.length&&(y=new An(`onBeforeInput`,`beforeinput`,null,n,i),o.push({event:y,listeners:b}),y.data=ee)),yd(o,e,r,n,i)}wd(o,t)})}function Ad(e,t,n){return{instance:e,listener:t,currentTarget:n}}function jd(e,t){for(var n=t+`Capture`,r=[];e!==null;){var i=e,a=i.stateNode;if(i=i.tag,i!==5&&i!==26&&i!==27||a===null||(i=an(e,n),i!=null&&r.unshift(Ad(e,i,a)),i=an(e,t),i!=null&&r.push(Ad(e,i,a))),e.tag===3)return r;e=e.return}return[]}function Md(e){if(e===null)return null;do e=e.return;while(e&&e.tag!==5&&e.tag!==27);return e||null}function Nd(e,t,n,r,i){for(var a=t._reactName,o=[];n!==null&&n!==r;){var s=n,c=s.alternate,l=s.stateNode;if(s=s.tag,c!==null&&c===r)break;s!==5&&s!==26&&s!==27||l===null||(c=l,i?(l=an(n,a),l!=null&&o.unshift(Ad(n,l,c))):i||(l=an(n,a),l!=null&&o.push(Ad(n,l,c)))),n=n.return}o.length!==0&&e.push({event:t,listeners:o})}var Pd=/\r\n?/g,Fd=/\u0000|\uFFFD/g;function Id(e){return(typeof e==`string`?e:``+e).replace(Pd,`
9+`).replace(Fd,``)}function Ld(e,t){return t=Id(t),Id(e)===t}function Rd(e,t,n,r,a,o){switch(n){case`children`:typeof r==`string`?t===`body`||t===`textarea`&&r===``||Ht(e,r):(typeof r==`number`||typeof r==`bigint`)&&t!==`body`&&Ht(e,``+r);break;case`className`:Et(e,`class`,r);break;case`tabIndex`:Et(e,`tabindex`,r);break;case`dir`:case`role`:case`viewBox`:case`width`:case`height`:Et(e,n,r);break;case`style`:Gt(e,r,o);break;case`data`:if(t!==`object`){Et(e,`data`,r);break}case`src`:case`href`:if(r===``&&(t!==`a`||n!==`href`)){e.removeAttribute(n);break}if(r==null||typeof r==`function`||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=Yt(``+r),e.setAttribute(n,r);break;case`action`:case`formAction`:if(typeof r==`function`){e.setAttribute(n,`javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')`);break}else typeof o==`function`&&(n===`formAction`?(t!==`input`&&Rd(e,t,`name`,a.name,a,null),Rd(e,t,`formEncType`,a.formEncType,a,null),Rd(e,t,`formMethod`,a.formMethod,a,null),Rd(e,t,`formTarget`,a.formTarget,a,null)):(Rd(e,t,`encType`,a.encType,a,null),Rd(e,t,`method`,a.method,a,null),Rd(e,t,`target`,a.target,a,null)));if(r==null||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=Yt(``+r),e.setAttribute(n,r);break;case`onClick`:r!=null&&(e.onclick=Xt);break;case`onScroll`:r!=null&&G(`scroll`,e);break;case`onScrollEnd`:r!=null&&G(`scrollend`,e);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(i(61));if(n=r.__html,n!=null){if(a.children!=null)throw Error(i(60));e.innerHTML=n}}break;case`multiple`:e.multiple=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`muted`:e.muted=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`defaultValue`:case`defaultChecked`:case`innerHTML`:case`ref`:break;case`autoFocus`:break;case`xlinkHref`:if(r==null||typeof r==`function`||typeof r==`boolean`||typeof r==`symbol`){e.removeAttribute(`xlink:href`);break}n=Yt(``+r),e.setAttributeNS(`http://www.w3.org/1999/xlink`,`xlink:href`,n);break;case`contentEditable`:case`spellCheck`:case`draggable`:case`value`:case`autoReverse`:case`externalResourcesRequired`:case`focusable`:case`preserveAlpha`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``+r):e.removeAttribute(n);break;case`inert`:case`allowFullScreen`:case`async`:case`autoPlay`:case`controls`:case`default`:case`defer`:case`disabled`:case`disablePictureInPicture`:case`disableRemotePlayback`:case`formNoValidate`:case`hidden`:case`loop`:case`noModule`:case`noValidate`:case`open`:case`playsInline`:case`readOnly`:case`required`:case`reversed`:case`scoped`:case`seamless`:case`itemScope`:r&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``):e.removeAttribute(n);break;case`capture`:case`download`:!0===r?e.setAttribute(n,``):!1!==r&&r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,r):e.removeAttribute(n);break;case`cols`:case`rows`:case`size`:case`span`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case`rowSpan`:case`start`:r==null||typeof r==`function`||typeof r==`symbol`||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case`popover`:G(`beforetoggle`,e),G(`toggle`,e),Tt(e,`popover`,r);break;case`xlinkActuate`:Dt(e,`http://www.w3.org/1999/xlink`,`xlink:actuate`,r);break;case`xlinkArcrole`:Dt(e,`http://www.w3.org/1999/xlink`,`xlink:arcrole`,r);break;case`xlinkRole`:Dt(e,`http://www.w3.org/1999/xlink`,`xlink:role`,r);break;case`xlinkShow`:Dt(e,`http://www.w3.org/1999/xlink`,`xlink:show`,r);break;case`xlinkTitle`:Dt(e,`http://www.w3.org/1999/xlink`,`xlink:title`,r);break;case`xlinkType`:Dt(e,`http://www.w3.org/1999/xlink`,`xlink:type`,r);break;case`xmlBase`:Dt(e,`http://www.w3.org/XML/1998/namespace`,`xml:base`,r);break;case`xmlLang`:Dt(e,`http://www.w3.org/XML/1998/namespace`,`xml:lang`,r);break;case`xmlSpace`:Dt(e,`http://www.w3.org/XML/1998/namespace`,`xml:space`,r);break;case`is`:Tt(e,`is`,r);break;case`innerText`:case`textContent`:break;default:(!(2<n.length)||n[0]!==`o`&&n[0]!==`O`||n[1]!==`n`&&n[1]!==`N`)&&(n=qt.get(n)||n,Tt(e,n,r))}}function zd(e,t,n,r,a,o){switch(n){case`style`:Gt(e,r,o);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(i(61));if(n=r.__html,n!=null){if(a.children!=null)throw Error(i(60));e.innerHTML=n}}break;case`children`:typeof r==`string`?Ht(e,r):(typeof r==`number`||typeof r==`bigint`)&&Ht(e,``+r);break;case`onScroll`:r!=null&&G(`scroll`,e);break;case`onScrollEnd`:r!=null&&G(`scrollend`,e);break;case`onClick`:r!=null&&(e.onclick=Xt);break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`innerHTML`:case`ref`:break;case`innerText`:case`textContent`:break;default:if(!vt.hasOwnProperty(n))a:{if(n[0]===`o`&&n[1]===`n`&&(a=n.endsWith(`Capture`),t=n.slice(2,a?n.length-7:void 0),o=e[it]||null,o=o==null?null:o[n],typeof o==`function`&&e.removeEventListener(t,o,a),typeof r==`function`)){typeof o!=`function`&&o!==null&&(n in e?e[n]=null:e.hasAttribute(n)&&e.removeAttribute(n)),e.addEventListener(t,r,a);break a}n in e?e[n]=r:!0===r?e.setAttribute(n,``):Tt(e,n,r)}}}function Bd(e,t,n){switch(t){case`div`:case`span`:case`svg`:case`path`:case`a`:case`g`:case`p`:case`li`:break;case`img`:G(`error`,e),G(`load`,e);var r=!1,a=!1,o;for(o in n)if(n.hasOwnProperty(o)){var s=n[o];if(s!=null)switch(o){case`src`:r=!0;break;case`srcSet`:a=!0;break;case`children`:case`dangerouslySetInnerHTML`:throw Error(i(137,t));default:Rd(e,t,o,s,n,null)}}a&&Rd(e,t,`srcSet`,n.srcSet,n,null),r&&Rd(e,t,`src`,n.src,n,null);return;case`input`:G(`invalid`,e);var c=o=s=a=null,l=null,u=null;for(r in n)if(n.hasOwnProperty(r)){var d=n[r];if(d!=null)switch(r){case`name`:a=d;break;case`type`:s=d;break;case`checked`:l=d;break;case`defaultChecked`:u=d;break;case`value`:o=d;break;case`defaultValue`:c=d;break;case`children`:case`dangerouslySetInnerHTML`:if(d!=null)throw Error(i(137,t));break;default:Rd(e,t,r,d,n,null)}}Lt(e,o,c,l,u,s,a,!1);return;case`select`:for(a in G(`invalid`,e),r=s=o=null,n)if(n.hasOwnProperty(a)&&(c=n[a],c!=null))switch(a){case`value`:o=c;break;case`defaultValue`:s=c;break;case`multiple`:r=c;default:Rd(e,t,a,c,n,null)}t=o,n=s,e.multiple=!!r,t==null?n!=null&&zt(e,!!r,n,!0):zt(e,!!r,t,!1);return;case`textarea`:for(s in G(`invalid`,e),o=a=r=null,n)if(n.hasOwnProperty(s)&&(c=n[s],c!=null))switch(s){case`value`:r=c;break;case`defaultValue`:a=c;break;case`children`:o=c;break;case`dangerouslySetInnerHTML`:if(c!=null)throw Error(i(91));break;default:Rd(e,t,s,c,n,null)}Vt(e,r,a,o);return;case`option`:for(l in n)if(n.hasOwnProperty(l)&&(r=n[l],r!=null))switch(l){case`selected`:e.selected=r&&typeof r!=`function`&&typeof r!=`symbol`;break;default:Rd(e,t,l,r,n,null)}return;case`dialog`:G(`beforetoggle`,e),G(`toggle`,e),G(`cancel`,e),G(`close`,e);break;case`iframe`:case`object`:G(`load`,e);break;case`video`:case`audio`:for(r=0;r<Sd.length;r++)G(Sd[r],e);break;case`image`:G(`error`,e),G(`load`,e);break;case`details`:G(`toggle`,e);break;case`embed`:case`source`:case`link`:G(`error`,e),G(`load`,e);case`area`:case`base`:case`br`:case`col`:case`hr`:case`keygen`:case`meta`:case`param`:case`track`:case`wbr`:case`menuitem`:for(u in n)if(n.hasOwnProperty(u)&&(r=n[u],r!=null))switch(u){case`children`:case`dangerouslySetInnerHTML`:throw Error(i(137,t));default:Rd(e,t,u,r,n,null)}return;default:if(Kt(t)){for(d in n)n.hasOwnProperty(d)&&(r=n[d],r!==void 0&&zd(e,t,d,r,n,void 0));return}}for(c in n)n.hasOwnProperty(c)&&(r=n[c],r!=null&&Rd(e,t,c,r,n,null))}function Vd(e,t,n,r){switch(t){case`div`:case`span`:case`svg`:case`path`:case`a`:case`g`:case`p`:case`li`:break;case`input`:var a=null,o=null,s=null,c=null,l=null,u=null,d=null;for(m in n){var f=n[m];if(n.hasOwnProperty(m)&&f!=null)switch(m){case`checked`:break;case`value`:break;case`defaultValue`:l=f;default:r.hasOwnProperty(m)||Rd(e,t,m,null,r,f)}}for(var p in r){var m=r[p];if(f=n[p],r.hasOwnProperty(p)&&(m!=null||f!=null))switch(p){case`type`:o=m;break;case`name`:a=m;break;case`checked`:u=m;break;case`defaultChecked`:d=m;break;case`value`:s=m;break;case`defaultValue`:c=m;break;case`children`:case`dangerouslySetInnerHTML`:if(m!=null)throw Error(i(137,t));break;default:m!==f&&Rd(e,t,p,m,r,f)}}It(e,s,c,l,u,d,o,a);return;case`select`:for(o in m=s=c=p=null,n)if(l=n[o],n.hasOwnProperty(o)&&l!=null)switch(o){case`value`:break;case`multiple`:m=l;default:r.hasOwnProperty(o)||Rd(e,t,o,null,r,l)}for(a in r)if(o=r[a],l=n[a],r.hasOwnProperty(a)&&(o!=null||l!=null))switch(a){case`value`:p=o;break;case`defaultValue`:c=o;break;case`multiple`:s=o;default:o!==l&&Rd(e,t,a,o,r,l)}t=c,n=s,r=m,p==null?!!r!=!!n&&(t==null?zt(e,!!n,n?[]:``,!1):zt(e,!!n,t,!0)):zt(e,!!n,p,!1);return;case`textarea`:for(c in m=p=null,n)if(a=n[c],n.hasOwnProperty(c)&&a!=null&&!r.hasOwnProperty(c))switch(c){case`value`:break;case`children`:break;default:Rd(e,t,c,null,r,a)}for(s in r)if(a=r[s],o=n[s],r.hasOwnProperty(s)&&(a!=null||o!=null))switch(s){case`value`:p=a;break;case`defaultValue`:m=a;break;case`children`:break;case`dangerouslySetInnerHTML`:if(a!=null)throw Error(i(91));break;default:a!==o&&Rd(e,t,s,a,r,o)}Bt(e,p,m);return;case`option`:for(var h in n)if(p=n[h],n.hasOwnProperty(h)&&p!=null&&!r.hasOwnProperty(h))switch(h){case`selected`:e.selected=!1;break;default:Rd(e,t,h,null,r,p)}for(l in r)if(p=r[l],m=n[l],r.hasOwnProperty(l)&&p!==m&&(p!=null||m!=null))switch(l){case`selected`:e.selected=p&&typeof p!=`function`&&typeof p!=`symbol`;break;default:Rd(e,t,l,p,r,m)}return;case`img`:case`link`:case`area`:case`base`:case`br`:case`col`:case`embed`:case`hr`:case`keygen`:case`meta`:case`param`:case`source`:case`track`:case`wbr`:case`menuitem`:for(var g in n)p=n[g],n.hasOwnProperty(g)&&p!=null&&!r.hasOwnProperty(g)&&Rd(e,t,g,null,r,p);for(u in r)if(p=r[u],m=n[u],r.hasOwnProperty(u)&&p!==m&&(p!=null||m!=null))switch(u){case`children`:case`dangerouslySetInnerHTML`:if(p!=null)throw Error(i(137,t));break;default:Rd(e,t,u,p,r,m)}return;default:if(Kt(t)){for(var _ in n)p=n[_],n.hasOwnProperty(_)&&p!==void 0&&!r.hasOwnProperty(_)&&zd(e,t,_,void 0,r,p);for(d in r)p=r[d],m=n[d],!r.hasOwnProperty(d)||p===m||p===void 0&&m===void 0||zd(e,t,d,p,r,m);return}}for(var v in n)p=n[v],n.hasOwnProperty(v)&&p!=null&&!r.hasOwnProperty(v)&&Rd(e,t,v,null,r,p);for(f in r)p=r[f],m=n[f],!r.hasOwnProperty(f)||p===m||p==null&&m==null||Rd(e,t,f,p,r,m)}function Hd(e){switch(e){case`css`:case`script`:case`font`:case`img`:case`image`:case`input`:case`link`:return!0;default:return!1}}function Ud(){if(typeof performance.getEntriesByType==`function`){for(var e=0,t=0,n=performance.getEntriesByType(`resource`),r=0;r<n.length;r++){var i=n[r],a=i.transferSize,o=i.initiatorType,s=i.duration;if(a&&s&&Hd(o)){for(o=0,s=i.responseEnd,r+=1;r<n.length;r++){var c=n[r],l=c.startTime;if(l>s)break;var u=c.transferSize,d=c.initiatorType;u&&Hd(d)&&(c=c.responseEnd,o+=u*(c<s?1:(s-l)/(c-l)))}if(--r,t+=8*(a+o)/(i.duration/1e3),e++,10<e)break}}if(0<e)return t/e/1e6}return navigator.connection&&(e=navigator.connection.downlink,typeof e==`number`)?e:5}var Wd=null,Gd=null;function Kd(e){return e.nodeType===9?e:e.ownerDocument}function qd(e){switch(e){case`http://www.w3.org/2000/svg`:return 1;case`http://www.w3.org/1998/Math/MathML`:return 2;default:return 0}}function Jd(e,t){if(e===0)switch(t){case`svg`:return 1;case`math`:return 2;default:return 0}return e===1&&t===`foreignObject`?0:e}function Yd(e,t){return e===`textarea`||e===`noscript`||typeof t.children==`string`||typeof t.children==`number`||typeof t.children==`bigint`||typeof t.dangerouslySetInnerHTML==`object`&&t.dangerouslySetInnerHTML!==null&&t.dangerouslySetInnerHTML.__html!=null}var Xd=null;function Zd(){var e=window.event;return e&&e.type===`popstate`?e===Xd?!1:(Xd=e,!0):(Xd=null,!1)}var Qd=typeof setTimeout==`function`?setTimeout:void 0,$d=typeof clearTimeout==`function`?clearTimeout:void 0,ef=typeof Promise==`function`?Promise:void 0,tf=typeof queueMicrotask==`function`?queueMicrotask:ef===void 0?Qd:function(e){return ef.resolve(null).then(e).catch(nf)};function nf(e){setTimeout(function(){throw e})}function rf(e){return e===`head`}function af(e,t){var n=t,r=0;do{var i=n.nextSibling;if(e.removeChild(n),i&&i.nodeType===8)if(n=i.data,n===`/$`||n===`/&`){if(r===0){e.removeChild(i),Rp(t);return}r--}else if(n===`$`||n===`$?`||n===`$~`||n===`$!`||n===`&`)r++;else if(n===`html`)yf(e.ownerDocument.documentElement);else if(n===`head`){n=e.ownerDocument.head,yf(n);for(var a=n.firstChild;a;){var o=a.nextSibling,s=a.nodeName;a[ut]||s===`SCRIPT`||s===`STYLE`||s===`LINK`&&a.rel.toLowerCase()===`stylesheet`||n.removeChild(a),a=o}}else n===`body`&&yf(e.ownerDocument.body);n=i}while(n);Rp(t)}function of(e,t){var n=e;e=0;do{var r=n.nextSibling;if(n.nodeType===1?t?(n._stashedDisplay=n.style.display,n.style.display=`none`):(n.style.display=n._stashedDisplay||``,n.getAttribute(`style`)===``&&n.removeAttribute(`style`)):n.nodeType===3&&(t?(n._stashedText=n.nodeValue,n.nodeValue=``):n.nodeValue=n._stashedText||``),r&&r.nodeType===8)if(n=r.data,n===`/$`){if(e===0)break;e--}else n!==`$`&&n!==`$?`&&n!==`$~`&&n!==`$!`||e++;n=r}while(n)}function sf(e){var t=e.firstChild;for(t&&t.nodeType===10&&(t=t.nextSibling);t;){var n=t;switch(t=t.nextSibling,n.nodeName){case`HTML`:case`HEAD`:case`BODY`:sf(n),dt(n);continue;case`SCRIPT`:case`STYLE`:continue;case`LINK`:if(n.rel.toLowerCase()===`stylesheet`)continue}e.removeChild(n)}}function cf(e,t,n,r){for(;e.nodeType===1;){var i=n;if(e.nodeName.toLowerCase()!==t.toLowerCase()){if(!r&&(e.nodeName!==`INPUT`||e.type!==`hidden`))break}else if(!r)if(t===`input`&&e.type===`hidden`){var a=i.name==null?null:``+i.name;if(i.type===`hidden`&&e.getAttribute(`name`)===a)return e}else return e;else if(!e[ut])switch(t){case`meta`:if(!e.hasAttribute(`itemprop`))break;return e;case`link`:if(a=e.getAttribute(`rel`),a===`stylesheet`&&e.hasAttribute(`data-precedence`)||a!==i.rel||e.getAttribute(`href`)!==(i.href==null||i.href===``?null:i.href)||e.getAttribute(`crossorigin`)!==(i.crossOrigin==null?null:i.crossOrigin)||e.getAttribute(`title`)!==(i.title==null?null:i.title))break;return e;case`style`:if(e.hasAttribute(`data-precedence`))break;return e;case`script`:if(a=e.getAttribute(`src`),(a!==(i.src==null?null:i.src)||e.getAttribute(`type`)!==(i.type==null?null:i.type)||e.getAttribute(`crossorigin`)!==(i.crossOrigin==null?null:i.crossOrigin))&&a&&e.hasAttribute(`async`)&&!e.hasAttribute(`itemprop`))break;return e;default:return e}if(e=mf(e.nextSibling),e===null)break}return null}function lf(e,t,n){if(t===``)return null;for(;e.nodeType!==3;)if((e.nodeType!==1||e.nodeName!==`INPUT`||e.type!==`hidden`)&&!n||(e=mf(e.nextSibling),e===null))return null;return e}function uf(e,t){for(;e.nodeType!==8;)if((e.nodeType!==1||e.nodeName!==`INPUT`||e.type!==`hidden`)&&!t||(e=mf(e.nextSibling),e===null))return null;return e}function df(e){return e.data===`$?`||e.data===`$~`}function ff(e){return e.data===`$!`||e.data===`$?`&&e.ownerDocument.readyState!==`loading`}function pf(e,t){var n=e.ownerDocument;if(e.data===`$~`)e._reactRetry=t;else if(e.data!==`$?`||n.readyState!==`loading`)t();else{var r=function(){t(),n.removeEventListener(`DOMContentLoaded`,r)};n.addEventListener(`DOMContentLoaded`,r),e._reactRetry=r}}function mf(e){for(;e!=null;e=e.nextSibling){var t=e.nodeType;if(t===1||t===3)break;if(t===8){if(t=e.data,t===`$`||t===`$!`||t===`$?`||t===`$~`||t===`&`||t===`F!`||t===`F`)break;if(t===`/$`||t===`/&`)return null}}return e}var hf=null;function gf(e){e=e.nextSibling;for(var t=0;e;){if(e.nodeType===8){var n=e.data;if(n===`/$`||n===`/&`){if(t===0)return mf(e.nextSibling);t--}else n!==`$`&&n!==`$!`&&n!==`$?`&&n!==`$~`&&n!==`&`||t++}e=e.nextSibling}return null}function _f(e){e=e.previousSibling;for(var t=0;e;){if(e.nodeType===8){var n=e.data;if(n===`$`||n===`$!`||n===`$?`||n===`$~`||n===`&`){if(t===0)return e;t--}else n!==`/$`&&n!==`/&`||t++}e=e.previousSibling}return null}function vf(e,t,n){switch(t=Kd(n),e){case`html`:if(e=t.documentElement,!e)throw Error(i(452));return e;case`head`:if(e=t.head,!e)throw Error(i(453));return e;case`body`:if(e=t.body,!e)throw Error(i(454));return e;default:throw Error(i(451))}}function yf(e){for(var t=e.attributes;t.length;)e.removeAttributeNode(t[0]);dt(e)}var bf=new Map,xf=new Set;function Sf(e){return typeof e.getRootNode==`function`?e.getRootNode():e.nodeType===9?e:e.ownerDocument}var Cf=O.d;O.d={f:nee,r:wf,D:Df,C:Of,L:kf,m:Af,X:Mf,S:jf,M:Nf};function nee(){var e=Cf.f(),t=wu();return e||t}function wf(e){var t=pt(e);t!==null&&t.tag===5&&t.type===`form`?Es(t):Cf.r(e)}var Tf=typeof document>`u`?null:document;function Ef(e,t,n){var r=Tf;if(r&&typeof t==`string`&&t){var i=Ft(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),xf.has(i)||(xf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Bd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Df(e){Cf.D(e),Ef(`dns-prefetch`,e,null)}function Of(e,t){Cf.C(e,t),Ef(`preconnect`,e,t)}function kf(e,t,n){Cf.L(e,t,n);var r=Tf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Ft(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Ft(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Ft(n.imageSizes)+`"]`)):i+=`[href="`+Ft(e)+`"]`;var a=i;switch(t){case`style`:a=Ff(e);break;case`script`:a=zf(e)}bf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),bf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(If(a))||t===`script`&&r.querySelector(Bf(a))||(t=r.createElement(`link`),Bd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Af(e,t){Cf.m(e,t);var n=Tf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Ft(r)+`"][href="`+Ft(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=zf(e)}if(!bf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),bf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Bf(a)))return}r=n.createElement(`link`),Bd(r,`link`,e),gt(r),n.head.appendChild(r)}}}function jf(e,t,n){Cf.S(e,t,n);var r=Tf;if(r&&e){var i=ht(r).hoistableStyles,a=Ff(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(If(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=bf.get(a))&&Uf(e,n);var c=o=r.createElement(`link`);gt(c),Bd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Hf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Mf(e,t){Cf.X(e,t);var n=Tf;if(n&&e){var r=ht(n).hoistableScripts,i=zf(e),a=r.get(i);a||(a=n.querySelector(Bf(i)),a||(e=h({src:e,async:!0},t),(t=bf.get(i))&&Wf(e,t),a=n.createElement(`script`),gt(a),Bd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nf(e,t){Cf.M(e,t);var n=Tf;if(n&&e){var r=ht(n).hoistableScripts,i=zf(e),a=r.get(i);a||(a=n.querySelector(Bf(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=bf.get(i))&&Wf(e,t),a=n.createElement(`script`),gt(a),Bd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Pf(e,t,n,r){var a=(a=fe.current)?Sf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Ff(n.href),n=ht(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Ff(n.href);var o=ht(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(If(e)))&&!o._p&&(s.instance=o,s.state.loading=5),bf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},bf.set(e,n),o||Rf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=zf(n),n=ht(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Ff(e){return`href="`+Ft(e)+`"`}function If(e){return`link[rel="stylesheet"][`+e+`]`}function Lf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Rf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Bd(t,`link`,n),gt(t),e.head.appendChild(t))}function zf(e){return`[src="`+Ft(e)+`"]`}function Bf(e){return`script[async]`+e}function Vf(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Ft(n.href)+`"]`);if(r)return t.instance=r,gt(r),r;var a=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),gt(r),Bd(r,`style`,a),Hf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Ff(n.href);var o=e.querySelector(If(a));if(o)return t.state.loading|=4,t.instance=o,gt(o),o;r=Lf(n),(a=bf.get(a))&&Uf(r,a),o=(e.ownerDocument||e).createElement(`link`),gt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Bd(o,`link`,r),t.state.loading|=4,Hf(o,n.precedence,e),t.instance=o;case`script`:return o=zf(n.src),(a=e.querySelector(Bf(o)))?(t.instance=a,gt(a),a):(r=n,(a=bf.get(o))&&(r=h({},n),Wf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),gt(a),Bd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Hf(r,n.precedence,e));return t.instance}function Hf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o<r.length;o++){var s=r[o];if(s.dataset.precedence===t)a=s;else if(a!==i)break}a?a.parentNode.insertBefore(e,a.nextSibling):(t=n.nodeType===9?n.head:n,t.insertBefore(e,t.firstChild))}function Uf(e,t){e.crossOrigin??=t.crossOrigin,e.referrerPolicy??=t.referrerPolicy,e.title??=t.title}function Wf(e,t){e.crossOrigin??=t.crossOrigin,e.referrerPolicy??=t.referrerPolicy,e.integrity??=t.integrity}var Gf=null;function Kf(e,t,n){if(Gf===null){var r=new Map,i=Gf=new Map;i.set(n,r)}else i=Gf,r=i.get(n),r||(r=new Map,i.set(n,r));if(r.has(e))return r;for(r.set(e,null),n=n.getElementsByTagName(e),i=0;i<n.length;i++){var a=n[i];if(!(a[ut]||a[rt]||e===`link`&&a.getAttribute(`rel`)===`stylesheet`)&&a.namespaceURI!==`http://www.w3.org/2000/svg`){var o=a.getAttribute(t)||``;o=e+o;var s=r.get(o);s?s.push(a):r.set(o,[a])}}return r}function qf(e,t,n){e=e.ownerDocument||e,e.head.insertBefore(n,t===`title`?e.querySelector(`head > title`):null)}function Jf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Yf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Ff(r.href),a=t.querySelector(If(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=$f.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,gt(a);return}a=t.ownerDocument||t,r=Lf(r),(i=bf.get(i))&&Uf(r,i),a=a.createElement(`link`),gt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Bd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=$f.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Zf=0;function Qf(e,t){return e.stylesheets&&e.count===0&&tp(e,e.stylesheets),0<e.count||0<e.imgCount?function(n){var r=setTimeout(function(){if(e.stylesheets&&tp(e,e.stylesheets),e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}},6e4+t);0<e.imgBytes&&Zf===0&&(Zf=62500*Ud());var i=setTimeout(function(){if(e.waitingForImages=!1,e.count===0&&(e.stylesheets&&tp(e,e.stylesheets),e.unsuspend)){var t=e.unsuspend;e.unsuspend=null,t()}},(e.imgBytes>Zf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function $f(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)tp(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ep=null;function tp(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ep=new Map,t.forEach(np,e),ep=null,$f.call(e))}function np(e,t){if(!(t.state.loading&4)){var n=ep.get(e);if(n)var r=n.get(null);else{n=new Map,ep.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a<i.length;a++){var o=i[a];(o.nodeName===`LINK`||o.getAttribute(`media`)!==`not all`)&&(n.set(o.dataset.precedence,o),r=o)}r&&n.set(null,r)}i=t.instance,o=i.getAttribute(`data-precedence`),a=n.get(o)||r,a===r&&n.set(null,i),n.set(o,i),this.count++,r=$f.bind(this),i.addEventListener(`load`,r),i.addEventListener(`error`,r),a?a.parentNode.insertBefore(i,a.nextSibling):(e=e.nodeType===9?e.head:e,e.insertBefore(i,e.firstChild)),t.state.loading|=4}}var rp={$$typeof:S,Provider:null,Consumer:null,_currentValue:k,_currentValue2:k,_threadCount:0};function ip(e,t,n,r,i,a,o,s,c){this.tag=1,this.containerInfo=e,this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.next=this.pendingContext=this.context=this.cancelPendingCommit=null,this.callbackPriority=0,this.expirationTimes=Ye(-1),this.entangledLanes=this.shellSuspendCounter=this.errorRecoveryDisabledLanes=this.expiredLanes=this.warmLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ye(0),this.hiddenUpdates=Ye(null),this.identifierPrefix=r,this.onUncaughtError=i,this.onCaughtError=a,this.onRecoverableError=o,this.pooledCache=null,this.pooledCacheLanes=0,this.formState=c,this.incompleteTransitions=new Map}function ap(e,t,n,r,i,a,o,s,c,l,u,d){return e=new ip(e,t,n,o,c,l,u,d,s),t=1,!0===a&&(t|=24),a=ii(3,null,null,t),e.current=a,a.stateNode=e,t=aa(),t.refCount++,e.pooledCache=t,t.refCount++,a.memoizedState={element:r,isDehydrated:n,cache:t},Ra(a),e}function op(e){return e?(e=ni,e):ni}function sp(e,t,n,r,i,a){i=op(i),r.context===null?r.context=i:r.pendingContext=i,r=Ba(t),r.payload={element:n},a=a===void 0?null:a,a!==null&&(r.callback=a),n=Va(e,r,t),n!==null&&(yu(n,e,t),Ha(n,e,t))}function cp(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var n=e.retryLane;e.retryLane=n!==0&&n<t?n:t}}function lp(e,t){cp(e,t),(e=e.alternate)&&cp(e,t)}function up(e){if(e.tag===13||e.tag===31){var t=$r(e,67108864);t!==null&&yu(t,e,67108864),lp(e,67108864)}}function dp(e){if(e.tag===13||e.tag===31){var t=_u();t=$e(t);var n=$r(e,t);n!==null&&yu(n,e,t),lp(e,t)}}var fp=!0;function pp(e,t,n,r){var i=D.T;D.T=null;var a=O.p;try{O.p=2,hp(e,t,n,r)}finally{O.p=a,D.T=i}}function mp(e,t,n,r){var i=D.T;D.T=null;var a=O.p;try{O.p=8,hp(e,t,n,r)}finally{O.p=a,D.T=i}}function hp(e,t,n,r){if(fp){var i=gp(r);if(i===null)kd(e,t,r,_p,n),Op(e,r);else if(Ap(i,e,t,n,r))r.stopPropagation();else if(Op(e,r),t&4&&-1<Dp.indexOf(e)){for(;i!==null;){var a=pt(i);if(a!==null)switch(a.tag){case 3:if(a=a.stateNode,a.current.memoizedState.isDehydrated){var o=L(a.pendingLanes);if(o!==0){var s=a;for(s.pendingLanes|=2,s.entangledLanes|=2;o;){var c=1<<31-Be(o);s.entanglements[1]|=c,o&=~c}cd(a),!(Bl&6)&&(au=Oe()+500,ld(0,!1))}}break;case 31:case 13:s=$r(a,2),s!==null&&yu(s,a,2),wu(),lp(a,2)}if(a=gp(r),a===null&&kd(e,t,r,_p,n),a===i)break;i=a}i!==null&&r.stopPropagation()}else kd(e,t,r,null,n)}}function gp(e){return e=Qt(e),vp(e)}var _p=null;function vp(e){if(_p=null,e=ft(e),e!==null){var t=c(e);if(t===null)e=null;else{var n=t.tag;if(n===13){if(e=u(t),e!==null)return e;e=null}else if(n===31){if(e=d(t),e!==null)return e;e=null}else if(n===3){if(t.stateNode.current.memoizedState.isDehydrated)return t.tag===3?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null)}}return _p=e,null}function yp(e){switch(e){case`beforetoggle`:case`cancel`:case`click`:case`close`:case`contextmenu`:case`copy`:case`cut`:case`auxclick`:case`dblclick`:case`dragend`:case`dragstart`:case`drop`:case`focusin`:case`focusout`:case`input`:case`invalid`:case`keydown`:case`keypress`:case`keyup`:case`mousedown`:case`mouseup`:case`paste`:case`pause`:case`play`:case`pointercancel`:case`pointerdown`:case`pointerup`:case`ratechange`:case`reset`:case`resize`:case`seeked`:case`submit`:case`toggle`:case`touchcancel`:case`touchend`:case`touchstart`:case`volumechange`:case`change`:case`selectionchange`:case`textInput`:case`compositionstart`:case`compositionend`:case`compositionupdate`:case`beforeblur`:case`afterblur`:case`beforeinput`:case`blur`:case`fullscreenchange`:case`focus`:case`hashchange`:case`popstate`:case`select`:case`selectstart`:return 2;case`drag`:case`dragenter`:case`dragexit`:case`dragleave`:case`dragover`:case`mousemove`:case`mouseout`:case`mouseover`:case`pointermove`:case`pointerout`:case`pointerover`:case`scroll`:case`touchmove`:case`wheel`:case`mouseenter`:case`mouseleave`:case`pointerenter`:case`pointerleave`:return 8;case`message`:switch(ke()){case Ae:return 2;case je:return 8;case Me:case Ne:return 32;case Pe:return 268435456;default:return 32}default:return 32}}var bp=!1,xp=null,Sp=null,Cp=null,wp=new Map,Tp=new Map,Ep=[],Dp=`mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset`.split(` `);function Op(e,t){switch(e){case`focusin`:case`focusout`:xp=null;break;case`dragenter`:case`dragleave`:Sp=null;break;case`mouseover`:case`mouseout`:Cp=null;break;case`pointerover`:case`pointerout`:wp.delete(t.pointerId);break;case`gotpointercapture`:case`lostpointercapture`:Tp.delete(t.pointerId)}}function kp(e,t,n,r,i,a){return e===null||e.nativeEvent!==a?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:a,targetContainers:[i]},t!==null&&(t=pt(t),t!==null&&up(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,i!==null&&t.indexOf(i)===-1&&t.push(i),e)}function Ap(e,t,n,r,i){switch(t){case`focusin`:return xp=kp(xp,e,t,n,r,i),!0;case`dragenter`:return Sp=kp(Sp,e,t,n,r,i),!0;case`mouseover`:return Cp=kp(Cp,e,t,n,r,i),!0;case`pointerover`:var a=i.pointerId;return wp.set(a,kp(wp.get(a)||null,e,t,n,r,i)),!0;case`gotpointercapture`:return a=i.pointerId,Tp.set(a,kp(Tp.get(a)||null,e,t,n,r,i)),!0}return!1}function jp(e){var t=ft(e.target);if(t!==null){var n=c(t);if(n!==null){if(t=n.tag,t===13){if(t=u(n),t!==null){e.blockedOn=t,tt(e.priority,function(){dp(n)});return}}else if(t===31){if(t=d(n),t!==null){e.blockedOn=t,tt(e.priority,function(){dp(n)});return}}else if(t===3&&n.stateNode.current.memoizedState.isDehydrated){e.blockedOn=n.tag===3?n.stateNode.containerInfo:null;return}}}e.blockedOn=null}function Mp(e){if(e.blockedOn!==null)return!1;for(var t=e.targetContainers;0<t.length;){var n=gp(e.nativeEvent);if(n===null){n=e.nativeEvent;var r=new n.constructor(n.type,n);Zt=r,n.target.dispatchEvent(r),Zt=null}else return t=pt(n),t!==null&&up(t),e.blockedOn=n,!1;t.shift()}return!0}function Np(e,t,n){Mp(e)&&n.delete(t)}function Pp(){bp=!1,xp!==null&&Mp(xp)&&(xp=null),Sp!==null&&Mp(Sp)&&(Sp=null),Cp!==null&&Mp(Cp)&&(Cp=null),wp.forEach(Np),Tp.forEach(Np)}function Fp(e,n){e.blockedOn===n&&(e.blockedOn=null,bp||(bp=!0,t.unstable_scheduleCallback(t.unstable_NormalPriority,Pp)))}var Ip=null;function Lp(e){Ip!==e&&(Ip=e,t.unstable_scheduleCallback(t.unstable_NormalPriority,function(){Ip===e&&(Ip=null);for(var t=0;t<e.length;t+=3){var n=e[t],r=e[t+1],i=e[t+2];if(typeof r!=`function`){if(vp(r||n)===null)continue;break}var a=pt(n);a!==null&&(e.splice(t,3),t-=3,ws(a,{pending:!0,data:i,method:n.method,action:r},r,i))}}))}function Rp(e){function t(t){return Fp(t,e)}xp!==null&&Fp(xp,e),Sp!==null&&Fp(Sp,e),Cp!==null&&Fp(Cp,e),wp.forEach(t),Tp.forEach(t);for(var n=0;n<Ep.length;n++){var r=Ep[n];r.blockedOn===e&&(r.blockedOn=null)}for(;0<Ep.length&&(n=Ep[0],n.blockedOn===null);)jp(n),n.blockedOn===null&&Ep.shift();if(n=(e.ownerDocument||e).$$reactFormReplay,n!=null)for(r=0;r<n.length;r+=3){var i=n[r],a=n[r+1],o=i[it]||null;if(typeof a==`function`)o||Lp(n);else if(o){var s=null;if(a&&a.hasAttribute(`formAction`)){if(i=a,o=a[it]||null)s=o.formAction;else if(vp(i)!==null)continue}else s=o.action;typeof s==`function`?n[r+1]=s:(n.splice(r,3),r-=3),Lp(n)}}}function zp(){function e(e){e.canIntercept&&e.info===`react-transition`&&e.intercept({handler:function(){return new Promise(function(e){return i=e})},focusReset:`manual`,scroll:`manual`})}function t(){i!==null&&(i(),i=null),r||setTimeout(n,20)}function n(){if(!r&&!navigation.transition){var e=navigation.currentEntry;e&&e.url!=null&&navigation.navigate(e.url,{state:e.getState(),info:`react-transition`,history:`replace`})}}if(typeof navigation==`object`){var r=!1,i=null;return navigation.addEventListener(`navigate`,e),navigation.addEventListener(`navigatesuccess`,t),navigation.addEventListener(`navigateerror`,t),setTimeout(n,100),function(){r=!0,navigation.removeEventListener(`navigate`,e),navigation.removeEventListener(`navigatesuccess`,t),navigation.removeEventListener(`navigateerror`,t),i!==null&&(i(),i=null)}}}function Bp(e){this._internalRoot=e}Vp.prototype.render=Bp.prototype.render=function(e){var t=this._internalRoot;if(t===null)throw Error(i(409));var n=t.current;sp(n,_u(),e,t,null,null)},Vp.prototype.unmount=Bp.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var t=e.containerInfo;sp(e.current,2,null,e,null,null),wu(),t[at]=null}};function Vp(e){this._internalRoot=e}Vp.prototype.unstable_scheduleHydration=function(e){if(e){var t=et();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Ep.length&&t!==0&&t<Ep[n].priority;n++);Ep.splice(n,0,e),n===0&&jp(e)}};var Hp=n.version;if(Hp!==`19.2.6`)throw Error(i(527,Hp,`19.2.6`));O.findDOMNode=function(e){var t=e._reactInternals;if(t===void 0)throw typeof e.render==`function`?Error(i(188)):(e=Object.keys(e).join(`,`),Error(i(268,e)));return e=p(t),e=e===null?null:m(e),e=e===null?null:e.stateNode,e};var Up={bundleType:0,version:`19.2.6`,rendererPackageName:`react-dom`,currentDispatcherRef:D,reconcilerVersion:`19.2.6`};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<`u`){var Wp=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Wp.isDisabled&&Wp.supportsFiber)try{Le=Wp.inject(Up),Re=Wp}catch{}}e.createRoot=function(e,t){if(!o(e))throw Error(i(299));var n=!1,r=``,a=qs,s=tee,c=Js;return t!=null&&(!0===t.unstable_strictMode&&(n=!0),t.identifierPrefix!==void 0&&(r=t.identifierPrefix),t.onUncaughtError!==void 0&&(a=t.onUncaughtError),t.onCaughtError!==void 0&&(s=t.onCaughtError),t.onRecoverableError!==void 0&&(c=t.onRecoverableError)),t=ap(e,1,!1,null,null,n,r,null,a,s,c,zp),e[at]=t.current,Dd(e),new Bp(t)}})),d=n(((e,t)=>{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=u()}));function f(e){return e===`♥`||e===`♦`?`红`:e===`♠`||e===`♣`?`黑`:`无色`}function p(e){return Math.max(0,e?.health??0)}var m=t((()=>{})),h=t((()=>{})),g=t((()=>{})),_=t((()=>{})),v=t((()=>{})),y=t((()=>{})),ee=t((()=>{})),b=t((()=>{m(),h(),g(),_(),v(),y(),ee()}));function x(e){let t=w.get(e);return t||(t={blockers:new Map},w.set(e,t)),t}function S(e,t,n){let r=`${t}:${++te}`;return x(e).blockers.set(r,n),()=>{x(e).blockers.delete(r)}}function C(e,t){let n=w.get(e);if(!n)return!1;for(let r of n.blockers.values())if(r(e,t))return!0;return!1}var w,te,ne=t((()=>{w=new WeakMap,te=0}));function T(e){let t=_e.get(e);return t||(t={actions:new Map,beforeHooks:new Map,afterHooks:new Map,judgeModifiers:new Map,instanceUnloads:new Map,lockedSkills:new Map,altResponseDecls:[]},_e.set(e,t)),t}function re(e,t,n){return`${e}:${t}:${n}`}function ie(e,t){return`${e}:${t}`}function ae(e,t){let n=e.pendingSlots.get(t);if(n?.isBlocking)return n;let r=[...e.pendingSlots.values()].find(e=>{let t=e.atom.target;return typeof t==`number`&&t<-1});if(r)return r;if(e.pendingSlots.size===1){let n=[...e.pendingSlots.values()][0],r=n.atom.target??n.atom.player;return typeof r==`number`&&r===t?n:void 0}}function E(e){for(let t of e.pendingSlots.values())if(t.isBlocking)return!0;return!1}function oe(e,t,n,r){if(e.currentPlayerIndex!==t)return`不是你的回合`;if(e.phase!==`出牌`)return`不是出牌阶段`;if(E(e))return`当前有等待响应`;let i=e.players[t];if(!i.alive)return`你已死亡`;let a=n.cardId;if(!a)return`cardId required`;if(!i.hand.includes(a))return`牌不在手牌中`;if(r?.cardName&&e.cardMap[a]?.name!==r.cardName)return`不是${r.cardName}`;let o=e.cardMap[a];if(o?.type===`锦囊牌`&&o.trickSubtype!==`延时锦囊`&&o.trickSubtype!==`响应锦囊`&&C(e,t))return`本回合不能使用锦囊牌`;if(r?.requireTarget){let e=n.targets;if(!Array.isArray(e)||e.length===0)return`target required`}return null}function se(e,t){let n=re(t.skillId,t.ownerId,t.actionType);T(e).actions.set(n,t)}function ce(e,t,n,r){return T(e).actions.get(re(t,n,r))}function D(e,t,n,r){T(e).actions.delete(re(t,n,r))}function O(e,t,n){let r=T(e),i=`${t}:${n}:`;for(let e of[...r.actions.keys()])e.startsWith(i)&&r.actions.delete(e);for(let e of[r.beforeHooks,r.afterHooks])for(let[r,i]of e){let a=i.filter(e=>!(e.skillId===t&&e.ownerId===n));a.length===0?e.delete(r):a.length!==i.length&&e.set(r,a)}r.judgeModifiers.get(n)?.skillId===t&&r.judgeModifiers.delete(n)}function k(e,t){return T(e).beforeHooks.get(t)??[]}function le(e,t){return T(e).afterHooks.get(t)??[]}function ue(e){return T(e).judgeModifiers}function de(e,t,n,r){let i={ownerId:t,atomType:n,requestType:r},a=T(e);return a.altResponseDecls.push(i),()=>{let e=a.altResponseDecls.indexOf(i);e>=0&&a.altResponseDecls.splice(e,1)}}function A(e,t,n,r){let i=T(e).altResponseDecls;for(let e of i)if(e.ownerId===n&&e.atomType===t&&!(e.requestType&&r&&e.requestType!==r))return!0;return!1}function j(e,t,n,r,i,a,o){return se(e,{skillId:t,ownerId:n,actionType:r,validate:i,execute:a,rollback:o}),()=>D(e,t,n,r)}function M(e,t,n,r,i){let a={skillId:t,ownerId:n,atomType:r,phase:`before`,handler:i},o=T(e),s=o.beforeHooks.get(r)??[];return s.push(a),o.beforeHooks.set(r,s),()=>{let e=o.beforeHooks.get(r);if(!e)return;let t=e.indexOf(a);t>=0&&e.splice(t,1)}}function N(e,t,n,r,i){let a={skillId:t,ownerId:n,atomType:r,phase:`after`,handler:i},o=T(e),s=o.afterHooks.get(r)??[];return s.push(a),o.afterHooks.set(r,s),()=>{let e=o.afterHooks.get(r);if(!e)return;let t=e.indexOf(a);t>=0&&e.splice(t,1)}}function fe(e,t,n,r){let i={skillId:t,ownerId:n,atomType:`判定`,phase:`after`,handler:r},a=T(e);return a.judgeModifiers.set(n,i),()=>{a.judgeModifiers.get(n)===i&&a.judgeModifiers.delete(n)}}function pe(e,t,n,r){T(e).instanceUnloads.set(ie(t,n),r)}function me(e,t,n){return T(e).instanceUnloads.get(ie(t,n))}function he(e,t,n){T(e).instanceUnloads.delete(ie(t,n))}function ge(e,t,n){T(e).lockedSkills.set(t,n)}function P(e,t){return T(e).lockedSkills.get(t)??!1}var _e,F=t((()=>{b(),ne(),_e=new WeakMap}));function ve(e,t){return e.players[t.target]?null:`target ${t.target} not found`}function ye(e,t,n){if(k(e,t).length===0)return{ownerViews:new Map,othersView:null};let r={type:t,source:n.source,target:n.target,amount:n.amount,damageType:n.damageType};return{ownerViews:new Map,othersView:r}}var be,xe,Se,Ce,we,Te,Ee,De,Oe,ke=t((()=>{F(),be=`__damageAmount`,xe=`__damageSource`,Se={type:`伤害结算开始时`,validate:ve,apply(){},async afterApply(e,t){e.localVars[be]=t.amount,e.localVars[xe]=t.source},toViewEvents(e,t){return ye(e,`伤害结算开始时`,t)},applyView(){}},Ce={type:`造成伤害时`,validate:ve,apply(){},async afterApply(e,t){e.localVars[be]=t.amount},toViewEvents(e,t){return ye(e,`造成伤害时`,t)},applyView(){}},we={type:`受到伤害时`,validate:ve,apply(){},async afterApply(e,t){e.localVars[be]=t.amount},toViewEvents(e,t){return ye(e,`受到伤害时`,t)},applyView(){}},Te={type:`造成伤害后`,validate:ve,apply(){},toViewEvents(e,t){return ye(e,`造成伤害后`,t)},applyView(){}},Ee={type:`受到伤害后`,validate:ve,apply(){},toViewEvents(e,t){return ye(e,`受到伤害后`,t)},applyView(){}},De={type:`伤害结算结束时`,validate:ve,apply(){},toViewEvents(e,t){return ye(e,`伤害结算结束时`,t)},applyView(){}},Oe={type:`伤害结算结束后`,validate:ve,apply(){},toViewEvents(e,t){return ye(e,`伤害结算结束后`,t)},applyView(){}}}));function Ae(e){let t=Ne.get(e);return t||(t={providers:new Set},Ne.set(e,t)),t}function je(e,t){let n=Ae(e);return n.providers.add(t),()=>{n.providers.delete(t)}}function Me(e,t,n){if(t<0||P(e,n))return!1;let r=Ae(e).providers;for(let i of r)if(i(e,t,n))return!0;return!1}var Ne,Pe=t((()=>{F(),Ne=new WeakMap}));function Fe(e){let t=new Map,n=(e,n)=>{let r=t.get(e);r===void 0&&(r=[],t.set(e,r)),r.push(n)};for(let t of e.zones.deck)n(t,`牌堆`);for(let t of e.zones.discardPile)n(t,`弃牌堆`);for(let t of e.zones.processing)n(t,`处理区`);for(let t of e.players){let e=`玩家${t.index}`;for(let r of t.hand)n(r,`${e}.手牌`);for(let r of Ie){let i=t.equipment[r];i!==void 0&&n(i,`${e}.装备(${r})`)}}for(let t=0;t<e.settlementStack.length;t++){let r=e.settlementStack[t],i=`结算帧[${t}](${r.skillId||`?`})`;for(let e of r.cards)n(e,i)}let r=[];for(let[n,i]of t)if(i.length>1){let t=e.cardMap[n]?.name??`?`;r.push(` ${n}(${t}) ×${i.length}: ${i.join(` / `)}`)}if(r.length>0)throw Error(`[牌唯一归属不变量] 检测到重复卡牌:\n${r.join(`
10+`)}`)}var Ie,Le=t((()=>{Ie=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`]}));function Re(e,t,n=!1){let r=e.config?.timeoutSec,i=864e5;return r===void 0?Math.min(t*1e3,i):r<=0?n?Math.min(t*1e3,i):i:Math.min(r*1e3,i)}var ze=t((()=>{}));function Be(e){return`target`in e&&typeof e.target==`number`?e.target:`player`in e&&typeof e.player==`number`?e.player:We}function Ve(e){e.viewBuffering||e.onStateChange?.()}function He(e,t){let n=Be(t.atom);e.seq+=1,e.atomHistory.push({kind:`notify`,seq:e.seq,timestamp:e.clock.now()-e.startedAt,skillId:``,eventType:`pendingResolved`,data:{target:n,atomType:t.atom.type}}),Ve(e)}function Ue(e,t){e.seq+=1,e.atomHistory.push({kind:`notify`,seq:e.seq,timestamp:e.clock.now()-e.startedAt,...t})}var We,Ge=t((()=>{b(),We=-1}));async function I(e,t,n,r){return await B(e,{type:`结算帧入栈`,skillId:t,from:n,params:r}),e.settlementStack[e.settlementStack.length-1]}async function L(e){await B(e,{type:`结算帧出栈`})}function Ke(e){return e.settlementStack[e.settlementStack.length-1]}function R(e){let t=e.settlementStack[e.settlementStack.length-1];return t?t.cards:e.zones.processing}function qe(){return{skillId:``,from:-1,params:Object.freeze({}),cards:[],cancelled:!1}}function Je(e,t,n){return e.settlementStack[e.settlementStack.length-1]?.cancelled===!0}function Ye(e,t,n){let r=e.settlementStack[e.settlementStack.length-1];r&&(r.cancelled=!1)}var z=t((()=>{b(),V()}));function Xe(e,t){if(e.length<=1)return[...e];let n=t.currentPlayerIndex,r=t.players.length;return[...e].sort((e,t)=>{let i=e.ownerId<0,a=t.ownerId<0;return i&&a?0:i?1:a?-1:(e.ownerId-n+r)%r-(t.ownerId-n+r)%r})}async function Ze(e,t){let n=Xe(le(e,t.type),e);for(let r of n){if(Me(e,r.ownerId,r.skillId))continue;let n=Ke(e)??qe(),i={state:e,atom:t,ownerId:r.ownerId,frame:n,params:n.params};await r.handler(i)}}async function Qe(e){let t=e.atomStack[e.atomStack.length-1];if(!t)return;let n=t.player;if(typeof n!=`number`)return;let r=ue(e);if(r.size===0)return;let i=e.players.length;for(let a=0;a<i;a++){let o=(n-a+i)%i,s=r.get(o);if(!s||!e.players[o]?.alive)continue;let c=Ke(e)??qe(),l={state:e,atom:t,ownerId:s.ownerId,frame:c,params:c.params};await s.handler(l)}}async function B(e,t){e.atomStack.push(t);let n=t,r=!1,i=Xe(k(e,t.type),e);for(let t of i){if(Me(e,t.ownerId,t.skillId))continue;let i=Ke(e)??qe(),a={state:e,atom:n,ownerId:t.ownerId,frame:i,params:i.params},o=await t.handler(a);if(o!==void 0){if(o.kind===`cancel`){r=!0;break}o.kind===`modify`&&(n=o.atom)}}if(r)return e.atomStack.pop(),Ue(e,{skillId:``,eventType:`atomCancelled`,data:{atomType:t.type}}),Ve(e),!1;let a=Zp(n.type),o=a.validate(e,n);if(o!==null)throw e.atomStack.pop(),Error(`applyAtom validate 失败: ${n.type} → ${o}`);let s=lee(e,n);if(cee(e,n),e.seq+=1,e.atomHistory.push({kind:`atom`,seq:e.seq,timestamp:e.clock.now()-e.startedAt,atom:n,viewEvents:s}),a.pending){let t,r,i=a.parallelSplit?.(n);i&&i.length>0?(t=i.map(e=>e.target),r=i.map(e=>e.slotAtom)):(t=[Be(n)],r=[n]);let o=a.pending.preResolve?.(e,n)??null,s=o===`skip`,c=!s&&o&&typeof o==`object`?o.delayMs:void 0;if(s)Ve(e);else{let i=[];for(let o=0;o<r.length;o++){let s=r[o],l=t[o],u=s.type===n.type?a:Zp(s.type);i.push($e(e,s,u,l,c))}await Promise.all(i)}return a.afterApply&&await a.afterApply(e,n),await Ze(e,n),a.afterHooks&&a.afterHooks(e,n),e.atomStack.pop(),e.assertInvariants&&Fe(e),!0}return Ve(e),a.afterApply&&await a.afterApply(e,n),await Ze(e,n),a.afterHooks&&a.afterHooks(e,n),e.atomStack.pop(),e.assertInvariants&&Fe(e),!0}function $e(e,t,n,r,i){return new Promise(a=>{let o=n.pending,s=t.timeout,c=typeof s==`number`?s:o.timeout,l=i??Re(e,c,r<0),u=!1,d=!1,f=!1,p=()=>{u||(u=!0,g(),a())},m={atom:t,definition:n,startTime:e.clock.now()-e.startedAt,deadline:e.clock.now()-e.startedAt+l,resolvedTimeoutMs:l,createdSeq:e.seq,isBlocking:o.isBlocking!==!1,resolve:p,get isTimeout(){return d},get isPaused(){return f},pause(){d||(f=!0,g())}},h=async()=>{if(e.pendingSlots.get(r)===m&&!f){d=!0,g();try{await o.onTimeout(e,t),Ve(e)}finally{let t=!1;e.pendingSlots.get(r)===m&&(e.pendingSlots.delete(r),t=!0),t&&He(e,m),p()}}};m._fireTimeoutNow=h;let g=e.clock.schedule(l,h);e.pendingSlots.set(r,m),Ve(e),e.onExecuteSettle?.(),e.onExecuteSettle=null})}var V=t((()=>{Qp(),F(),Pe(),Le(),ze(),Ge(),z()}));function et(e,t){if(e.zones.deck.includes(t))return{zone:`牌堆`};if(e.zones.discardPile.includes(t))return{zone:`弃牌堆`};if(e.zones.processing.includes(t))return{zone:`处理区`};for(let n of e.settlementStack)if(n.cards.includes(t))return{zone:`处理区`};for(let n of e.players){if(n.hand.includes(t))return{zone:`手牌`,player:n.index};for(let e of[`武器`,`防具`,`进攻马`,`防御马`,`宝物`])if(n.equipment[e]===t)return{zone:`装备`,player:n.index}}return null}async function tt(e,t,n){et(e,n)===null&&await B(e,{type:`弃置`,player:t,cardIds:[n]})}async function nt(e,t,n,r){let i=et(e,n);if(i===null){await B(e,{type:`获得`,player:r,cardId:n,from:t});return}i.zone===`弃牌堆`&&await B(e,{type:`移动牌`,cardId:n,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:r}})}var rt=t((()=>{V()}));function it(e,t){return e.players[t.player]?null:`player ${t.player} not found`}function at(e,t,n){if(k(e,t).length===0)return{ownerViews:new Map,othersView:null};let r={type:t,player:n.player,killer:n.killer};return{ownerViews:new Map,othersView:r}}function ot(e,t){return e.players[t.target]?null:`target ${t.target} not found`}var st,ct,lt,ut,dt,ft,pt,mt=t((()=>{F(),rt(),st={type:`亮身份牌前`,validate:it,apply(){},toViewEvents(e,t){if(k(e,`亮身份牌前`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`亮身份牌前`,player:t.player};return{ownerViews:new Map,othersView:n}},applyView(){}},ct={type:`亮身份牌`,validate:it,apply(){},effect:{sound:`death`,animation:`fade`,duration:1500,vfx:`card/killer`},toViewEvents(e,t){let n=e.players[t.player]?.identity,r={type:`亮身份牌`,player:t.player,identity:n};return{ownerViews:new Map,othersView:r}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n>=0){let r=t.identity;r&&(e.players[n].identity=r,e.players[n].identityHidden=!1)}}},lt={type:`死亡时`,validate:it,apply(){},toViewEvents(e,t){return at(e,`死亡时`,t)},applyView(){}},ut={type:`系统处理牌`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.alive=!1;for(let t of n.hand)e.zones.discardPile.push(t);n.hand=[];for(let t of Object.keys(n.equipment)){let r=n.equipment[t];r&&(e.zones.discardPile.push(r),delete n.equipment[t])}for(let t of n.pendingTricks)et(e,t.card.id)===null&&e.zones.discardPile.push(t.card.id);n.pendingTricks=[]},effect:{animation:`fade`,duration:1500},toViewEvents(e,t){let n=e.players[t.player]?.character,r=(e.players[t.player]?.pendingTricks??[]).filter(t=>et(e,t.card.id)===null).length,i={type:`系统处理牌`,player:t.player,trickDiscardCount:r,...n?{effect:{sound:`death/${n}`}}:{}};return{ownerViews:new Map,othersView:i}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n>=0){let r=e.players[n],i=r.handCount,a=Object.values(r.equipment).filter(Boolean).length,o=typeof t.trickDiscardCount==`number`?t.trickDiscardCount:r.pendingTricks?.length??0;e.zones&&(e.zones.discardPileCount+=i+a+o),r.alive=!1,e.viewer===t.player&&(r.hand=[]),r.handCount=0,r.equipment={},r.pendingTricks=[]}},toViewLog(e){return{player:e.player,text:`阵亡`}}},dt={type:`死亡后`,validate:it,apply(){},toViewEvents(e,t){return at(e,`死亡后`,t)},applyView(){}},ft={type:`进入濒死状态时`,validate:ot,apply(){},toViewEvents(e,t){if(k(e,`进入濒死状态时`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`进入濒死状态时`,target:t.target};return{ownerViews:new Map,othersView:n}},applyView(){}},pt={type:`新的濒死状态时`,validate:ot,apply(){},toViewEvents(e,t){if(k(e,`新的濒死状态时`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`新的濒死状态时`,target:t.target};return{ownerViews:new Map,othersView:n}},applyView(){}}}));function ht(e,t){return e.players[t.player]?null:`player ${t.player} not found`}function gt(e,t){return e.players[t.player]?t.cardId!==void 0&&!e.cardMap[t.cardId]?`card ${t.cardId} not found`:null:`player ${t.player} not found`}function _t(e,t,n){if(k(e,t).length===0)return{ownerViews:new Map,othersView:null};let r={type:t,player:n.player,judgeType:n.judgeType};return n.cardId!==void 0&&(r.cardId=n.cardId),{ownerViews:new Map,othersView:r}}var vt,yt,bt,xt=t((()=>{V(),F(),vt={type:`判定时`,validate:ht,apply(){},toViewEvents(e,t){return _t(e,`判定时`,t)},applyView(){}},yt={type:`判定牌生效前`,validate:gt,apply(){},async afterApply(e){await Qe(e)},toViewEvents(e,t){return _t(e,`判定牌生效前`,t)},applyView(){}},bt={type:`判定牌生效后`,validate:gt,apply(){},toViewEvents(e,t){return _t(e,`判定牌生效后`,t)},applyView(){}}}));function St(e,t){if(`target`in t){if(!e.players[t.target])return`target ${t.target} not found`}else if(!e.players[t.player])return`player ${t.player} not found`;return null}function Ct(e,t,n){if(k(e,t).length===0)return{ownerViews:new Map,othersView:null};let r=`target`in n?{type:t,target:n.target,amount:n.amount,...`source`in n?{source:n.source}:{}}:{type:t,player:n.player};return{ownerViews:new Map,othersView:r}}function wt(){}var Tt,Et,Dt,Ot,kt,At,jt,Mt,Nt,Pt,Ft,It=t((()=>{F(),Tt={type:`扣减体力`,validate(e,t){if(t.amount<0)return`amount must be >= 0`;let n=e.players[t.target];return n?n.alive?null:`target ${t.target} is dead`:`target ${t.target} not found`},apply(e,t){let n=e.players[t.target];n.health-=t.amount},effect:{sound:`injure_1`,animation:`shake`,particles:`blood`,duration:800},toViewEvents(e,t){let n={type:`扣减体力`,target:t.target,amount:t.amount,effect:{sound:`injure_${Math.min(Math.max(t.amount,1),3)}`,vfx:`card/damage`}};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.target);if(n<0)return;let r=e.players[n];r.health-=t.amount},toViewLog(e){return{player:e.target,text:`扣减 ${e.amount??0} 点体力`}}},Et=`__modifyAmount`,Dt={type:`确定回复数值时`,validate:St,apply(e,t){e.localVars[Et]=t.amount},toViewEvents(e,t){return Ct(e,`确定回复数值时`,t)},applyView:wt},Ot={type:`回复体力后`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`回复体力后`,t)},applyView:wt},kt={type:`失去体力时`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`失去体力时`,t)},applyView:wt},At={type:`失去体力后`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`失去体力后`,t)},applyView:wt},jt={type:`扣减体力前`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`扣减体力前`,t)},applyView:wt},Mt={type:`扣减体力时`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`扣减体力时`,t)},applyView:wt},Nt={type:`扣减体力后`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`扣减体力后`,t)},applyView:wt},Pt={type:`减上限后`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`减上限后`,t)},applyView:wt},Ft={type:`加上限后`,validate:St,apply(){},toViewEvents(e,t){return Ct(e,`加上限后`,t)},applyView:wt}}));function Lt(e,t){return e.cardMap[t.cardId]?null:`card ${t.cardId} not found`}function Rt(e,t,n){if(k(e,t).length===0)return{ownerViews:new Map,othersView:null};let r={type:t,cardId:n.cardId,from:n.from,to:n.to,reason:n.reason};return{ownerViews:new Map,othersView:r}}var zt,Bt,Vt,Ht=t((()=>{F(),zt=`__moveTo`,Bt={type:`移动到目标区域前`,validate:Lt,apply(){},async afterApply(e,t){e.localVars[zt]=t.to},toViewEvents(e,t){return Rt(e,`移动到目标区域前`,t)},applyView(){}},Vt={type:`移动到目标区域后`,validate:Lt,apply(){},toViewEvents(e,t){return Rt(e,`移动到目标区域后`,t)},applyView(){}}}));function Ut(e,t){return e.players[t.initiator]?e.players[t.target]?null:`target ${t.target} not found`:`initiator ${t.initiator} not found`}function Wt(e){return e?{name:e.name,suit:e.suit,rank:e.rank}:null}var Gt,Kt,qt,Jt=t((()=>{F(),Gt={type:`拼点扣置`,validate:Ut,apply(e,t){let n=e.settlementStack[e.settlementStack.length-1],r=n?n.cards:e.zones.processing,i=[{player:t.initiator,cardId:t.initiatorCard},{player:t.target,cardId:t.targetCard}];for(let{player:t,cardId:n}of i){if(!n)continue;let i=e.players[t];i&&(i.hand=i.hand.filter(e=>e!==n),r.push(n))}},effect:{sound:`flip`,animation:`flip`,duration:800},toViewEvents(e,t){let n=Wt(e.cardMap[t.initiatorCard]),r=Wt(e.cardMap[t.targetCard]),i={type:`拼点扣置`,initiator:t.initiator,target:t.target,initiatorCard:t.initiatorCard,targetCard:t.targetCard,effect:{sound:`flip`,animation:`flip`,duration:800}},a={...i,initiatorCardFace:n},o={...i,targetCardFace:r},s={...i};return{ownerViews:new Map([[t.initiator,a],[t.target,o]]),othersView:s}},applyView(e,t){let n=t.initiator,r=t.target,i=t.initiatorCard,a=t.targetCard,o=(t,n)=>{let r=e.players.findIndex(e=>e.index===t);r<0||(e.players[r].handCount=Math.max(0,e.players[r].handCount-1),n&&e.players[r].hand&&(e.players[r].hand=e.players[r].hand.filter(e=>e.id!==n)))};o(n,i),o(r,a),e.zones&&(i&&e.zones.processing.push(i),a&&e.zones.processing.push(a));let s=e.settlementStack[e.settlementStack.length-1];s&&(i&&s.cards.push(i),a&&s.cards.push(a))},toViewLog(e,t){let n=e.initiator,r=e.target,i=t===n?e.initiatorCardFace:t===r?e.targetCardFace:void 0;return i?{player:n,text:`拼点:扣置 ${i.suit}${i.rank}(面朝下)`}:{player:n,text:`拼点:扣置一张牌(面朝下)`}}},Kt={type:`拼点亮出`,validate:Ut,apply(){},effect:{sound:`flip`,animation:`flip`,duration:600},toViewEvents(e,t){let n={type:`拼点亮出`,initiator:t.initiator,target:t.target,initiatorCard:t.initiatorCard,targetCard:t.targetCard,initiatorCardFace:Wt(e.cardMap[t.initiatorCard]),targetCardFace:Wt(e.cardMap[t.targetCard]),effect:{sound:`flip`,animation:`flip`,duration:600}};return{ownerViews:new Map,othersView:n}},applyView(){},toViewLog(e){let t=e.initiatorCardFace,n=e.targetCardFace,r=e.initiator,i=e.target;return{player:r,text:`拼点亮出:${t?`${t.suit}${t.rank}`:`?`} vs ${n?`${n.suit}${n.rank}`:`?`}(目标 ${i})`}}},qt={type:`拼点后`,validate(e,t){return e.players[t.initiator]?e.players[t.target]?null:`target ${t.target} not found`:`initiator ${t.initiator} not found`},apply(){},toViewEvents(e,t){if(k(e,`拼点后`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`拼点后`,initiator:t.initiator,target:t.target,initiatorCard:t.initiatorCard,targetCard:t.targetCard,result:t.result};return{ownerViews:new Map,othersView:n}},applyView(){}}}));function Yt(e,t){return e.players[t]?null:`player ${t} not found`}function Xt(e,t,n){return k(e,t).length===0?{ownerViews:new Map,othersView:null}:{ownerViews:new Map,othersView:{type:t,player:n}}}var Zt,Qt,$t,en,tn,nn=t((()=>{F(),Zt={type:`翻面后`,validate(e,t){return Yt(e,t.player)},apply(){},toViewEvents(e,t){if(k(e,`翻面后`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`翻面后`,player:t.player,faceDown:t.faceDown};return{ownerViews:new Map,othersView:n}},applyView(){}},Qt={type:`横置后`,validate(e,t){return Yt(e,t.player)},apply(){},toViewEvents(e,t){if(k(e,`横置后`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`横置后`,player:t.player,chained:t.chained};return{ownerViews:new Map,othersView:n}},applyView(){}},$t={type:`武将牌明置后`,validate(e,t){return Yt(e,t.player)},apply(){},toViewEvents(e,t){return Xt(e,`武将牌明置后`,t.player)},applyView(){}},en={type:`武将牌移除后`,validate(e,t){return Yt(e,t.player)},apply(){},toViewEvents(e,t){return Xt(e,`武将牌移除后`,t.player)},applyView(){}},tn={type:`游戏牌亮出后`,validate(e,t){return e.players[t.player]?e.cardMap[t.cardId]?null:`card ${t.cardId} not found`:`player ${t.player} not found`},apply(){},toViewEvents(e,t){if(k(e,`游戏牌亮出后`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`游戏牌亮出后`,player:t.player,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){}}}));function rn(e){let t=e.players.length;if(t===0)return{nextIdx:0,roundIncrement:!1};let n=e.currentPlayerIndex,r=(n+1)%t,i=t;for(;!e.players[r].alive&&i>0;)r=(r+1)%t,i--;return{nextIdx:r,roundIncrement:r<=n}}var an,on=t((()=>{an={type:`下一玩家`,validate(){return null},apply(e){let{nextIdx:t,roundIncrement:n}=rn(e);n&&(e.turn.round+=1),e.currentPlayerIndex=t},toViewEvents(e,t){let{nextIdx:n}=rn(e);return{ownerViews:new Map,othersView:{type:`下一玩家`,newPlayer:n}}},applyView(e,t){e.currentPlayerIndex=t.newPlayer},toViewLog(){return null}}})),sn,cn=t((()=>{sn={type:`使用时`,validate(e,t){return e.players[t.source]?null:`source ${t.source} not found`},apply(){},effect:{animation:`highlight`,duration:600},toViewEvents(e,t){let n=e.cardMap[t.cardId]?.name??t.cardId,r={type:`使用时`,source:t.source,cardId:t.cardId,cardName:n,effect:{sound:`card/${n}`,animation:`highlight`,duration:600}};return{ownerViews:new Map,othersView:r}},applyView(){}}})),ln,un=t((()=>{F(),ln={type:`使用结算结束后`,validate(e,t){return e.players[t.source]?null:`source ${t.source} not found`},apply(){},toViewEvents(e,t){if(k(e,`使用结算结束后`).length===0&&le(e,`使用结算结束后`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`使用结算结束后`,source:t.source,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){}}})),dn,fn=t((()=>{F(),dn={type:`使用结算结束时`,validate(e,t){return e.players[t.target]?null:`target ${t.target} not found`},apply(){},toViewEvents(e,t){if(k(e,`使用结算结束时`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`使用结算结束时`,source:t.source,target:t.target,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){}}})),pn,mn,hn=t((()=>{V(),ze(),pn=50,mn={type:`出牌窗口`,validate(e,t){return e.players[t.player]?null:`player not found`},apply(e){},pending:{async onTimeout(e,t){await B(e,{type:`阶段结束`,player:t.player,phase:`出牌`})},prompt:{type:`confirm`,title:`出牌阶段`,cancelLabel:`结束回合`},timeout:pn,isBlocking:!1},effect:{blockUntilDone:!0,duration:200},toViewEvents(e,t){let n=Re(e,pn),r={type:`出牌窗口`,player:t.player,timeoutMs:n},i={type:`出牌窗口`,player:t.player,timeoutMs:n};return{ownerViews:new Map([[t.player,r]]),othersView:i}},applyView(e,t){let n=t.player,r=t.timeoutMs??pn*1e3;e.viewer===n?e.pending={type:`awaits`,atom:{type:`出牌窗口`,player:n},prompt:{type:`confirm`,title:`出牌阶段`,cancelLabel:`结束回合`},target:n,isBlocking:!1,deadline:Date.now()+r,totalMs:r}:e.pending={type:`awaits`,atom:{type:`出牌窗口`,player:n},prompt:{type:`confirm`,title:`等待出牌`,cancelLabel:``},target:n,isBlocking:!1,deadline:Date.now()+r,totalMs:r}}}})),gn,_n=t((()=>{gn={name:`曹操`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`奸雄`,path:`../../skills/奸雄`},{name:`护驾`,path:`../../skills/护驾`}]}})),vn,yn=t((()=>{vn={name:`司马懿`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`反馈`,path:`../../skills/反馈`},{name:`鬼才`,path:`../../skills/鬼才`}]}})),bn,xn=t((()=>{bn={name:`夏侯惇`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`刚烈`,path:`../../skills/刚烈`}]}})),Sn,Cn=t((()=>{Sn={name:`张辽`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`突袭`,path:`../../skills/突袭`}]}})),wn,Tn=t((()=>{wn={name:`许褚`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`裸衣`,path:`../../skills/裸衣`}]}})),En,Dn=t((()=>{En={name:`郭嘉`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`天妒`,path:`../../skills/天妒`},{name:`遗计`,path:`../../skills/遗计`}]}})),On,kn=t((()=>{On={name:`甄姬`,maxHealth:3,gender:`女`,faction:`魏`,skills:[{name:`倾国`,path:`../../skills/倾国`},{name:`洛神`,path:`../../skills/洛神`}]}})),An,eee=t((()=>{An={name:`夏侯渊`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`神速`,path:`../../skills/神速`}]}})),jn,Mn=t((()=>{jn={name:`曹仁`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`据守`,path:`../../skills/据守`}]}})),Nn,Pn=t((()=>{Nn={name:`荀彧`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`驱虎`,path:`../../skills/驱虎`},{name:`节命`,path:`../../skills/节命`}]}})),Fn,In=t((()=>{Fn={name:`典韦`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`强袭`,path:`../../skills/强袭`}]}})),Ln,Rn=t((()=>{Ln={name:`曹丕`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`行殇`,path:`../../skills/行殇`},{name:`放逐`,path:`../../skills/放逐`},{name:`颂威`,path:`../../skills/颂威`}]}})),zn,Bn=t((()=>{zn={name:`徐晃`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`断粮`,path:`../../skills/断粮`}]}})),Vn,Hn=t((()=>{Vn={name:`张郃`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`巧变`,path:`../../skills/巧变`}]}})),Un,Wn=t((()=>{Un={name:`邓艾`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`屯田`,path:`../../skills/屯田`},{name:`凿险`,path:`../../skills/凿险`}]}})),Gn,Kn=t((()=>{Gn={name:`界曹操`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界奸雄`,path:`../../skills/界奸雄`},{name:`界护驾`,path:`../../skills/界护驾`}]}})),qn,Jn=t((()=>{qn={name:`界司马懿`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`反馈`,path:`../../skills/反馈`},{name:`界鬼才`,path:`../../skills/界鬼才`}]}})),Yn,Xn=t((()=>{Yn={name:`界夏侯惇`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界刚烈`,path:`../../skills/界刚烈`}]}})),Zn,Qn=t((()=>{Zn={name:`界张辽`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界突袭`,path:`../../skills/界突袭`}]}})),$n,er=t((()=>{$n={name:`界许褚`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界裸衣`,path:`../../skills/界裸衣`}]}})),tr,nr=t((()=>{tr={name:`界郭嘉`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`天妒`,path:`../../skills/天妒`},{name:`界遗计`,path:`../../skills/界遗计`}]}})),rr,ir=t((()=>{rr={name:`界甄姬`,maxHealth:3,gender:`女`,faction:`魏`,skills:[{name:`倾国`,path:`../../skills/倾国`},{name:`界洛神`,path:`../../skills/界洛神`}]}})),ar,or=t((()=>{ar={name:`界夏侯渊`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界神速`,path:`../../skills/界神速`}]}})),sr,cr=t((()=>{sr={name:`界曹仁`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界据守`,path:`../../skills/界据守`},{name:`解围`,path:`../../skills/解围`}]}})),lr,ur=t((()=>{lr={name:`界荀彧`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`驱虎`,path:`../../skills/驱虎`},{name:`界节命`,path:`../../skills/界节命`}]}})),dr,fr=t((()=>{dr={name:`界典韦`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界强袭`,path:`../../skills/界强袭`}]}})),pr,mr=t((()=>{pr={name:`界曹丕`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`行殇`,path:`../../skills/行殇`},{name:`界放逐`,path:`../../skills/界放逐`},{name:`颂威`,path:`../../skills/颂威`}]}})),hr,gr=t((()=>{hr={name:`界徐晃`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界断粮`,path:`../../skills/界断粮`},{name:`截辎`,path:`../../skills/截辎`}]}})),_r,vr=t((()=>{_r={name:`界张郃`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界巧变`,path:`../../skills/界巧变`}]}})),yr,br=t((()=>{yr={name:`界邓艾`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界屯田`,path:`../../skills/界屯田`},{name:`界凿险`,path:`../../skills/界凿险`},{name:`急袭`,path:`../../skills/急袭`}]}})),xr,Sr=t((()=>{xr={name:`界于禁`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界镇军`,path:`../../skills/界镇军`},{name:`界毅重`,path:`../../skills/界毅重`}]}})),Cr,wr=t((()=>{Cr={name:`界张春华`,maxHealth:3,gender:`女`,faction:`魏`,skills:[{name:`界绝情`,path:`../../skills/界绝情`},{name:`界伤逝`,path:`../../skills/界伤逝`},{name:`界翦灭`,path:`../../skills/界翦灭`}]}})),Tr,Er=t((()=>{Tr={name:`界曹冲`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`界称象`,path:`../../skills/界称象`},{name:`界仁心`,path:`../../skills/界仁心`}]}})),Dr,Or=t((()=>{Dr={name:`界曹彰`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界将驰`,path:`../../skills/界将驰`}]}})),kr,Ar=t((()=>{kr={name:`界曹植`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`界落英`,path:`../../skills/界落英`},{name:`界酒诗`,path:`../../skills/界酒诗`}]}})),jr,Mr=t((()=>{jr={name:`界李典`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`界恂恂`,path:`../../skills/界恂恂`},{name:`界忘隙`,path:`../../skills/界忘隙`}]}})),Nr,Pr=t((()=>{Nr={name:`界王异`,maxHealth:3,gender:`女`,faction:`魏`,skills:[{name:`界贞烈`,path:`../../skills/界贞烈`},{name:`界秘计`,path:`../../skills/界秘计`}]}})),Fr,Ir=t((()=>{Fr={name:`界郭淮`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`界精策`,path:`../../skills/界精策`}]}})),Lr,Rr=t((()=>{Lr={name:`界郭皇后`,maxHealth:3,gender:`女`,faction:`魏`,skills:[{name:`界矫诏`,path:`../../skills/界矫诏`},{name:`界殚心`,path:`../../skills/界殚心`}]}})),zr,Br=t((()=>{zr={name:`刘备`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`仁德`,path:`../../skills/仁德`},{name:`激将`,path:`../../skills/激将`}]}})),Vr,Hr=t((()=>{Vr={name:`界刘备`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界仁德`,path:`../../skills/界仁德`},{name:`界激将`,path:`../../skills/界激将`}]}})),Ur,Wr=t((()=>{Ur={name:`关羽`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`武圣`,path:`../../skills/武圣`}]}})),Gr,Kr=t((()=>{Gr={name:`界关羽`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界武圣`,path:`../../skills/界武圣`},{name:`义绝`,path:`../../skills/义绝`}]}})),qr,Jr=t((()=>{qr={name:`张飞`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`咆哮`,path:`../../skills/咆哮`}]}})),Yr,Xr=t((()=>{Yr={name:`界张飞`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界咆哮`,path:`../../skills/界咆哮`}]}})),Zr,Qr=t((()=>{Zr={name:`赵云`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`龙胆`,path:`../../skills/龙胆`}]}})),$r,ei=t((()=>{$r={name:`界赵云`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界龙胆`,path:`../../skills/界龙胆`},{name:`涯角`,path:`../../skills/涯角`}]}})),ti,ni=t((()=>{ti={name:`诸葛亮`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`观星`,path:`../../skills/观星`},{name:`空城`,path:`../../skills/空城`}]}})),ri,ii=t((()=>{ri={name:`界诸葛亮`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`界观星`,path:`../../skills/界观星`},{name:`界空城`,path:`../../skills/界空城`}]}})),ai,oi=t((()=>{ai={name:`黄月英`,maxHealth:3,gender:`女`,faction:`蜀`,skills:[{name:`集智`,path:`../../skills/集智`},{name:`奇才`,path:`../../skills/奇才`}]}})),si,ci=t((()=>{si={name:`界黄月英`,maxHealth:3,gender:`女`,faction:`蜀`,skills:[{name:`界集智`,path:`../../skills/界集智`},{name:`界奇才`,path:`../../skills/界奇才`}]}})),li,ui=t((()=>{li={name:`马超`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`马术`,path:`../../skills/马术`},{name:`铁骑`,path:`../../skills/铁骑`}]}})),di,fi=t((()=>{di={name:`界马超`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`马术`,path:`../../skills/马术`},{name:`界铁骑`,path:`../../skills/界铁骑`}]}})),pi,mi=t((()=>{pi={name:`界马岱`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`马术`,path:`../../skills/马术`},{name:`界潜袭`,path:`../../skills/界潜袭`}]}})),hi,gi=t((()=>{hi={name:`黄忠`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`烈弓`,path:`../../skills/烈弓`}]}})),_i,vi=t((()=>{_i={name:`界黄忠`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界烈弓`,path:`../../skills/界烈弓`}]}})),yi,bi=t((()=>{yi={name:`魏延`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`狂骨`,path:`../../skills/狂骨`}]}})),xi,Si=t((()=>{xi={name:`界魏延`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界狂骨`,path:`../../skills/界狂骨`},{name:`奇谋`}]}})),Ci,wi=t((()=>{Ci={name:`卧龙诸葛`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`八阵`,path:`../../skills/八阵`},{name:`火计`,path:`../../skills/火计`},{name:`看破`,path:`../../skills/看破`}]}})),Ti,Ei=t((()=>{Ti={name:`界卧龙诸葛`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`八阵`,path:`../../skills/八阵`},{name:`界火计`,path:`../../skills/界火计`},{name:`界看破`,path:`../../skills/界看破`}]}})),Di,Oi=t((()=>{Di={name:`庞统`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`连环`,path:`../../skills/连环`},{name:`涅槃`,path:`../../skills/涅槃`}]}})),ki,Ai=t((()=>{ki={name:`界庞统`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`界连环`,path:`../../skills/界连环`},{name:`界涅槃`,path:`../../skills/界涅槃`}]}})),ji,Mi=t((()=>{ji={name:`孟获`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`祸首`,path:`../../skills/祸首`},{name:`再起`,path:`../../skills/再起`}]}})),Ni,Pi=t((()=>{Ni={name:`界孟获`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`祸首`,path:`../../skills/祸首`},{name:`界再起`,path:`../../skills/界再起`}]}})),Fi,Ii=t((()=>{Fi={name:`祝融`,maxHealth:4,gender:`女`,faction:`蜀`,skills:[{name:`巨象`,path:`../../skills/巨象`},{name:`烈刃`,path:`../../skills/烈刃`}]}})),Li,Ri=t((()=>{Li={name:`界祝融`,maxHealth:4,gender:`女`,faction:`蜀`,skills:[{name:`巨象`,path:`../../skills/巨象`},{name:`烈刃`,path:`../../skills/烈刃`}]}})),zi,Bi=t((()=>{zi={name:`姜维`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`挑衅`,path:`../../skills/挑衅`},{name:`志继`,path:`../../skills/志继`}]}})),Vi,Hi=t((()=>{Vi={name:`界姜维`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界挑衅`,path:`../../skills/界挑衅`},{name:`界志继`,path:`../../skills/界志继`}]}})),Ui,Wi=t((()=>{Ui={name:`刘禅`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`享乐`,path:`../../skills/享乐`},{name:`放权`,path:`../../skills/放权`},{name:`若愚`,path:`../../skills/若愚`}]}})),Gi,Ki=t((()=>{Gi={name:`界刘禅`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`享乐`,path:`../../skills/享乐`},{name:`界放权`,path:`../../skills/界放权`},{name:`界若愚`,path:`../../skills/界若愚`}]}})),qi,Ji=t((()=>{qi={name:`界关兴张苞`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界父魂`,path:`../../skills/界父魂`}]}})),Yi,Xi=t((()=>{Yi={name:`界夏侯氏`,maxHealth:3,gender:`女`,faction:`蜀`,skills:[{name:`界樵拾`,path:`../../skills/界樵拾`},{name:`界燕语`,path:`../../skills/界燕语`}]}})),Zi,Qi=t((()=>{Zi={name:`界廖化`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界当先`,path:`../../skills/界当先`},{name:`界伏枥`,path:`../../skills/界伏枥`}]}})),$i,ea=t((()=>{$i={name:`界张松`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`界强识`,path:`../../skills/界强识`},{name:`界献图`,path:`../../skills/界献图`}]}})),ta,na=t((()=>{ta={name:`界徐庶`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`界诛害`,path:`../../skills/界诛害`},{name:`界潜心`,path:`../../skills/界潜心`}]}})),ra,ia=t((()=>{ra={name:`界法正`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`界眩惑`,path:`../../skills/界眩惑`},{name:`界恩怨`,path:`../../skills/界恩怨`}]}})),aa,oa=t((()=>{aa={name:`界简雍`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`界纵适`,path:`../../skills/界纵适`},{name:`界巧说`,path:`../../skills/界巧说`}]}})),sa,ca=t((()=>{sa={name:`孙权`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`制衡`,path:`../../skills/制衡`},{name:`救援`,path:`../../skills/救援`}]}})),la,ua=t((()=>{la={name:`界孙权`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界制衡`,path:`../../skills/界制衡`},{name:`界救援`,path:`../../skills/界救援`}]}})),da,fa=t((()=>{da={name:`甘宁`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`奇袭`,path:`../../skills/奇袭`}]}})),pa,ma=t((()=>{pa={name:`界甘宁`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`奇袭`,path:`../../skills/奇袭`},{name:`奋威`,path:`../../skills/奋威`}]}})),ha,ga=t((()=>{ha={name:`吕蒙`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`克己`,path:`../../skills/克己`}]}})),_a,va=t((()=>{_a={name:`界吕蒙`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界克己`,path:`../../skills/界克己`},{name:`勤学`,path:`../../skills/勤学`},{name:`博图`,path:`../../skills/博图`}]}})),ya,ba=t((()=>{ya={name:`黄盖`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`苦肉`,path:`../../skills/苦肉`}]}})),xa,Sa=t((()=>{xa={name:`界黄盖`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界苦肉`,path:`../../skills/界苦肉`},{name:`诈降`,path:`../../skills/诈降`}]}})),Ca,wa=t((()=>{Ca={name:`周瑜`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`反间`,path:`../../skills/反间`},{name:`英姿`,path:`../../skills/英姿`}]}})),Ta,Ea=t((()=>{Ta={name:`界周瑜`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`界英姿`,path:`../../skills/界英姿`},{name:`界反间`,path:`../../skills/界反间`}]}})),Da,Oa=t((()=>{Da={name:`大乔`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`国色`,path:`../../skills/国色`},{name:`流离`,path:`../../skills/流离`}]}})),ka,Aa=t((()=>{ka={name:`界大乔`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`界国色`,path:`../../skills/界国色`},{name:`流离`,path:`../../skills/流离`}]}})),ja,Ma=t((()=>{ja={name:`陆逊`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`谦逊`,path:`../../skills/谦逊`},{name:`连营`,path:`../../skills/连营`}]}})),Na,Pa=t((()=>{Na={name:`界陆逊`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`界谦逊`,path:`../../skills/界谦逊`},{name:`界连营`,path:`../../skills/界连营`}]}})),Fa,Ia=t((()=>{Fa={name:`孙尚香`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`结姻`,path:`../../skills/结姻`},{name:`枭姬`,path:`../../skills/枭姬`}]}})),La,Ra=t((()=>{La={name:`界孙尚香`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`界结姻`,path:`../../skills/界结姻`},{name:`枭姬`,path:`../../skills/枭姬`}]}})),za,Ba=t((()=>{za={name:`小乔`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`天香`,path:`../../skills/天香`},{name:`红颜`,path:`../../skills/红颜`}]}})),Va,Ha=t((()=>{Va={name:`界小乔`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`界红颜`,path:`../../skills/界红颜`},{name:`界天香`,path:`../../skills/界天香`},{name:`飘零`,path:`../../skills/飘零`}]}})),Ua,Wa=t((()=>{Ua={name:`周泰`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`不屈`,path:`../../skills/不屈`}]}})),Ga,Ka=t((()=>{Ga={name:`界周泰`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界不屈`},{name:`奋激`}]}})),qa,Ja=t((()=>{qa={name:`太史慈`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`天义`,path:`../../skills/天义`}]}})),Ya,Xa=t((()=>{Ya={name:`界太史慈`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`天义`,path:`../../skills/天义`},{name:`酣战`,path:`../../skills/酣战`}]}})),Za,Qa=t((()=>{Za={name:`鲁肃`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`好施`,path:`../../skills/好施`},{name:`缔盟`,path:`../../skills/缔盟`}]}})),$a,eo=t((()=>{$a={name:`界鲁肃`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`界好施`,path:`../../skills/界好施`},{name:`界缔盟`,path:`../../skills/界缔盟`}]}})),to,no=t((()=>{to={name:`孙坚`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`英魂`,path:`../../skills/英魂`}]}})),ro,io=t((()=>{ro={name:`界孙坚`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`英魂`},{name:`武烈`}]}})),ao,oo=t((()=>{ao={name:`孙策`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`激昂`,path:`../../skills/激昂`},{name:`魂姿`,path:`../../skills/魂姿`},{name:`制霸`,path:`../../skills/制霸`}]}})),so,co=t((()=>{so={name:`界孙策`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界激昂`,path:`../../skills/界激昂`},{name:`界魂姿`,path:`../../skills/界魂姿`},{name:`界制霸`,path:`../../skills/界制霸`}]}})),lo,H=t((()=>{lo={name:`张昭张纮`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`直谏`,path:`../../skills/直谏`},{name:`固政`,path:`../../skills/固政`}]}})),uo,fo=t((()=>{uo={name:`界张昭张纮`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`界直谏`,path:`../../skills/界直谏`},{name:`界固政`,path:`../../skills/界固政`}]}})),po,mo=t((()=>{po={name:`界凌统`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界旋风`,path:`../../skills/界旋风`}]}})),ho,go=t((()=>{ho={name:`界吴国太`,maxHealth:3,gender:`女`,faction:`吴`,skills:[{name:`界甘露`,path:`../../skills/界甘露`},{name:`界补益`,path:`../../skills/界补益`}]}})),_o,vo=t((()=>{_o={name:`界徐盛`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界破军`,path:`../../skills/界破军`}]}})),yo,bo=t((()=>{yo={name:`界程普`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界疠火`,path:`../../skills/界疠火`},{name:`界醇醪`,path:`../../skills/界醇醪`}]}})),xo,So=t((()=>{xo={name:`界虞翻`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`界纵玄`,path:`../../skills/界纵玄`},{name:`界直言`,path:`../../skills/界直言`}]}})),Co,wo=t((()=>{Co={name:`界韩当`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`界弓骑`,path:`../../skills/界弓骑`},{name:`界解烦`,path:`../../skills/界解烦`}]}})),To,Eo=t((()=>{To={name:`华佗`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`急救`,path:`../../skills/急救`},{name:`青囊`,path:`../../skills/青囊`}]}})),Do,Oo=t((()=>{Do={name:`吕布`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`无双`,path:`../../skills/无双`}]}})),ko,Ao=t((()=>{ko={name:`貂蝉`,maxHealth:3,gender:`女`,faction:`群`,skills:[{name:`离间`,path:`../../skills/离间`},{name:`闭月`,path:`../../skills/闭月`}]}})),jo,Mo=t((()=>{jo={name:`界貂蝉`,maxHealth:3,gender:`女`,faction:`群`,skills:[{name:`离间`,path:`../../skills/离间`},{name:`界闭月`,path:`../../skills/界闭月`}]}})),No,Po=t((()=>{No={name:`张角`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`雷击`,path:`../../skills/雷击`},{name:`鬼道`,path:`../../skills/鬼道`},{name:`黄天`,path:`../../skills/黄天`}]}})),Fo,Io=t((()=>{Fo={name:`于吉`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`蛊惑`,path:`../../skills/蛊惑`}]}})),Lo,Ro=t((()=>{Lo={name:`界于吉`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界蛊惑`,path:`../../skills/界蛊惑`}]}})),zo,Bo=t((()=>{zo={name:`袁绍`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`乱击`,path:`../../skills/乱击`}]}})),Vo,Ho=t((()=>{Vo={name:`界袁绍`,maxHealth:4,gender:`男`,faction:`群`,isLord:!0,skills:[{name:`界乱击`,path:`../../skills/界乱击`},{name:`界血裔`,path:`../../skills/界血裔`}]}})),Uo,Wo=t((()=>{Uo={name:`庞德`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`马术`,path:`../../skills/马术`},{name:`鞬出`,path:`../../skills/鞬出`}]}})),Go,Ko=t((()=>{Go={name:`界庞德`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`马术`,path:`../../skills/马术`},{name:`界鞬出`,path:`../../skills/界鞬出`}]}})),qo,Jo=t((()=>{qo={name:`颜良文丑`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`双雄`,path:`../../skills/双雄`}]}})),Yo,Xo=t((()=>{Yo={name:`界颜良文丑`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`界双雄`,path:`../../skills/界双雄`}]}})),Zo,Qo=t((()=>{Zo={name:`董卓`,maxHealth:8,gender:`男`,faction:`群`,skills:[{name:`酒池`,path:`../../skills/酒池`},{name:`肉林`,path:`../../skills/肉林`},{name:`崩坏`,path:`../../skills/崩坏`},{name:`暴虐`,path:`../../skills/暴虐`}]}})),$o,es=t((()=>{$o={name:`界董卓`,maxHealth:8,gender:`男`,faction:`群`,skills:[{name:`界酒池`,path:`../../skills/界酒池`},{name:`肉林`,path:`../../skills/肉林`},{name:`界崩坏`,path:`../../skills/界崩坏`},{name:`界暴虐`,path:`../../skills/界暴虐`}]}})),ts,ns=t((()=>{ts={name:`贾诩`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`完杀`,path:`../../skills/完杀`},{name:`乱武`,path:`../../skills/乱武`},{name:`帷幕`,path:`../../skills/帷幕`}]}})),rs,is=t((()=>{rs={name:`界贾诩`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界帷幕`,path:`../../skills/界帷幕`},{name:`界乱武`,path:`../../skills/界乱武`},{name:`界完杀`,path:`../../skills/界完杀`}]}})),as,os=t((()=>{as={name:`左慈`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`化身`,path:`../../skills/化身`},{name:`新生`,path:`../../skills/新生`}]}})),ss,cs=t((()=>{ss={name:`蔡文姬`,maxHealth:3,gender:`女`,faction:`群`,skills:[{name:`悲歌`,path:`../../skills/悲歌`},{name:`断肠`,path:`../../skills/断肠`}]}})),ls,us=t((()=>{ls={name:`界蔡文姬`,maxHealth:3,gender:`女`,faction:`群`,skills:[{name:`界悲歌`,path:`../../skills/界悲歌`},{name:`断肠`,path:`../../skills/断肠`}]}})),ds,fs=t((()=>{ds={name:`界伏皇后`,maxHealth:3,gender:`女`,faction:`群`,skills:[{name:`界惴恐`,path:`../../skills/界惴恐`},{name:`界求援`,path:`../../skills/界求援`}]}})),ps,ms=t((()=>{ps={name:`界公孙瓒`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`界义从`,path:`../../skills/界义从`},{name:`界趫猛`,path:`../../skills/界趫猛`}]}})),hs,gs=t((()=>{hs={name:`界刘表`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界自守`,path:`../../skills/界自守`},{name:`界宗室`,path:`../../skills/界宗室`}]}})),_s,vs=t((()=>{_s={name:`界华佗`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`急救`,path:`../../skills/急救`},{name:`界除疠`,path:`../../skills/界除疠`}]}})),ys,bs=t((()=>{ys={name:`界华雄`,maxHealth:6,gender:`男`,faction:`群`,skills:[{name:`界耀武`,path:`../../skills/界耀武`},{name:`界势斩`,path:`../../skills/界势斩`}]}})),xs,Ss=t((()=>{xs={name:`界吕布`,maxHealth:5,gender:`男`,faction:`群`,skills:[{name:`无双`,path:`../../skills/无双`},{name:`界利驭`,path:`../../skills/界利驭`}]}})),Cs,ws=t((()=>{Cs={name:`界左慈`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`化身`,path:`../../skills/化身`},{name:`新生`,path:`../../skills/新生`}]}})),Ts,Es=t((()=>{Ts={name:`界张角`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界雷击`,path:`../../skills/界雷击`},{name:`界鬼道`,path:`../../skills/界鬼道`},{name:`界黄天`,path:`../../skills/界黄天`}]}})),Ds,Os=t((()=>{Ds={name:`界李儒`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界灭计`,path:`../../skills/界灭计`},{name:`界绝策`,path:`../../skills/界绝策`},{name:`界焚城`,path:`../../skills/界焚城`}]}})),ks,As=t((()=>{ks={name:`界沮授`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界矢北`,path:`../../skills/界矢北`},{name:`界渐营`,path:`../../skills/界渐营`}]}})),js,Ms=t((()=>{js={name:`界蔡夫人`,maxHealth:3,gender:`女`,faction:`群`,skills:[{name:`界窃听`,path:`../../skills/界窃听`},{name:`界献州`,path:`../../skills/界献州`}]}})),Ns,Ps=t((()=>{Ns={name:`界陈宫`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`界智迟`,path:`../../skills/界智迟`},{name:`界明策`,path:`../../skills/界明策`}]}})),Fs,Is=t((()=>{Fs={name:`界高顺`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`界陷阵`,path:`../../skills/界陷阵`},{name:`界禁酒`,path:`../../skills/界禁酒`}]}})),Ls,Rs=t((()=>{Ls={name:`华雄`,maxHealth:6,gender:`男`,faction:`群`,skills:[{name:`耀武`,path:`../../skills/耀武`}]}})),zs,Bs=t((()=>{zs={name:`毌丘俭`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`征荣`,path:`../../skills/征荣`},{name:`鸿举`,path:`../../skills/鸿举`}]}})),Vs,Hs=t((()=>{Vs={name:`王基`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`奇制`,path:`../../skills/奇制`},{name:`进趋`,path:`../../skills/进趋`}]}})),Us,Ws=t((()=>{Us={name:`蒯越蒯良`,maxHealth:3,gender:`男`,faction:`魏`,skills:[{name:`荐降`,path:`../../skills/荐降`},{name:`审时`,path:`../../skills/审时`}]}})),Gs,Ks=t((()=>{Gs={name:`郝昭`,maxHealth:4,gender:`男`,faction:`魏`,skills:[{name:`镇骨`,path:`../../skills/镇骨`}]}})),qs,tee=t((()=>{qs={name:`王平`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`飞军`,path:`../../skills/飞军`},{name:`兵略`,path:`../../skills/兵略`}]}})),Js,Ys=t((()=>{Js={name:`诸葛瞻`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`罪论`,path:`../../skills/罪论`},{name:`父荫`,path:`../../skills/父荫`}]}})),Xs,Zs=t((()=>{Xs={name:`陈到`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`往烈`,path:`../../skills/往烈`}]}})),Qs,$s=t((()=>{Qs={name:`卧龙诸葛亮`,maxHealth:3,gender:`男`,faction:`蜀`,skills:[{name:`八阵`,path:`../../skills/八阵`},{name:`火计`,path:`../../skills/火计`},{name:`看破`,path:`../../skills/看破`}]}})),ec,tc=t((()=>{ec={name:`严颜`,maxHealth:4,gender:`男`,faction:`蜀`,skills:[{name:`拒战`,path:`../../skills/拒战`}]}})),nc,rc=t((()=>{nc={name:`陆抗`,maxHealth:4,gender:`男`,faction:`吴`,skills:[{name:`谦节`,path:`../../skills/谦节`},{name:`决堰`,path:`../../skills/决堰`},{name:`破势`,path:`../../skills/破势`}]}})),ic,ac=t((()=>{ic={name:`陆绩`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`怀橘`,path:`../../skills/怀橘`},{name:`遗礼`,path:`../../skills/遗礼`},{name:`整论`,path:`../../skills/整论`}]}})),oc,sc=t((()=>{oc={name:`张昭张弘`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`直谏`,path:`../../skills/直谏`},{name:`固政`,path:`../../skills/固政`}]}})),cc,lc=t((()=>{cc={name:`周妃`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`良姻`,path:`../../skills/良姻`},{name:`箜声`,path:`../../skills/箜声`}]}})),uc,dc=t((()=>{uc={name:`孙亮`,maxHealth:3,gender:`男`,faction:`吴`,skills:[{name:`溃诛`,path:`../../skills/溃诛`},{name:`掣政`,path:`../../skills/掣政`},{name:`立军`,path:`../../skills/立军`}]}})),fc,pc=t((()=>{fc={name:`袁术`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`庸肆`,path:`../../skills/庸肆`},{name:`伪帝`,path:`../../skills/伪帝`}]}})),mc,hc=t((()=>{mc={name:`卢植`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`明任`,path:`../../skills/明任`},{name:`贞良`,path:`../../skills/贞良`}]}})),gc,_c=t((()=>{gc={name:`张绣`,maxHealth:4,gender:`男`,faction:`群`,skills:[{name:`雄乱`,path:`../../skills/雄乱`},{name:`从谏`,path:`../../skills/从谏`}]}})),vc,yc=t((()=>{vc={name:`许攸`,maxHealth:3,gender:`男`,faction:`群`,skills:[{name:`成略`,path:`../../skills/成略`},{name:`恃才`,path:`../../skills/恃才`},{name:`寸目`,path:`../../skills/寸目`}]}})),bc,xc,Sc,Cc,wc,Tc=t((()=>{_n(),yn(),xn(),Cn(),Tn(),Dn(),kn(),eee(),Mn(),Pn(),In(),Rn(),Bn(),Hn(),Wn(),Kn(),Jn(),Xn(),Qn(),er(),nr(),ir(),or(),cr(),ur(),fr(),mr(),gr(),vr(),br(),Sr(),wr(),Er(),Or(),Ar(),Mr(),Pr(),Ir(),Rr(),Br(),Hr(),Wr(),Kr(),Jr(),Xr(),Qr(),ei(),ni(),ii(),oi(),ci(),ui(),fi(),mi(),gi(),vi(),bi(),Si(),wi(),Ei(),Oi(),Ai(),Mi(),Pi(),Ii(),Ri(),Bi(),Hi(),Wi(),Ki(),Ji(),Xi(),Qi(),ea(),na(),ia(),oa(),ca(),ua(),fa(),ma(),ga(),va(),ba(),Sa(),wa(),Ea(),Oa(),Aa(),Ma(),Pa(),Ia(),Ra(),Ba(),Ha(),Wa(),Ka(),Ja(),Xa(),Qa(),eo(),no(),io(),oo(),co(),H(),fo(),mo(),go(),vo(),bo(),So(),wo(),Eo(),Oo(),Ao(),Mo(),Po(),Io(),Ro(),Bo(),Ho(),Wo(),Ko(),Jo(),Xo(),Qo(),es(),ns(),is(),os(),cs(),us(),fs(),ms(),gs(),vs(),bs(),Ss(),ws(),Es(),Os(),As(),Ms(),Ps(),Is(),Rs(),Bs(),Hs(),Ws(),Ks(),tee(),Ys(),Zs(),$s(),tc(),rc(),ac(),sc(),lc(),dc(),pc(),hc(),_c(),yc(),bc=[gn,vn,bn,Sn,wn,En,On,An,jn,Nn,Fn,Ln,zn,Vn,Un,Gn,qn,Yn,Zn,$n,tr,rr,ar,sr,lr,dr,pr,hr,_r,yr,xr,Cr,Tr,Dr,kr,jr,Nr,Fr,Lr,zs,Vs,Us,Gs],xc=[zr,Vr,Ur,Gr,qr,Yr,Zr,$r,ai,si,li,di,pi,hi,_i,yi,xi,Ci,Ti,ti,ri,Di,ki,ji,Ni,Fi,Li,zi,Vi,Ui,Gi,qi,Yi,Zi,$i,ta,ra,aa,qs,Js,Xs,Qs,ec],Sc=[sa,la,da,pa,ha,_a,ya,xa,Ca,Ta,Da,ka,ja,Na,Fa,La,za,Va,Ua,Ga,qa,Ya,Za,$a,to,ro,ao,so,lo,uo,po,ho,_o,yo,xo,Co,nc,ic,oc,cc,uc],Cc=[To,Do,ko,jo,No,Fo,Lo,zo,Vo,Uo,Go,qo,Yo,Zo,$o,ts,rs,as,ss,ls,ds,ps,hs,_s,ys,xs,Cs,Ts,Ds,ks,js,Ns,Fs,Ls,fc,mc,gc,vc],wc=[...bc,...xc,...Sc,...Cc]})),Ec=t((()=>{Tc()}));function Dc(e){for(let t of Mc)if(e.startsWith(t))return e.slice(t.length);return e}function Oc(e){return Nc.get(e)}function kc(e){return Nc.get(e)?.gender??`男`}function Ac(e){return Nc.get(e)?.isLord??!1}var jc,Mc,Nc,Pc,Fc=t((()=>{Ec(),jc=[`刘备`,`曹操`,`孙权`,`孙策`,`张角`,`董卓`,`刘禅`],Mc=[`界`,`SP`],Nc=new Map(wc.map(e=>{let t=e;return[t.name,{name:t.name,faction:t.faction,maxHealth:t.maxHealth,gender:t.gender,skills:t.skills.map(e=>e.name),isLord:t.isLord===!0||jc.includes(Dc(t.name))}]})),Pc=new Set([`护驾`,`界护驾`,`激将`,`界激将`,`救援`,`界救援`,`制霸`,`界制霸`,`暴虐`,`界暴虐`,`黄天`,`界黄天`,`若愚`,`界若愚`,`界血裔`])}));function Ic(e,t,n){let r=e??4;return t===`主公`&&n>4?r+1:r}var Lc,Rc=t((()=>{Fc(),Lc={type:`分配武将`,validate(e,t){return e.players[t.target]?t.character?null:`character required`:`target ${t.target} not found`},apply(e,t){let n=e.players[t.target];if(!n)throw Error(`分配武将: target ${t.target} not found (validate 已通过)`);n.nickname??=n.name,n.character=t.character,n.name=t.character,n.skills=t.skills;let r=Oc(t.character);r&&(n.faction=r.faction);let i=Ic(r?.maxHealth,n.identity,e.players.length);n.maxHealth=i,n.health=i},toViewEvents(e,t){let n=Oc(t.character),r=e.players[t.target]?.identity,i=Ic(n?.maxHealth,r,e.players.length),a={type:`分配武将`,target:t.target,character:t.character,skills:t.skills,faction:n?.faction,maxHealth:i,health:i};if(e.charSelecting){let e={type:`分配武将`,target:t.target};return{ownerViews:new Map([[t.target,a]]),othersView:e}}return{ownerViews:new Map,othersView:a}},applyView(e,t){let n=t.target,r=t.character;if(!r)return;let i=t.skills??[],a=e.players.findIndex(e=>e.index===n);if(a<0)return;e.players[a].character=r,e.players[a].name=r,e.players[a].skills=i;let o=t.faction;o&&(e.players[a].faction=o);let s=t.maxHealth;typeof s==`number`&&(e.players[a].maxHealth=s,e.players[a].health=s)}}})),zc,Bc=t((()=>{zc={type:`判定`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e){if(e.zones.deck.length===0)return;let t=e.zones.deck.pop(),n=e.settlementStack[e.settlementStack.length-1];n?n.cards.push(t):e.zones.processing.push(t)},toViewEvents(e,t){let n=e.zones.deck[e.zones.deck.length-1],r=n?e.cardMap[n]:void 0,i=e.players[t.player]?.pendingTricks.find(e=>e.name===t.judgeType),a={type:`判定`,player:t.player,judgeType:t.judgeType,...r?{cardId:n,card:{name:r.name,suit:r.suit,rank:r.rank}}:{},...i?{pendingCard:{name:i.card.name,suit:i.card.suit,rank:i.card.rank}}:{}};return{ownerViews:new Map,othersView:a}},effect:{sound:`flip`,animation:`flip`,blockUntilDone:!0,duration:1800},applyView(e,t){if(!e.zones)return;let n=t.cardId;if(e.zones.deckCount=Math.max(0,e.zones.deckCount-1),!n)return;let r=e.settlementStack[e.settlementStack.length-1];r&&r.cards.push(n),e.zones.processing.push(n)},toViewLog(e){let t=e.card,n=e.judgeType??``;return t?{player:e.player,text:`判定(${n}):${t.suit??``}${t.rank??``} ${t.name??``}`}:{player:e.player,text:`判定(${n})`}}}})),Vc,Hc=t((()=>{z(),Vc={type:`收取判定牌`,validate(e,t){return e.cardMap[t.cardId]?R(e).includes(t.cardId)?null:`card ${t.cardId} 不在处理区`:`card ${t.cardId} not found`},apply(e,t){let n=e.settlementStack[e.settlementStack.length-1],r=n?n.cards:e.zones.processing,i=r.indexOf(t.cardId);i>=0&&r.splice(i,1)},toViewEvents(e,t){let n={type:`收取判定牌`,player:t.player,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=t.cardId;if(!n)return;let r=e.settlementStack[e.settlementStack.length-1];r&&(r.cards=r.cards.filter(e=>e!==n)),e.zones&&(e.zones.processing=e.zones.processing.filter(e=>e!==n))}}})),Uc,Wc=t((()=>{Uc={type:`加标签`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.tags.includes(t.tag)||n.tags.push(t.tag)}}})),Gc,Kc=t((()=>{Gc={type:`加标记`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){e.players[t.player].marks.push(t.mark)},effect:{sound:`chain`,animation:`pulse`,duration:400},toViewEvents(e,t){let n={type:`加标记`,player:t.player,mark:t.mark};return t.distanceVars&&(n.distanceVars=t.distanceVars),{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.mark;r&&e.players[n].marks.push(r);let i=t.distanceVars;i&&(e.players[n].distanceVars={...e.players[n].distanceVars,...i})}}}));function qc(e){return Ol+e}function Jc(e){return kl+e}function Yc(e){return Al+e}function Xc(e){return jl+e}function Zc(e){return e+Ml}function Qc(e){return`秘计/pendingFrom贞烈/${e}`}function $c(e){return`手牌上限/bonus:${e}`}function el(e){return typeof e==`number`?e:void 0}function tl(e){return typeof e==`boolean`?e:void 0}function nl(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}function rl(e){return Array.isArray(e)&&e.every(e=>typeof e==`number`)?e:void 0}function il(e){return el(e?.[Sl])}function al(e){return el(e?.[Cl])}function ol(e){return el(e?.[wl])}function sl(e,t){return el(e?.[$c(t)])}function cl(e){return tl(e?.[yl])}function ll(e){return nl(e?.[bl])}function ul(e){return rl(e?.[xl])}function dl(e,t){return tl(e?.[Qc(t)])}function fl(e){return el(e?.[gl])}function pl(e){return el(e?.[_l])}function ml(e){return el(e?.[vl])}function hl(e){let t=e?.[Tl];if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;if(typeof n.zone==`string`&&!(n.cardId!==null&&typeof n.cardId!=`string`)&&!(n.handIndex!==null&&typeof n.handIndex!=`number`))return t}var gl,_l,vl,yl,bl,xl,Sl,Cl,wl,Tl,El,Dl,Ol,kl,Al,jl,Ml,Nl,Pl,Fl,Il,Ll,Rl,zl,Bl,Vl,U,Hl,Ul,Wl,Gl,Kl,ql,Jl,W=t((()=>{gl=`奇制/count`,_l=`杀/quotaUsed`,vl=`杀/extraUsed`,yl=`魂姿/awakened`,bl=`化身/牌池`,xl=`兵略/已飞军目标`,Sl=`距离/进攻修正`,Cl=`距离/防御修正`,wl=`距离/出杀范围`,Tl=`选牌/结果`,El=`杀/usedCount`,Dl=`杀/exemptSuit`,Ol=`杀/unlimited/`,kl=`杀/extra/`,Al=`杀/blocked/`,jl=`杀/target/`,Ml=`/usedThisTurn`,Nl=`陷阵/winTarget`,Pl=`成略/suits`,Fl=`将驰/choice2`,Il=`界弓骑/active`,Ll=`当先/noRangeActive`,Rl=`天义/win`,zl=`决堰/本回合:坐骑`,Bl=`往烈/首张可用`,Vl=`雄乱/目标`,U=`双雄/color`,Hl=`界双雄/color`,Ul=`审时/态`,Wl=`成略/态`,Gl=`当先/extraPhase`,Kl=`拒战/态`,ql=`__view/`,Jl=[Nl,Pl,Fl,Il,Ll,Rl,zl,Bl,Vl,U,Hl,Ul,Wl,Gl,Kl]}));function Yl(e,t,n){let r=e.players[t].vars;n===`武器`&&delete r[wl]}var Xl,Zl=t((()=>{W(),Xl={type:`卸下`,validate(e,t){let n=e.players[t.player];return n?n.equipment[t.slot]?null:`no equipment in slot ${t.slot}`:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player],r=n.equipment[t.slot];delete n.equipment[t.slot],n.hand.push(r),Yl(e,t.player,t.slot)},effect:{sound:`unequip`,animation:`fade`,duration:400},toViewEvents(e,t){let n=e.players[t.player].equipment[t.slot],r={type:`卸下`,player:t.player,slot:t.slot,...n?{cardId:n}:{}};return{ownerViews:new Map,othersView:r}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.slot,i=t.cardId;if(r&&delete e.players[n].equipment[r],i&&(e.players[n].handCount+=1,e.players[n].hand)){let t=e.cardMap[i];t&&e.players[n].hand.push(t)}r===`武器`&&e.players[n].distanceVars&&(e.players[n].distanceVars={...e.players[n].distanceVars,attackRange:void 0})}}})),Ql,$l=t((()=>{Ql={type:`去标签`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.tags=n.tags.filter(e=>e!==t.tag)}}})),eu,tu=t((()=>{eu={type:`去标记`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player],r=n.marks.findIndex(e=>e.id===t.markId);r<0||n.marks.splice(r,1)},effect:{sound:`chain`,animation:`pulse`,duration:300},toViewEvents(e,t){let n={type:`去标记`,player:t.player,markId:t.markId};return t.distanceVars&&(n.distanceVars=t.distanceVars),{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.markId;r&&(e.players[n].marks=e.players[n].marks.filter(e=>e.id!==r));let i=t.distanceVars;i&&(e.players[n].distanceVars={...e.players[n].distanceVars,...i})}}})),nu,ru=t((()=>{nu={type:`回合开始`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e){},toViewEvents(e,t){let n={type:`回合开始`,player:t.player,round:e.turn.round};return{ownerViews:new Map,othersView:n}},effect:{sound:`turn_start`,duration:1500},applyView(e,t){e.currentPlayerIndex=t.player,typeof t.round==`number`&&(e.turn.round=t.round)},toViewLog(e){return{player:e.player,text:`回合开始`}}}})),iu,au=t((()=>{W(),iu={type:`回合用量`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){(t.key.startsWith(`杀/`)||Jl.includes(t.key))&&t.player===e.currentPlayerIndex&&(e.turn.vars[ql+t.key]=t.value)},toViewEvents(e,t){let n={type:`回合用量`,player:t.player,key:t.key,value:t.value};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players[t.player];n&&(n.turnUsage??={},n.turnUsage[t.key]=t.value)}}})),ou,su=t((()=>{ou={type:`回合结束`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e){e.turn.vars={};for(let t of e.players)t.marks=t.marks.filter(e=>e.duration!==`turn`),t.vars=Object.fromEntries(Object.entries(t.vars).filter(([e])=>!e.endsWith(`/usedThisTurn`)&&!e.endsWith(`/healed`)&&!e.endsWith(`/givenCount`)&&!e.endsWith(`/givenTargets`)&&!e.endsWith(`/basicUsed`)))},toViewEvents(e,t){let n={type:`回合结束`,player:t.player};return{ownerViews:new Map,othersView:n}},effect:{sound:`turn_end`,duration:800},applyView(e){e.turn.vars={};for(let t of e.players)t.marks=t.marks.filter(e=>e.duration!==`turn`),t.turnUsage={}},toViewLog(e){return{player:e.player,text:`回合结束`}}}})),cu,lu=t((()=>{cu={type:`回合结束后`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(){},toViewEvents(){return{ownerViews:new Map,othersView:null}},applyView(){}}})),uu,du=t((()=>{uu={type:`回复体力`,validate(e,t){if(t.amount<=0)return`amount must be > 0`;let n=e.players[t.target];return n?n.alive?null:`target is dead`:`target ${t.target} not found`},apply(e,t){let n=e.players[t.target];n.health=Math.min(n.maxHealth,n.health+t.amount)},effect:{sound:`heal`,particles:`ice`,duration:800},toViewEvents(e,t){let n={type:`回复体力`,target:t.target,amount:t.amount};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.target);if(n<0)return;let r=e.players[n];r.health=Math.min(r.maxHealth,r.health+t.amount)},toViewLog(e){return{player:e.target,text:`回复 ${e.amount??0} 点体力`}}}})),fu,pu=t((()=>{fu={type:`声明打出时`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=e.cardMap[t.cardId]?.name??t.cardId,r={type:`声明打出时`,player:t.player,cardId:t.cardId,cardName:n};return{ownerViews:new Map,othersView:r}},applyView(){}}})),mu,hu=t((()=>{mu={type:`失去体力`,validate(e,t){if(t.amount<=0)return`amount must be > 0`;let n=e.players[t.target];return n?n.alive?null:`target is dead`:`target ${t.target} not found`},apply(e,t){let n=e.players[t.target];n.health-=t.amount},effect:{sound:`lose_health`,animation:`shake`,duration:800},toViewEvents(e,t){let n={type:`失去体力`,target:t.target,amount:t.amount};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.target);if(n<0)return;let r=e.players[n];r.health-=t.amount},toViewLog(e){return{player:e.target,text:`失去 ${e.amount??0} 点体力`}}}})),gu,_u,vu=t((()=>{gu=700,_u={type:`展示`,validate(e,t){return e.players[t.player]?e.cardMap[t.cardId]?null:`card ${t.cardId} not found`:`player ${t.player} not found`},apply(){},effect:{sound:`flip`,animation:`flip`,duration:gu},toViewEvents(e,t){let n=e.cardMap[t.cardId],r=n?{name:n.name,suit:n.suit,rank:n.rank}:null,i={sound:`flip`,animation:`flip`,duration:gu},a={type:`展示`,player:t.player,cardId:t.cardId,card:r,effect:i};return{ownerViews:new Map,othersView:a}},applyView(){},toViewLog(e){let t=e.card;return t?{player:e.player,text:`展示:${t.suit}${t.rank}(${t.name})`}:{player:e.player,text:`展示`}}}})),yu,bu=t((()=>{yu={type:`展示结束`,validate(e,t){return e.players[t.player]?e.cardMap[t.cardId]?null:`card ${t.cardId} not found`:`player ${t.player} not found`},apply(){},toViewEvents(e,t){let n={type:`展示结束`,player:t.player,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){}}})),xu,Su=t((()=>{xu={type:`帧参数赋值`,validate(e){return e.settlementStack.length===0?`settlementStack 为空,无栈顶帧可赋值`:null},apply(e,t){let n=e.settlementStack[e.settlementStack.length-1];n.params[t.key]=t.value},toViewEvents(e,t){let n={type:`帧参数赋值`,key:t.key,value:t.value};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.settlementStack[e.settlementStack.length-1];n&&(n.params[t.key]=t.value)}}})),Cu,wu,Tu=t((()=>{V(),Cu=`__弃置/手牌卡`,wu={type:`弃置`,validate(e,t){return t.cardIds.length===0?`no cards to discard`:e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player],r=new Set(t.cardIds);e.localVars[Cu]=t.cardIds.filter(e=>n.hand.includes(e)),n.hand=n.hand.filter(e=>!r.has(e));let i={};for(let[e,t]of Object.entries(n.equipment))t&&!r.has(t)&&(i[e]=t);n.equipment=i,e.zones.discardPile.push(...t.cardIds)},async afterApply(e,t){let n=e.localVars[Cu];if(delete e.localVars[Cu],!(!n||n.length===0))for(let r of n)await B(e,{type:`移动到目标区域后`,cardId:r,from:{zone:`手牌`,player:t.player},to:{zone:`弃牌堆`},reason:`弃置`})},effect:{sound:`flip`,animation:`flip`,duration:600},toViewEvents(e,t){let n=e.players[t.player],r=new Set(Object.values(n.equipment).filter(Boolean)),i={};for(let e of t.cardIds)n.hand.includes(e)?i[e]=`hand`:r.has(e)?i[e]=`equipment`:i[e]=`judge`;let a={type:`弃置`,player:t.player,cardIds:t.cardIds,zones:i,cardNames:t.cardIds.map(t=>e.cardMap[t]?.name).filter(Boolean)};return{ownerViews:new Map,othersView:a}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.cardIds??[],i=t.zones??{},a=new Set(r),o={};for(let[t,r]of Object.entries(e.players[n].equipment))r&&a.has(r)||r&&(o[t]=r);e.players[n].equipment=o;let s=r.filter(e=>i[e]===`hand`).length;e.players[n].handCount=Math.max(0,e.players[n].handCount-s),e.players[n].hand&&s>0&&(e.players[n].hand=e.players[n].hand.filter(e=>!a.has(e.id))),e.zones&&(e.zones.discardPileCount+=r.length)},toViewLog(e,t){let n=e.cardIds,r=Array.isArray(n)?n.length:0,i=e.cardNames;if(i&&i.length>0){let t=i.join(`、`);return{player:e.player,text:`弃置了 ${r} 张牌:${t}`}}return{player:e.player,text:`弃置了 ${r} 张牌`}}}})),Eu,Du=t((()=>{Eu={type:`归还暂存牌`,validate(e,t){return e.players[t.player]?typeof t.varsKey!=`string`||t.varsKey.length===0?`varsKey 不能为空`:(e.players[t.player].vars[t.varsKey]??[]).length===0?`player ${t.player} 的 vars['${t.varsKey}'] 无暂存牌可归还`:null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player],r=n.vars[t.varsKey]??[];if(delete n.vars[t.varsKey],!n.alive){for(let t of r)e.zones.discardPile.push(t);return}for(let e of r)n.hand.includes(e)||n.hand.push(e)},effect:{sound:`flip`,animation:`slide`,duration:600},toViewEvents(e,t){let n=e.players[t.player].vars[t.varsKey]??[],r=e.players[t.player].alive===!0,i=n.map(t=>e.cardMap[t]).filter(e=>!!e).map(e=>({id:e.id,name:e.name,suit:e.suit,rank:e.rank}));if(!r){let e={type:`归还暂存牌`,player:t.player,count:n.length,cards:i,toDiscard:!0};return{ownerViews:new Map,othersView:e}}let a={type:`归还暂存牌`,player:t.player,cards:i},o={type:`归还暂存牌`,player:t.player,count:n.length};return{ownerViews:new Map([[t.player,a]]),othersView:o}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.cards,i=r?r.length:t.count??0;if(t.toDiscard){e.zones&&(e.zones.discardPileCount+=i);return}if(e.players[n].handCount+=i,r&&e.players[n].hand)for(let t of r){let r=e.cardMap[t.id];r&&(e.players[n].hand.some(e=>e.id===t.id)||e.players[n].hand.push(r))}},toViewLog(e){let t=e.cards?.length??e.count??0;return{player:e.player,text:`归还 ${t} 张移出的牌`}}}})),Ou,ku,Au,ju,Mu,Nu=t((()=>{Ou={name:`杀`,type:`基本牌`,subtype:`杀`,targetFilter:{type:`inRange`},effect:{type:`damage`,amount:1},responseWindow:`kill_response`,usageLimit:{perTurn:1}},ku={name:`闪`,type:`基本牌`,subtype:`闪`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},Au={name:`桃`,type:`基本牌`,subtype:`桃`,targetFilter:{type:`self`},effect:{type:`回复体力`,amount:1}},ju={name:`酒`,type:`基本牌`,subtype:`酒`,targetFilter:{type:`self`},effect:{type:`sequence`,steps:[]}},Mu=[Ou,ku,Au,ju]})),Pu,Fu,Iu,Lu,Ru,zu,Bu,Vu,Hu,Uu,Wu,Gu,Ku,qu,Ju,Yu,Xu=t((()=>{Pu={name:`过河拆桥`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`,condition:e=>e.hand.length>0},effect:{type:`弃置`,source:`hand`,count:1,target:`selected`},responseWindow:`trick_response`},Fu={name:`顺手牵羊`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`inRange`},effect:{type:`获得`,from:`player`,source:`selected`},responseWindow:`trick_response`},Iu={name:`无中生有`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`self`},effect:{type:`摸牌`,count:2},responseWindow:`trick_response`},Lu={name:`决斗`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`},effect:{type:`damage`,amount:1},responseWindow:`trick_response`},Ru={name:`万箭齐发`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`none`},effect:{type:`damage`,amount:1},aoeResponse:`闪`},zu={name:`南蛮入侵`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`none`},effect:{type:`damage`,amount:1},aoeResponse:`杀`},Bu={name:`桃园结义`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`none`},effect:{type:`回复体力`,amount:1}},Vu={name:`五谷丰登`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`none`},effect:{type:`摸牌`,count:1}},Hu={name:`乐不思蜀`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`},effect:{type:`添加延时锦囊`,trickName:`乐不思蜀`,target:`selected`},responseWindow:`trick_response`},Uu={name:`兵粮寸断`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`},effect:{type:`添加延时锦囊`,trickName:`兵粮寸断`,target:`selected`},responseWindow:`trick_response`},Wu={name:`闪电`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`self`},effect:{type:`添加延时锦囊`,trickName:`闪电`,target:`self`}},Gu={name:`无懈可击`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},Ku={name:`铁索连环`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`},effect:{type:`sequence`,steps:[]},responseWindow:`trick_response`},qu={name:`火攻`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`,condition:e=>e.hand.length>0},effect:{type:`damage`,amount:1,damageType:`火焰`},responseWindow:`trick_response`},Ju={name:`借刀杀人`,type:`锦囊牌`,subtype:`锦囊`,targetFilter:{type:`other`},effect:{type:`sequence`,steps:[]},responseWindow:`trick_response`},Yu=[Pu,Fu,Iu,Lu,Ru,zu,Bu,Vu,Hu,Uu,Wu,Gu,Ku,qu,Ju]})),Zu,Qu,$u,ed,td,nd,rd,id,ad,od,sd,cd,ld,ud,dd,fd,pd,md,hd,gd,_d,vd,yd,bd,xd,Sd,Cd,wd,G=t((()=>{Zu={name:`诸葛连弩`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:1,weaponEffect:{type:`诸葛连弩`},slashUnlimited:!0},Qu={name:`青釭剑`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:2,weaponEffect:{type:`青釭剑`}},$u={name:`寒冰剑`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:2,weaponEffect:{type:`寒冰剑`}},ed={name:`雌雄双股剑`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:2,weaponEffect:{type:`雌雄双股剑`}},td={name:`贯石斧`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:3,weaponEffect:{type:`贯石斧`}},nd={name:`青龙偃月刀`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:3,weaponEffect:{type:`青龙偃月刀`}},rd={name:`丈八蛇矛`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:3},id={name:`方天画戟`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:4,slashTargetBonusWhenLastCard:3},ad={name:`麒麟弓`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:5},od={name:`八卦阵`,type:`装备牌`,subtype:`防具`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},armorEffect:{type:`八卦阵`}},sd={name:`仁王盾`,type:`装备牌`,subtype:`防具`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},armorEffect:{type:`仁王盾`}},cd={name:`藤甲`,type:`装备牌`,subtype:`防具`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},armorEffect:{type:`藤甲`}},ld={name:`白银狮子`,type:`装备牌`,subtype:`防具`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},armorEffect:{type:`白银狮子`}},ud={name:`古锭刀`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:2},dd={name:`朱雀羽扇`,type:`装备牌`,subtype:`武器`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]},range:4},fd={name:`骅骝`,type:`装备牌`,subtype:`防御马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},pd={name:`赤兔`,type:`装备牌`,subtype:`进攻马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},md={name:`紫骍`,type:`装备牌`,subtype:`进攻马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},hd={name:`大宛`,type:`装备牌`,subtype:`进攻马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},gd={name:`的卢`,type:`装备牌`,subtype:`防御马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},_d={name:`绝影`,type:`装备牌`,subtype:`防御马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},vd={name:`爪黄飞电`,type:`装备牌`,subtype:`防御马`,targetFilter:{type:`none`},effect:{type:`sequence`,steps:[]}},yd=[Zu,Qu,$u,ed,td,nd,rd,id,ad,ud,dd],bd=[od,sd,cd,ld],xd=[pd,md,hd,gd,_d,vd,fd],Sd=[...yd,...bd,...xd],Cd=new Map(xd.map(e=>[e.name,e.subtype===`进攻马`?{attackMod:1}:{defenseMod:1}])),wd=Object.fromEntries(xd.map(e=>[e.name,`skills/马匹技能#${e.name}`]))})),Td=t((()=>{Nu(),Xu(),G()}));function Ed(e){return Od.get(e)??`基本牌`}function Dd(e,t){if(e.length===1)return t[e[0]]?.color??`无色`;let n;for(let r of e){let e=t[r]?.color;if(!e)return`无色`;if(n===void 0)n=e;else if(n!==e)return`无色`}return n??`无色`}var Od,kd,Ad=t((()=>{Td(),Od=(()=>{let e=new Map;for(let t of[...Mu,...Yu,...Sd])e.set(t.name,t.type);return e})(),kd={type:`当作`,validate(e,t){let n=e.players[t.player];return n?n.alive?t.cardIds.every(e=>n.hand.includes(e))?t.cardIds.every(t=>e.cardMap[t])?null:`cards not found`:`cards not in hand`:`player not alive`:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player],r=e.cardMap[t.cardIds[0]],i=t.cardIds.length===1,a={id:t.shadowId,name:t.outputName,suit:i?r.suit:``,color:Dd(t.cardIds,e.cardMap),rank:r.rank,type:Ed(t.outputName),shadowOf:i?t.cardIds[0]:void 0};t.outputDamageType&&(a.damageType=t.outputDamageType),e.cardMap[t.shadowId]=a,n.hand=n.hand.filter(e=>!t.cardIds.includes(e)),n.hand.push(t.shadowId)},effect:{sound:`flip`,animation:`flash`,duration:400},toViewEvents(e,t){let n={sound:`flip`,animation:`flash`,duration:400},r={type:`当作`,player:t.player,cardIds:t.cardIds,shadowId:t.shadowId,outputName:t.outputName,outputDamageType:t.outputDamageType,effect:n},i={type:`当作`,player:t.player,count:t.cardIds.length,effect:n};return{ownerViews:new Map([[t.player,r]]),othersView:i}},applyView(e,t){let n=t.player,r=e.players.findIndex(e=>e.index===n);if(r<0)return;let i=t,a=i.cardIds,o=i.shadowId,s=i.count??a?.length??1,c=typeof i.outputName==`string`?i.outputName:`杀`;if(e.players[r].handCount=Math.max(0,e.players[r].handCount-(s-1)),a&&o&&e.players[r].hand){let t=e.cardMap[o];if(!t){let n=e.cardMap[a[0]],r=s===1,l=i.outputDamageType;t={id:o,name:c,suit:r?n?.suit??``:``,color:Dd(a,e.cardMap),rank:n?.rank??`A`,type:Ed(c),shadowOf:r?a[0]:void 0},l&&(t.damageType=l),e.cardMap[o]=t}let n=new Set(a);e.players[r].hand=e.players[r].hand.filter(e=>!n.has(e.id)),e.players[r].hand.push(t)}},toViewLog(e){let t=e;return{player:e.player,text:`使用转化出${typeof t.outputName==`string`?t.outputName:`牌`}`}}}})),jd,Md=t((()=>{jd={type:`成为目标`,validate(e,t){return e.players[t.source]?e.players[t.target]?null:`target ${t.target} not found`:`source ${t.source} not found`},apply(e){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=t.cardId?e.cardMap[t.cardId]?.name??t.cardId:void 0,r={type:`成为目标`,source:t.source,target:t.target,...t.cardId===void 0?{}:{cardId:t.cardId},...n===void 0?{}:{cardName:n}};return{ownerViews:new Map,othersView:r}},applyView(e,t){}}})),Nd,Pd=t((()=>{Nd={type:`成为目标后`,validate(e,t){return e.players[t.source]?e.players[t.target]?null:`target ${t.target} not found`:`source ${t.source} not found`},apply(){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=t.cardId?e.cardMap[t.cardId]?.name??t.cardId:void 0,r={type:`成为目标后`,source:t.source,target:t.target,...t.cardId===void 0?{}:{cardId:t.cardId},...n===void 0?{}:{cardName:n}};return{ownerViews:new Map,othersView:r}},applyView(){}}})),Fd,Id=t((()=>{Fd={type:`打出牌时`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=e.cardMap[t.cardId]?.name??t.cardId,r={type:`打出牌时`,player:t.player,cardId:t.cardId,cardName:n,effect:{sound:`card/${n}`,animation:`highlight`,duration:400}};return{ownerViews:new Map,othersView:r}},applyView(){}}})),Ld,Rd=t((()=>{Ld={type:`扣牌`,validate(e,t){return e.players[t.player]?e.cardMap[t.cardId]?e.players[t.player].hand.includes(t.cardId)?null:`card not in hand`:`card ${t.cardId} not found`:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.hand=n.hand.filter(e=>e!==t.cardId),e.zones.discardPile.push(t.cardId),e.localVars[`蛊惑/扣牌`]=t.cardId,e.localVars[`蛊惑/声明`]=t.declaredName},effect:{sound:`flip`,animation:`flip`,duration:800},toViewEvents(e,t){let n=e.cardMap[t.cardId],r=n?{name:n.name,suit:n.suit,rank:n.rank}:null,i={sound:`flip`,animation:`flip`,duration:800},a={type:`扣牌`,player:t.player,cardId:t.cardId,card:r,declaredName:t.declaredName,effect:i},o={type:`扣牌`,player:t.player,declaredName:t.declaredName,effect:i};return{ownerViews:new Map([[t.player,a]]),othersView:o}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n>=0){e.players[n].handCount=Math.max(0,e.players[n].handCount-1);let r=t.cardId;r&&e.players[n].hand&&(e.players[n].hand=e.players[n].hand.filter(e=>e.id!==r))}e.zones&&(e.zones.discardPileCount+=1)},toViewLog(e,t){let n=e.declaredName;if(t===e.player&&e.card){let t=e.card;return{player:e.player,text:`蛊惑:扣置 ${t.suit}${t.rank},声明为【${n}】`}}return{player:e.player,text:`蛊惑:扣置一张手牌,声明为【${n}】`}}}})),zd,Bd=t((()=>{zd={type:`指定目标`,validate(e,t){return e.players[t.source]?e.players[t.target]?null:`target ${t.target} not found`:`source ${t.source} not found`},apply(e){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=t.cardId?e.cardMap[t.cardId]?.name??t.cardId:void 0,r={type:`指定目标`,source:t.source,target:t.target,...t.cardId===void 0?{}:{cardId:t.cardId},...n===void 0?{}:{cardName:n}};return{ownerViews:new Map,othersView:r}},applyView(e,t){},toViewLog(e,t,n){let r=e.target,i=n?.(r)??`P${r}`,a=e.source;n?.(a)??`${a}`;let o=e.cardName??e.cardId;return{player:a,text:`${o?`使用 ${o} `:``}指定 ${i} 为目标`}}}})),Vd,Hd=t((()=>{Vd={type:`指定目标后`,validate(e,t){return e.players[t.source]?e.players[t.target]?null:`target ${t.target} not found`:`source ${t.source} not found`},apply(){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=t.cardId?e.cardMap[t.cardId]?.name??t.cardId:void 0,r={type:`指定目标后`,source:t.source,target:t.target,...t.cardId===void 0?{}:{cardId:t.cardId},...n===void 0?{}:{cardName:n}};return{ownerViews:new Map,othersView:r}},applyView(){}}}));function Ud(e){let t=e|0;return{next(){t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296},nextInt(e){return Math.floor(this.next()*e)},getState(){return t}}}var Wd=t((()=>{}));function Gd(e,t,n=!1){if(e.zones.deck.length>=t)return{drawn:n?e.zones.deck.slice(0,t):e.zones.deck.slice(-t).reverse(),reshuffled:!1};let r=[...e.zones.deck,...e.zones.discardPile],i=Ud(e.rngSeed);for(let e=r.length-1;e>0;e--){let t=i.nextInt(e+1);[r[e],r[t]]=[r[t],r[e]]}return{drawn:n?r.slice(0,t):r.slice(-t).reverse(),newDeck:n?r.slice(t):r.slice(0,-t),reshuffled:!0,newSeed:i.getState()}}var Kd,qd=t((()=>{Wd(),Kd={type:`摸牌`,validate(e,t){return e.players[t.player]?t.count<=0?`count must be > 0`:e.zones.deck.length+e.zones.discardPile.length<t.count?`no cards available (deck + discardPile)`:null:`player ${t.player} not found`},apply(e,t){let n=!!t.fromBottom,r=Gd(e,t.count,n);r.reshuffled?(e.zones.deck=r.newDeck,e.zones.discardPile=[],e.rngSeed=r.newSeed):e.zones.deck=n?e.zones.deck.slice(t.count):e.zones.deck.slice(0,-t.count),e.players[t.player].hand.push(...r.drawn)},effect:{sound:`flip`,animation:`slide`,duration:600},toViewEvents(e,t){let n={sound:`flip`,animation:`slide`,duration:600},r=Gd(e,t.count,!!t.fromBottom),i=r.drawn.map(t=>e.cardMap[t]).filter(Boolean),a={type:`摸牌`,player:t.player,count:t.count,effect:n,reshuffled:r.reshuffled,...r.reshuffled?{newDeckCount:r.newDeck.length,newDiscardPileCount:0}:{}},o={...a,cards:i},s={...a};return{ownerViews:new Map([[t.player,o]]),othersView:s}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.count??0;e.players[n].handCount+=r,t.cards&&e.players[n].hand&&e.players[n].hand.push(...t.cards),e.zones&&(t.reshuffled?(e.zones.deckCount=t.newDeckCount??Math.max(0,e.zones.deckCount-r),e.zones.discardPileCount=t.newDiscardPileCount??0):e.zones.deckCount=Math.max(0,e.zones.deckCount-r))},toViewLog(e,t){let n=e.count??0,r=e.cards;if((e.player===t||r&&r.length>0)&&r&&r.length>0){let t=r.map(e=>`${e.suit??``}${e.rank??``}${e.name}`).join(`、`);return{player:e.player,text:`摸了 ${n} 张牌:${t}`}}return{player:e.player,text:`摸了 ${n} 张牌`}}}})),Jd,Yd=t((()=>{Jd={type:`整理牌堆`,validate(e,t){let n=new Set(e.zones.deck);if(t.cards.length!==e.zones.deck.length)return`card count mismatch`;for(let e of t.cards)if(!n.has(e))return`card ${e} not in deck`;return null},apply(e,t){e.zones.deck=[...t.cards]},effect:{sound:`card_place`,animation:`flip`,duration:600},toViewEvents(e,t){let n={type:`整理牌堆`,topCount:t.topCount??0,bottomCount:t.bottomCount??0};return{ownerViews:new Map,othersView:n}},applyView(){},toViewLog(e){let t=e.topCount??0,n=e.bottomCount??0,r=[];return t>0&&r.push(`${t}张放牌堆顶`),n>0&&r.push(`${n}张放牌堆底`),r.length===0?null:{player:-1,text:`整理牌堆:${r.join(`,`)}`}}}})),Xd,Zd=t((()=>{F(),Xd={type:`检测有效性`,validate(e,t){return e.players[t.target]?null:`target ${t.target} not found`},apply(){},toViewEvents(e,t){if(k(e,`检测有效性`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`检测有效性`,source:t.source,target:t.target,cardId:t.cardId};return{ownerViews:new Map([[t.target,n]]),othersView:n}},applyView(){},toViewLog(){return null}}})),Qd,$d=t((()=>{Qd={type:`添加延时锦囊`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.pendingTricks.some(e=>e.name===t.trick.name)||n.pendingTricks.push(t.trick)},effect:{sound:`flip`,animation:`glow`,duration:800},toViewEvents(e,t){let n={type:`添加延时锦囊`,player:t.player,trickName:t.trick.name,trick:t.trick};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;e.players[n].pendingTricks??=[];let r=t.trick;if(r?.card?.id){let t=e.players[n].pendingTricks,i=r.card.id;t.includes(i)||t.push(i)}},toViewLog(e){let t=e.trick;return{player:e.player,text:`判定区放入 ${t?.name??`延时锦囊`}`}}}})),ef,tf=t((()=>{G(),ef={type:`添加技能`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.skills.includes(t.skillId)||n.skills.push(t.skillId)},effect:{animation:`glow`,duration:500},toViewEvents(e,t){let n={type:`添加技能`,player:t.player,skillId:t.skillId},r=Cd.get(t.skillId);return r&&(n.mountDistanceVars=r),{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.skillId;e.players[n].skills.includes(r)||e.players[n].skills.push(r);let i=t.mountDistanceVars;i&&(e.players[n].distanceVars={...e.players[n].distanceVars,...i})}}})),nf,rf=t((()=>{nf={type:`清过期标记`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){e.players[t.player].marks=e.players[t.player].marks.filter(e=>e.duration!==`turn`)},toViewEvents(e,t){let n={type:`清过期标记`,player:t.player};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);n<0||(e.players[n].marks=e.players[n].marks.filter(e=>e.duration!==`turn`))}}})),af,of=t((()=>{F(),af={type:`生效前`,validate(e,t){return e.players[t.target]?null:`target ${t.target} not found`},apply(){},toViewEvents(e,t){if(k(e,`生效前`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`生效前`,source:t.source,target:t.target,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){}}})),sf,cf=t((()=>{sf={type:`生效后`,validate(e,t){return e.players[t.target]?null:`target ${t.target} not found`},apply(){},toViewEvents(e,t){let n=e.cardMap[t.cardId]?.name??t.cardId,r={type:`生效后`,source:t.source,target:t.target,cardId:t.cardId,cardName:n};return{ownerViews:new Map,othersView:r}},applyView(){}}})),lf,uf=t((()=>{F(),lf={type:`生效时`,validate(e,t){return e.players[t.target]?null:`target ${t.target} not found`},apply(){},toViewEvents(e,t){if(k(e,`生效时`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`生效时`,source:t.source,target:t.target,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){}}})),df,ff=t((()=>{W(),df={type:`移出至暂存区`,validate(e,t){if(!e.players[t.source])return`source ${t.source} not found`;if(!e.players[t.target])return`target ${t.target} not found`;if(typeof t.varsKey!=`string`||t.varsKey.length===0)return`varsKey 不能为空`;if(!Array.isArray(t.cardIds)||t.cardIds.length===0)return`cardIds 不能为空`;let n=e.players[t.target],r=new Set(Object.values(n.equipment).filter(e=>!!e));for(let e of t.cardIds)if(!n.hand.includes(e)&&!r.has(e))return`card ${e} not in target ${t.target} hand or equipment`;return new Set(t.cardIds).size===t.cardIds.length?null:`cardIds 不能重复`},apply(e,t){let n=e.players[t.target],r=new Set(t.cardIds);n.hand=n.hand.filter(e=>!r.has(e));for(let e of Object.keys(n.equipment)){let t=n.equipment[e];t&&r.has(t)&&(delete n.equipment[e],e===`武器`&&delete n.vars[wl])}let i=n.vars[t.varsKey]??[];for(let e of t.cardIds)i.includes(e)||i.push(e);n.vars[t.varsKey]=i},effect:{sound:`flip`,animation:`slide`,duration:600},toViewEvents(e,t){let n=e.players[t.target],r=t.cardIds.map(t=>e.cardMap[t]).filter(e=>!!e).map(e=>({id:e.id,name:e.name,suit:e.suit,rank:e.rank})),i=e=>{for(let t of Object.keys(n.equipment))if(n.equipment[t]===e)return t},a=[],o=[];for(let e of t.cardIds){let t=i(e);t?o.push({slot:t,cardId:e}):a.push(e)}let s={type:`移出至暂存区`,source:t.source,target:t.target,cardIds:t.cardIds,cards:r,handIds:a,equipEntries:o},c={type:`移出至暂存区`,source:t.source,target:t.target,handCount:a.length,equipEntries:o};return{ownerViews:new Map([[t.source,s],[t.target,s]]),othersView:c}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.target);if(n<0)return;let r=t.handIds,i=r?r.length:t.handCount??0;if(i>0&&(e.players[n].handCount=Math.max(0,e.players[n].handCount-i)),r&&e.players[n].hand){let t=new Set(r);e.players[n].hand=e.players[n].hand.filter(e=>!t.has(e.id))}let a=t.equipEntries;if(a)for(let t of a)delete e.players[n].equipment[t.slot],t.slot===`武器`&&e.players[n].distanceVars&&(e.players[n].distanceVars={...e.players[n].distanceVars,attackRange:void 0})},toViewLog(e){let t=e.handIds?.length??e.handCount??0,n=e.equipEntries?.length??0,r=t+n;return{player:e.source,text:`将 P${e.target} 的 ${r} 张牌移出游戏(手牌${t} 装备${n})`}}}})),pf,mf=t((()=>{pf={type:`移动牌`,validate(e,t){return e.cardMap[t.cardId]?null:`card ${t.cardId} not found`},apply(e,t){if(t.from.zone===`手牌`){let n=t.from;e.players[n.player].hand=e.players[n.player].hand.filter(e=>e!==t.cardId)}else if(t.from.zone===`牌堆`)e.zones.deck=e.zones.deck.filter(e=>e!==t.cardId);else if(t.from.zone===`弃牌堆`)e.zones.discardPile=e.zones.discardPile.filter(e=>e!==t.cardId);else if(t.from.zone===`处理区`){let n=e.settlementStack[e.settlementStack.length-1];n?n.cards=n.cards.filter(e=>e!==t.cardId):e.zones.processing=e.zones.processing.filter(e=>e!==t.cardId)}if(t.to.zone===`手牌`){let n=t.to;e.players[n.player].hand.push(t.cardId)}else if(t.to.zone===`牌堆`)e.zones.deck.push(t.cardId);else if(t.to.zone===`弃牌堆`){let n=e.cardMap[t.cardId];n?.ephemeral?delete e.cardMap[t.cardId]:n?.shadowOf?(e.zones.discardPile.push(n.shadowOf),delete e.cardMap[t.cardId]):e.zones.discardPile.push(t.cardId)}else if(t.to.zone===`处理区`){let n=e.settlementStack[e.settlementStack.length-1];n?n.cards.push(t.cardId):e.zones.processing.push(t.cardId)}},toViewEvents(e,t){let n=e.cardMap[t.cardId],r=n?{name:n.name,suit:n.suit,rank:n.rank}:null,i=t.from.zone===`手牌`?t.from.player:void 0,a=t.to.zone===`手牌`?t.to.player:void 0;if(t.to.zone===`弃牌堆`&&i!==void 0&&r){let a=n?.shadowOf?e.cardMap[n.shadowOf]:void 0,o={type:`弃牌`,player:i,card:a?{name:a.name,suit:a.suit,rank:a.rank}:r,cardId:t.cardId,effect:{sound:`flip`,duration:600}};return{ownerViews:new Map,othersView:o}}if(t.to.zone===`处理区`&&i!==void 0&&r){let e={type:`打出`,player:i,card:r,cardId:t.cardId,effect:{animation:`flip`,duration:800}};return{ownerViews:new Map,othersView:e}}if(t.from.zone===`牌堆`&&a!==void 0&&n){let e={sound:`flip`,animation:`slide`,duration:600};return{ownerViews:new Map([[a,{type:`摸牌`,player:a,count:1,cards:[n],effect:e}]]),othersView:{type:`摸牌`,player:a,count:1,effect:e}}}let o={type:`移动牌`,cardId:t.cardId,from:t.from,to:t.to,player:i??a,...e.cardMap[t.cardId]?.ephemeral?{ephemeral:!0}:{}};return{ownerViews:new Map,othersView:o}},applyView(e,t){if(t.type===`移动牌`&&e.zones){let n=t.from,r=t.to,i=t.cardId;if(n?.zone===`牌堆`)e.zones.deckCount=Math.max(0,e.zones.deckCount-1);else if(n?.zone===`弃牌堆`)e.zones.discardPileCount=Math.max(0,e.zones.discardPileCount-1);else if(n?.zone===`处理区`){let t=e.settlementStack[e.settlementStack.length-1];t&&(t.cards=t.cards.filter(e=>e!==i)),e.zones&&(e.zones.processing=e.zones.processing.filter(e=>e!==i))}if(r?.zone===`牌堆`)e.zones.deckCount+=1;else if(r?.zone===`弃牌堆`)t.ephemeral!==!0&&(e.zones.discardPileCount+=1);else if(r?.zone===`处理区`){let t=e.settlementStack[e.settlementStack.length-1];t&&t.cards.push(i),e.zones&&e.zones.processing.push(i)}}let n=e.players.findIndex(e=>e.index===t.player);if(!(n<0))switch(t.type){case`弃牌`:if(e.players[n].handCount=Math.max(0,e.players[n].handCount-1),e.players[n].hand&&t.cardId){let r=t.cardId;e.players[n].hand=e.players[n].hand.filter(e=>e.id!==r)}e.zones&&(e.zones.discardPileCount+=1);break;case`打出`:if(e.players[n].handCount=Math.max(0,e.players[n].handCount-1),e.players[n].hand&&t.cardId){let r=t.cardId;e.players[n].hand=e.players[n].hand.filter(e=>e.id!==r)}if(e.zones&&t.cardId){e.zones.processing.push(t.cardId);let n=e.settlementStack[e.settlementStack.length-1];n&&n.cards.push(t.cardId)}break;case`摸牌`:{let r=t.count??1;e.players[n].handCount+=r,t.cards&&e.players[n].hand&&e.players[n].hand.push(...t.cards),e.zones&&(e.zones.deckCount=Math.max(0,e.zones.deckCount-r));break}default:{let n=t.from,r=t.to,i=t.cardId;if(n?.zone===`手牌`&&n?.player!==void 0){let t=e.players.findIndex(e=>e.index===n.player);t>=0&&(e.players[t].handCount=Math.max(0,e.players[t].handCount-1),e.players[t].hand&&(e.players[t].hand=e.players[t].hand.filter(e=>e.id!==i)))}if(r?.zone===`手牌`&&r?.player!==void 0){let t=e.players.findIndex(e=>e.index===r.player);if(t>=0&&(e.players[t].handCount+=1,i&&e.players[t].hand)){let n=e.cardMap[i];n&&e.players[t].hand.push(n)}}break}}}}})),hf,gf=t((()=>{hf={type:`移除延时锦囊`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){e.players[t.player].pendingTricks=e.players[t.player].pendingTricks.filter(e=>e.name!==t.trickName)},effect:{sound:`flip`,animation:`fade`,duration:600},toViewEvents(e,t){let n=e.players[t.player].pendingTricks.find(e=>e.name===t.trickName),r={type:`移除延时锦囊`,player:t.player,trickName:t.trickName,...n?.card?.id?{cardId:n.card.id}:{}};return{ownerViews:new Map,othersView:r}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=e.players[n].pendingTricks;if(!r||r.length===0)return;let i=t.cardId,a=t.trickName;if(i){e.players[n].pendingTricks=r.filter(e=>e!==i);return}if(!a)return;let o=Object.keys(e.cardMap).find(t=>e.cardMap[t]?.name===a);o?e.players[n].pendingTricks=r.filter(e=>e!==o):e.players[n].pendingTricks=[...r]}}})),_f,vf=t((()=>{G(),_f={type:`移除技能`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){e.players[t.player].skills=e.players[t.player].skills.filter(e=>e!==t.skillId)},effect:{animation:`fade`,duration:400},toViewEvents(e,t){let n={type:`移除技能`,player:t.player,skillId:t.skillId},r=Cd.get(t.skillId);return r&&(n.clearMountDistanceVars=r),{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.skillId;e.players[n].skills=e.players[n].skills.filter(e=>e!==r);let i=t.clearMountDistanceVars;i&&(e.players[n].distanceVars={...e.players[n].distanceVars,attackMod:i.attackMod===void 0?e.players[n].distanceVars?.attackMod:void 0,defenseMod:i.defenseMod===void 0?e.players[n].distanceVars?.defenseMod:void 0})}}})),yf,bf=t((()=>{Wd(),yf={type:`结算帧入栈`,validate(){return null},apply(e,t){let n={skillId:t.skillId,from:t.from,params:{...t.params??{}},cards:[],cancelled:!1};e.settlementStack.push(n)},toViewEvents(e,t){let n=Ud(e.rngSeed).next()<.5?`1`:`2`,r={type:`结算帧入栈`,skillId:t.skillId,from:t.from,params:{...t.params??{}},effect:{sound:`skill/${t.skillId}/${n}`}};return{ownerViews:new Map,othersView:r}},applyView(e,t){e.settlementStack.push({skillId:t.skillId,from:t.from,params:{...t.params??{}},cards:[],cancelled:!1})}}})),xf,Sf=t((()=>{xf={type:`结算帧出栈`,validate(e){return e.settlementStack.length===0?`settlementStack 为空,无可弹出帧`:null},apply(e){e.settlementStack.pop()},toViewEvents(){return{ownerViews:new Map,othersView:{type:`结算帧出栈`}}},applyView(e){e.settlementStack.pop()}}})),Cf,nee=t((()=>{V(),Cf={type:`给予`,validate(e,t){if(!e.cardMap[t.cardId])return`card ${t.cardId} not found`;let n=e.players[t.from];return n?n.hand.includes(t.cardId)?e.players[t.to]?null:`to ${t.to} not found`:`card not in from's hand`:`from ${t.from} not found`},apply(e,t){let n=t.from,r=t.to;e.players[n].hand=e.players[n].hand.filter(e=>e!==t.cardId),e.players[r].hand.push(t.cardId)},effect:{sound:`flip`,animation:`slide`,duration:600},async afterApply(e,t){await B(e,{type:`移动到目标区域后`,cardId:t.cardId,from:{zone:`手牌`,player:t.from},to:{zone:`手牌`,player:t.to},reason:`给予`})},toViewEvents(e,t){let n={sound:`flip`,animation:`slide`,duration:600},r={type:`给予`,cardId:t.cardId,cardName:e.cardMap[t.cardId]?.name,from:t.from,to:t.to,effect:n},i={type:`给予`,from:t.from,to:t.to,effect:n};return{ownerViews:new Map([[t.from,r],[t.to,r]]),othersView:i}},applyView(e,t){let n=t.cardId,r=e.players.findIndex(e=>e.index===t.from);r>=0&&(e.players[r].handCount=Math.max(0,e.players[r].handCount-1),n&&e.players[r].hand&&(e.players[r].hand=e.players[r].hand.filter(e=>e.id!==n)));let i=e.players.findIndex(e=>e.index===t.to);if(i>=0&&(e.players[i].handCount+=1,n&&e.players[i].hand)){let t=e.cardMap[n];t&&e.players[i].hand.push(t)}},toViewLog(e,t,n){let r=e.from,i=e.to,a=e.cardName,o=n?.(i)??`P${i}`;return(r===t||i===t)&&a?{player:r,text:`将 ${a} 给予了 ${o}`}:{player:r,text:`给 ${o} 一张牌`}}}})),wf,Tf=t((()=>{wf={type:`置创牌`,validate(e,t){return e.players[t.player]?e.zones.deck.length===0?`牌堆为空,无法置创牌`:null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player],{varsKey:r,resultKey:i}=t,a=e.zones.deck.pop(),o=e.cardMap[a]?.rank,s=n.vars[r]??[],c=o!==void 0&&s.some(t=>e.cardMap[t]?.rank===o);c?e.zones.discardPile.push(a):(s.push(a),n.vars[r]=s),e.localVars[i]=c},effect:{sound:`flip`,animation:`flip`,duration:800},toViewEvents(e,t){let{varsKey:n}=t,r=e.zones.deck[e.zones.deck.length-1],i=r?e.cardMap[r]:void 0,a=e.players[t.player].vars[n]??[],o=i?.rank,s=o!==void 0&&a.some(t=>e.cardMap[t]?.rank===o),c={type:`置创牌`,player:t.player,cardId:r,suit:i?.suit,rank:o,duplicate:s};return{ownerViews:new Map,othersView:c}},applyView(e,t){e.zones&&(e.zones.deckCount=Math.max(0,e.zones.deckCount-1),t.duplicate&&(e.zones.discardPileCount+=1))},toViewLog(e){let t=e.rank,n=e.suit,r=e.duplicate;return{player:e.player,text:`翻开创牌 ${n??``}${t??`?`}${r?`(点数重复!)`:``}`}}}})),Ef,Df,Of=t((()=>{V(),Ef=`__获得/来自手牌`,Df={type:`获得`,validate(e,t){return e.cardMap[t.cardId]?e.players[t.player]?t.from!==void 0&&!e.players[t.from]?`from ${t.from} not found`:null:`player ${t.player} not found`:`card ${t.cardId} not found`},apply(e,t){let n=!1;if(t.from!==void 0){let r=e.players[t.from];n=r.hand.includes(t.cardId),r.hand=r.hand.filter(e=>e!==t.cardId);let i={};for(let[e,n]of Object.entries(r.equipment))n&&n!==t.cardId&&(i[e]=n);r.equipment=i}e.localVars[Ef]=n,e.players[t.player].hand.push(t.cardId)},effect:{sound:`flip`,animation:`slide`,duration:600},async afterApply(e,t){let n=e.localVars[Ef];delete e.localVars[Ef],!(!n||t.from===void 0)&&await B(e,{type:`移动到目标区域后`,cardId:t.cardId,from:{zone:`手牌`,player:t.from},to:{zone:`手牌`,player:t.player},reason:`获得`})},toViewEvents(e,t){let n={sound:`flip`,animation:`slide`,duration:600},r=t.from===void 0?void 0:e.players[t.from].hand.includes(t.cardId)?`hand`:`equipment`,i={type:`获得`,player:t.player,cardId:t.cardId,cardName:e.cardMap[t.cardId]?.name,...t.from===void 0?{}:{from:t.from,fromZone:r},effect:n},a={type:`获得`,player:t.player,...t.from===void 0?{}:{from:t.from,fromZone:r},...r===`equipment`?{cardId:t.cardId}:{},effect:n},o=new Map([[t.player,i]]);return t.from!==void 0&&o.set(t.from,i),{ownerViews:o,othersView:a}},applyView(e,t){let n=t.cardId,r=e.players.findIndex(e=>e.index===t.player);if(r<0)return;if(e.players[r].handCount+=1,n&&e.players[r].hand){let t=e.cardMap[n];t&&e.players[r].hand.push(t)}let i=t.from,a=t.fromZone;if(i!==void 0){let t=e.players.findIndex(e=>e.index===i);if(t>=0)if(a===`equipment`){let r={};for(let[i,a]of Object.entries(e.players[t].equipment))a&&a!==n&&(r[i]=a);e.players[t].equipment=r}else e.players[t].handCount=Math.max(0,e.players[t].handCount-1),n&&e.players[t].hand&&(e.players[t].hand=e.players[t].hand.filter(e=>e.id!==n))}},toViewLog(e,t,n){let r=e.player,i=e.cardName,a=e.from,o=r===t||a===t;if(a!==void 0){let e=n?.(a)??`P${a}`;return o&&i?{player:r,text:`从 ${e} 处获得了 ${i}`}:{player:r,text:`从 ${e} 处获得了一张牌`}}return o&&i?{player:r,text:`获得了 ${i}`}:{player:r,text:`获得了一张牌`}}}})),kf,Af=t((()=>{kf={type:`被抵消`,validate(e,t){return e.players[t.target]?null:`target ${t.target} not found`},apply(){},toViewEvents(e,t){let n={type:`被抵消`,source:t.source,target:t.target,cardId:t.cardId};return{ownerViews:new Map,othersView:n}},applyView(){},toViewLog(e){return{player:e.target,text:`抵消`}}}}));function jf(e){switch(e){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function Mf(e,t,n,r){let i=e.players[t].vars;n===`武器`&&(i[wl]=r.range??1)}var Nf,Pf=t((()=>{W(),Nf={type:`装备`,validate(e,t){let n=e.players[t.player];if(!n)return`player ${t.player} not found`;if(!n.hand.includes(t.cardId))return`card not in player's hand`;let r=e.cardMap[t.cardId];return r?jf(r.subtype)?null:`card is not equipment`:`card ${t.cardId} not found`},apply(e,t){let n=e.cardMap[t.cardId],r=jf(n.subtype),i=e.players[t.player];i.hand=i.hand.filter(e=>e!==t.cardId),i.equipment[r]=t.cardId,Mf(e,t.player,r,n)},effect:{animation:`glow`,duration:400},toViewEvents(e,t){let n=e.cardMap[t.cardId],r=jf(n.subtype),i={type:`装备`,player:t.player,cardId:t.cardId,cardName:n.name,slot:r,...r===`武器`?{range:n.range??1}:{},effect:{sound:`equip/${n.name}`}};return{ownerViews:new Map,othersView:i}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.slot;r&&(e.players[n].equipment[r]=t.cardId),r===`武器`&&typeof t.range==`number`&&(e.players[n].distanceVars={...e.players[n].distanceVars,attackRange:t.range}),e.players[n].handCount=Math.max(0,e.players[n].handCount-1),e.players[n].hand&&(e.players[n].hand=e.players[n].hand.filter(e=>e.id!==t.cardId))},toViewLog(e){return{player:e.player,text:`装备了 ${e.cardName??e.cardId}`}}}})),Ff,If=t((()=>{Ff={type:`设上限`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.maxHealth=t.amount,n.health=Math.min(n.health,t.amount)},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=e.players[n];r.maxHealth=t.amount,r.health=Math.min(r.health,t.amount)}}})),Lf,Rf=t((()=>{Lf={type:`设横置`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e,t){let n=e.players[t.player];n.marks=n.marks.filter(e=>e.id!==`chained`),t.chained&&n.marks.push({id:`chained`,scope:n.index})},effect:{sound:`chain`,animation:`pulse`,duration:500},toViewEvents(e,t){let n={type:`设横置`,player:t.player,chained:t.chained};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=e.players.findIndex(e=>e.index===t.player);if(n<0)return;let r=t.chained;e.players[n].marks=e.players[n].marks.filter(e=>e.id!==`chained`),r&&e.players[n].marks.push({id:`chained`,scope:e.players[n].index})}}}));function zf(e,t,n,r){let i=k(e,t);for(let e of i)if(e.ownerId===n)return!0;return A(e,t,n,r)}function Bf(e){return e.handEmpty?`skip`:e.hasMatching?`normal`:`silent`}function Vf(e){let t=Bf(e);return t===`skip`?`skip`:t===`silent`?{delayMs:Gf}:null}function Hf(e,t,n){let r=e.players[t];if(!r)return{handEmpty:!0,hasMatching:!1};let i=r.hand;if(i.length===0)return{handEmpty:!0,hasMatching:!1};let a=!1;for(let t of i){let r=e.cardMap[t];if(r)try{if(n(r)){a=!0;break}}catch{a=!0;break}}return{handEmpty:!1,hasMatching:a}}function Uf(e,t,n,r,i){return zf(e,t,n,i)?`normal`:Bf(Hf(e,n,r))}function Wf(e,t,n,r,i){return zf(e,t,n,i)?null:Vf(Hf(e,n,r))}var Gf,Kf,qf=t((()=>{F(),Gf=1500,Kf={type:`confirm`,title:`等待回应`,cancelLabel:``}})),Jf,Yf,Xf,Zf=t((()=>{ze(),qf(),Jf=15,Yf={type:`useCard`,title:`是否出杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},Xf={type:`询问杀`,validate(e,t){return e.players[t.target]?null:`target not found`},apply(e){},pending:{onTimeout:async()=>{},prompt:Yf,timeout:Jf,preResolve:(e,t)=>Wf(e,`询问杀`,t.target,e=>e.name===`杀`)},effect:{blockUntilDone:!0,duration:200},toViewEvents(e,t){let n=Uf(e,`询问杀`,t.target,e=>e.name===`杀`),r=n===`silent`?Gf:Re(e,Jf),i={type:`询问杀`,target:t.target,source:t.source,timeoutMs:r,responseMode:n};return{ownerViews:new Map([[t.target,i]]),othersView:i}},applyView(e,t){let n=t.target,r=t.responseMode??`normal`;if(r===`skip`)return;let i=t.timeoutMs??Jf*1e3,a={type:`询问杀`,target:n,source:t.source};if(r===`silent`){e.pending={type:`awaits`,atom:a,prompt:Kf,target:n,responseMode:`silent`,deadline:Date.now()+i,totalMs:i};return}e.viewer===n?e.pending={type:`awaits`,atom:a,prompt:Yf,target:n,responseMode:`normal`,deadline:Date.now()+i,totalMs:i}:e.pending={type:`awaits`,atom:a,prompt:{type:`confirm`,title:`等待出杀`,cancelLabel:``},target:n,deadline:Date.now()+i,totalMs:i}}}})),Qf,$f,ep,tp=t((()=>{ze(),qf(),Qf=15,$f={type:`useCard`,title:`是否出闪`,cardFilter:{filter:e=>e.name===`闪`,min:1,max:1}},ep={type:`询问闪`,validate(e,t){return e.players[t.target]?null:`target not found`},apply(e){},pending:{onTimeout:async()=>{},prompt:$f,timeout:Qf,preResolve:(e,t)=>Wf(e,`询问闪`,t.target,e=>e.name===`闪`)},effect:{blockUntilDone:!0,duration:200},toViewEvents(e,t){let n=Uf(e,`询问闪`,t.target,e=>e.name===`闪`),r=n===`silent`?Gf:Re(e,Qf),i={type:`询问闪`,target:t.target,source:t.source,timeoutMs:r,responseMode:n};return{ownerViews:new Map([[t.target,i]]),othersView:i}},applyView(e,t){let n=t.target,r=t.responseMode??`normal`;if(r===`skip`)return;let i=t.timeoutMs??Qf*1e3,a={type:`询问闪`,target:n,source:t.source};if(r===`silent`){e.pending={type:`awaits`,atom:a,prompt:Kf,target:n,responseMode:`silent`,deadline:Date.now()+i,totalMs:i};return}e.viewer===n?e.pending={type:`awaits`,atom:a,prompt:$f,target:n,responseMode:`normal`,deadline:Date.now()+i,totalMs:i}:e.pending={type:`awaits`,atom:a,prompt:{type:`confirm`,title:`等待出闪`,cancelLabel:``},target:n,deadline:Date.now()+i,totalMs:i}}}}));function np(e){let t=ap.get(e);return t||(t={providers:new Map},ap.set(e,t)),t}function rp(e,t,n){let r=np(e),i=r.providers.get(t);return i||(i=new Set,r.providers.set(t,i)),i.add(n),()=>{let e=r.providers.get(t);e&&(e.delete(n),e.size===0&&r.providers.delete(t))}}function ip(e,t){let n=np(e).providers.get(t);if(n&&n.size>0){let r=-1/0;for(let i of n){let n=i(e,t);typeof n==`number`&&n>r&&(r=n)}if(r!==-1/0)return r}let r=sl(e.turn.vars,t)??0;return p(e.players[t])+r}var ap,op=t((()=>{b(),W(),ap=new WeakMap}));function sp(e,t){if(e.type!==`choosePlayer`)return e;let n=e;if(n.candidates!==void 0||!n.filter)return e;let r=t.players.map((e,t)=>({index:t,name:e.name,character:e.character,faction:e.faction,health:e.health,maxHealth:e.maxHealth,alive:e.alive,equipment:{...e.equipment},skills:[...e.skills],handCount:e.hand.length,marks:[...e.marks],pendingTricks:e.pendingTricks.map(e=>e.card.id)})),i={players:r,cardMap:t.cardMap},a=[];for(let e=0;e<r.length;e++){if(!r[e].alive)continue;let t;try{t=!!n.filter(i,e)}catch{t=!0}t&&a.push(e)}return{...n,candidates:a}}var cp=t((()=>{}));function lp(e,t,n){if(e.type!==`useCard`&&e.type!==`useCardAndTarget`)return e;let r=e,i=r.cardFilter;if(i.candidates!==void 0||n<0||!i.filter)return e;let a=t.players[n];if(!a)return e;let o=[];for(let e of a.hand){let n=t.cardMap[e];n&&i.filter(n)&&o.push(e)}return{...r,cardFilter:{...i,candidates:o}}}var up=t((()=>{}));function dp(e){if(e.mandatory===!0||e.prompt.type!==`useCard`)return null;let t=e.prompt.cardFilter?.filter;return typeof t==`function`?t:null}var fp,pp=t((()=>{V(),ze(),op(),cp(),up(),qf(),fp={type:`请求回应`,validate(e,t){return t.target<0||e.players[t.target]?null:`target not found`},apply(e){},pending:{async onTimeout(e,t){if(t.requestType===`__弃牌`){let n=t.target,r=e.players[n];if(!r)return;let i=ip(e,n);if(r.hand.length<=i)return;let a=r.hand.length-i,o={桃:0,杀:1,闪:2,无懈可击:3};await B(e,{type:`弃置`,player:n,cardIds:[...r.hand].sort((t,n)=>{let r=e.cardMap[t];return(o[e.cardMap[n]?.name??``]??9)-(o[r?.name??``]??9)}).slice(0,a)});return}},prompt:{type:`confirm`,title:`请回应`},timeout:30,preResolve:(e,t)=>{if(t.target<0)return null;let n=dp(t);return n?Wf(e,`请求回应`,t.target,n,t.requestType):null}},effect:{blockUntilDone:!0,duration:200},toViewEvents(e,t){let n=t.timeout??fp.pending.timeout,r=t.target<0,i=dp(t),a=i&&t.target>=0?Uf(e,`请求回应`,t.target,i,t.requestType):`normal`,o=a===`silent`?Gf:Re(e,n,r),s=lp(sp(t.prompt,e),e,t.target),c={type:`请求回应`,requestType:t.requestType,target:t.target,prompt:s,timeoutMs:o,mandatory:t.mandatory===!0?!0:void 0,responseMode:a};if(t.target<0)return{ownerViews:new Map([[t.target,c]]),othersView:c};let l={type:`请求回应`,requestType:t.requestType,target:t.target,timeoutMs:o,mandatory:t.mandatory===!0?!0:void 0,responseMode:a};return{ownerViews:new Map([[t.target,c]]),othersView:l}},applyView(e,t){let n=t.target,r=t.requestType,i=t.prompt,a=t.timeoutMs??30*1e3,o=t.mandatory===!0,s=t.responseMode??`normal`;if(n<0){if(!i||e.viewer>=0&&e.players[e.viewer]?.alive===!1)return;e.pending={type:`awaits`,atom:{type:`请求回应`,requestType:r,target:n,prompt:i},prompt:i,target:n,deadline:Date.now()+a,totalMs:a,mandatory:o};return}if(s!==`skip`)if(e.viewer===n){if(s===`silent`){e.pending={type:`awaits`,atom:{type:`请求回应`,requestType:r,target:n},prompt:Kf,target:n,responseMode:`silent`,deadline:Date.now()+a,totalMs:a,mandatory:o};return}if(!i)return;e.pending={type:`awaits`,atom:{type:`请求回应`,requestType:r,target:n,prompt:i},prompt:i,target:n,responseMode:`normal`,deadline:Date.now()+a,totalMs:a,mandatory:o}}else e.pending={type:`awaits`,atom:{type:`请求回应`,requestType:r,target:n},prompt:{type:`confirm`,title:`等待回应`,cancelLabel:``},target:n,deadline:Date.now()+a,totalMs:a,mandatory:o}}}}));function mp(e){return hp[e]??``}var hp,gp=t((()=>{hp={杀:`对攻击范围内的一名角色使用,目标可出闪抵消。默认每回合限一次。`,闪:`抵消一次杀的效果。`,桃:`濒死时回复 1 点体力,或自己的出牌阶段回复 1 点体力。`,酒:`出牌阶段使用,本回合下一张杀伤害+1;或濒死时当桃用。`,过河拆桥:`弃置目标区域内一张牌(无距离限制)。`,顺手牵羊:`获取目标区域内一张牌(距离限制1)。`,无中生有:`摸两张牌。`,桃园结义:`所有角色回复 1 点体力。`,借刀杀人:`令目标对其攻击范围内的另一角色出杀。`,决斗:`与目标轮流出杀,先不出杀的一方受 1 点伤害。`,南蛮入侵:`所有其他角色需出杀,否则受 1 点伤害。`,万箭齐发:`所有其他角色需出闪,否则受 1 点伤害。`,五谷丰登:`从牌堆亮出等同于存活角色数的牌,每名角色依次拿一张。`,乐不思蜀:`延时锦囊,判定非红桃则跳过出牌阶段。`,无懈可击:`抵消一张锦囊牌的效果。`,闪电:`延时锦囊,判定黑桃2-9则造成 3 点伤害。`,兵粮寸断:`延时锦囊,判定非草花则跳过摸牌阶段。`,铁索连环:`锦囊,横置或重置一至两名角色的连环状态;或重铸(弃此牌摸一张)。连环状态下受到属性伤害时传导至所有连环角色。`,火攻:`锦囊,目标展示一张手牌,若你弃置一张同花色手牌,对其造成 1 点火焰伤害。`,诸葛连弩:`锁定技,出杀次数不限。`,青釭剑:`锁定技,你使用杀无视目标防具。`,寒冰剑:`当你使用杀造成伤害时,可改为弃置目标两张牌。`,雌雄双股剑:`当你使用杀指定异性目标时,可令其选择弃一张手牌或让你摸一张牌。`,贯石斧:`杀被闪后可弃2张牌强命。`,青龙偃月刀:`杀被闪后可再出一张杀。`,丈八蛇矛:`你可将两张手牌当一张杀使用或打出。`,方天画戟:`当你使用杀是手牌最后一张时,可额外指定至多两个目标。`,麒麟弓:`当你使用杀造成伤害时,可弃置目标一匹坐骑。`,八卦阵:`防具,需出闪时可判定,红牌视为闪。`,仁王盾:`防具,锁定技,对你使用的黑色杀无效。`,赤兔:`进攻马,距离-1。`,紫骍:`进攻马,距离-1。`,大宛:`进攻马,距离-1。`,的卢:`防御马,距离+1。`,绝影:`防御马,距离+1。`,爪黄飞电:`防御马,距离+1。`,古锭刀:`锁定技,当你使用杀造成伤害时,若目标没有手牌,此伤害+1。`,朱雀羽扇:`你可将一张普通杀当火杀使用或打出。`,藤甲:`锁定技,南蛮入侵/万箭齐发/普通杀对你无效;当你受到火焰伤害时,此伤害+1。`,白银狮子:`锁定技,当你受到大于1点的伤害时,伤害改为1点;当你失去装备区里的白银狮子后,回复1点体力。`,骅骝:`防御马,距离+1。`}}));function _p(e){let t=Cp.get(e);if(!t)throw Error(`deck.ts: 未知牌名「${e}」,未在 CardDef 注册表中找到`);return t}function vp(){let e=[],t=0;for(let[n,r,i,a]of[...xp,...Sp]){let{type:o,subtype:s}=_p(n),c=mp(n),l={name:n,type:o,subtype:s,suit:r,color:f(r),rank:i,description:c,id:`${n}-${r}${i}-${t++}`},u=bp.get(n);u!=null&&(l.range=u);let d=Cp.get(n);d?.slashUnlimited&&(l.slashUnlimited=!0),d?.slashTargetBonusWhenLastCard!=null&&(l.slashTargetBonusWhenLastCard=d.slashTargetBonusWhenLastCard),a?.trickSubtype&&(l.trickSubtype=a.trickSubtype),a?.damageType&&(l.damageType=a.damageType),e.push(l)}return e}function yp(e,t){let n=[...e];for(let e=n.length-1;e>0;e--){let r=t.nextInt(e+1);[n[e],n[r]]=[n[r],n[e]]}return n}var bp,xp,Sp,Cp,wp=t((()=>{b(),G(),gp(),Td(),bp=new Map;for(let e of Sd)typeof e.range==`number`&&bp.set(e.name,e.range);xp=[[`桃园结义`,`♥`,`A`],[`万箭齐发`,`♥`,`A`],[`闪`,`♥`,`2`],[`闪`,`♥`,`2`],[`桃`,`♥`,`3`],[`五谷丰登`,`♥`,`3`],[`桃`,`♥`,`4`],[`五谷丰登`,`♥`,`4`],[`麒麟弓`,`♥`,`5`],[`赤兔`,`♥`,`5`],[`桃`,`♥`,`6`],[`乐不思蜀`,`♥`,`6`,{trickSubtype:`延时锦囊`}],[`桃`,`♥`,`7`],[`无中生有`,`♥`,`7`],[`桃`,`♥`,`8`],[`无中生有`,`♥`,`8`],[`桃`,`♥`,`9`],[`无中生有`,`♥`,`9`],[`杀`,`♥`,`10`],[`杀`,`♥`,`10`],[`杀`,`♥`,`J`],[`无中生有`,`♥`,`J`],[`桃`,`♥`,`Q`],[`过河拆桥`,`♥`,`Q`],[`闪电`,`♥`,`Q`,{trickSubtype:`延时锦囊`}],[`闪`,`♥`,`K`],[`爪黄飞电`,`♥`,`K`],[`决斗`,`♠`,`A`],[`闪电`,`♠`,`A`,{trickSubtype:`延时锦囊`}],[`雌雄双股剑`,`♠`,`2`],[`八卦阵`,`♠`,`2`],[`寒冰剑`,`♠`,`2`],[`过河拆桥`,`♠`,`3`],[`顺手牵羊`,`♠`,`3`],[`过河拆桥`,`♠`,`4`],[`顺手牵羊`,`♠`,`4`],[`青龙偃月刀`,`♠`,`5`],[`绝影`,`♠`,`5`],[`乐不思蜀`,`♠`,`6`,{trickSubtype:`延时锦囊`}],[`青釭剑`,`♠`,`6`],[`杀`,`♠`,`7`],[`南蛮入侵`,`♠`,`7`],[`杀`,`♠`,`8`],[`杀`,`♠`,`8`],[`杀`,`♠`,`9`],[`杀`,`♠`,`9`],[`杀`,`♠`,`10`],[`杀`,`♠`,`10`],[`顺手牵羊`,`♠`,`J`],[`无懈可击`,`♠`,`J`,{trickSubtype:`响应锦囊`}],[`过河拆桥`,`♠`,`Q`],[`丈八蛇矛`,`♠`,`Q`],[`南蛮入侵`,`♠`,`K`],[`大宛`,`♠`,`K`],[`诸葛连弩`,`♦`,`A`],[`决斗`,`♦`,`A`],[`闪`,`♦`,`2`],[`闪`,`♦`,`2`],[`闪`,`♦`,`3`],[`顺手牵羊`,`♦`,`3`],[`闪`,`♦`,`4`],[`顺手牵羊`,`♦`,`4`],[`闪`,`♦`,`5`],[`贯石斧`,`♦`,`5`],[`杀`,`♦`,`6`],[`闪`,`♦`,`6`],[`杀`,`♦`,`7`],[`闪`,`♦`,`7`],[`杀`,`♦`,`8`],[`闪`,`♦`,`8`],[`杀`,`♦`,`9`],[`闪`,`♦`,`9`],[`杀`,`♦`,`10`],[`闪`,`♦`,`10`],[`闪`,`♦`,`J`],[`闪`,`♦`,`J`],[`桃`,`♦`,`Q`],[`方天画戟`,`♦`,`Q`],[`无懈可击`,`♦`,`Q`,{trickSubtype:`响应锦囊`}],[`杀`,`♦`,`K`],[`紫骍`,`♦`,`K`],[`决斗`,`♣`,`A`],[`诸葛连弩`,`♣`,`A`],[`杀`,`♣`,`2`],[`八卦阵`,`♣`,`2`],[`仁王盾`,`♣`,`2`],[`杀`,`♣`,`3`],[`过河拆桥`,`♣`,`3`],[`杀`,`♣`,`4`],[`过河拆桥`,`♣`,`4`],[`杀`,`♣`,`5`],[`的卢`,`♣`,`5`],[`杀`,`♣`,`6`],[`乐不思蜀`,`♣`,`6`,{trickSubtype:`延时锦囊`}],[`杀`,`♣`,`7`],[`南蛮入侵`,`♣`,`7`],[`杀`,`♣`,`8`],[`杀`,`♣`,`8`],[`杀`,`♣`,`9`],[`杀`,`♣`,`9`],[`杀`,`♣`,`10`],[`杀`,`♣`,`10`],[`杀`,`♣`,`J`],[`杀`,`♣`,`J`],[`借刀杀人`,`♣`,`Q`],[`无懈可击`,`♣`,`Q`,{trickSubtype:`响应锦囊`}],[`借刀杀人`,`♣`,`K`],[`无懈可击`,`♣`,`K`,{trickSubtype:`响应锦囊`}]],Sp=[[`无懈可击`,`♥`,`A`,{trickSubtype:`响应锦囊`}],[`火攻`,`♥`,`2`],[`火攻`,`♥`,`3`],[`杀`,`♥`,`4`,{damageType:`火焰`}],[`桃`,`♥`,`5`],[`桃`,`♥`,`6`],[`杀`,`♥`,`7`,{damageType:`火焰`}],[`闪`,`♥`,`8`],[`闪`,`♥`,`9`],[`杀`,`♥`,`10`,{damageType:`火焰`}],[`闪`,`♥`,`J`],[`闪`,`♥`,`Q`],[`无懈可击`,`♥`,`K`,{trickSubtype:`响应锦囊`}],[`白银狮子`,`♣`,`A`],[`藤甲`,`♣`,`2`],[`酒`,`♣`,`3`],[`兵粮寸断`,`♣`,`4`,{trickSubtype:`延时锦囊`}],[`杀`,`♣`,`5`,{damageType:`雷电`}],[`杀`,`♣`,`6`,{damageType:`雷电`}],[`杀`,`♣`,`7`,{damageType:`雷电`}],[`杀`,`♣`,`8`,{damageType:`雷电`}],[`酒`,`♣`,`9`],[`铁索连环`,`♣`,`10`],[`铁索连环`,`♣`,`J`],[`铁索连环`,`♣`,`Q`],[`铁索连环`,`♣`,`K`],[`古锭刀`,`♠`,`A`],[`藤甲`,`♠`,`2`],[`酒`,`♠`,`3`],[`杀`,`♠`,`4`,{damageType:`雷电`}],[`杀`,`♠`,`5`,{damageType:`雷电`}],[`杀`,`♠`,`6`,{damageType:`雷电`}],[`杀`,`♠`,`7`,{damageType:`雷电`}],[`杀`,`♠`,`8`,{damageType:`雷电`}],[`酒`,`♠`,`9`],[`兵粮寸断`,`♠`,`10`,{trickSubtype:`延时锦囊`}],[`铁索连环`,`♠`,`J`],[`铁索连环`,`♠`,`Q`],[`无懈可击`,`♠`,`K`,{trickSubtype:`响应锦囊`}],[`朱雀羽扇`,`♦`,`A`],[`桃`,`♦`,`2`],[`桃`,`♦`,`3`],[`杀`,`♦`,`4`,{damageType:`火焰`}],[`杀`,`♦`,`5`,{damageType:`火焰`}],[`闪`,`♦`,`6`],[`闪`,`♦`,`7`],[`闪`,`♦`,`8`],[`酒`,`♦`,`9`],[`闪`,`♦`,`10`],[`闪`,`♦`,`J`],[`火攻`,`♦`,`Q`],[`骅骝`,`♦`,`K`]],Cp=new Map;for(let e of[...Mu,...Yu,...Sd])Cp.set(e.name,{type:e.type,subtype:e.subtype,slashUnlimited:e.slashUnlimited,slashTargetBonusWhenLastCard:e.slashTargetBonusWhenLastCard})})),Tp,Ep,Dp,Op,kp,Ap,jp,Mp,Np=t((()=>{b(),Wd(),wp(),V(),ze(),Tp=[`回合管理`,`装备通用`,`使用牌`,`打出牌`,`铁索连环`],Ep={2:{主公:1,忠臣:0,反贼:1,内奸:0},3:{主公:1,忠臣:0,反贼:1,内奸:1},4:{主公:1,忠臣:1,反贼:1,内奸:1},5:{主公:1,忠臣:1,反贼:2,内奸:1},6:{主公:1,忠臣:1,反贼:3,内奸:1},7:{主公:1,忠臣:2,反贼:3,内奸:1},8:{主公:1,忠臣:2,反贼:4,内奸:1}},Dp={type:`抽身份`,validate:(e,t)=>e.players.length===0?`没有玩家`:Ep[t.playerCount]?null:`不支持的玩家数量: ${t.playerCount}`,apply(e,t){let{playerCount:n,seed:r}=t,i=Ud(r),a=Ep[n],o=[];for(let[e,t]of Object.entries(a))for(let n=0;n<t;n++)o.push(e);for(let e=o.length-1;e>0;e--){let t=i.nextInt(e+1),n=o[e];o[e]=o[t],o[t]=n}let s=o.indexOf(`主公`),c=s>0?[...o.slice(s),...o.slice(0,s)]:o;for(let t=0;t<e.players.length;t++){let n=c[t]||`未知`;e.players[t].identity=n}}},Op={type:`初始化洗牌`,validate:()=>null,apply(e,t){let n=Ud(t.seed),r=yp(vp(),n),i=Object.keys(e.cardMap);for(let t of i)delete e.cardMap[t];for(let t of r)e.cardMap[t.id]=t;e.zones.deck.length=0;for(let t of r)e.zones.deck.push(t.id);e.rngSeed=t.seed},toViewEvents(){return{ownerViews:new Map,othersView:{type:`初始化洗牌`,deckCount:vp().length}}},applyView(e,t){e.zones&&(e.zones.deckCount=t.deckCount??e.zones.deckCount)}},kp={type:`发牌`,validate:e=>e.players.length===0?`没有玩家`:e.zones.deck.length===0?`牌堆为空`:null,apply(e,t){let{handSize:n}=t,r=0;for(let t of e.players){let i=e.zones.deck.slice(r,r+n);t.hand.push(...i),r+=n}e.zones.deck=e.zones.deck.slice(r)},toViewEvents(e,t){let{handSize:n}=t,r=new Map,i=0;for(let t of e.players){let a=e.zones.deck.slice(i,i+n).map(t=>e.cardMap[t]).filter(Boolean);i+=n,r.set(t.index,{type:`发牌`,handSize:n,cards:a})}return{ownerViews:r,othersView:{type:`发牌`,handSize:n}}},applyView(e,t){let n=t.handSize??4;for(let r of e.players)r.handCount+=n,t.cards&&r.hand&&r.hand.push(...t.cards);let r=e.players.length*n;e.zones&&(e.zones.deckCount=Math.max(0,e.zones.deckCount-r))}},Ap={type:`选将询问`,validate(e,t){return e.players[t.target]?!Array.isArray(t.candidates)||t.candidates.length===0?`candidates required`:null:`target ${t.target} not found`},apply(e){},toViewEvents(e,t){let n=t.target,r=t.candidates,i=Re(e,60),a={type:`选将询问`,target:n,candidates:r,timeoutMs:i,pending:{startTime:e.clock.now(),deadline:e.clock.now()+i,prompt:{type:`chooseCharacter`,title:`请选择武将`,candidates:r}}};return{ownerViews:new Map([[n,a]]),othersView:{type:`等待选将`,waitingFor:n,waitingForName:`主公`}}},applyView(e,t){let n=t.target,r=t.candidates??[],i=t.timeoutMs??6e4;e.viewer===n&&(e.pending={type:`awaits`,atom:{type:`选将询问`,target:n,candidates:r},prompt:{type:`chooseCharacter`,title:`请选择武将`,candidates:r},target:n,deadline:Date.now()+i,totalMs:i})},pending:{async onTimeout(e,t){let n=t.target,r=e.players[n];if(!r||r.character)return;let i=t.candidates,a=new Set(e.players.map(e=>e.character)),o=i.filter(e=>!a.has(e.name)),s=o.length>0?o:i,c=s[Ud(e.seq^n*2654435761).nextInt(s.length)];await B(e,{type:`分配武将`,target:n,character:c.name,skills:[...Tp,...c.skills]})},prompt:{type:`chooseCharacter`,title:`请选择武将`,candidates:[]},timeout:60},effect:{blockUntilDone:!0,duration:200}},jp={type:`并行选将`,validate(e,t){if(!Array.isArray(t.selections)||t.selections.length===0)return`selections required`;for(let n of t.selections){if(!e.players[n.target])return`target ${n.target} not found`;if(!Array.isArray(n.candidates)||n.candidates.length===0)return`candidates required for target ${n.target}`}return null},apply(e){},toViewEvents(e,t){let n=t.selections,r=Re(e,60),i=new Map;for(let t of n)i.set(t.target,{type:`并行选将`,selections:n.map(e=>({target:e.target,candidates:e.candidates})),timeoutMs:r,pending:{startTime:e.clock.now(),deadline:e.clock.now()+r,prompt:{type:`chooseCharacter`,title:`请选择武将`,candidates:t.candidates}}});return{ownerViews:i,othersView:{type:`等待选将`,waitingFor:-1,waitingForName:`其他玩家`}}},applyView(e,t){let n=(t.selections??[]).find(t=>t.target===e.viewer);if(n){let r=t.timeoutMs??6e4;e.pending={type:`awaits`,atom:{type:`选将询问`,target:n.target,candidates:n.candidates},prompt:{type:`chooseCharacter`,title:`请选择武将`,candidates:n.candidates},target:n.target,deadline:Date.now()+r,totalMs:r}}},pending:{onTimeout:async()=>{},prompt:{type:`chooseCharacter`,title:`请选择武将`,candidates:[]},timeout:60},parallelSplit(e){return e.selections.map(e=>({target:e.target,slotAtom:{type:`选将询问`,target:e.target,candidates:e.candidates}}))},effect:{blockUntilDone:!0,duration:200}},Mp={type:`亮将`,validate(e,t){if(!Array.isArray(t.assignments)||t.assignments.length===0)return`assignments required`;for(let n of t.assignments){if(!e.players[n.target])return`target ${n.target} not found`;if(!n.character)return`character required`}return null},apply(e){},toViewEvents(e,t){let n={type:`亮将`,assignments:t.assignments};return{ownerViews:new Map,othersView:n}},applyView(e,t){let n=t.assignments??[];for(let t of n){let n=e.players.find(e=>e.index===t.target);n&&(n.character=t.character,n.name=t.character,n.faction=t.faction,n.skills=t.skills,typeof t.maxHealth==`number`&&(n.maxHealth=t.maxHealth),typeof t.health==`number`&&(n.health=t.health))}}}})),Pp,Fp=t((()=>{Pp={type:`选择目标时`,validate(e,t){if(!e.players[t.source])return`source ${t.source} not found`;for(let n of t.targets)if(!e.players[n])return`target ${n} not found`;return null},apply(){},effect:{animation:`highlight`,duration:400},toViewEvents(e,t){let n=e.cardMap[t.cardId]?.name??t.cardId,r={type:`选择目标时`,source:t.source,cardId:t.cardId,cardName:n,targets:t.targets};return{ownerViews:new Map,othersView:r}},applyView(){}}})),Ip,Lp=t((()=>{Wd(),Ip={type:`重洗`,validate(e){return e.zones.discardPile.length===0?`discardPile is empty`:null},apply(e){let t=[...e.zones.deck,...e.zones.discardPile],n=Ud(e.rngSeed);for(let e=t.length-1;e>0;e--){let r=n.nextInt(e+1);[t[e],t[r]]=[t[r],t[e]]}e.zones.deck=t,e.zones.discardPile=[],e.rngSeed=n.getState()},effect:{sound:`shuffle`,animation:`flip`,duration:400},toViewEvents(e){let t=e.zones.deck.length+e.zones.discardPile.length;return{ownerViews:new Map,othersView:{type:`重洗`,totalCards:t,newDeckCount:t,newDiscardPileCount:0}}},applyView(e,t){e.zones&&(e.zones.deckCount=t.newDeckCount??e.zones.deckCount+e.zones.discardPileCount,e.zones.discardPileCount=t.newDiscardPileCount??0)},toViewLog(){return{player:-1,text:`重洗牌堆`}}}})),Rp,zp,Bp=t((()=>{Rp=[`准备`,`判定`,`摸牌`,`出牌`,`弃牌`,`回合结束`],zp={type:`阶段开始`,validate(e,t){return e.players[t.player]?Rp.includes(t.phase)?null:`invalid phase ${t.phase}`:`player ${t.player} not found`},apply(e,t){let n=t.phase;e.phase=n,e.turn.phase=n},toViewEvents(e,t){let n={type:`阶段开始`,player:t.player,phase:t.phase};return{ownerViews:new Map,othersView:n}},effect:{sound:`phase_start`,duration:1e3},applyView(e,t){e.phase=t.phase,e.turn.phase=t.phase},toViewLog(e){return{player:e.player,text:`${e.phase}阶段开始`}}}})),Vp,Hp=t((()=>{Vp={type:`阶段结束`,validate(e,t){return e.players[t.player]?null:`player ${t.player} not found`},apply(e){},toViewEvents(e,t){let n={type:`阶段结束`,player:t.player,phase:t.phase};return{ownerViews:new Map,othersView:n}},effect:{sound:`phase_end`,duration:600},applyView(e,t){let n=t.phase;e.phase!==n&&(e.phase=n)},toViewLog(e){return{player:e.player,text:`${e.phase}阶段结束`}}}}));function Up(e,t){return e.players[t.player]?null:`player ${t.player} not found`}function Wp(e,t){if(k(e,`阶段间`).length===0)return{ownerViews:new Map,othersView:null};let n={type:`阶段间`,player:t.player,from:t.from,to:t.to};return{ownerViews:new Map,othersView:n}}var Gp,ree=t((()=>{F(),Gp={type:`阶段间`,validate:Up,apply(){},toViewEvents(e,t){return Wp(e,t)},applyView(){}}})),Kp,qp,iee=t((()=>{Kp=new Set([`甄姬`,`貂蝉`,`黄月英`,`大乔`,`小乔`,`孙尚香`,`蔡文姬`,`祝融`,`界甄姬`,`界貂蝉`,`界黄月英`,`界大乔`,`界小乔`,`界孙尚香`,`界蔡文姬`,`界祝融`,`界张春华`,`界王异`,`界夏侯氏`,`界郭皇后`,`界吴国太`,`界蔡夫人`,`界伏皇后`]),qp={type:`陷入濒死`,validate(e,t){return e.players[t.target]?null:`target not found`},apply(){},effect:{animation:`flash_red`,duration:600},toViewEvents(e,t){let n=e.players[t.target],r=Kp.has(n?.character??``)?`sos_female`:`sos_male`,i={type:`陷入濒死`,target:t.target,effect:{sound:r}};return{ownerViews:new Map,othersView:i}},applyView(){}}}));function Jp(e){return{type:e,validate:()=>null,apply:()=>{},applyView:()=>{}}}var Yp,aee=t((()=>{Yp={等待选将:Jp(`等待选将`),打出:Jp(`打出`)}})),Xp,oee=t((()=>{ke(),mt(),xt(),It(),Ht(),Jt(),nn(),on(),cn(),un(),fn(),hn(),Rc(),Bc(),Hc(),Wc(),Kc(),Zl(),$l(),tu(),ru(),au(),su(),lu(),du(),pu(),hu(),vu(),bu(),Su(),Tu(),Du(),Ad(),Md(),Pd(),Id(),Rd(),Bd(),Hd(),qd(),Yd(),Zd(),$d(),tf(),rf(),of(),cf(),uf(),ff(),mf(),gf(),vf(),bf(),Sf(),nee(),Tf(),Of(),Af(),Pf(),If(),Rf(),Zf(),tp(),pp(),Np(),Fp(),Lp(),Bp(),Hp(),ree(),iee(),aee(),Xp={伤害结算开始时:Se,造成伤害时:Ce,受到伤害时:we,造成伤害后:Te,受到伤害后:Ee,伤害结算结束时:De,伤害结算结束后:Oe,亮身份牌前:st,亮身份牌:ct,死亡时:lt,系统处理牌:ut,死亡后:dt,进入濒死状态时:ft,新的濒死状态时:pt,判定时:vt,判定牌生效前:yt,判定牌生效后:bt,扣减体力:Tt,确定回复数值时:Dt,回复体力后:Ot,失去体力时:kt,失去体力后:At,扣减体力前:jt,扣减体力时:Mt,扣减体力后:Nt,减上限后:Pt,加上限后:Ft,移动到目标区域前:Bt,移动到目标区域后:Vt,拼点扣置:Gt,拼点亮出:Kt,拼点后:qt,翻面后:Zt,横置后:Qt,武将牌明置后:$t,武将牌移除后:en,游戏牌亮出后:tn,下一玩家:an,使用时:sn,使用结算结束后:ln,使用结算结束时:dn,出牌窗口:mn,分配武将:Lc,判定:zc,收取判定牌:Vc,加标签:Uc,加标记:Gc,卸下:Xl,去标签:Ql,去标记:eu,回合开始:nu,回合用量:iu,回合结束:ou,回合结束后:cu,回复体力:uu,声明打出时:fu,失去体力:mu,展示:_u,展示结束:yu,帧参数赋值:xu,弃置:wu,归还暂存牌:Eu,当作:kd,成为目标:jd,成为目标后:Nd,打出牌时:Fd,扣牌:Ld,指定目标:zd,指定目标后:Vd,摸牌:Kd,整理牌堆:Jd,检测有效性:Xd,添加延时锦囊:Qd,添加技能:ef,清过期标记:nf,生效前:af,生效后:sf,生效时:lf,移出至暂存区:df,移动牌:pf,移除延时锦囊:hf,移除技能:_f,结算帧入栈:yf,结算帧出栈:xf,给予:Cf,置创牌:wf,获得:Df,被抵消:kf,装备:Nf,设上限:Ff,设横置:Lf,询问杀:Xf,询问闪:ep,请求回应:fp,抽身份:Dp,初始化洗牌:Op,发牌:kp,选将询问:Ap,并行选将:jp,亮将:Mp,选择目标时:Pp,重洗:Ip,阶段开始:zp,阶段结束:Vp,阶段间:Gp,陷入濒死:qp}}));function Zp(e){return Xp[e]??Yp[e]??see(e)}function see(e){throw Error(`Atom "${e}" not found`)}function cee(e,t){Zp(t.type).apply(e,t)}function lee(e,t){let n=Zp(t.type).toViewEvents?.(e,t),r=e=>e.type===t.type?e:{...e,atomType:t.type};if(n){let e=new Map;for(let[t,i]of n.ownerViews)e.set(t,i?r(i):null);return{ownerViews:e,othersView:n.othersView?r(n.othersView):null}}let i={...t};return{ownerViews:new Map,othersView:i}}var Qp=t((()=>{oee()})),K=a(),uee=d();Qp();function $p(e,t,n=0){let r=Zp(t.atomType??t.type);r.applyView?.(e,t);let i=r.toViewLog?.(t,e.viewer,t=>{if(!(t<0))return e.players.find(e=>e.index===t)?.name});i&&e.log.push({time:n,player:i.player,text:i.text})}function em(e){return e?.events.length??0}function dee(e,t){let n=JSON.parse(JSON.stringify(e));n.viewer=t.viewer;let r=new Map;for(let{index:e,hand:n}of t.privateHands)r.set(e,[...n]);let i=new Map;for(let{index:e,identity:n,identityHidden:r}of t.identityView)i.set(e,{identity:n,identityHidden:r});return n.players=n.players.map(e=>{let t=i.get(e.index);return{...e,hand:r.get(e.index),identity:t?.identity,identityHidden:t?.identityHidden}}),n}function fee(e,t,n){let r=e.seats[t];if(!r)return null;let i=dee(e.baseline,r),a=Math.max(0,Math.min(n,r.events.length));for(let e=0;e<a;e++){let{event:t,time:n}=r.events[e];if((typeof t.atomType==`string`?t.atomType:t.type)===`notify`){if(t.eventType===`pendingResolved`){let e=t.data?.target;e!==void 0&&(e<0||e===i.viewer||i.pending?.target===e)&&(i.pending=null)}continue}$p(i,t,n)}return i}function pee(e){return Object.keys(e.seats).map(Number).sort((e,t)=>e-t)}Qp();var mee=400,tm=400;function hee(e){let t=e.atomType??e.type,n;try{n=Zp(t).effect?.duration}catch{n=void 0}return e.effect?.duration??n??tm}function gee(e){let t=(0,K.useMemo)(()=>pee(e),[e]),[n,r]=(0,K.useState)(()=>t.find(e=>e>=0)??t[0]??0),i=(0,K.useMemo)(()=>em(e.seats[n]),[e,n]),[a,o]=(0,K.useState)(0),[s,c]=(0,K.useState)(!1),[l,u]=(0,K.useState)(1),[d,f]=(0,K.useState)(null),[p,m]=(0,K.useState)([]),h=Math.min(a,i),g=(0,K.useMemo)(()=>fee(e,n,h),[e,n,h]),_=(0,K.useCallback)(()=>{o(t=>{let r=Math.min(t,i);if(r>=i)return c(!1),r;let a=r+1,o=e.seats[n].events[a-1];if(o){let e={seq:a-1,event:o.event};f(e),m([e])}return a})},[e,n,i]),v=(0,K.useRef)(null);return(0,K.useEffect)(()=>{if(!s){v.current&&=(clearTimeout(v.current),null);return}if(h>=i){c(!1);return}let t=e.seats[n].events[h],r=t?hee(t.event):tm,a=Math.max(r,mee)/l;return v.current=setTimeout(()=>{_()},a),()=>{v.current&&=(clearTimeout(v.current),null)}},[s,l,n,h,i,e,_]),{view:g,step:h,total:i,seat:n,seats:t,playing:s,speed:l,currentEvent:d,ingestedEvents:p,next:(0,K.useCallback)(()=>{_()},[_]),prev:(0,K.useCallback)(()=>{o(t=>{let r=Math.max(0,Math.min(t,i)-1),a=r>0?e.seats[n].events[r-1]:null;return f(a?{seq:r-1,event:a.event}:null),m([]),r})},[e,n,i]),goTo:(0,K.useCallback)(e=>{o(Math.max(0,Math.min(e,i))),c(!1),f(null),m([])},[i]),setSeat:(0,K.useCallback)(t=>{r(t);let n=em(e.seats[t]);o(e=>Math.min(e,n)),c(!1),f(null),m([])},[e]),togglePlay:(0,K.useCallback)(()=>{h>=i?(o(0),f(null),m([]),c(!0)):c(e=>!e)},[h,i]),setSpeed:u}}function _ee(e,t,n){let r={view:e,lastSeq:t,newEvents:[],phaseChangedTo:null};switch(n.type){case`initialView`:{let e=n.state;return{...r,view:e,lastSeq:n.lastSeq,seatIndex:e.viewer,phaseChangedTo:`playing`}}case`event`:{if(!e||n.seq<=t)return r;let i=e,a=[];if(n.notify&&n.notify.eventType===`pendingResolved`){let e=n.notify.data.target;e!==void 0&&(e===i.viewer||e<0)&&i.pending&&(i={...i,pending:null})}return n.view&&(i={...i,players:i.players.map(e=>({...e,hand:e.hand?[...e.hand]:e.hand,skills:[...e.skills??[]],marks:[...e.marks??[]],equipment:{...e.equipment??{}},pendingTricks:[...e.pendingTricks??[]],distanceVars:e.distanceVars?{...e.distanceVars}:e.distanceVars,turnUsage:e.turnUsage?{...e.turnUsage}:e.turnUsage})),zones:i.zones?{...i.zones,processing:[...i.zones.processing??[]]}:i.zones,log:[...i.log]},$p(i,n.view,n.timestamp),a.push(n.view)),n.deadline!==void 0&&(n.deadline!==null&&i.pending&&(i={...i,pending:{...i.pending,deadline:n.deadline.deadline,totalMs:n.deadline.totalMs}}),i={...i,deadline:n.deadline===null?null:n.deadline.deadline,deadlineTotalMs:n.deadline===null?0:n.deadline.totalMs}),{...r,view:i,lastSeq:n.seq,newEvents:a}}case`gameOver`:return{...r,phaseChangedTo:`ended`,gameOverWinner:n.winner};case`game_reset`:return{...r,view:null,lastSeq:0,resetToLobby:!0,phaseChangedTo:`lobby`};case`room_joined`:return{...r,playerId:n.playerId,roomId:n.roomId,seatIndex:typeof n.seatIndex==`number`?n.seatIndex:r.seatIndex};case`room_state`:return{...r,roomState:{readyPlayers:n.readyPlayers,playerIds:n.playerIds,hostId:n.hostId,maxPlayers:n.maxPlayers,config:n.config,spectatorIds:n.spectatorIds??[],viewGrants:n.viewGrants??{},pendingViewRequests:n.pendingViewRequests??{},roomType:n.roomType,seats:n.seats??[],pendingSeatSwaps:n.pendingSeatSwaps??{},playerNames:n.playerNames??{}}};case`room_config`:return{...r};case`player_ready`:return{...r};case`game_started`:return{...r,phaseChangedTo:`playing`};case`actionRejected`:return{...r,actionRejected:!0};default:return r}}var nm=`base`,vee={manifestVersion:1,id:nm,name:`基础资源包`,version:`1.0.0`,author:`内置`,description:`游戏自带的基础视听资源(图片/音频/特效)`,priority:0,resources:[]},rm=`sgs:resource-packs`;function yee(e){return e===`image`?`.png`:e===`audio`?`.mp3`:`.json`}var bee=new class{packs=new Map;resolved=new Map;enabledSet=new Set;initialized=!1;loadIndex(e){this.packs.clear();for(let{id:t,manifest:n}of e.packs)this.packs.set(t,n);this.packs.has(`base`)||this.packs.set(nm,vee),this.remerge(),this.initialized=!0}remerge(){let e=new Map,t=[...this.packs.values()].filter(e=>this.enabledSet.has(e.id)).sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id));for(let n of t)for(let t of n.resources){let r=t.file??`${t.id}${yee(t.type)}`;e.set(t.id,{packId:n.id,file:r})}this.resolved=e}get(e){let t=this.resolved.get(e);return t?`/packs/${t.packId}/${t.file}`:null}listPacks(){return[...this.packs.values()].sort((e,t)=>t.priority-e.priority||e.id.localeCompare(t.id)).map(e=>({id:e.id,name:e.name,version:e.version,author:e.author,description:e.description,homepage:e.homepage,priority:e.priority,resourceCount:e.resources.length,enabled:this.enabledSet.has(e.id)}))}setPackEnabled(e,t){this.packs.has(e)&&(t?this.enabledSet.add(e):this.enabledSet.delete(e),this.persistSettings(),this.remerge())}loadSettings(){let e=null;try{let t=localStorage.getItem(rm);if(t){let n=JSON.parse(t);Array.isArray(n.enabled)&&(e=n.enabled)}}catch{}e??=[nm],this.enabledSet=new Set((e??[]).filter(e=>this.packs.has(e))),this.persistSettings()}persistSettings(){try{localStorage.setItem(rm,JSON.stringify({enabled:[...this.enabledSet]}))}catch{}}async init(){if(this.initialized)return;let e;try{e=await(await fetch(`/packs/index.json`)).json()}catch{e={packs:[]}}this.loadIndex(e),this.loadSettings(),this.remerge(),this.initialized=!0}reset(){this.packs.clear(),this.resolved.clear(),this.enabledSet.clear(),this.initialized=!1}};function q(e){let{view:t,perspectiveIdx:n}=e,r=t.pending,i=r!=null&&r.isBlocking!==!1;return t.currentPlayerIndex===n&&t.phase===`出牌`&&!i}function im(e){return e===0}function am(e,t){let n=e.players[t];if(!n)return 1;let r=n.equipment.武器;if((r?e.cardMap[r]:void 0)?.slashUnlimited)return 1/0;let i=n.turnUsage??{};for(let[e,t]of Object.entries(i))if(e.startsWith(`杀/unlimited/`)&&t)return 1/0;let a=1;for(let[e,t]of Object.entries(i))e.startsWith(`杀/extra/`)&&typeof t==`number`&&(a+=t);return a}function xee(e,t,n){let r=e.players[t];if(!r)return 1;let i=1,a=r.equipment.武器,o=a?e.cardMap[a]:void 0;o?.slashTargetBonusWhenLastCard&&(r.hand?.length??0)===1&&(i=Math.max(i,o.slashTargetBonusWhenLastCard));let s=r.turnUsage??{};for(let[e,t]of Object.entries(s))e.startsWith(`杀/target/`)&&typeof t==`number`&&(i+=t);return n?.name===`杀`&&n.damageType===`火焰`&&r.tags?.includes(`杀/火杀多目标`)&&(i=Math.max(i,2)),i}function om(e,t){let n=e.players[t]?.turnUsage?.[El];return typeof n==`number`?n:0}function sm(e,t){let n=e.players[t];if(!n)return!1;let r=n.turnUsage??{};for(let[e,t]of Object.entries(r))if(e.startsWith(`杀/blocked/`)&&t)return!1;let i=r[Dl];if(typeof i==`string`&&i!==``)if(e.viewer===t){if(n.hand?.some(e=>e.name===`杀`&&e.suit===i))return!0}else return!0;return om(e,t)<am(e,t)}var J=t((()=>{W()}));function See(e,t,n){let r=e.filter(e=>e.alive),i=r.length;if(i<=1)return 0;let a=r.findIndex(n=>n.name===e[t]?.name),o=r.findIndex(t=>t.name===e[n]?.name);if(a<0||o<0)return 1/0;let s=Math.abs(a-o);return Math.min(s,i-s)}function cm(e,t,n){if(e.some(e=>e.turnUsage?.[`陷阵/winTarget`]===n)||e[t]?.turnUsage?.[`成略/suits`]||e[t]?.turnUsage?.[`决堰/本回合:坐骑`]||e[t]?.turnUsage?.[`往烈/首张可用`]||e[t]?.turnUsage?.[`雄乱/目标`]===n)return 1;let r=See(e,t,n),i=e[t],a=e[n];return r-=i?.distanceVars?.attackMod??0,r+=a?.distanceVars?.defenseMod??0,Math.max(1,r)}function lm(e,t,n,r){if(n===r)return!1;if(e.some(e=>e.turnUsage?.[`陷阵/winTarget`]===r)||e[n]?.turnUsage?.[`天义/win`]===n||e[n]?.turnUsage?.[Jc(`诈降`)]||e[n]?.turnUsage?.[`成略/suits`]||e[n]?.skills?.includes(`界武圣`)||e[n]?.skills?.includes(`界烈弓`)||e[n]?.turnUsage?.[`将驰/choice2`]||e[n]?.turnUsage?.[`界弓骑/active`]||e[n]?.turnUsage?.[`当先/noRangeActive`])return!0;let i=e[n]?.distanceVars?.attackRange??1;return cm(e,n,r)<=i}var um=t((()=>{W()}));J(),um();var Cee=15e3;function wee(e){let[t,n]=(0,K.useState)(null);return(0,K.useEffect)(()=>{if(e==null){n(null);return}let t=()=>n(Math.max(0,Math.ceil((e-Date.now())/1e3)));t();let r=setInterval(t,200);return()=>clearInterval(r)},[e]),t}function Tee(e,t=Cee){let n=(0,K.useRef)(null);return(0,K.useEffect)(()=>{if(e==null){n.current&&(n.current.style.width=`0%`);return}let r=0,i=()=>{let a=Math.max(0,e-Date.now()),o=Math.max(0,Math.min(1,a/t));n.current&&(n.current.style.width=`${o*100}%`),a>0&&(r=requestAnimationFrame(i))};return i(),()=>cancelAnimationFrame(r)},[e,t]),n}var Eee=`nm-chooseOptionCard`,Dee=`nm-chooseOptionCardName`,Oee=`nm-emptyHand`,kee=`nm-handCard`,Aee=`nm-handColumn`,jee=`nm-handHeader`,Mee=`nm-handList`,Nee=`nm-handTitle`,Pee=`nm-phaseStrip`,Fee=`nm-phaseStripBadge`,dm=`nm-promptActions`,fm=`nm-promptActionsWrap`,Iee=`nm-promptBoxAwaiting`,pm=`nm-promptBtn`,mm=`nm-promptBtnDisabled`,hm=`nm-promptBtnPrimary`,Lee=`nm-promptDesc`,Ree=`nm-promptDescInline`,zee=`nm-promptTitle`,gm=`nm-waitingHint`;function _m(e){return`skills/${e}`}function Bee(e){return e.replace(/^(?:\.\.\/)+/,``)}function vm(){let e=new Map,t=(t,n,r)=>{let i=Bee(n),a=e.get(t);if(a!==void 0&&a!==i)throw Error(`技能 "${t}" 声明冲突: ${r} 声明 ${i},但已有 ${a}`);e.set(t,i)};for(let e of wc)for(let n of e.skills)t(n.name,n.path??_m(n.name),`武将 ${e.name}`);for(let e of Sd)t(e.name,wd[e.name]??_m(e.name),`装备 ${e.name}`);for(let[e,n]of Object.entries(bm))t(e,n,`系统技能`);for(let[e,n]of Object.entries(xm))t(e,n,`衍生技`);return e}function Vee(e){return vm().get(e)}function ym(e){return vm().has(e)}var bm,xm,Sm=t((()=>{Tc(),G(),bm={回合管理:`skills/回合管理`,装备通用:`skills/装备通用`,使用牌:`skills/cards/use-card`,打出牌:`skills/cards/play-card`,铁索连环:`skills/铁索连环`,开局:`skills/开局`,护甲:`skills/护甲`},xm={界荐言:`skills/界荐言`,攻心:`skills/攻心`}})),Cm,wm,Tm,Y,Em=t((()=>{Cm=`modulepreload`,wm=function(e,t){return new URL(e,t).href},Tm={},Y=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=wm(t,n),t in Tm)return;Tm[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:Cm,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})}}));async function Hee(e,t,n,r){r===void 0?delete e.localVars[`死亡/killer`]:e.localVars[`死亡/killer`]=r,await B(e,{type:`扣减体力前`,target:t,amount:n}),await B(e,{type:`扣减体力时`,target:t,amount:n}),await B(e,{type:`扣减体力`,target:t,amount:n}),await B(e,{type:`扣减体力后`,target:t,amount:n})}var Uee=t((()=>{V(),It()}));async function Dm(e,t,n,r,i,a){let o=r;if(e.localVars[be]=o,!await B(e,{type:`伤害结算开始时`,source:t,target:n,amount:o,cardId:i,damageType:a}))return;o=e.localVars[be],t=e.localVars[xe],e.localVars[be]=o,await B(e,{type:`造成伤害时`,source:t,target:n,amount:o,cardId:i,damageType:a}),o=e.localVars[be],e.localVars[be]=o;let s=await B(e,{type:`受到伤害时`,source:t,target:n,amount:o,cardId:i,damageType:a});if(o=e.localVars[be],!s||o<=0){await B(e,{type:`伤害结算结束时`,source:t,target:n,amount:0,cardId:i,damageType:a}),await B(e,{type:`伤害结算结束后`,source:t,target:n,amount:0,cardId:i,damageType:a});return}o>0&&await Hee(e,n,o,t),await B(e,{type:`造成伤害后`,source:t,target:n,amount:o,cardId:i,damageType:a}),await B(e,{type:`受到伤害后`,source:t,target:n,amount:o,cardId:i,damageType:a}),await B(e,{type:`伤害结算结束时`,source:t,target:n,amount:o,cardId:i,damageType:a}),await B(e,{type:`伤害结算结束后`,source:t,target:n,amount:o,cardId:i,damageType:a})}var Om=t((()=>{V(),Uee(),ke()})),Wee=r({arrowVolleyEffect:()=>km});async function Gee(e){let{state:t,source:n,target:r,cardId:i}=e;if(await B(t,{type:`询问闪`,target:r,source:n}),Je(t,i,r))await B(t,{type:`被抵消`,source:n,target:r,cardId:i});else{if(!t.players[r]?.alive)return;await Dm(t,n,r,1,i)}}var km,Am=t((()=>{V(),Om(),z(),km={timing:`出牌阶段`,target:{kind:`allOthers`},resolve:Gee,prompt:{type:`useCard`,title:`万箭齐发`,cardFilter:{filter:e=>e.name===`万箭齐发`,min:1,max:1}},label:`万箭齐发`,style:`danger`}}));async function jm(e,t,n){await B(e,{type:`判定时`,player:t,judgeType:n}),await B(e,{type:`判定`,player:t,judgeType:n});let r=Mm(e);delete e.localVars[Pm],await B(e,{type:`判定牌生效前`,player:t,judgeType:n,cardId:r});let i=Mm(e);return i!==void 0&&(e.localVars[Pm]=i),await B(e,{type:`判定牌生效后`,player:t,judgeType:n,cardId:i}),await Kee(e,i),e.localVars[Pm]}function Mm(e){let t=e.settlementStack[e.settlementStack.length-1],n=t?t.cards:e.zones.processing;return n.length>0?n[n.length-1]:void 0}async function Nm(e,t,n){let r=R(e),i=r[r.length-1];i!==void 0&&(await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:t},to:{zone:`处理区`}}))}async function Kee(e,t){if(t===void 0)return;let n=e.settlementStack[e.settlementStack.length-1];(n?n.cards:e.zones.processing).includes(t)&&await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}var Pm,Fm=t((()=>{V(),z(),Pm=`判定/finalJudgeCardId`})),qee=r({indulgenceEffect:()=>Lm});function Jee(e,t,n){let r=n.target??n.targets?.[0];return r===void 0?`目标不合法`:r===t?`不能对自己使用`:e.players[r]?.alive?e.players[r].pendingTricks.some(e=>e.name===`乐不思蜀`)?`目标判定区已有乐不思蜀`:null:`目标已死亡`}async function Yee(e){let{state:t,target:n}=e;await jm(t,n,`乐不思蜀`);let r=t.localVars[`判定/finalJudgeCardId`];delete t.localVars[`判定/finalJudgeCardId`];let i=r?t.cardMap[r]:void 0;i&&i.suit!==`♥`&&await B(t,{type:`加标签`,player:n,tag:Im}),await B(t,{type:`移除延时锦囊`,player:n,trickName:`乐不思蜀`})}var Im,Lm,Xee=t((()=>{V(),Fm(),Im=`乐不思蜀/跳过出牌`,Lm={timing:`出牌阶段`,target:{kind:`other`,min:1,max:1},delayed:!0,skipPhase:{tag:Im,phase:`出牌`},cancelledBy:{cardName:`无懈可击`,broadcast:!0},canUse:Jee,resolve:Yee,prompt:{type:`useCardAndTarget`,title:`乐不思蜀`,cardFilter:{filter:e=>e.name===`乐不思蜀`,min:1,max:1},targetFilter:{min:1,max:1}},label:`乐不思蜀`,style:`danger`}})),Zee=r({bountifulHarvestEffect:()=>Rm});function Qee(e,t){let n=e.players.filter(e=>e.alive),r=n.length;if(r===0)return[];let i=n.findIndex(e=>e.index===t);if(i<0)return n.map(e=>e.index);let a=[];for(let e=0;e<r;e++)a.push(n[(i+e)%r].index);return a}async function $ee(e,t,n,r){let i=n.filter(t=>R(e).includes(t));if(i.length===0)return;await B(e,{type:`请求回应`,requestType:`五谷丰登/select`,target:t,prompt:{type:`pickProcessingCard`,title:`五谷丰登:选择 1 张牌`,cards:i.map(t=>{let n=e.cardMap[t];return n?{cardId:t,cardName:n.name,suit:n.suit,rank:n.rank}:null}).filter(e=>e!==null)},timeout:20});let a=e.localVars[`五谷丰登/选择`];delete e.localVars[`五谷丰登/选择`];let o=n.filter(t=>R(e).includes(t)),s=a&&o.includes(a)?a:o[0];if(s){await B(e,{type:`移动牌`,cardId:s,from:{zone:`处理区`},to:{zone:`手牌`,player:t}});let n=e.players[t]?.name??`P${t}`;await B(e,{type:`帧参数赋值`,key:`pickedBy`,value:{...r.params.pickedBy??{},[s]:n}})}}async function ete(e){let{state:t,source:n,target:r}=e;if(!t.localVars[`五谷丰登/已翻牌`]){t.localVars[`五谷丰登/已翻牌`]=!0;let e=Qee(t,n).length,r=[];for(let n=0;n<e&&t.zones.deck.length!==0;n++){let e=t.zones.deck[t.zones.deck.length-1];await B(t,{type:`移动牌`,cardId:e,from:{zone:`牌堆`},to:{zone:`处理区`}}),r.push(e)}t.localVars[`五谷丰登/亮牌`]=r,await B(t,{type:`帧参数赋值`,key:`revealedIds`,value:r})}let i=t.localVars[`五谷丰登/亮牌`];if(!i||!i.some(e=>R(t).includes(e)))return;let a=t.settlementStack[t.settlementStack.length-1];i.some(e=>R(t).includes(e))&&await $ee(t,r,i,a)}async function tte(e,t,n){let r=e.localVars[`五谷丰登/亮牌`];if(r)for(let t of r)R(e).includes(t)&&await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}});delete e.localVars[`五谷丰登/亮牌`],delete e.localVars[`五谷丰登/已翻牌`],delete e.localVars[`五谷丰登/选择`]}var Rm,zm=t((()=>{V(),z(),Rm={timing:`出牌阶段`,target:{kind:`allPlayers`},resolve:ete,onSettle:tte,respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`||r.atom.requestType!==`五谷丰登/select`)return`当前不是五谷丰登选牌窗口`;let i=n.cardId;return i?e.localVars[`五谷丰登/亮牌`]?.includes(i)?R(e).includes(i)?null:`该牌已被选走`:`该牌不在可选范围`:`cardId required`},execute:async(e,t,n)=>{let r=n.cardId;e.localVars[`五谷丰登/选择`]=r}},prompt:{type:`useCard`,title:`五谷丰登`,cardFilter:{filter:e=>e.name===`五谷丰登`,min:1,max:1}},label:`五谷丰登`,style:`primary`}}));async function Bm(e,t,n,r){if(!t.broadcast){if(e.localVars[Hm]=!1,await B(e,{type:`询问闪`,target:r,source:n}),!Vm(e)){let t=e.settlementStack[e.settlementStack.length-1],n=(t?t.cards:e.zones.processing).filter(t=>e.cardMap[t]?.name===`闪`);if(n.length>0&&t){t.cancelled=!0;for(let t of n)await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}}return delete e.localVars[Hm],Vm(e)}for(;e.localVars[Hm]=!1,await B(e,{type:`请求回应`,requestType:t.cardName,target:-2,cancelTarget:r,prompt:{type:`useCard`,title:`是否打出${t.cardName}?`,cardFilter:{filter:e=>e.name===t.cardName,min:1,max:1}},timeout:10}),!(e.localVars[Hm]!==!0||Vm(e)););return delete e.localVars[Hm],Vm(e)}function Vm(e){let t=e.settlementStack,n=t[t.length-1];return n?n.cancelled===!0:!1}var Hm,Um=t((()=>{b(),V(),Hm=`抵消/已回应`}));function nte(e,t,n){if(e<=1)return 0;let r=Math.abs(t-n);return Math.min(r,e-r)}function Wm(e,t,n,r){if(ite(e,t,n,r))return 1;let i=e.players.filter(e=>e.alive),a=i.findIndex(e=>e.index===t),o=i.findIndex(e=>e.index===n);if(a<0||o<0)return 1/0;let s=nte(i.length,a,o),c=il(e.players[t].vars)??0;s-=c;let l=al(e.players[n].vars)??0;return s+=l,Math.max(1,s)}function Gm(e,t,n,r){if(t===n)return!1;if(rte(e,t,n,r))return!0;let i=ol(e.players[t].vars)??1;return Wm(e,t,n)<=i}function Km(e){let t=Ym.get(e);return t||(t={exemptors:new Map,distanceExemptors:new Map},Ym.set(e,t)),t}function qm(e,t,n){let r=Km(e),i=r.exemptors.get(t);return i||(i=new Set,r.exemptors.set(t,i)),i.add(n),()=>{let e=r.exemptors.get(t);e&&(e.delete(n),e.size===0&&r.exemptors.delete(t))}}function rte(e,t,n,r){let i=Km(e).exemptors.get(t);if(!i)return!1;for(let a of i)if(a(e,t,n,r))return!0;return!1}function Jm(e,t,n){let r=Km(e),i=r.distanceExemptors.get(t);return i||(i=new Set,r.distanceExemptors.set(t,i)),i.add(n),()=>{let e=r.distanceExemptors.get(t);e&&(e.delete(n),e.size===0&&r.distanceExemptors.delete(t))}}function ite(e,t,n,r){let i=Km(e).distanceExemptors.get(t);if(!i)return!1;for(let a of i)if(a(e,t,n,r))return!0;return!1}var Ym,Xm=t((()=>{W(),Ym=new WeakMap}));function Zm(e){let t=dh.get(e);return t||(t={quotaProviders:new Map,extraProviders:new Map,unlimitedProviders:new Map,blockers:new Map,exemptors:new Map},dh.set(e,t)),t}function Qm(e,t,n,r){let i=e[t],a=i.get(n);return a||(a=new Set,i.set(n,a)),a.add(r),()=>{let e=i.get(n);e&&(e.delete(r),e.size===0&&i.delete(n))}}function ate(e,t,n){return Qm(Zm(e),`quotaProviders`,t,n)}function $m(e,t,n){return Qm(Zm(e),`extraProviders`,t,n)}function eh(e,t,n){return Qm(Zm(e),`unlimitedProviders`,t,n)}function th(e,t){let n=1,r=Zm(e).quotaProviders.get(t);if(r)for(let i of r){let r=i(e,t);r>n&&(n=r)}return n}function ote(e,t){let n=0,r=Zm(e).extraProviders.get(t);if(r)for(let i of r)n+=i(e,t);return n}function nh(e,t){let n=Zm(e).unlimitedProviders.get(t);if(!n)return!1;for(let r of n)if(r(e,t))return!0;return!1}function rh(e){return pl(e.turn.vars)??0}function ih(e){return ml(e.turn.vars)??0}function ah(e){return rh(e)+ih(e)}function oh(e,t,n){return Qm(Zm(e),`blockers`,t,n)}function ste(e,t){let n=Zm(e).blockers.get(t);if(!n)return!1;for(let r of n)if(r(e,t))return!0;return!1}function sh(e,t,n){return Qm(Zm(e),`exemptors`,t,n)}function ch(e,t,n){if(n===void 0)return!1;let r=Zm(e).exemptors.get(t);if(!r)return!1;for(let i of r)if(i(e,t,n))return!0;return!1}function lh(e,t,n){return ste(e,t)?!1:n!==void 0&&ch(e,t,n)||nh(e,t)?!0:rh(e)<th(e,t)||ih(e)<ote(e,t)}function uh(e){let t=e.currentPlayerIndex;nh(e,t)||rh(e)<th(e,t)?e.turn.vars[_l]=rh(e)+1:e.turn.vars[vl]=ih(e)+1}var dh,fh=t((()=>{W(),dh=new WeakMap})),cte=r({computeAutoTargets:()=>hh,findLegalTargets:()=>gh,isCardBanned:()=>ph,isLegalTarget:()=>mh,validateCardUse:()=>_h});function ph(e,t,n){let r=e.players[t];return r?!!(r.tags.includes(`义绝/禁出牌`)||e.turn.vars[`往烈/禁出牌`]===t):!1}function lte(e,t,n,r){if(n===`杀`){let n=r.cardId;if(!lh(e,t,n))return`出杀次数已达上限`}return null}function mh(e,t,n,r,i){let a=Wg(n);if(!a)return!1;let o=a.target;if(r===t){if(o.kind===`self`||o.kind===`allPlayers`||o.kind===`any`)return!0;if(o.kind===`wounded`){let n=e.players[t];return!!n&&n.health<n.maxHealth}return!1}let s=e.players[r];if(!s?.alive)return!1;switch(o.kind){case`effect`:case`self`:return!1;case`inAttackRange`:return Gm(e,t,r);case`distance`:return e.players[t]?.tags.includes(`奇才/无距离限制`)?!0:Wm(e,t,r,i)<=o.dist;case`allOthers`:case`allPlayers`:case`other`:case`any`:return!0;case`wounded`:return s.health<s.maxHealth;default:return!1}}function hh(e,t,n){let r=Wg(n);if(!r)return[];let i=r.target;if(i.kind!==`allOthers`&&i.kind!==`allPlayers`)return[];let a=e.players.filter(e=>e.alive),o=a.length;if(o===0)return[];let s=a.findIndex(e=>e.index===t);if(s<0)return a.map(e=>e.index);let c=[],l=+(i.kind===`allOthers`);for(let e=l;e<o;e++)c.push(a[(s+e)%o].index);return c}function gh(e,t,n,r){let i=[];for(let a=0;a<e.players.length;a++)mh(e,t,n,a,r)&&i.push(a);return i}function _h(e,t,n,r,i=`play`){if(i===`play`){let i=oe(e,t,n,{cardName:r});if(i)return i}else{let t=n.cardId;if(!t)return`cardId required`;let i=e.cardMap[t];if(!i)return`牌不存在`;if(i.name!==r)return`不是${r}`}if(ph(e,t,r))return`你不能使用此牌`;if(i===`play`){let i=lte(e,t,r,n);if(i)return i}let a=Wg(r);if(!a)return`${r} 尚未注册 CardEffect`;if(a.target.kind!==`self`&&a.target.kind!==`effect`){let i=n.cardId;if(gh(e,t,r,i).length===0)return`没有合法目标`}if(a.canUse){let r=a.canUse(e,t,n);if(r)return r}return null}var vh=t((()=>{Xm(),fh(),F(),Yg()}));function X(e,t,n){return!!e.players[t]?.vars[Zc(n)]}async function Z(e,t,n){e.players[t].vars[Zc(n)]=!0,await B(e,{type:`回合用量`,player:t,key:Zc(n),value:!0})}function yh(e){return t=>q(t)&&!t.view.players[t.perspectiveIdx]?.turnUsage?.[Zc(e)]}var Q=t((()=>{V(),W()})),ute=r({registerWineHook:()=>bh,wineEffect:()=>xh});function bh(e){M(e,`酒`,-1,`造成伤害时`,async e=>{let t=e.atom;if(t.source===void 0||(t.amount??0)<=0)return;let n=e.state.players[t.source];if(n&&n.marks.some(e=>e.id===`酒/nextKillDamageBonus`)&&(t.cardId===void 0?void 0:e.state.cardMap[t.cardId])?.name===`杀`)return await B(e.state,{type:`去标记`,player:t.source,markId:`酒/nextKillDamageBonus`}),{kind:`modify`,atom:{...e.atom,amount:(t.amount??0)+1}}})}async function dte(e){let{state:t,source:n}=e;await Z(t,n,`酒`),await B(t,{type:`加标记`,player:n,mark:{id:`酒/nextKillDamageBonus`,scope:-1,payload:1,duration:`turn`}})}function fte(e,t,n){if(X(e,t,`酒`)&&!e.players[t]?.tags.includes(`酒/无次数限制`))return`本回合已使用过酒`;let r=n.target??n.targets?.[0];return r!==void 0&&r!==t?`只能对自己使用酒`:null}var xh,Sh=t((()=>{V(),F(),J(),Q(),xh={timing:`出牌阶段`,target:{kind:`self`},canUse:fte,resolve:dte,respond:{validate:(e,t,n)=>{if(e.pendingSlots.get(t)?.atom.type!==`请求回应`)return`当前不需要回应`;if(e.pendingSlots.get(t).atom.requestType!==`桃/求桃`)return`当前不是求桃`;let r=n.cardId;return r?e.players[t].hand.includes(r)?e.cardMap[r].name===`酒`?null:`只能用酒救援`:`牌不在手牌中`:`cardId required`},execute:async(e,t,n)=>{let r=n.cardId;await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:t},to:{zone:`弃牌堆`}}),e.localVars[`求桃/已救`]=!0}},prompt:{type:`useCard`,title:`饮酒`,cardFilter:{filter:e=>e.name===`酒`,min:1,max:1}},respondPrompt:{type:`useCard`,title:`濒死:使用酒(当桃)`,cardFilter:{filter:e=>e.name===`酒`,min:1,max:1}},label:`酒`,style:`default`,activeWhen:e=>e.view.players[e.perspectiveIdx]?.tags?.includes(`酒/无次数限制`)?q(e):yh(`酒`)(e)}}));async function Ch(e,t,n){await B(e,{type:`加标签`,player:t,tag:`${n}/翻面`}),await B(e,{type:`翻面后`,player:t,faceDown:!0})}async function wh(e,t,n){await B(e,{type:`去标签`,player:t,tag:`${n}/翻面`}),await B(e,{type:`翻面后`,player:t,faceDown:!1})}async function Th(e,t,n){return await B(e,{type:`设横置`,player:t,chained:n})?(await B(e,{type:`横置后`,player:t,chained:n}),!0):!1}function Eh(e,t){return e.players[t]?.marks.some(e=>e.id===`chained`)??!1}function pte(e){N(e,`铁索连环`,-1,`伤害结算结束后`,async e=>{let t=e.atom,n=t.damageType;if(n!==`火焰`&&n!==`雷电`)return;let r=t.amount??1;if(r<=0)return;let i=t.target;if(typeof i==`number`&&Eh(e.state,i)&&!e.state.localVars[jh]){e.state.localVars[jh]=!0;try{let a=t.source??-1,o=e.state.players.filter(e=>e.alive&&e.index!==i&&e.marks.some(e=>e.id===`chained`));for(let t of o)e.state.players[t.index]?.alive&&await Dm(e.state,a,t.index,r,void 0,n);let s=e.state.players.filter(e=>e.marks.some(e=>e.id===Ah));for(let t of s)await Th(e.state,t.index,!1)}finally{delete e.state.localVars[jh]}}})}function Dh(e,t){return e.players[t].tags.some(e=>e.endsWith(`/翻面`))}async function Oh(e,t){let n=(e.players[t]?.tags??[]).filter(e=>e.endsWith(`/翻面`));for(let r of n)await B(e,{type:`去标签`,player:t,tag:r});n.length>0&&await B(e,{type:`翻面后`,player:t,faceDown:!1})}async function kh(e,t){await B(e,{type:`清过期标记`,player:t}),await B(e,{type:`下一玩家`}),await B(e,{type:`回合结束`,player:t})&&await B(e,{type:`回合结束后`,player:t})}var Ah,jh,Mh=t((()=>{b(),V(),Om(),F(),Ah=`chained`,jh=`铁索连环/传导中`})),mte=r({skipPhase:()=>Nh});async function Nh(e,t,n){return n!==void 0&&await B(e,{type:`去标签`,player:t.player,tag:n}),await B(e,{type:`阶段结束`,player:t.player,phase:t.phase}),{kind:`cancel`}}var Ph=t((()=>{V()})),hte=r({chargeOnSettle:()=>Hh,createSkill:()=>Fh,default:()=>Wh,onInit:()=>Bh,onMount:()=>Vh,registerDelayedTrickHooks:()=>zh,resumeDelayedSettlement:()=>Rh,runUseFlow:()=>Lh});function Fh(e,t){return{id:e,ownerId:t,name:`使用牌`,description:`统一的卡牌使用入口`}}async function Ih(e,t,n,r,i,a,o=!1){if(!await B(e,{type:`检测有效性`,source:n,target:r,cardId:i})||t.hasEffect&&!t.hasEffect(e,r))return;let s=Ke(e);s&&(s.cancelled=!1),await B(e,{type:`生效前`,source:n,target:r,cardId:i});{let a=e.cardMap[i],s=!o&&a?.type===`锦囊牌`?{cardName:`无懈可击`,broadcast:!0}:void 0,c=t.cancelledBy??s;c&&await Bm(e,c,n,r)}Je(e,i,r)&&(await B(e,{type:`被抵消`,source:n,target:r,cardId:i}),Je(e,i,r))||(await B(e,{type:`生效时`,source:n,target:r,cardId:i}),await B(e,{type:`生效后`,source:n,target:r,cardId:i}),await t.resolve({state:e,source:n,target:r,cardId:i,targetIndex:a}),await B(e,{type:`使用结算结束时`,source:n,target:r,cardId:i}))}async function Lh(e,t,n,r,i,a){let o=Gg(i),s=[],c=await I(e,i,t,{cardId:n,targets:[...r],resolvedTargets:[...r],skippedTargets:s});try{if(await B(e,{type:`选择目标时`,source:t,cardId:n,targets:r}),o.target.kind===`effect`){a?.virtual||await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:t},to:{zone:`处理区`}}),await B(e,{type:`使用时`,source:t,cardId:n}),await Ih(e,o,t,t,n,0,a?.virtual||a?.skipCancelQuery),!a?.virtual&&R(e).includes(n)&&await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await B(e,{type:`使用结算结束后`,source:t,cardId:n});return}o.delayed,a?.virtual||await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:t},to:{zone:`处理区`}}),await B(e,{type:`使用时`,source:t,cardId:n});for(let i of r)await B(e,{type:`指定目标`,source:t,target:i,cardId:n});for(let i=0;i<r.length;i++){let a=(c.params.resolvedTargets??r)[i];e.players[a]?.alive&&(await B(e,{type:`成为目标`,source:t,target:a,cardId:n})||c.params.skippedTargets.push(a))}if(o.delayed){let o=c.params.resolvedTargets??r,s=e.cardMap[n];for(let n of o)c.params.skippedTargets.includes(n)||await B(e,{type:`添加延时锦囊`,player:n,trick:{name:i,source:t,card:s}});a?.virtual||await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}for(let i=0;i<r.length;i++){let a=(c.params.resolvedTargets??r)[i];e.players[a]?.alive&&(c.params.skippedTargets.includes(a)||await B(e,{type:`指定目标后`,source:t,target:a,cardId:n}))}for(let i=0;i<r.length;i++){let a=(c.params.resolvedTargets??r)[i];e.players[a]?.alive&&(c.params.skippedTargets.includes(a)||await B(e,{type:`成为目标后`,source:t,target:a,cardId:n}))}for(let i=0;i<r.length;i++){let s=(c.params.resolvedTargets??r)[i];e.players[s]?.alive&&(o.delayed||c.params.skippedTargets.includes(s)||await Ih(e,o,t,s,n,i,a?.virtual))}!a?.virtual&&R(e).includes(n)&&await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),o.delayed||await B(e,{type:`使用结算结束后`,source:t,cardId:n}),a?.onSettle&&await a.onSettle()}finally{R(e).includes(n)&&await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await L(e)}}async function Rh(e,t,n,r,i){let a=Gg(r),o=await I(e,r,t,{cardId:i,targets:[n],resolvedTargets:[n]});try{return await Ih(e,a,t,n,i,0,!1),o.cancelled}finally{await L(e)}}function zh(e){N(e,`延时锦囊`,-1,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`判定`)return;let n=t.player,r=e.state.players[n];if(!r)return;let i=qg().filter(([,e])=>e.delayed).map(([e])=>e);for(;;){if(e.state.zones.deck.length===0)return;let t=[...r.pendingTricks].reverse().find(e=>i.includes(e.name));if(!t)break;if(await Rh(e.state,t.source,n,t.name,t.card.id)){let r=Wg(t.name);r?.onCancelled?await r.onCancelled(e.state,n,t.card.id):await B(e.state,{type:`移除延时锦囊`,player:n,trickName:t.name})}}}),M(e,`延时锦囊`,-1,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`)return;let n=t.player,r=e.state.players[n];if(r&&!(t.phase!==`出牌`&&t.phase!==`摸牌`))for(let[,n]of qg()){let i=n.skipPhase;if(i&&i.phase===t.phase&&r.tags.includes(i.tag)){let{skipPhase:n}=await Y(async()=>{let{skipPhase:e}=await Promise.resolve().then(()=>(Ph(),mte));return{skipPhase:e}},void 0,import.meta.url);return n(e.state,t,i.tag)}}})}function Bh(e,t){let n=e.ownerId,r=[];Uh.has(t)||(Uh.add(t),bh(t),zh(t),pte(t));for(let[e,i]of qg()){let a=j(t,e,n,`use`,(t,r)=>{let i=r.cardId;if(!i)return`cardId required`;let a=t.cardMap[i];return a?a.name===e?(!Array.isArray(r.targets)&&typeof r.target==`number`&&(r.targets=[r.target]),_h(t,n,r,e)):`不是${e}`:`牌不存在`},async(t,r)=>{let a=r.cardId;!Array.isArray(r.targets)&&typeof r.target==`number`&&(r.targets=[r.target]);let o=i.preUse?i.preUse(t,n,r):r.targets??[];i.target.kind===`self`?o=[n]:o.length===0&&(o=hh(t,n,e)),await Lh(t,n,a,o,e,{onSettle:Hh(t,n,a)})});a&&r.push(a)}return()=>r.forEach(e=>e())}function Vh(e,t){for(let[e,n]of qg())n.timing!==`生效前`&&t.defineAction(`use`,{label:n.label,style:n.style,prompt:n.prompt,...n.activeWhen?{activeWhen:n.activeWhen}:{}},e)}function Hh(e,t,n){let r=e.cardMap[n]?.name;if(!r)return;let i=Wg(r);if(!(!i?.onSettle||i.delayed))return()=>i.onSettle(e,t,n)}var Uh,Wh,Gh=t((()=>{V(),z(),F(),Um(),vh(),Yg(),Sh(),Mh(),Em(),Uh=new WeakSet,Wh={createSkill:Fh,onInit:Bh,onMount:Vh}}));function Kh(e){let t=Yh.get(e);return t||(t={targetProviders:new Map},Yh.set(e,t)),t}function qh(e,t,n){let r=Kh(e).targetProviders,i=r.get(t);return i||(i=new Set,r.set(t,i)),i.add(n),()=>{let e=r.get(t);e&&(e.delete(n),e.size===0&&r.delete(t))}}function Jh(e,t,n){let r=Kh(e).targetProviders.get(t);if(!r||r.size===0)return 1;let i=1;for(let a of r){let r=a(e,t,n);r>i&&(i=r)}return i}var Yh,Xh=t((()=>{Yh=new WeakMap})),gte=r({borrowedSwordEffect:()=>eg});async function _te(e,t,n){let r=e.players[n]?.equipment.武器;r&&(await B(e,{type:`卸下`,player:n,slot:`武器`}),await B(e,{type:`获得`,player:t,cardId:r,from:n}))}async function vte(e){let{state:t,source:n,target:r}=e,i=t.localVars[$h];await B(t,{type:`请求回应`,requestType:Zh,target:r,prompt:{type:`useCardAndTarget`,title:`借刀杀人:对 ${t.players[i]?.name??`?`} 使用一张杀,或交出武器`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:3,filter:()=>!0}},timeout:20});let a=t.localVars[Qh];delete t.localVars[Qh],a?await Lh(t,r,a.cardId,a.targets,`杀`):await _te(t,n,r)}function yte(e,t,n){let r,i;if(Array.isArray(n.targets)&&n.targets.length>=2&&typeof n.targets[0]==`number`&&typeof n.targets[1]==`number`){let e=n.targets;r=e[0],i=e[1]}else r=n.target,i=n.killTarget;if(typeof r!=`number`)return`target required`;if(typeof i!=`number`)return`killTarget required`;let a=e.players[r];return a?.alive?a.equipment.武器?r===t?`不能对自己使用`:e.players[i]?.alive?i===r?`杀的目标不能是借刀杀人目标`:null:`杀的目标不合法`:`目标没有武器`:`目标不合法`}var Zh,Qh,$h,eg,tg=t((()=>{V(),Gh(),vh(),Xm(),Xh(),Zh=`借刀杀人/出杀`,Qh=`借刀杀人/出杀选择`,$h=`借刀杀人/killTarget`,eg={timing:`出牌阶段`,target:{kind:`other`,min:1,max:1},canUse:yte,resolve:vte,preUse:(e,t,n)=>{let r,i;if(Array.isArray(n.targets)&&n.targets.length>=2&&typeof n.targets[0]==`number`&&typeof n.targets[1]==`number`){let e=n.targets;r=e[0],i=e[1]}else r=n.target,i=n.killTarget;return e.localVars[$h]=i,[r]},respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.target!==t)return`不是问你的`;if(r.atom.requestType!==Zh)return`当前不是借刀杀人询问`;let i=n.cardId;if(i===void 0)return null;let a=n.targets;if(!Array.isArray(a)||a.length===0)return`请选择杀的目标`;if(!e.players[t]?.hand.includes(i))return`牌不在手牌中`;if(e.cardMap[i]?.name!==`杀`)return`只能使用杀`;if(ph(e,t,`杀`))return`你不能使用杀`;let o=e.localVars[$h];if(o!==void 0&&!a.includes(o))return`必须包含借刀杀人指定的目标`;for(let n of a)if(!Gm(e,t,n,i))return`目标不在攻击范围内`;let s=Jh(e,t,i);return a.length>s?`最多指定 ${s} 个目标`:null},execute:async(e,t,n)=>{let r=n.cardId,i=n.targets;typeof r==`string`&&Array.isArray(i)&&(e.localVars[Qh]={cardId:r,targets:i})}},prompt:{type:`useCardAndTarget`,title:`借刀杀人`,cardFilter:{filter:e=>e.name===`借刀杀人`,min:1,max:1},targetFilter:{min:2,max:2,slots:[{label:`借刀目标`,filter:(e,t)=>t!==e.currentPlayerIndex&&!!e.players[t]?.alive&&!!e.players[t]?.equipment.武器},{label:`杀的目标`,filter:(e,t,n)=>!!e.players[t]?.alive&&!n.selected.includes(t)}]}},respondPrompt:{type:`useCardAndTarget`,title:`借刀杀人:对指定角色使用一张杀,或交出武器`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:3,filter:()=>!0}},label:`借刀杀人`,style:`danger`}})),bte=r({supplyShortageEffect:()=>rg});function xte(e,t,n){let r=n.target??n.targets?.[0];if(r===void 0)return`目标不合法`;if(r===t)return`不能对自己使用`;if(!e.players[r]?.alive)return`目标已死亡`;let i=!!e.players[t]?.tags.includes(`奇才/无距离限制`),a=n.cardId;return!i&&Wm(e,t,r,a)>1?`距离太远`:e.players[r].pendingTricks.some(e=>e.name===`兵粮寸断`)?`目标判定区已有兵粮寸断`:null}async function Ste(e){let{state:t,target:n}=e;await jm(t,n,`兵粮寸断`);let r=t.localVars[`判定/finalJudgeCardId`];delete t.localVars[`判定/finalJudgeCardId`];let i=r?t.cardMap[r]:void 0;i&&i.suit!==`♣`&&await B(t,{type:`加标签`,player:n,tag:ng}),await B(t,{type:`移除延时锦囊`,player:n,trickName:`兵粮寸断`})}var ng,rg,ig=t((()=>{V(),Fm(),Xm(),ng=`兵粮寸断/跳过摸牌`,rg={timing:`出牌阶段`,target:{kind:`distance`,dist:1,min:1,max:1},delayed:!0,skipPhase:{tag:ng,phase:`摸牌`},cancelledBy:{cardName:`无懈可击`,broadcast:!0},canUse:xte,resolve:Ste,prompt:{type:`useCardAndTarget`,title:`兵粮寸断`,cardFilter:{filter:e=>e.name===`兵粮寸断`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return!n||n.alive===!1?!1:e.players[e.currentPlayerIndex]?.tags?.includes(`奇才/无距离限制`)?!0:cm(e.players,e.currentPlayerIndex,t)<=1}}},label:`兵粮寸断`,style:`danger`}})),Cte=r({consumePlayedSlashes:()=>og,createSkill:()=>ag,default:()=>lg,onInit:()=>sg,onMount:()=>cg,runPlayFlow:()=>wte});function ag(e,t){return{id:e,ownerId:t,name:`打出牌`,description:`统一的卡牌打出入口`}}async function wte(e,t,n){await B(e,{type:`声明打出时`,player:t,cardId:n}),await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:t},to:{zone:`处理区`}}),await B(e,{type:`打出牌时`,player:t,cardId:n})}async function og(e){let t=R(e).filter(t=>e.cardMap[t]?.name===`杀`);for(let n of t)await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}});return t}function sg(e,t){let n=e.ownerId,r=[];for(let[e,i]of qg())if(i.respond)if(i.target.kind===`effect`){let a=j(t,e,n,`respond`,(e,t)=>i.respond.validate(e,n,t),async(t,r)=>{let i=r.cardId;i&&(t.localVars[`抵消/已回应`]=!0,await Lh(t,n,i,[n],e))});a&&r.push(a)}else{let a=j(t,e,n,`respond`,(e,t)=>i.respond.validate(e,n,t),(e,t)=>i.respond.execute(e,n,t));a&&r.push(a)}return()=>r.forEach(e=>e())}function cg(e,t){for(let[e,n]of qg())n.respond&&t.defineAction(`respond`,{label:n.label,style:n.style,prompt:n.respondPrompt??n.prompt},e)}var lg,ug=t((()=>{V(),z(),F(),Yg(),Gh(),lg={createSkill:ag,onInit:sg,onMount:cg}})),Tte=r({duelEffect:()=>dg});function Ete(e,t,n){let r=n.targets;return r.length===1?r[0]===t?`不能对自己使用决斗`:null:`决斗只能指定一名目标`}async function Dte(e,t,n,r){let i=0,a=null,o=0;for(;a===null;){if(o++>=100){a=i===0?n:t;break}let r=i===0?n:t;await B(e,{type:`询问杀`,target:r,source:i===0?t:n}),(await og(e)).length>0?i=+(i===0):a=r}await Dm(e,a===n?t:n,a,1,r)}async function Ote(e){let{state:t,source:n,target:r,cardId:i}=e;await Dte(t,n,r,i)}var dg,fg=t((()=>{V(),Om(),ug(),dg={timing:`出牌阶段`,target:{kind:`other`,min:1,max:1},canUse:Ete,resolve:Ote,prompt:{type:`useCardAndTarget`,title:`决斗`,cardFilter:{filter:e=>e.name===`决斗`,min:1,max:1},targetFilter:{min:1,max:1}},label:`决斗`,style:`danger`}})),kte=r({barbarianInvasionEffect:()=>pg});async function Ate(e){let{state:t,source:n,target:r,cardId:i}=e;if(await B(t,{type:`询问杀`,target:r,source:n}),(await og(t)).length===0){if(!t.players[r]?.alive)return;await Dm(t,n,r,1,i)}}var pg,mg=t((()=>{V(),Om(),ug(),pg={timing:`出牌阶段`,target:{kind:`allOthers`},resolve:Ate,prompt:{type:`useCard`,title:`南蛮入侵`,cardFilter:{filter:e=>e.name===`南蛮入侵`,min:1,max:1}},label:`南蛮入侵`,style:`danger`}})),jte=r({exNihiloEffect:()=>hg});async function Mte(e){let{state:t,target:n}=e;await B(t,{type:`摸牌`,player:n,count:2})}var hg,gg=t((()=>{V(),hg={timing:`出牌阶段`,target:{kind:`self`},resolve:Mte,prompt:{type:`useCard`,title:`无中生有`,cardFilter:{filter:e=>e.name===`无中生有`,min:1,max:1}},label:`无中生有`,style:`primary`}})),Nte=r({nullificationEffect:()=>vg}),_g,vg,yg=t((()=>{F(),_g=`无懈可击`,vg={timing:`生效前`,target:{kind:`effect`},resolve:async e=>{let{state:t}=e,n=t.settlementStack[t.settlementStack.length-2];n&&(n.cancelled=!0)},respond:{validate:(e,t,n)=>{let r=ae(e,t);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`||r.atom.requestType!==_g)return`当前不是无懈可击窗口`;let i=n.cardId;if(!i)return`cardId required`;let a=e.players[t];return a.alive?a.hand.includes(i)?e.cardMap[i].name===_g?null:`只能打出无懈可击`:`牌不在手牌中`:`你已死亡`},execute:async()=>{}},prompt:{type:`useCard`,title:`打出无懈可击`,cardFilter:{filter:e=>e.name===_g,min:1,max:1}},respondPrompt:{type:`useCard`,title:`打出无懈可击`,cardFilter:{filter:e=>e.name===_g,min:1,max:1}},label:_g,style:`danger`}})),Pte=r({slashEffect:()=>bg});function Fte(e,t,n){let r=n.cardId;if(!(Array.isArray(n.targets)&&n.targets.every(n=>e.players[n]?.alive===!0?Gm(e,t,n,r):!1)))return`目标不合法`;let i=Array.isArray(n.targets)?n.targets:[],a=Jh(e,t,r);return i.length>a?`最多指定 ${a} 个目标`:null}async function Ite(e){let{state:t,source:n,target:r,cardId:i}=e,a=t.cardMap[i]?.damageType;await Dm(t,n,r,1,i,a)}async function Lte(e,t,n){ch(e,t,n)||(uh(e),await B(e,{type:`回合用量`,player:t,key:El,value:ah(e)}))}var bg,xg=t((()=>{V(),Om(),Xm(),um(),fh(),Xh(),J(),W(),bg={timing:`出牌阶段`,target:{kind:`inAttackRange`,min:1,max:3},canUse:Fte,resolve:Ite,onSettle:Lte,cancelledBy:{cardName:`闪`,broadcast:!1},respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.target!==t)return`不是问你的`;let i=r.atom.type,a=r.atom.requestType;if(!(i===`询问杀`||i===`请求回应`&&a===`杀/respondKill`))return`当前不是出杀的窗口`;let o=n.cardId;if(o){if(!e.players[t].hand.includes(o))return`牌不在手牌中`;if(e.cardMap[o]?.name!==`杀`)return`只能打出杀`}return null},execute:async(e,t,n)=>{let r=n.cardId;r&&await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:t},to:{zone:`处理区`}})}},prompt:{type:`useCardAndTarget`,title:`出杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:3,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},respondPrompt:{type:`useCard`,title:`打出杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},label:`杀`,style:`danger`,activeWhen:e=>q(e)&&sm(e.view,e.perspectiveIdx)}})),Rte=r({peachEffect:()=>Sg});function zte(e,t,n){let r=n.target??n.targets?.[0]??t;return e.players[r]?.alive===!0&&e.players[r]?.health<e.players[r]?.maxHealth?null:`桃只能对受伤角色使用`}async function Bte(e){let{state:t,source:n,target:r}=e;await B(t,{type:`回复体力`,target:r,amount:1,source:n})}function Vte(e){if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.health<t.maxHealth:!1}var Sg,Cg=t((()=>{V(),J(),Sg={timing:`出牌阶段`,target:{kind:`wounded`,min:0,max:1},canUse:zte,resolve:Bte,respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.target!==t)return`不是问你的`;if(r.atom.type!==`请求回应`||r.atom.requestType!==`桃/求桃`)return`当前不是求桃`;let i=n.cardId;if(i){if(!e.players[t].hand.includes(i))return`牌不在手牌中`;if(e.cardMap[i].name!==`桃`)return`只能用桃救援`}return null},execute:async(e,t,n)=>{let r=n.cardId;r&&(await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:t},to:{zone:`弃牌堆`}}),e.localVars[`求桃/已救`]=!0)}},prompt:{type:`useCardAndTarget`,title:`出桃`,cardFilter:{filter:e=>e.name===`桃`,min:1,max:1},targetFilter:{min:0,max:1,filter:(e,t)=>{let n=e.players[t];return n?.alive===!0&&n.health<n.maxHealth}},selfTarget:!0},respondPrompt:{type:`useCard`,title:`打出桃`,cardFilter:{filter:e=>e.name===`桃`,min:1,max:1}},label:`桃`,style:`primary`,activeWhen:Vte}})),Hte=r({peachGardenEffect:()=>wg});async function Ute(e){let{state:t,target:n}=e,r=t.players[n];r?.alive&&(r.health>=r.maxHealth||await B(t,{type:`回复体力`,target:n,amount:1}))}var wg,Tg=t((()=>{V(),wg={timing:`出牌阶段`,target:{kind:`allPlayers`},hasEffect:(e,t)=>{let n=e.players[t];return!!n?.alive&&n.health<n.maxHealth},resolve:Ute,prompt:{type:`useCard`,title:`桃园结义`,cardFilter:{filter:e=>e.name===`桃园结义`,min:1,max:1}},label:`桃园结义`,style:`primary`}})),Wte=r({fireAttackEffect:()=>Eg});async function Gte(e){let{state:t,source:n,target:r,cardId:i}=e,a=t.players[r];if(!a||a.hand.length===0)return;delete t.localVars[`火攻/展示`],delete t.localVars[`火攻/展示花色`],delete t.localVars[`火攻/弃牌`];let o=a.hand[0];await B(t,{type:`请求回应`,requestType:`火攻/展示`,target:r,prompt:{type:`useCard`,title:`火攻:展示一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let s=t.localVars[`火攻/展示`];s||(s={cardId:o,suit:t.cardMap[o]?.suit??``},t.localVars[`火攻/展示`]=s,t.localVars[`火攻/展示花色`]=s.suit),await B(t,{type:`展示`,player:r,cardId:s.cardId});let c=s.suit,l=t.players[n];if(!(l?.alive&&l.hand.some(e=>t.cardMap[e]?.suit===c))){await B(t,{type:`展示结束`,player:r,cardId:s.cardId});return}delete t.localVars[`火攻/弃牌`],await B(t,{type:`请求回应`,requestType:`火攻/弃牌`,target:n,prompt:{type:`useCard`,title:`火攻:弃置一张 ${c} 手牌对其造成1点火焰伤害(不弃则无效)`,cardFilter:{filter:e=>e.suit===c,min:1,max:1}},timeout:15});let u=t.localVars[`火攻/弃牌`];u&&t.players[r]?.alive&&(await B(t,{type:`弃置`,player:n,cardIds:[u],voluntary:!0}),await Dm(t,n,r,1,i,`火焰`)),await B(t,{type:`展示结束`,player:r,cardId:s.cardId})}function Kte(e,t,n){let r=n.targets;if(!Array.isArray(r)||r.length!==1)return`火攻只能指定一名目标`;let i=r[0],a=e.players[i];return a?.alive?a.hand.length===0?`目标必须有手牌`:null:`目标不合法`}var Eg,Dg=t((()=>{V(),Om(),Eg={timing:`出牌阶段`,target:{kind:`any`,min:1,max:1},canUse:Kte,resolve:Gte,respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是火攻窗口`;let i=r.atom.requestType;if(i!==`火攻/展示`&&i!==`火攻/弃牌`)return`当前不是火攻窗口`;let a=n.cardId;if(typeof a!=`string`)return`cardId required`;let o=e.players[t];if(!o?.alive)return`你已死亡`;if(!o.hand.includes(a))return`牌不在手牌中`;if(i===`火攻/弃牌`){let t=e.localVars[`火攻/展示花色`],n=e.cardMap[a];if(!t||n?.suit!==t)return`必须弃置与展示牌相同花色的手牌`}return null},execute:async(e,t,n)=>{let r=e.pendingSlots.get(t).atom.requestType,i=n.cardId,a=e.cardMap[i];r===`火攻/展示`?(e.localVars[`火攻/展示`]={cardId:i,suit:a?.suit??``},e.localVars[`火攻/展示花色`]=a?.suit??``):e.localVars[`火攻/弃牌`]=i}},prompt:{type:`useCardAndTarget`,title:`火攻`,cardFilter:{filter:e=>e.name===`火攻`,min:1,max:1},targetFilter:{min:1,max:1,allowSelf:!0}},respondPrompt:{type:`useCard`,title:`火攻`,cardFilter:{filter:()=>!0,min:1,max:1}},label:`火攻`,style:`danger`}}));function Og(e,t){let n=e.players[t];if(!n)return;let r=[...n.hand];if(r.length===0)return;let i=e.actionLog,a=i.length-1;if(a>0){let e=i[a-1];if(e.message.skillId===`系统规则`&&e.message.actionType===`设置手牌顺序`&&e.message.params.target===t){let t=e.message.params.order;if(Array.isArray(t)&&t.length===r.length&&t.every((e,t)=>e===r[t]))return}}let o={id:`order-${i.length}-${t}`,timestamp:e.clock.now()-e.startedAt,message:{skillId:`系统规则`,actionType:`设置手牌顺序`,ownerId:i[a].message.ownerId,params:{target:t,order:r},baseSeq:i[a].baseSeq},baseSeq:i[a].baseSeq};i.splice(a,0,o)}async function kg(e,t,n,r,i){let a=i.mode===`obtain`,o=Object.entries(r.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`})),s=i.includeJudge===!1?[]:r.pendingTricks.map(e=>({cardId:e.card.id,cardName:e.card.name})),c=r.hand.length,l=o.length>0?{zone:`equipment`,cardId:o[0].cardId}:s.length>0?{zone:`judge`,cardId:s[0].cardId}:{zone:`hand`,handIndex:0};c>0&&Og(e,n);let u={type:`请求回应`,requestType:i.requestType,target:t,prompt:{type:`pickTargetCard`,mode:i.mode,title:i.title,target:n,equipment:o,judge:s,handCount:c},defaultChoice:l,timeout:20};await B(e,u);let d=hl(e.localVars);delete e.localVars[Tl];let f=u.prompt.equipment??[],p=l;p.zone===`equipment`&&(f.some(e=>e.cardId===p.cardId)||(p=f.length>0?{zone:`equipment`,cardId:f[0].cardId}:s.length>0?{zone:`judge`,cardId:s[0].cardId}:{zone:`hand`,handIndex:0}));let m=d?.zone??p.zone;if(m===`equipment`){let r=d?.cardId??p.cardId;if(!f.some(e=>e.cardId===r))return;a?await B(e,{type:`获得`,player:t,cardId:r,from:n}):await B(e,{type:`弃置`,player:n,cardIds:[r]})}else if(m===`judge`){let i=d?.cardId??p.cardId,o=r.pendingTricks.find(e=>e.card.id===i);o&&(await B(e,{type:`移除延时锦囊`,player:n,trickName:o.name}),a?await nt(e,n,i,t):await tt(e,n,i))}else{let i=d?.handIndex??0,o=r.hand[i]??r.hand[0];o&&(a?await B(e,{type:`获得`,player:t,cardId:o,from:n}):await B(e,{type:`弃置`,player:n,cardIds:[o]}))}}var Ag=t((()=>{V(),rt(),W()})),qte=r({dismantleEffect:()=>jg});function Jte(e,t,n){let r=n.targets;if(!Array.isArray(r)||r.length===0)return`目标不合法`;for(let n of r){if(n===t)return`不能对自己使用`;if(!e.players[n]?.alive)return`目标已死亡`;let r=e.players[n];if(!r)return`目标不合法`;if(!(r.hand.length>0||Object.keys(r.equipment).length>0||r.pendingTricks.length>0))return`目标无可弃置的牌`}return null}async function Yte(e){let{state:t,source:n,target:r}=e,i=t.players[r];i&&await kg(t,n,r,i,{mode:`discard`,requestType:`过河拆桥_选牌`,title:`选择弃置的目标牌`})}var jg,Mg=t((()=>{Ag(),W(),jg={timing:`出牌阶段`,target:{kind:`other`,min:1,max:1},canUse:Jte,resolve:Yte,respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是选牌窗口`;let i=r.atom;if(i.requestType!==`过河拆桥_选牌`)return`当前不是选牌窗口`;let a=n.zone;if(a===`equipment`||a===`judge`){if(typeof n.cardId!=`string`)return`cardId required`}else if(a===`hand`){if(typeof n.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|judge|hand)`;if(a===`equipment`&&typeof n.cardId==`string`){let e=i.prompt?.equipment;if(e&&!e.some(e=>e.cardId===n.cardId))return`该装备不可选`}return null},execute:async(e,t,n)=>{e.localVars[Tl]={zone:n.zone,cardId:n.cardId??null,handIndex:n.handIndex??null}}},prompt:{type:`useCardAndTarget`,title:`过河拆桥`,cardFilter:{filter:e=>e.name===`过河拆桥`,min:1,max:1},targetFilter:{min:1,max:1}},label:`过河拆桥`,style:`primary`}})),Xte=r({chainEffect:()=>Ng});async function Zte(e){let{state:t,target:n}=e;await Th(t,n,!Eh(t,n))}function Qte(e,t,n){let r=n.targets;if(!Array.isArray(r)||r.length<1||r.length>2)return`需选择一至两名角色`;for(let t of r)if(!e.players[t]?.alive)return`目标不合法`;return null}var Ng,Pg=t((()=>{Mh(),Ng={timing:`出牌阶段`,target:{kind:`any`,min:1,max:2},canUse:Qte,resolve:Zte,prompt:{type:`useCardAndTarget`,title:`铁索连环`,cardFilter:{filter:e=>e.name===`铁索连环`,min:1,max:1},targetFilter:{min:1,max:2,allowSelf:!0}},label:`铁索连环`,style:`primary`}})),$te=r({dodgeEffect:()=>Ig}),Fg,Ig,Lg=t((()=>{Fg=`闪/色限制`,Ig={timing:`生效前`,target:{kind:`effect`},resolve:async e=>{let{state:t}=e,n=t.settlementStack[t.settlementStack.length-2];n&&(n.cancelled=!0)},respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.target!==t)return`不是问你的`;if(!(r.atom.type===`询问闪`||r.atom.type===`请求回应`&&r.atom.requestType===`闪`))return`当前不是出闪的窗口`;let i=n.cardId;if(i){if(!e.players[t].hand.includes(i))return`牌不在手牌中`;let n=e.cardMap[i];if(n?.name!==`闪`)return`只能打出闪`;let r=e.localVars[Fg];if(r&&n.color!==r)return`只能打出${r}色的闪`}return null},execute:async()=>{}},prompt:{type:`useCard`,title:`打出闪`,cardFilter:{filter:e=>e.name===`闪`,min:1,max:1}},respondPrompt:{type:`useCard`,title:`打出闪`,cardFilter:{filter:e=>e.name===`闪`,min:1,max:1}},label:`闪`,style:`default`}})),ene=r({lightningEffect:()=>Bg});function tne(e){if(e.suit!==`♠`)return!1;let t=e.rank,n=t===`A`?1:t===`J`?11:t===`Q`?12:t===`K`?13:parseInt(t,10);return n>=2&&n<=9}function nne(e,t){let n=e.players.length;for(let r=1;r<=n;r++){let i=(t+r)%n,a=e.players[i];if(a.alive&&!a.pendingTricks.some(e=>e.name===zg))return i}return null}async function Rg(e,t,n){await B(e,{type:`移除延时锦囊`,player:t,trickName:zg});let r=nne(e,t);r!==null&&await B(e,{type:`添加延时锦囊`,player:r,trick:{name:zg,source:t,card:n}})}async function rne(e,t,n){await Rg(e,t,e.players[t]?.pendingTricks.find(e=>e.name===zg)?.card??e.cardMap[n]??{id:n,name:zg,suit:`♠`,color:`黑`,rank:`A`,type:`锦囊牌`})}async function ine(e){let{state:t,target:n,cardId:r}=e;await jm(t,n,zg);let i=t.localVars[`判定/finalJudgeCardId`];delete t.localVars[`判定/finalJudgeCardId`];let a=i?t.cardMap[i]:void 0,o=t.players[n]?.pendingTricks.find(e=>e.name===zg)?.card??t.cardMap[r]??a??{id:r,name:zg,suit:`♠`,color:`黑`,rank:`A`,type:`锦囊牌`};a&&tne(a)?(await Dm(t,-1,n,3,void 0,`雷电`),await B(t,{type:`移除延时锦囊`,player:n,trickName:zg})):await Rg(t,n,o)}var zg,Bg,Vg=t((()=>{b(),V(),Fm(),Om(),zg=`闪电`,Bg={timing:`出牌阶段`,target:{kind:`self`},delayed:!0,cancelledBy:{cardName:`无懈可击`,broadcast:!0},resolve:ine,onCancelled:rne,prompt:{type:`useCard`,title:`闪电`,cardFilter:{filter:e=>e.name===zg,min:1,max:1}},label:`闪电`,style:`danger`}})),ane=r({snatchEffect:()=>Hg});function one(e,t,n){let r=n.target??n.targets?.[0];if(r===void 0)return`目标不合法`;if(r===t)return`不能对自己使用`;if(!e.players[r]?.alive)return`目标已死亡`;let i=!!e.players[t]?.tags.includes(`奇才/无距离限制`),a=n.cardId;if(!i&&Wm(e,t,r,a)>1)return`距离太远`;let o=e.players[r];return o?o.hand.length>0||Object.keys(o.equipment).length>0||o.pendingTricks.length>0?null:`目标无可获取的牌`:`目标不合法`}async function sne(e){let{state:t,source:n,target:r}=e,i=t.players[r];i&&await kg(t,n,r,i,{mode:`obtain`,requestType:`顺手牵羊_选牌`,title:`选择获得的目标牌`})}var Hg,Ug=t((()=>{Xm(),um(),Ag(),W(),Hg={timing:`出牌阶段`,target:{kind:`distance`,dist:1,min:1,max:1},canUse:one,resolve:sne,respond:{validate:(e,t,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`||r.atom.requestType!==`顺手牵羊_选牌`)return`当前不是选牌窗口`;let i=n.zone;if(i===`equipment`||i===`judge`){if(typeof n.cardId!=`string`)return`cardId required`}else if(i===`hand`){if(typeof n.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|judge|hand)`;return null},execute:async(e,t,n)=>{e.localVars[Tl]={zone:n.zone,cardId:n.cardId??null,handIndex:n.handIndex??null}}},prompt:{type:`useCardAndTarget`,title:`顺手牵羊`,cardFilter:{filter:e=>e.name===`顺手牵羊`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return!n||n.alive===!1?!1:e.players[e.currentPlayerIndex]?.tags?.includes(`奇才/无距离限制`)?!0:cm(e.players,e.currentPlayerIndex,t)<=1}}},label:`顺手牵羊`,style:`primary`}})),cne=r({cardEffectMap:()=>Jg,getAllCardEffects:()=>qg,getCardEffect:()=>Wg,hasCardEffect:()=>Kg,requireCardEffect:()=>Gg});function Wg(e){return Jg[e]}function Gg(e){let t=Jg[e];if(!t)throw Error(`CardEffect 未注册: ${e}`);return t}function Kg(e){return e in Jg}function qg(){return Object.entries(Jg)}var Jg,Yg=t((()=>{Am(),Xee(),zm(),tg(),ig(),fg(),mg(),gg(),yg(),xg(),Cg(),Tg(),Dg(),Mg(),Sh(),Pg(),Lg(),Vg(),Ug(),Jg={万箭齐发:km,乐不思蜀:Lm,五谷丰登:Rm,借刀杀人:eg,兵粮寸断:rg,决斗:dg,南蛮入侵:pg,无中生有:hg,无懈可击:vg,杀:bg,桃:Sg,桃园结义:wg,火攻:Eg,过河拆桥:jg,酒:xh,铁索连环:Ng,闪:Ig,闪电:Bg,顺手牵羊:Hg}})),lne=r({createSkill:()=>une,onInit:()=>dne,onMount:()=>fne});function une(e,t){return{id:e,ownerId:t,name:`丈八蛇矛`,description:`可将两张手牌当杀使用`}}function Xg(e,t){return`${e}#${t}#丈八蛇矛`}function dne(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardIds;if(!Array.isArray(c)||c.length!==2)return`需要选择 2 张手牌`;let[l,u]=c;if(typeof l!=`string`||typeof u!=`string`)return`cardIds 必须为字符串`;if(l===u)return`不能选择同一张牌`;let d=!!o&&o.hand.includes(l)&&o.hand.includes(u),f=e.cardMap[l],p=e.cardMap[u],m=!!f&&!!p,h=o.equipment.武器,g=(h?e.cardMap[h]:void 0)?.name===`丈八蛇矛`,_=e.pendingSlots.get(n),v=_?.atom?.type,y=_?.atom?.requestType,ee=_?.atom?.target;return s&&d&&m&&g&&(r&&i&&a||_&&ee===n&&(v===`询问杀`||v===`请求回应`&&y===`杀/respondKill`))?null:`丈八蛇矛转化条件不满足`},async(e,t)=>{let r=t.cardIds,[i,a]=r;await B(e,{type:`当作`,player:n,cardIds:r,shadowId:Xg(i,a),outputName:`杀`})},(e,t)=>{let r=t.cardIds,[i,a]=Array.isArray(r)?r:[],o=i&&a?Xg(i,a):void 0;if(o){delete e.cardMap[o];let t=e.players[n],r=t.hand.indexOf(o);r>=0&&t.hand.splice(r,1),t.hand.push(i,a)}});let r=de(t,n,`询问杀`);return()=>{r()}}function fne(e,t){t.defineAction(`transform`,{label:`丈八蛇矛`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择 2 张手牌当杀使用`,cardFilter:{filter:()=>!0,min:2,max:2},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t)return!1;let n=t.equipment.武器;if((n?e.view.cardMap[n]:void 0)?.name!==`丈八蛇矛`||(t.handCount??0)<2)return!1;let r=q(e)&&sm(e.view,e.perspectiveIdx),i=e.view.pending,a=i?.atom?.type,o=i?.atom?.requestType,s=!!i&&i.target===e.perspectiveIdx&&(a===`询问杀`||a===`请求回应`&&o===`杀/respondKill`);return r||s}})}var pne=t((()=>{F(),V(),um(),J()})),mne=r({createSkill:()=>Zg,default:()=>n_,onInit:()=>Qg});function Zg(e,t){return{id:e,ownerId:t,name:`不屈`,description:`锁定技:濒死时将牌堆顶一张牌作"创"牌置于武将牌上,点数与已有创牌均不同则回复至1体力,相同则移去此牌`,isLocked:!0}}function Qg(e,t){let n=e.ownerId;return N(t,e.id,n,`陷入濒死`,async e=>{if(e.atom.target!==n||!e.state.players[n]?.alive||e.state.zones.deck.length===0)return;delete e.state.localVars[t_],await B(e.state,{type:`置创牌`,player:n,varsKey:e_,resultKey:t_});let t=e.state.localVars[t_];if(delete e.state.localVars[t_],t)return;let r=e.state.players[n].health,i=Math.max(0,1-r);i>0&&await B(e.state,{type:`回复体力`,target:n,amount:i}),e.state.localVars[$g]=n}),()=>{}}var $g,e_,t_,n_,hne=t((()=>{V(),F(),$g=`不屈/存活`,e_=`不屈/创牌`,t_=`不屈/重复`,n_={createSkill:Zg,onInit:Qg}})),gne=r({createSkill:()=>r_,default:()=>h_,onInit:()=>i_,onMount:()=>a_});function r_(e,t){return{id:e,ownerId:t,name:`义绝`,description:`出牌阶段限一次,弃置一张牌并令一名其他角色展示一张手牌;黑色则其本回合非锁定技失效且不能使用或打出手牌,你对其红桃杀伤害+1;红色则你获得之,然后可令其回1点体力`}}function i_(e,t){let n=e.ownerId,r=je(t,(e,t,n)=>e.players[t]?.tags.includes(u_)===!0);j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`义绝`))return`本回合已使用过义绝`;let i=t.cardId;if(!i)return`请选择要弃置的牌`;if(!r.hand.includes(i))return`弃置的牌必须在手牌中`;let a=t.targets;if(!Array.isArray(a)||a.length!==1)return`需要指定一名目标`;let o=a[0];if(o===n)return`不能对自己使用义绝`;let s=e.players[o];return s?.alive?s.hand.length===0?`目标没有手牌`:null:`目标不合法`},async(e,t)=>{let r=n;await Z(e,r,`义绝`);let i=t.targets[0],a=t.cardId;await I(e,`义绝`,r,{...t}),await B(e,{type:`弃置`,player:r,cardIds:[a],voluntary:!0});let o=e.players[i];if(!o?.alive||o.hand.length===0){await L(e);return}let s=o.hand.map(t=>{let n=e.cardMap[t];return n?{cardId:t,cardName:n.name,suit:n.suit,rank:n.rank}:null}).filter(e=>e!==null);delete e.localVars[c_],await B(e,{type:`请求回应`,requestType:o_,target:i,prompt:{type:`pickProcessingCard`,title:`义绝:选择一张手牌展示`,cards:s},timeout:30});let c=e.localVars[c_],l=e.players[i]?.hand??[];(!c||!l.includes(c))&&(c=l[0]),delete e.localVars[c_];let u=c?e.cardMap[c]:void 0;if(!u){await L(e);return}if(await B(e,{type:`展示`,player:i,cardId:c}),u.color===`黑`)await B(e,{type:`加标签`,player:i,tag:u_}),await B(e,{type:`加标签`,player:i,tag:d_}),await B(e,{type:`加标签`,player:i,tag:f_});else{if(await B(e,{type:`移动牌`,cardId:c,from:{zone:`手牌`,player:i},to:{zone:`手牌`,player:r}}),delete e.localVars[l_],await B(e,{type:`请求回应`,requestType:s_,target:r,prompt:{type:`confirm`,title:`义绝:是否令 ${e.players[i]?.name??`目标`} 回复1点体力?`,confirmLabel:`回复`,cancelLabel:`不回复`},defaultChoice:!1,timeout:15}),e.localVars[l_]===!0){let t=e.players[i];t?.alive&&t.health<t.maxHealth&&await B(e,{type:`回复体力`,target:i,amount:1,source:r})}delete e.localVars[l_]}await L(e)});let i=[];for(let n of t.players){let r=n.index,a=j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return`当前不需要回应`;let i=n.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===o_){let n=t.cardId;return n?e.players[r].hand.includes(n)?null:`牌不在手牌中`:`请选择一张手牌展示`}return a===s_?typeof t.choice==`boolean`?null:`需要选择一项`:`当前不是义绝回应`},async(e,t)=>{let n=e.pendingSlots.get(r)?.atom?.requestType;n===o_?e.localVars[c_]=t.cardId:n===s_&&(e.localVars[l_]=t.choice===!0)});i.push(a)}let a=async e=>{let t=e.atom,r=t.target;if(typeof r!=`number`||r<0||r===n||!e.state.players[r]?.tags.includes(d_))return;if(t.type===`询问闪`||t.type===`询问杀`)return{kind:`cancel`};let i=t.prompt?.type;if(i&&m_.has(i))return{kind:`cancel`}};return M(t,e.id,n,`请求回应`,a),M(t,e.id,n,`询问闪`,a),M(t,e.id,n,`询问杀`,a),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0)return;let r=t.target;if(r===void 0)return;let i=t.cardId;if(typeof i!=`string`)return;let a=e.state.cardMap[i];if(!(a?.name!==`杀`||a.suit!==`♥`)&&e.state.players[r]?.tags.includes(f_))return{kind:`modify`,atom:{...e.atom,amount:(t.amount??0)+1}}}),N(t,e.id,n,`回合结束`,async e=>{if(e.atom.player===n)for(let t of e.state.players)for(let n of p_)t.tags.includes(n)&&await B(e.state,{type:`去标签`,player:t.index,tag:n})}),()=>{i.forEach(e=>e()),r()}}function a_(e,t){return t.defineAction(`use`,{label:`义绝`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`义绝:弃置一张牌,令一名其他角色展示一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(t,n)=>n!==e.ownerId&&(t.players[n]?.handCount??0)>0}},activeWhen:t=>{if(!yh(`义绝`)(t))return!1;let n=t.view.players[t.perspectiveIdx];return!n||!((n.hand?.length??0)>0)?!1:t.view.players.some(t=>t.index!==e.ownerId&&t.alive&&(t.handCount??0)>0)}}),t.defineAction(`respond`,{label:`义绝`,style:`danger`,prompt:{type:`pickProcessingCard`,title:`义绝:选择一张手牌展示`,cards:[]}}),()=>{}}var o_,s_,c_,l_,u_,d_,f_,p_,m_,h_,_ne=t((()=>{V(),z(),Q(),F(),Pe(),o_=`义绝/reveal`,s_=`义绝/heal`,c_=`义绝/revealedCardId`,l_=`义绝/healChoice`,u_=`义绝/非锁定技失效`,d_=`义绝/禁出牌`,f_=`义绝/红桃杀加伤`,p_=[u_,d_,f_],m_=new Set([`useCard`,`useCardAndTarget`,`pickProcessingCard`,`pickTargetCard`,`distribute`]),h_={createSkill:r_,onInit:i_,onMount:a_}})),vne=r({createSkill:()=>g_,default:()=>b_,onInit:()=>v_,onMount:()=>y_});function g_(e,t){return{id:e,ownerId:t,name:`乱击`,description:`你可以将两张同花色的手牌当【万箭齐发】使用`}}function __(e,t){return`${e}#${t}#乱击`}function v_(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardIds;if(!Array.isArray(c)||c.length!==2)return`需要选择 2 张手牌`;let[l,u]=c;if(typeof l!=`string`||typeof u!=`string`)return`cardIds 必须为字符串`;if(l===u)return`不能选择同一张牌`;let d=!!o&&o.hand.includes(l)&&o.hand.includes(u),f=e.cardMap[l],p=e.cardMap[u],m=!!f&&!!p,h=!!f&&!!p&&f.suit!==``&&f.suit===p.suit;return r&&i&&a&&s&&d&&m&&h?null:`乱击需要两张同花色的手牌`},async(e,t)=>{let r=t.cardIds,[i,a]=r;await B(e,{type:`当作`,player:n,cardIds:r,shadowId:__(i,a),outputName:`万箭齐发`})},(e,t)=>{let r=t.cardIds,[i,a]=Array.isArray(r)?r:[],o=i&&a?__(i,a):void 0;if(o){delete e.cardMap[o];let t=e.players[n],r=t.hand.indexOf(o);r>=0&&t.hand.splice(r,1),t.hand.push(i,a)}}),()=>{}}function y_(e,t){t.defineAction(`transform`,{label:`乱击`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`选择 2 张同花色的手牌当万箭齐发使用`,cardFilter:{filter:()=>!0,min:2,max:2,comboFilter:e=>e[0]?.suit===e[1]?.suit},targetFilter:{min:0,max:0}},transform:t=>({name:`万箭齐发`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];if(!t?.hand)return!1;let n={};for(let e of t.hand)if(e.suit&&(n[e.suit]=(n[e.suit]??0)+1,n[e.suit]>=2))return!0;return!1}})}var b_,yne=t((()=>{F(),V(),J(),b_={createSkill:g_,onInit:v_,onMount:y_}})),bne=r({createSkill:()=>x_,default:()=>O_,onInit:()=>C_,onMount:()=>w_});function x_(e,t){return{id:e,ownerId:t,name:`乱武`,description:`限定技:出牌阶段令所有其他角色依次对距离最近者出杀,无法如此做者失去1点体力`}}function S_(e,t){let n=1/0,r=new Map;for(let i=0;i<e.players.length;i++){if(i===t||!e.players[i]?.alive)continue;let a=Wm(e,t,i);r.set(i,a),a<n&&(n=a)}let i=[];for(let[e,t]of r)t===n&&i.push(e);return i}function C_(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`use`,(e,t)=>e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:e.players[n]?.vars[T_]?`乱武已使用过(限定技)`:e.players[n]?.alive?e.players.filter(e=>e.alive&&e.index!==n).length===0?`场上没有其他角色`:null:`玩家不存在或已死亡`:`只能在出牌阶段发动`:`不是你的回合`,async(e,r)=>{let i=n;e.players[i].vars[T_]=!0,await I(t,`乱武`,i,{});try{let t=e.players.length;for(let n=1;n<t;n++){let r=(i+n)%t;if(r===i||!e.players[r]?.alive)continue;let a=S_(e,r);if(a.length===0){await B(e,{type:`失去体力`,target:r,amount:1});continue}delete e.localVars[E_],await B(e,{type:`请求回应`,requestType:D_,target:r,prompt:{type:`useCardAndTarget`,title:`乱武:对距离最近的角色使用一张【杀】,否则失去1点体力`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>a.includes(t)}},timeout:20});let o=e.localVars[E_];delete e.localVars[E_],o&&e.players[r].hand.includes(o.cardId)&&S_(e,r).includes(o.target)&&e.players[o.target]?.alive?await Lh(e,r,o.cardId,[o.target],`杀`):await B(e,{type:`失去体力`,target:r,amount:1})}}finally{await L(t)}}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;if(n.atom.requestType!==D_)return`当前不是乱武询问`;let r=t.cardId,a=t.target;return typeof r==`string`?typeof a==`number`?e.players[i]?.hand.includes(r)?e.cardMap[r]?.name===`杀`?S_(e,i).includes(a)?null:`目标不是距离最近的角色`:`只能使用杀`:`牌不在手牌中`:`请选择目标`:`请选择一张杀`},async(e,t)=>{e.localVars[E_]={cardId:t.cardId,target:t.target}}))}return()=>{for(let e of r)e()}}function w_(e,t){return t.defineAction(`use`,{label:`乱武`,style:`primary`,prompt:{type:`confirm`,title:`乱武(限定技):令所有其他角色依次对距离最近者出杀,无法如此做者失去1点体力`},activeWhen:e=>q(e)}),t.defineAction(`respond`,{label:`出杀`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`乱武:对距离最近的角色使用一张【杀】,否则失去1点体力`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1}}}),()=>{}}var T_,E_,D_,O_,xne=t((()=>{V(),z(),Gh(),J(),F(),Xm(),T_=`乱武/used`,E_=`乱武/出杀`,D_=`乱武/出杀`,O_={createSkill:x_,onInit:C_,onMount:w_}})),Sne=r({createSkill:()=>A_,default:()=>N_,onInit:()=>j_,onMount:()=>M_});function k_(e,t){return e.cardMap[t]?.type===`基本牌`}function A_(e,t){return{id:e,ownerId:t,name:`享乐`,description:`锁定技:其他角色用杀指定你为目标时,需额外弃一张基本牌,否则杀对你无效`,isLocked:!0}}function j_(e,t){let n=e.ownerId;for(let n of t.players){let r=n.index;j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n||n.atom.type!==`请求回应`)return`当前不需要回应`;if(n.atom.requestType!==`享乐/discard`)return`当前不是享乐回应`;let i=t.cardId;return typeof i==`string`?e.players[r].hand.includes(i)?k_(e,i)?null:`只能弃置基本牌(杀/闪/桃)`:`牌不在手牌中`:`请选择一张基本牌`},async(e,t)=>{e.localVars[`享乐/discardCard`]=t.cardId})}return M(t,e.id,n,`检测有效性`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.source;if(r===void 0||r===n)return;let i=t.cardId;if(!i||e.state.cardMap[i]?.name!==`杀`)return;let a=e.state.players[r];if(!a?.alive)return;if(!a.hand.some(t=>k_(e.state,t)))return{kind:`cancel`};delete e.state.localVars[`享乐/discardCard`],await B(e.state,{type:`请求回应`,requestType:`享乐/discard`,target:r,prompt:{type:`useCard`,title:`享乐:弃置一张基本牌,否则杀对 ${e.state.players[n].name} 无效`,cardFilter:{filter:e=>e.type===`基本牌`,min:1,max:1}},timeout:20});let o=e.state.localVars[`享乐/discardCard`];if(delete e.state.localVars[`享乐/discardCard`],o&&a.hand.includes(o)){await B(e.state,{type:`弃置`,player:r,cardIds:[o]});return}return{kind:`cancel`}}),()=>{}}function M_(e,t){t.defineAction(`respond`,{label:`享乐`,style:`default`,prompt:{type:`useCard`,title:`享乐:弃置一张基本牌`,cardFilter:{filter:e=>e.type===`基本牌`,min:1,max:1}}})}var N_,Cne=t((()=>{V(),F(),N_={createSkill:A_,onInit:j_,onMount:M_}})),wne=r({createSkill:()=>P_,default:()=>L_,onInit:()=>F_,onMount:()=>I_});function P_(e,t){return{id:e,ownerId:t,name:`仁德`,description:`出牌阶段:将任意张手牌交给其他角色;以此法失去第二张牌时回复1点体力`}}function F_(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.allocation,l=t.targets,u=t.cardId,d=t.targets,f;if(Array.isArray(c)&&c.length>0&&Array.isArray(c[0].cardIds))f=c;else if(Array.isArray(l)&&l.length>0&&Array.isArray(l[0].cardIds))f=l;else if(u&&Array.isArray(d)&&d.length>0)f=[{target:d[0],cardIds:[u]}];else return`需要指定牌和目标`;let p=f.reduce((e,t)=>e+t.cardIds.length,0)>0,m=[],h=!0,g=!0;if(p)for(let e of f){if(!Array.isArray(e.cardIds)){g=!1;continue}for(let t of e.cardIds)m.includes(t)&&(h=!1),m.push(t),o.hand.includes(t)||(g=!1)}let _=p&&f.every(t=>t.target!==n&&e.players[t.target]?.alive===!0);return r&&i&&a&&s&&p&&h&&g&&_?null:`现在不能使用仁德`},async(e,t)=>{let r=n;await I(e,`仁德`,r,{...t});let i=t.allocation,a=t.targets,o;o=Array.isArray(i)&&i.length>0&&Array.isArray(i[0].cardIds)?i:Array.isArray(a)&&a.length>0&&Array.isArray(a[0].cardIds)?a:[{target:a[0],cardIds:[t.cardId]}];let s=e.players[r],c=(typeof s.vars[`仁德/givenCount`]==`number`?s.vars[`仁德/givenCount`]:0)+o.reduce((e,t)=>e+t.cardIds.length,0),l=c>=2&&!s.vars[`仁德/healed`];for(let t of o)for(let n of t.cardIds)await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:r},to:{zone:`手牌`,player:t.target}});s.vars[`仁德/givenCount`]=c,l&&(await B(e,{type:`回复体力`,target:r,amount:1}),s.vars[`仁德/healed`]=!0),await L(e)}),()=>{}}function I_(e,t){return t.defineAction(`use`,{label:`仁德`,style:`primary`,prompt:{type:`distribute`,mode:`allocate`,title:`仁德:选择要送出的手牌和目标角色`,source:`hand`,minPerTarget:1,maxPerTarget:99,minTotal:1,maxTotal:99,allowSelf:!1}}),()=>{}}var L_,Tne=t((()=>{V(),z(),F(),L_={createSkill:P_,onInit:F_,onMount:I_}})),Ene=r({createSkill:()=>Dne,onInit:()=>One});function Dne(e,t){return{id:e,ownerId:t,name:`仁王盾`,description:`防具:黑色杀对你无效`,isLocked:!0}}function One(e,t){let n=e.ownerId;return M(t,e.id,n,`检测有效性`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.cardId;if(!r)return;let i=e.state.cardMap[r];if(i?.name===`杀`&&i.color===`黑`)return{kind:`cancel`}}),()=>{}}var kne=t((()=>{F()})),Ane=r({createSkill:()=>R_,default:()=>G_,onInit:()=>z_,onMount:()=>B_});function R_(e,t){return{id:e,ownerId:t,name:V_,description:`当你成为锦囊牌的目标时,若此牌的目标数大于1,你可以交给其中一名目标角色一张牌,然后摸一张牌,若你给出的是装备牌,改为摸两张牌`}}function z_(e,t){let n=e.ownerId,r=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==H_)return`当前不是从谏询问`;let a=t.cardId;if(!a)return null;if(!e.players[n]?.hand.includes(a))return`牌不在手牌中`;let o=e.localVars[W_],s=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);return typeof s==`number`?!Array.isArray(o)||!o.includes(s)?`目标不在本牌目标中`:null:`请选择一名目标角色`},async(e,t)=>{let n=t.cardId;if(!n){e.localVars[U_]=null;return}let r=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);if(typeof r!=`number`){e.localVars[U_]=null;return}e.localVars[U_]={cardId:n,target:r}}),i=N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n)return;let r=e.state,i=r.players[n];if(!i?.alive||(t.cardId?r.cardMap[t.cardId]:void 0)?.type!==`锦囊牌`)return;let a=e.params.resolvedTargets??e.params.targets??[];if(a.length<=1||i.hand.length===0)return;let o=a.filter(e=>r.players[e]?.alive);r.localVars[W_]=o,delete r.localVars[U_],await B(r,{type:`请求回应`,requestType:H_,target:n,prompt:{type:`useCardAndTarget`,title:`从谏:交给一名目标角色一张牌(装备牌摸两张,其他摸一张);不交可放弃`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>o.includes(t)&&!!e.players[t]?.alive}},timeout:30});let s=r.localVars[U_];delete r.localVars[U_],delete r.localVars[W_],s&&(await B(r,{type:`给予`,cardId:s.cardId,from:n,to:s.target}),await B(r,{type:`摸牌`,player:n,count:r.cardMap[s.cardId]?.type===`装备牌`?2:1}))});return()=>{r(),i()}}function B_(e,t){}var V_,H_,U_,W_,G_,jne=t((()=>{V(),F(),V_=`从谏`,H_=`从谏/给牌`,U_=`从谏/给牌`,W_=`从谏/可选目标`,G_={createSkill:R_,onInit:z_,onMount:B_}})),Mne=r({createSkill:()=>K_,default:()=>X_,onInit:()=>q_,onMount:()=>J_});function K_(e,t){return{id:e,ownerId:t,name:`伪帝`,description:`锁定技,你视为拥有主公的主公技`,isLocked:!0}}function q_(e,t){let n=e.ownerId,r=N(t,e.id,n,`回合开始`,async e=>{let t=e.state,r=t.players[n];if(!r?.alive||r.vars[Y_])return;let i=t.players.find(e=>e.alive&&e.identity===`主公`&&e.index!==n);if(!i)return;let a=i.skills.filter(e=>Pc.has(e));if(a.length!==0){r.vars[Y_]=!0;for(let e of a)await B(t,{type:`添加技能`,player:n,skillId:e})}});return()=>{r()}}function J_(e,t){}var Y_,X_,Nne=t((()=>{V(),F(),Fc(),Y_=`伪帝/granted`,X_={createSkill:K_,onInit:q_,onMount:J_}})),Pne=r({createSkill:()=>Z_,default:()=>tv,onInit:()=>$_,onMount:()=>ev});function Z_(e,t){return{id:e,ownerId:t,name:`倾国`,description:`你可以将一张黑色手牌当【闪】使用或打出`}}function Q_(e){return`${e}#倾国`}function $_(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a),l=!!s&&s.color===`黑`;return i&&c&&l?null:`现在不能使用倾国`},async(e,t)=>{let r=t.cardId,i=Q_(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`闪`})},(e,t)=>{let r=t.cardId,i=Q_(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)});let r=de(t,n,`询问闪`);return()=>{r()}}function ev(e,t){t.defineAction(`transform`,{label:`倾国`,style:`passive`,prompt:{type:`useCard`,title:`选择一张黑色手牌当闪打出`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}},transform:t=>({name:`闪`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.pending;if(!t||t.atom.type!==`询问闪`||t.target!==e.perspectiveIdx)return!1;let n=e.view.players[e.perspectiveIdx];return n?n.hand?.some(e=>e.color===`黑`)??!1:!1}})}var tv,Fne=t((()=>{F(),V(),tv={createSkill:Z_,onInit:$_,onMount:ev}})),Ine=r({createSkill:()=>nv,default:()=>cv,onInit:()=>rv,onMount:()=>iv});function nv(e,t){return{id:e,ownerId:t,name:`克己`,description:`出牌阶段结束时,若你本回合未使用或打出过【杀】,你可以跳过弃牌阶段`}}function rv(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===sv?null:`当前不是克己确认`:`当前不需要回应`},async(e,t)=>{e.localVars[ov]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.from.zone!==`手牌`||t.from.player!==n||t.to.zone===`处理区`&&e.state.cardMap[t.cardId]?.name===`杀`&&(e.state.turn.vars[av]=!0)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`弃牌`&&!e.state.turn.vars[av]&&(delete e.state.localVars[ov],await B(e.state,{type:`请求回应`,requestType:sv,target:n,prompt:{type:`confirm`,title:`克己:本回合未出杀,是否跳过弃牌阶段?`,confirmLabel:`跳过`,cancelLabel:`不跳过`},defaultChoice:!1,timeout:15}),e.state.localVars[ov]))return await B(e.state,{type:`阶段结束`,player:n,phase:`弃牌`}),{kind:`cancel`}}),()=>{}}function iv(e,t){t.defineAction(`respond`,{label:`克己`,style:`primary`,prompt:{type:`confirm`,title:`克己:是否跳过弃牌阶段?`,confirmLabel:`跳过`,cancelLabel:`不跳过`}})}var av,ov,sv,cv,Lne=t((()=>{V(),F(),av=`克己/playedSlash`,ov=`克己/confirmed`,sv=`克己/confirm`,cv={createSkill:nv,onInit:rv,onMount:iv}})),Rne=r({createSkill:()=>zne,onInit:()=>Bne,onMount:()=>Vne});function zne(e,t){return{id:e,ownerId:t,name:`八卦阵`,description:`防具技:当你需要出闪时,可以判定,若为红色则视为出闪`}}function Bne(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>e.pendingSlots.get(n)?.atom.type===`请求回应`?e.pendingSlots.get(n).atom.requestType===`八卦阵/confirm`?null:`当前不是八卦阵确认`:`当前不需要回应`,async(e,t)=>{e.localVars[`八卦阵/confirmed`]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`询问闪`,async e=>{if(e.atom.target!==n||e.state.zones.deck.length===0)return;let t=e.state.players[n]?.equipment?.防具;if(!t||e.state.cardMap[t]?.name!==`八卦阵`||(delete e.state.localVars[`八卦阵/confirmed`],await B(e.state,{type:`请求回应`,requestType:`八卦阵/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动八卦阵?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`八卦阵/confirmed`]))return;let r=await jm(e.state,n,`八卦阵`);if(!r)return;let i=e.state.cardMap[r];if(i&&(i.suit===`♥`||i.suit===`♦`)){let t=`八卦阵:${n}:${r}`,a={id:t,name:`闪`,suit:i.suit,color:i.color,rank:i.rank,type:`基本牌`,ephemeral:!0};return e.state.cardMap[t]=a,await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`处理区`}}),{kind:`cancel`}}}),()=>{}}function Vne(e,t){t.defineAction(`respond`,{label:`八卦阵`,style:`default`,prompt:{type:`confirm`,title:`是否发动八卦阵?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var Hne=t((()=>{V(),Fm(),F()})),Une=r({createSkill:()=>lv,default:()=>fv,onInit:()=>uv,onMount:()=>dv});function lv(e,t){return{id:e,ownerId:t,name:`八阵`,description:`锁定技:没有装备防具时,视为装备着八卦阵`,isLocked:!0}}function Wne(e,t){let n=e.players[t]?.equipment;return n?!n.防具:!0}function uv(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>e.pendingSlots.get(n)?.atom.type===`请求回应`?e.pendingSlots.get(n).atom.requestType===`八阵/confirm`?null:`当前不是八阵确认`:`当前不需要回应`,async(e,t)=>{e.localVars[`八阵/confirmed`]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`询问闪`,async e=>{if(e.atom.target!==n||!Wne(e.state,n)||e.state.zones.deck.length===0||(delete e.state.localVars[`八阵/confirmed`],await B(e.state,{type:`请求回应`,requestType:`八阵/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动八阵(判定,红色视为出闪)?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`八阵/confirmed`]))return;let t=await jm(e.state,n,`八阵`);if(!t)return;let r=e.state.cardMap[t];if(r&&(r.suit===`♥`||r.suit===`♦`)){let i=`八阵:${n}:${t}`,a={id:i,name:`闪`,suit:r.suit,color:r.color,rank:r.rank,type:`基本牌`,ephemeral:!0};return e.state.cardMap[i]=a,await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`处理区`}}),{kind:`cancel`}}}),()=>{}}function dv(e,t){t.defineAction(`respond`,{label:`八阵`,style:`default`,prompt:{type:`confirm`,title:`是否发动八阵?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var fv,Gne=t((()=>{V(),Fm(),F(),fv={createSkill:lv,onInit:uv,onMount:dv}})),Kne=r({createSkill:()=>pv,default:()=>gv,onInit:()=>mv,onMount:()=>hv});function pv(e,t){return{id:e,ownerId:t,name:`兵略`,description:`锁定技,当你首次对一名角色发动"飞军"时,你摸两张牌`,isLocked:!0}}function mv(e,t){return()=>{}}function hv(e,t){return()=>{}}var gv,qne=t((()=>{gv={createSkill:pv,onInit:mv,onMount:hv}})),Jne=r({createSkill:()=>_v,default:()=>Yne,onInit:()=>vv,onMount:()=>yv});function _v(e,t){return{id:e,ownerId:t,name:`再起`,description:`摸牌阶段,若已受伤,可放弃摸牌,展示牌堆顶X张(X=已损失体力+1),红桃回血弃置,其余入门`}}function vv(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===bv?null:`当前不是再起回应`:`当前不需要回应`},async(e,t)=>{e.localVars[xv]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`摸牌`||e.state.currentPlayerIndex!==n)return;let r=e.state.players[n];if(!r?.alive)return;let i=r.maxHealth-p(r);if(i<=0||e.state.zones.deck.length===0)return;let a=Math.min(i+1,e.state.zones.deck.length);if(delete e.state.localVars[xv],await B(e.state,{type:`请求回应`,requestType:bv,target:n,prompt:{type:`confirm`,title:`是否发动再起?(放弃摸牌,展示牌堆顶${a}张,红桃回血,其余入手)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[xv]!==!0)return;let o=[];for(let t=0;t<a;t++){let t=e.state.zones.deck[e.state.zones.deck.length-1];if(!t)break;await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`牌堆`},to:{zone:`处理区`}}),o.push(t)}if(o.length===0)return;for(let t of o){let r=e.state.cardMap[t];if(r)if(r.suit===`♥`){let r=e.state.players[n];r.health<r.maxHealth&&await B(e.state,{type:`回复体力`,target:n,amount:1}),await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}else await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`手牌`,player:n}})}let s=R(e.state).filter(e=>o.includes(e));for(let t of s)await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}});return await B(e.state,{type:`阶段结束`,player:n,phase:`摸牌`}),{kind:`cancel`}}),()=>{}}function yv(e,t){t.defineAction(`respond`,{label:`再起`,style:`primary`,prompt:{type:`confirm`,title:`是否发动再起?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var bv,xv,Yne,Xne=t((()=>{b(),V(),z(),F(),bv=`再起/trigger`,xv=`再起/triggered`,Yne={createSkill:_v,onInit:vv,onMount:yv}})),Zne=r({ABOLISH_PREFIX:()=>Cv,createSkill:()=>Qne,default:()=>ire,isSlotGroupAbolished:()=>$ne,onInit:()=>tre,onMount:()=>nre});function Qne(e,t){return{id:e,ownerId:t,name:Sv,description:`出牌阶段限一次,废除一个装备栏并于本回合获得对应效果:武器栏杀次数+3;防具栏摸三张且手牌上限+3;坐骑栏使用牌无距离限制;宝物栏获得集智`}}function $ne(e,t,n){let r=Dv[n];return r?r.every(n=>e.players[t]?.vars[Cv+n]):!1}function ere(e,t,n){let r=Dv[n];return r?r.some(n=>!e.players[t]?.vars[Cv+n]):!1}function tre(e,t){let n=e.ownerId,r=j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(X(e,n,Sv))return`本回合已使用过决堰`;if(!e.players[n]?.alive)return`玩家不存在或已死亡`;let r=t.slot??t.option;return typeof r!=`string`||!rre.includes(r)?`请选择要废除的装备栏`:ere(e,n,r)?null:`该装备栏已全部废除`},async(e,t)=>{let r=t.slot??t.option;await Z(e,n,Sv),await I(e,Sv,n,{group:r});let i=Dv[r],a=e.players[n];for(let t of i){let r=a.equipment[t];r&&(await B(e,{type:`卸下`,player:n,slot:t}),await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:n},to:{zone:`弃牌堆`}})),e.players[n].vars[Cv+t]=!0}if(r===`武器`)e.turn.vars[wv]=!0,await B(e,{type:`回合用量`,player:n,key:Jc(`决堰`),value:3});else if(r===`防具`){await B(e,{type:`摸牌`,player:n,count:3});let t=$c(n),r=sl(e.turn.vars,n)??0;e.turn.vars[t]=r+3}else r===`坐骑`?(e.turn.vars[Tv]=!0,await B(e,{type:`回合用量`,player:n,key:Tv,value:!0})):r===`宝物`&&(await B(e,{type:`添加技能`,player:n,skillId:`集智`}),e.players[n].vars[Ev]=!0);await L(e)}),i=$m(t,n,(e,t)=>t===n&&e.turn.vars[wv]?3:0),a=Jm(t,n,(e,t,r)=>t===n?!!e.turn.vars[Tv]:!1),o=N(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`||t.player!==n)return;let r=e.state.players[n];r?.vars[Ev]&&(delete r.vars[Ev],r.skills.includes(`集智`)&&await B(e.state,{type:`移除技能`,player:n,skillId:`集智`}))});return()=>{r(),i(),a(),o()}}function nre(e,t){t.defineAction(`use`,{label:`决堰`,style:`primary`,activeWhen:yh(Sv),prompt:{type:`chooseOption`,title:`决堰:选择要废除的装备栏(本回合获得对应效果)`,options:[{value:`武器`,label:`武器栏 — 使用杀的限制次数+3`},{value:`防具`,label:`防具栏 — 摸三张牌且手牌上限+3`},{value:`坐骑`,label:`坐骑栏 — 使用牌无距离限制`},{value:`宝物`,label:`宝物栏 — 获得集智`}]}})}var Sv,Cv,wv,Tv,Ev,Dv,rre,ire,Ov=t((()=>{V(),z(),F(),Q(),fh(),Xm(),W(),Sv=`决堰`,Cv=`决堰/废除:`,wv=`决堰/本回合:武器`,Tv=zl,Ev=`决堰/集智临时`,Dv={武器:[`武器`],防具:[`防具`],坐骑:[`进攻马`,`防御马`],宝物:[`宝物`]},rre=[`武器`,`防具`,`坐骑`,`宝物`],ire={createSkill:Qne,onInit:tre,onMount:nre}})),are=r({createSkill:()=>ore,default:()=>ure,onInit:()=>sre,onMount:()=>cre});function ore(e,t){return{id:e,ownerId:t,name:`凿险`,description:`觉醒技:准备阶段田≥3时,减1体力上限并获得"急袭"(田当顺手牵羊)`}}function sre(e,t){let n=e.ownerId;return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`准备`||t.player!==n||e.state.players[n]?.vars[kv])return;let r=e.state.players[n];if(!r?.alive||r.marks.filter(e=>e.id.startsWith(lre)).length<3)return;e.state.players[n].vars[kv]=!0;let i=r.maxHealth-1;await B(e.state,{type:`设上限`,player:n,amount:i}),await B(e.state,{type:`添加技能`,player:n,skillId:`急袭`})}),()=>{}}function cre(e,t){}var kv,lre,ure,dre=t((()=>{V(),F(),kv=`凿险/awakened`,lre=`屯田/田:`,ure={createSkill:ore,onInit:sre,onMount:cre}})),fre=r({createSkill:()=>Av,default:()=>Fv,onInit:()=>jv,onMount:()=>Mv});function Av(e,t){return{id:e,ownerId:t,name:`刚烈`,description:`受到伤害后判定,非红桃则来源弃两张手牌或受 1 点伤害`}}function jv(e,t){let n=e.ownerId,r=[];for(let i of t.players){let a=i.index,o=a===n,s=j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let i=r.requestType;return i===Pv||o&&i===Nv?null:`当前不是刚烈回应`},async(e,t)=>{e.pendingSlots.get(a)?.atom?.requestType===Nv?e.localVars[`刚烈/confirmed`]=t.choice===!0:e.localVars[`刚烈/choice`]=t.choice===!0?`discard`:`damage`});r.push(s)}return N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.judgeType!==`刚烈`||t.player!==n)return;let r=R(e.state);if(r.length===0)return;let i=r[r.length-1],a=e.state.cardMap[i];a&&(e.state.localVars[`刚烈/judgeSuit`]=a.suit)}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0||t.source===void 0||t.source===n)return;let r=t.source;if(!e.state.players[r]?.alive||e.state.zones.deck.length===0||(delete e.state.localVars[`刚烈/confirmed`],await B(e.state,{type:`请求回应`,requestType:Nv,target:n,prompt:{type:`confirm`,title:`是否发动刚烈?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`刚烈/confirmed`]))return;delete e.state.localVars[`刚烈/judgeSuit`],await jm(e.state,n,`刚烈`);let i=e.state.localVars[`刚烈/judgeSuit`];if(i!==void 0&&i!==`♥`){if(e.state.players[r].hand.length>=2&&(delete e.state.localVars[`刚烈/choice`],await B(e.state,{type:`请求回应`,requestType:Pv,target:r,prompt:{type:`confirm`,title:`刚烈:弃置两张手牌,或受到 1 点伤害?`,confirmLabel:`弃两张手牌`,cancelLabel:`受 1 点伤害`},defaultChoice:!1,timeout:30}),e.state.localVars[`刚烈/choice`]===`discard`)){let t=[...e.state.players[r].hand];await B(e.state,{type:`弃置`,player:r,cardIds:t.slice(0,2)});return}await Dm(e.state,n,r,1)}}),()=>{r.forEach(e=>e())}}function Mv(e,t){t.defineAction(`respond`,{label:`刚烈`,style:`danger`,prompt:{type:`confirm`,title:`刚烈:弃置两张手牌,或受到 1 点伤害?`,confirmLabel:`弃两张手牌`,cancelLabel:`受 1 点伤害`}})}var Nv,Pv,Fv,pre=t((()=>{V(),z(),Fm(),Om(),F(),Nv=`刚烈/confirm`,Pv=`刚烈/choose`,Fv={createSkill:Av,onInit:jv,onMount:Mv}})),mre=r({createSkill:()=>hre,onInit:()=>gre,onMount:()=>_re});function hre(e,t){return{id:e,ownerId:t,name:`制衡`,description:`出牌阶段限一次:弃任意张牌(手牌/装备),摸等量的牌`}}function gre(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=t.cardIds??(typeof t.cardId==`string`?[t.cardId]:void 0);if(!Array.isArray(r)||r.length===0)return`cardIds required (at least 1)`;if(new Set(r).size!==r.length)return`cardIds 含重复牌`;if(X(e,n,`制衡`))return`本回合已使用过制衡`;let i=e.players[n];if(!i)return`player not found`;for(let e of r){let t=i.hand.includes(e),n=Object.values(i.equipment).includes(e);if(!t&&!n)return`牌不在手牌或装备区中`}return null},async(e,t)=>{await Z(e,n,`制衡`);let r=n;await I(e,`制衡`,r,{...t});let i=t.cardIds??(typeof t.cardId==`string`?[t.cardId]:[]);await B(e,{type:`弃置`,player:r,cardIds:i,voluntary:!0}),await B(e,{type:`摸牌`,player:r,count:i.length}),await L(e)}),()=>{}}function _re(e,t){return t.defineAction(`use`,{label:`制衡`,style:`primary`,prompt:{type:`distribute`,mode:`select`,title:`制衡:选择要弃置的牌(可多选)`,source:`handAndEquip`,minTotal:1,maxTotal:99},activeWhen:e=>yh(`制衡`)(e)}),()=>{}}var vre=t((()=>{V(),z(),Q(),F()})),yre=r({createSkill:()=>Lv,default:()=>Kv,onInit:()=>Rv,onMount:()=>zv});function Iv(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function Lv(e,t){return{id:e,ownerId:t,name:`制霸`,description:`主公技:其他吴势力角色出牌阶段可与你拼点,若其没赢你可获得双方拼点牌;觉醒后可拒绝拼点`}}function Rv(e,t){let n=e.ownerId,r=[];for(let i of t.players){let a=i.index;if(a===n||i.faction!==`吴`)continue;let o=j(t,e.id,a,`use`,(e,t)=>{if(n!==0)return`制霸为主公技,孙策非主公`;let r=e.players[n];if(!r?.alive)return`主公不存在或已死亡`;if(r.hand.length===0)return`孙策没有手牌,无法拼点`;let i=e.players[a];if(!i?.alive)return`已死亡`;let o=e.currentPlayerIndex===a,s=e.phase===`出牌`,c=!E(e);if(!o||!s||!c)return`现在不能使用制霸`;if(X(e,a,`制霸`))return`本回合已使用过制霸`;let l=t.cardId;return typeof l==`string`?i.hand.includes(l)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`},async(e,t)=>{let r=t.cardId;await Z(e,a,`制霸`);let i=e.players[n];if(!(cl(i.vars)&&(delete e.localVars[Uv],await B(e,{type:`请求回应`,requestType:Bv,target:n,prompt:{type:`confirm`,title:`${e.players[a].name} 欲与你制霸拼点,是否接受?`,confirmLabel:`接受`,cancelLabel:`拒绝`},defaultChoice:!0,timeout:20}),e.localVars[Uv]===!1))){await I(e,`制霸`,a,{...t});try{await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:a},to:{zone:`处理区`}}),delete e.localVars[Wv],await B(e,{type:`请求回应`,requestType:Vv,target:n,prompt:{type:`useCard`,title:`制霸:与 ${e.players[a].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let t=e.localVars[Wv];if(!t||!e.players[n].hand.includes(t)){await B(e,{type:`移动牌`,cardId:r,from:{zone:`处理区`},to:{zone:`弃牌堆`}});return}if(await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:n},to:{zone:`处理区`}}),Iv(e.cardMap[r]?.rank??``)>Iv(e.cardMap[t]?.rank??``))for(let n of[r,t])await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}});else{delete e.localVars[Gv],await B(e,{type:`请求回应`,requestType:Hv,target:n,prompt:{type:`confirm`,title:`制霸:对方拼点没赢,是否获得双方拼点牌?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!0,timeout:20});let i=e.localVars[Gv]!==!1;for(let a of[r,t])await B(e,{type:`移动牌`,cardId:a,from:{zone:`处理区`},to:i?{zone:`手牌`,player:n}:{zone:`弃牌堆`}})}}finally{await L(e)}}});r.push(o)}for(let i of t.players){let a=i.index,o=j(t,e.id,a,`respond`,(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let o=i.requestType;if(o===Bv||o===Hv)return a===n?null:`只有孙策可以回应`;if(o===Vv){if(a!==n)return`只有孙策可以选择拼点牌`;let r=t.cardId;return typeof r==`string`?e.players[a].hand.includes(r)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`}return`当前不是制霸回应`},async(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return;let r=n.atom.requestType;r===Bv?e.localVars[Uv]=t.choice===!0||t.confirmed===!0:r===Vv?e.localVars[Wv]=t.cardId:r===Hv&&(e.localVars[Gv]=t.choice===!0||t.confirmed===!0)});r.push(o)}return()=>{r.forEach(e=>e())}}function zv(e,t){t.defineAction(`respond`,{label:`制霸`,style:`primary`,prompt:{type:`confirm`,title:`制霸`,confirmLabel:`确认`,cancelLabel:`取消`}})}var Bv,Vv,Hv,Uv,Wv,Gv,Kv,bre=t((()=>{V(),z(),Q(),F(),W(),Bv=`制霸/refuse`,Vv=`制霸/lordCard`,Hv=`制霸/take`,Uv=`制霸/refuseResult`,Wv=`制霸/lordCardId`,Gv=`制霸/takeResult`,Kv={createSkill:Lv,onInit:Rv,onMount:zv}})),xre=r({createSkill:()=>qv,default:()=>$v,onInit:()=>Jv,onMount:()=>Yv});function qv(e,t){return{id:e,ownerId:t,name:`勤学`,description:`觉醒技:准备或结束阶段,若手牌数比体力值多2或更多,减1体力上限,回复1体力或摸2牌,然后获得"攻心"`}}function Jv(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===Xv?null:`当前不是勤学选择`:`当前不需要回应`},async(e,t)=>{e.localVars[Zv]=t.choice===!0?`draw`:`heal`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`&&t.phase!==`回合结束`||e.state.players[n]?.vars[Qv])return;let r=e.state.players[n];if(!r?.alive||r.hand.length-p(r)<2)return;e.state.players[n].vars[Qv]=!0;let i=r.maxHealth-1;await B(e.state,{type:`设上限`,player:n,amount:i}),delete e.state.localVars[Zv],await B(e.state,{type:`请求回应`,requestType:Xv,target:n,prompt:{type:`confirm`,title:`勤学:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`},defaultChoice:!1,timeout:30});let a=e.state.localVars[Zv];if(delete e.state.localVars[Zv],a===`draw`)await B(e.state,{type:`摸牌`,player:n,count:2});else{let t=e.state.players[n].health,r=e.state.players[n].maxHealth,i=Math.min(1,Math.max(0,r-t));i>0&&await B(e.state,{type:`回复体力`,target:n,amount:i})}await B(e.state,{type:`添加技能`,player:n,skillId:`攻心`})}),()=>{}}function Yv(e,t){t.defineAction(`respond`,{label:`勤学`,style:`primary`,prompt:{type:`confirm`,title:`勤学:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`}})}var Xv,Zv,Qv,$v,Sre=t((()=>{b(),V(),F(),Xv=`勤学/choose`,Zv=`勤学/choice`,Qv=`勤学/awakened`,$v={createSkill:qv,onInit:Jv,onMount:Yv}})),Cre=r({createSkill:()=>ry,default:()=>Dy,onInit:()=>iy,onMount:()=>sy});function ey(e,t){return e.players[t]?.character===cy}function wre(e){let t=new Set;for(let n of e.players)n.character&&t.add(n.character);return t}function ty(e,t,n){let r=wre(e),i=ll(e.players[t]?.vars)??[],a=new Set([...r,...i]),o=wc.map(e=>e.name).filter(e=>!a.has(e));if(o.length===0)return[];let s=Ud(e.rngSeed);for(let e=o.length-1;e>0;e--){let t=s.nextInt(e+1),n=o[e];o[e]=o[t],o[t]=n}return e.rngSeed=s.getState(),o.slice(0,Math.min(n,o.length))}function ny(e){let t=Oc(e);return t?t.skills.filter(e=>!Ey.has(e)):[]}function ry(e,t){return{id:e,ownerId:t,name:`化身`,description:`游戏开始时随机获得未登场武将牌作为化身牌(左慈2张/界左慈3张),亮出一张并获得其一个技能(限定/觉醒/主公技除外);回合开始或结束时可更改/替换/移去化身牌`}}function iy(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===yy){let r=Number(t.option);if(!Number.isInteger(r)||![Cy,wy,Ty].includes(r))return`需要 option(1=替换, 2=移去, 3=不操作)`;let i=ll(e.players[n]?.vars)??[];return r===Cy&&i.length<2?`化身牌不足,无法替换`:r===wy&&i.length<2?`化身牌不足,无法移去`:null}if(a===by){let r=Number(t.option);if(!Number.isInteger(r)||![1,2].includes(r))return`需要 option(1 或 2)`;let i=ll(e.players[n]?.vars)??[],a=Math.min(2,i.length-1);return r>a?`最多移去 ${a} 张`:null}if(a===vy)return typeof t.choice==`boolean`?null:`需要 choice(布尔)`;if(a===_y){let r=ll(e.players[n]?.vars)??[],i=t.option;return typeof i==`string`?r.includes(i)?null:`该武将不在化身牌池中`:`需要 option(武将名)`}if(a===gy){let r=e.localVars[xy(n)]??[],i=t.option;return typeof i==`string`?r.length>0&&!r.includes(i)?`该技能不在候选中`:null:`需要 option(技能名)`}return`当前不是化身询问`},async(e,t)=>{let r=e.pendingSlots.get(n).atom.requestType;r===yy?e.localVars[my]=Number(t.option):r===by?e.localVars[hy]=Number(t.option):r===vy?e.localVars[py]=t.choice===!0:r===_y?e.localVars[Sy]=t.option:r===gy&&(e.localVars[fy]=t.option,delete e.localVars[xy(n)])}),N(t,e.id,n,`回合开始`,async e=>{let t=e.state;if(t.players[n]?.alive){if(!t.localVars[dy(n)]){t.localVars[dy(n)]=!0,await Tre(t,n);return}e.atom.player===n&&await oy(t,n)}}),N(t,e.id,n,`回合结束后`,async e=>{e.atom.player===n&&e.state.players[n]?.alive&&await oy(e.state,n)}),()=>{}}async function Tre(e,t){let n=e.players[t];if(!n)return;let r=ty(e,t,ey(e,t)?3:2);n.vars[bl]=r,n.vars[ly]=0,r.length!==0&&await ay(e,t)}async function ay(e,t,n){let r=e.players[t];if(!r)return;let i=ll(r.vars);if(!i||i.length===0)return;let a=i.map((e,t)=>t).filter(e=>ny(i[e]).length>0).filter(e=>e!==n);if(a.length===0)return;let o;a.length===1?o=a[0]:(o=await Are(e,t,i,a),o<0&&(o=a[0])),r.vars[ly]=o;let s=i[o],c=await jre(e,t,s,ny(s));c&&(await B(e,{type:`添加技能`,player:t,skillId:c}),r.vars[uy]=c)}async function oy(e,t){ey(e,t)?await Dre(e,t):await Ere(e,t)}async function Ere(e,t){let n=e.players[t];if(!n)return;let r=ll(n.vars);if(!r||r.length<2)return;delete e.localVars[py],await B(e,{type:`请求回应`,requestType:vy,target:t,prompt:{type:`confirm`,title:`化身:是否更改化身牌?`,confirmLabel:`更改`,cancelLabel:`不更改`},defaultChoice:!1,timeout:30});let i=e.localVars[py];if(delete e.localVars[py],i!==!0)return;let a=n.vars[ly]??0;if(ny(r[+(a===0)]).length===0)return;let o=n.vars[uy];o&&(await B(e,{type:`移除技能`,player:t,skillId:o}),delete n.vars[uy]),await ay(e,t,a)}async function Dre(e,t){let n=e.players[t];if(!n)return;let r=ll(n.vars);if(!r||r.length<2)return;delete e.localVars[my],await B(e,{type:`请求回应`,requestType:yy,target:t,prompt:{type:`chooseOption`,title:`化身:选择行动`,options:[{value:String(Cy),label:`替换展示的化身牌及技能`},{value:String(wy),label:`移去化身牌并获得等量新的`},{value:String(Ty),label:`不操作`}]},defaultChoice:String(Ty),timeout:30});let i=e.localVars[my];delete e.localVars[my],i===Cy?await Ore(e,t):i===wy&&await kre(e,t)}async function Ore(e,t){let n=e.players[t];if(!n)return;let r=ll(n.vars);if(!r||r.length<2)return;let i=n.vars[ly]??0;if(!r.some((e,t)=>t!==i&&ny(e).length>0))return;let a=n.vars[uy];a&&(await B(e,{type:`移除技能`,player:t,skillId:a}),delete n.vars[uy]),await ay(e,t,i)}async function kre(e,t){let n=e.players[t];if(!n)return;let r=ll(n.vars);if(!r||r.length<2)return;let i=n.vars[ly]??0,a=Math.min(2,r.length-1);delete e.localVars[hy],await B(e,{type:`请求回应`,requestType:by,target:t,prompt:{type:`chooseOption`,title:`化身:移去几张化身牌并获得等量新的?`,options:Array.from({length:a},(e,t)=>({value:String(t+1),label:`移去 ${t+1} 张并获得 ${t+1} 张新的(展示牌保留)`}))},defaultChoice:`1`,timeout:30});let o=e.localVars[hy];if(delete e.localVars[hy],typeof o!=`number`)return;let s=Math.min(o,a);if(s<1)return;let c=[];for(let e=r.length-1;e>=0&&c.length<s;e--)e!==i&&c.push(e);let l=new Set(c),u=[],d=0;for(let e=0;e<r.length;e++)l.has(e)||(e===i&&(d=u.length),u.push(r[e]));let f=ty(e,t,s);u.push(...f),n.vars[bl]=u,n.vars[ly]=d}async function Are(e,t,n,r){delete e.localVars[Sy];let i={};for(let e of r){let t=Oc(n[e]);i[n[e]]={faction:t?.faction??`群`,skills:ny(n[e])}}await B(e,{type:`请求回应`,requestType:_y,target:t,prompt:{type:`chooseOption`,title:`化身:选择一张化身牌`,options:r.map(e=>({value:n[e],label:n[e]})),characterCards:i},defaultChoice:n[r[0]],timeout:30});let a=e.localVars[Sy];return delete e.localVars[Sy],a?n.indexOf(a):-1}async function jre(e,t,n,r){if(r.length===0)return;if(r.length===1)return r[0];delete e.localVars[fy],e.localVars[xy(t)]=r,await B(e,{type:`请求回应`,requestType:gy,target:t,prompt:{type:`chooseOption`,title:`化身:从「${n}」选择一个技能`,options:r.map(e=>({value:e,label:e}))},defaultChoice:r[0],timeout:30});let i=e.localVars[fy];return delete e.localVars[fy],(!i||!r.includes(i))&&(i=r[0]),i}function sy(e,t){t.defineAction(`respond`,{label:`化身`,style:`primary`,prompt:{type:`confirm`,title:`化身`,confirmLabel:`确定`,cancelLabel:`取消`}})}var cy,ly,uy,dy,fy,py,my,hy,gy,_y,vy,yy,by,xy,Sy,Cy,wy,Ty,Ey,Dy,Mre=t((()=>{V(),Wd(),F(),Ec(),Fc(),W(),cy=`界左慈`,ly=`化身/亮出`,uy=`化身/当前技能`,dy=e=>`化身/init/${e}`,fy=`化身/selectedSkill`,py=`化身/switchChoice`,my=`化身/actionChoice`,hy=`化身/swapCount`,gy=`化身/选技能`,_y=`化身/选化身牌`,vy=`化身/是否切换`,yy=`化身/选择行动`,by=`化身/移除数量`,xy=e=>`化身/candidates/${e}`,Sy=`化身/characterChoice`,Cy=1,wy=2,Ty=3,Ey=new Set([`乱武`,`涅槃`,`凿险`,`志继`,`若愚`,`魂姿`,`护驾`,`救援`,`暴虐`,`激将`,`颂威`,`黄天`,`制霸`]),Dy={createSkill:ry,onInit:iy,onMount:sy}}));async function Oy(e,t){await B(e,{type:`回合开始`,player:t}),await B(e,{type:`阶段开始`,player:t,phase:`准备`}),await B(e,{type:`阶段结束`,player:t,phase:`准备`})}var ky=t((()=>{V()})),Nre=r({createSkill:()=>Ay,default:()=>Ry,onInit:()=>jy,onMount:()=>My});function Pre(e){e.turn.vars={};for(let t of e.players)t.marks=t.marks.filter(e=>e.duration!==`turn`),t.vars=Object.fromEntries(Object.entries(t.vars).filter(([e])=>!e.endsWith(`/usedThisTurn`)&&!e.endsWith(`/healed`)&&!e.endsWith(`/givenCount`)&&!e.endsWith(`/givenTargets`)&&!e.endsWith(`/basicUsed`)))}function Fre(e){return e.players.filter(e=>e.alive).length}function Ay(e,t){return{id:e,ownerId:t,name:`博图`,description:`每轮限X次(X为存活角色数至多3),回合结束后若本回合弃牌堆含四种花色,可执行一个额外回合`}}function jy(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===Iy?null:`当前不是博图确认`:`当前不需要回应`},async(e,t)=>{e.localVars[Ly]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`回合开始`,async e=>{let t=e.atom;t.type===`回合开始`&&t.player===n&&(e.state.players[n].vars[Ny]=e.state.zones.discardPile.length)}),M(t,e.id,n,`回合结束后`,async e=>{let t=e.atom;if(t.type!==`回合结束后`||t.player!==n)return;let r=e.state,i=r.players[n];if(!i?.alive)return;let a=r.turn.round;i.vars[Py]!==a&&(i.vars[Py]=a,i.vars[Fy]=0);let o=Math.min(Fre(r),3),s=i.vars[Fy]??0;if(s>=o)return;let c=i.vars[Ny];if(typeof c!=`number`||r.zones.discardPile.length<c)return;let l=r.zones.discardPile.slice(c),u=new Set(l.map(e=>r.cardMap[e]?.suit).filter(e=>e===`♠`||e===`♥`||e===`♣`||e===`♦`));if(!(u.has(`♠`)&&u.has(`♥`)&&u.has(`♣`)&&u.has(`♦`)))return;delete r.localVars[Ly],await B(r,{type:`请求回应`,requestType:Iy,target:n,prompt:{type:`confirm`,title:`博图:本回合弃牌堆已含四种花色,是否执行一个额外回合?`,description:`每轮限 ${o} 次(已用 ${s} 次)`,confirmLabel:`执行额外回合`,cancelLabel:`不执行`},defaultChoice:!1,timeout:20});let d=r.localVars[Ly];if(delete r.localVars[Ly],d)return r.players[n].vars[Fy]=s+1,Pre(r),r.currentPlayerIndex=n,await Oy(r,n),{kind:`cancel`}}),()=>{}}function My(e,t){}var Ny,Py,Fy,Iy,Ly,Ry,Ire=t((()=>{V(),ky(),F(),Ny=`博图/base`,Py=`博图/lastRound`,Fy=`博图/count`,Iy=`博图/confirm`,Ly=`博图/confirmed`,Ry={createSkill:Ay,onInit:jy,onMount:My}})),Lre=r({createSkill:()=>zy,default:()=>Ky,onInit:()=>Vy,onMount:()=>Hy});function zy(e,t){return{id:e,ownerId:t,name:`双雄`,description:`摸牌阶段,改为进行一次判定,获得判定牌,本回合可将与之颜色不同的手牌当决斗使用`}}function By(e){return`${e}#双雄`}function Vy(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===Uy?null:`当前不是双雄询问`:`当前不需要回应`},async(e,t)=>{e.pendingSlots.get(n)?.atom?.requestType===Uy&&(e.localVars[Wy]=t.choice===!0||t.confirmed===!0)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`摸牌`&&e.state.currentPlayerIndex===n&&e.state.players[n]?.alive&&!(e.state.zones.deck.length<1)&&(delete e.state.localVars[Wy],await B(e.state,{type:`请求回应`,requestType:Uy,target:n,prompt:{type:`confirm`,title:`是否发动双雄?(放弃摸牌,进行判定,获得判定牌,本回合异色手牌当决斗)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[Wy]===!0))return await jm(e.state,n,`双雄`),delete e.state.localVars[Wy],Nh(e.state,{player:n,phase:`摸牌`})}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.player!==n||t.judgeType!==`双雄`)return;let r=R(e.state);if(r.length===0)return;let i=r[r.length-1],a=e.state.cardMap[i];if(!a)return;let o=a.color;e.state.turn.vars[Gy]=o,await B(e.state,{type:`回合用量`,player:n,key:Gy,value:o}),await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`手牌`,player:n}})}),j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=e.turn.vars[Gy],l=typeof c==`string`&&c!==``,u=t.cardId,d=typeof u==`string`,f=d&&o.hand.includes(u),p=d?e.cardMap[u]:void 0,m=!!p,h=!!p&&!!c&&p.color!==c;return r&&i&&a&&s&&l&&f&&m&&h?null:`双雄:需要一张与本回合判定牌颜色不同的手牌`},async(e,t)=>{let r=t.cardId,i=By(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`决斗`})},(e,t)=>{let r=t.cardId,i=By(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),()=>{}}function Hy(e,t){t.defineAction(`respond`,{label:`双雄`,style:`primary`,prompt:{type:`confirm`,title:`是否发动双雄?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),t.defineAction(`transform`,{label:`双雄`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`选择一张与本回合判定牌颜色不同的手牌当决斗使用`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1}},transform:t=>({name:`决斗`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];if(!t?.hand)return!1;let n=t.turnUsage?.[Gy];return typeof n!=`string`||n===``?!1:t.hand.some(e=>e.color!==n)}})}var Uy,Wy,Gy,Ky,Rre=t((()=>{V(),z(),Fm(),F(),Ph(),J(),W(),Uy=`双雄/confirm`,Wy=`双雄/triggered`,Gy=U,Ky={createSkill:zy,onInit:Vy,onMount:Hy}})),zre=r({createSkill:()=>qy,default:()=>eb,onInit:()=>Jy,onMount:()=>Yy});function qy(e,t){return{id:e,ownerId:t,name:`反间`,description:`出牌阶段限一次,你可以令一名其他角色选择一种花色,令其获得并展示你的一张手牌,若此牌花色与其选择的花色不同,你对其造成1点伤害`}}function Jy(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`反间`))return`本回合已使用过反间`;if(r.hand.length===0)return`需要有手牌才能发动反间`;let i=t.targets;if(!Array.isArray(i)||i.length!==1)return`需要指定一名目标`;let a=i[0];return a===n?`不能对自己使用反间`:e.players[a]?.alive?null:`目标不合法`},async(e,t)=>{let r=n,i=t.targets[0];await Z(e,r,`反间`),await I(e,`反间`,r,{...t}),delete e.localVars[Zy],await B(e,{type:`请求回应`,requestType:Xy,target:i,prompt:{type:`chooseSuit`,title:`反间:选择一种花色(猜对则不受伤害,猜错受1点伤害)`},defaultChoice:$y,timeout:30});let a=e.localVars[Zy];(!a||!Qy.includes(a))&&(a=$y);let o=e.players[r];if(!o||!o.alive||o.hand.length===0){await L(e);return}let s=Ud(e.rngSeed),c=s.nextInt(o.hand.length);e.rngSeed=s.getState();let l=o.hand[c];await B(e,{type:`移动牌`,cardId:l,from:{zone:`手牌`,player:r},to:{zone:`手牌`,player:i}});let u=e.cardMap[l],d=e.players[i];u&&u.suit!==a&&d?.alive&&await Dm(e,r,i,1),await L(e)});let r=[];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;if(r.requestType!==Xy)return`当前不是反间选花色`;let a=t.suit;return typeof a!=`string`||!Qy.includes(a)?`需要选择 ♠/♥/♣/♦ 中的一种花色`:null},async(e,t)=>{e.localVars[Zy]=t.suit});r.push(a)}return()=>{r.forEach(e=>e())}}function Yy(e,t){return t.defineAction(`use`,{label:`反间`,style:`danger`,prompt:{type:`selectTarget`,title:`反间:令一名其他角色猜花色`,targetFilter:{min:1,max:1,filter:(t,n)=>n!==e.ownerId}},activeWhen:e=>yh(`反间`)(e)&&(e.view.players[e.perspectiveIdx]?.hand?.length??0)>0}),t.defineAction(`respond`,{label:`反间`,style:`danger`,prompt:{type:`chooseSuit`,title:`反间:选择一种花色(猜对则不受伤害,猜错受1点伤害)`}}),()=>{}}var Xy,Zy,Qy,$y,eb,Bre=t((()=>{V(),z(),Om(),Wd(),Q(),F(),Xy=`反间/选花色`,Zy=`反间/suit`,Qy=[`♠`,`♥`,`♣`,`♦`],$y=`♠`,eb={createSkill:qy,onInit:Jy,onMount:Yy}})),Vre=r({createSkill:()=>Hre,onInit:()=>Ure,onMount:()=>Wre});function Hre(e,t){return{id:e,ownerId:t,name:`反馈`,description:`受到伤害后,你可以获得伤害来源的一张牌`}}function Ure(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===`反馈/confirm`)return null;if(i===`反馈/选牌`){let e=t.zone;if(e===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand)`;return null}return`当前不是反馈回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===`反馈/confirm`?e.localVars[`反馈/confirmed`]=t.choice===!0||t.confirmed===!0:r===`反馈/选牌`&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0||t.source===void 0||t.source===n)return;let r=e.state.players[t.source];if(!r?.alive||!(r.hand.length>0||Object.keys(r.equipment).length>0)||(delete e.state.localVars[`反馈/confirmed`],await B(e.state,{type:`请求回应`,requestType:`反馈/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动反馈?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`反馈/confirmed`]))return;let i=e.state.players[t.source];i&&await kg(e.state,n,t.source,i,{mode:`obtain`,requestType:`反馈/选牌`,title:`反馈:选择获得来源的一张牌`,includeJudge:!1})}),()=>{}}function Wre(e,t){t.defineAction(`respond`,{label:`反馈`,style:`default`,prompt:{type:`confirm`,title:`是否发动反馈?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var Gre=t((()=>{V(),F(),Ag(),W()})),Kre=r({createSkill:()=>tb,default:()=>rb,onInit:()=>nb});function tb(e,t){return{id:e,ownerId:t,name:`古锭刀`,description:`锁定技,当你使用杀造成伤害时,若目标没有手牌,此伤害+1。`,isLocked:!0}}function nb(e,t){let n=e.ownerId;return M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.amount??0;if(r<=0)return;let i=e.state.players[n];if(!i)return;let a=i.equipment.武器;if(!a||e.state.cardMap[a]?.name!==`古锭刀`)return;let o=t.cardId;if(!o||e.state.cardMap[o]?.name!==`杀`)return;let s=t.target;if(typeof s!=`number`)return;let c=e.state.players[s];if(c&&!(c.hand.length>0))return{kind:`modify`,atom:{...e.atom,amount:r+1}}}),()=>{}}var rb,qre=t((()=>{F(),rb={createSkill:tb,onInit:nb}})),Jre=r({createSkill:()=>Yre,onInit:()=>Xre});function Yre(e,t){return{id:e,ownerId:t,name:`咆哮`,description:`锁定技:出牌阶段使用【杀】无次数限制`,isLocked:!0}}function Xre(e,t){let n=e.ownerId,r=eh(t,n,()=>!0),i=N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`出牌`&&t.player===n&&await B(e.state,{type:`回合用量`,player:n,key:qc(`咆哮`),value:!0})});return()=>{r(),i()}}var Zre=t((()=>{V(),F(),fh(),W()})),Qre=r({createSkill:()=>nie,onInit:()=>rie});function $re(e){let t=ib.indexOf(e);return t<0||t>=ib.length-1?null:ib[t+1]}function eie(e,t){let n=e.players.length;for(let r=1;r<=n;r++){let i=(t+r)%n;if(e.players[i].alive)return i}return t}async function tie(e,t){let n=e.players.filter(e=>e.alive).length,r=t,i=0;for(;Dh(e,r)&&i<n;)await Oh(e,r),await B(e,{type:`下一玩家`}),r=e.currentPlayerIndex,i++;await B(e,{type:`回合开始`,player:r}),await B(e,{type:`阶段开始`,player:r,phase:`准备`}),await B(e,{type:`阶段结束`,player:r,phase:`准备`})}function nie(e,t){return{id:e,ownerId:t,name:`回合管理`,description:`监听上家回合结束,自动开始自己的回合`}}function rie(e,t){let n=e.ownerId,r=e.ownerId;return N(t,e.id,n,`阶段结束`,async e=>{if(e.atom.type!==`阶段结束`)return;let{player:t,phase:n}=e.atom;if(t!==r)return;let i=$re(n);if(i&&await B(e.state,{type:`阶段间`,player:t,from:n,to:i})&&(await B(e.state,{type:`阶段开始`,player:t,phase:i}),e.state.phase===i)){if(i===`摸牌`&&await B(e.state,{type:`摸牌`,player:t,count:2}),i===`弃牌`){let n=e.state.players[t].hand.length,r=ip(e.state,t);if(n>r){let i=n-r;await B(e.state,{type:`请求回应`,requestType:`__弃牌`,target:t,prompt:{type:`useCard`,title:`弃牌阶段:需弃 ${i} 张牌`,cardFilter:{filter:()=>!0,min:i,max:i}},timeout:30})}}if(i===`出牌`){(async()=>{for(;e.state.phase===`出牌`&&e.state.currentPlayerIndex===t;)await B(e.state,{type:`出牌窗口`,player:t,timeout:50})})();return}if(i===`回合结束`){await B(e.state,{type:`清过期标记`,player:t}),await B(e.state,{type:`下一玩家`}),await B(e.state,{type:`回合结束`,player:t})&&await B(e.state,{type:`回合结束后`,player:t});return}(i===`准备`||i===`判定`||i===`摸牌`||i===`弃牌`)&&await B(e.state,{type:`阶段结束`,player:t,phase:i})}}),N(t,e.id,n,`回合结束后`,async e=>{if(e.atom.type!==`回合结束后`)return;let t=e.atom.player,n=e.state;eie(n,t)===r&&await tie(e.state,r)}),j(t,e.id,n,`end`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`||e.phase===`弃牌`,a=!E(e);return r&&i&&a?null:`现在不能结束回合`},async(e,t)=>{await B(e,{type:`阶段结束`,player:n,phase:e.phase})}),j(t,e.id,n,`start`,(e,t)=>{let r=n===0&&e.currentPlayerIndex===0,i=e.phase===`准备`&&e.pendingSlots.size===0;return r&&i?null:`现在不能开局`},async(e,t)=>{let r=n;await B(e,{type:`回合开始`,player:r}),await B(e,{type:`阶段开始`,player:r,phase:`准备`}),await B(e,{type:`阶段结束`,player:r,phase:`准备`})}),()=>{}}var ib,iie=t((()=>{V(),F(),op(),Mh(),ib=[`准备`,`判定`,`摸牌`,`出牌`,`弃牌`,`回合结束`]})),aie=r({createSkill:()=>ob,default:()=>pb,onInit:()=>sb,onMount:()=>cb});function ab(e){return`固政/弃牌/${e}`}function ob(e,t){return{id:e,ownerId:t,name:`固政`,description:`其他角色弃牌阶段结束时:将其一张弃牌返回其手牌,然后获得其余弃牌`}}function sb(e,t){let n=e.ownerId;return N(t,e.id,n,`弃置`,async e=>{if(e.state.phase!==`弃牌`)return;let t=e.atom,n=ab(t.player),r=e.state.localVars[n];e.state.localVars[n]=[...r??[],...t.cardIds]}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.phase!==`弃牌`)return;let r=t.player;if(r===n)return;let i=e.state,a=i.localVars[ab(r)];if(delete i.localVars[ab(r)],!a||a.length===0||!i.players[n]?.alive)return;if(await I(i,`固政`,n,{target:r,cardIds:[...a]}),delete i.localVars[db],await B(i,{type:`请求回应`,requestType:lb,target:n,prompt:{type:`confirm`,title:`是否发动固政?(${i.players[r]?.name??``} 弃置了 ${a.length} 张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),i.localVars[db]!==!0){await L(i);return}let o=a.filter(e=>i.zones.discardPile.includes(e)),s;if(o.length<=1){if(o.length===0){await L(i);return}s=o[0]}else{delete i.localVars[fb],await B(i,{type:`请求回应`,requestType:ub,target:n,prompt:{type:`pickProcessingCard`,title:`固政:选择一张牌返回其手牌(其余你将获得)`,cards:o.map(e=>{let t=i.cardMap[e];return{cardId:e,cardName:t?.name??`?`,suit:t?.suit??``,rank:t?.rank??``}})},defaultChoice:o[0],timeout:30});let e=i.localVars[fb];s=e&&o.includes(e)?e:o[0]}let c=o.filter(e=>e!==s);await B(i,{type:`移动牌`,cardId:s,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:r}});for(let e of c)await B(i,{type:`移动牌`,cardId:e,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}});await L(i)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是固政窗口`;let i=r.atom;return i.requestType===lb?null:i.requestType===ub?typeof t.cardId==`string`?null:`需要选择一张牌`:`当前不是固政窗口`},async(e,t)=>{let r=e.pendingSlots.get(n).atom;r.requestType===lb?e.localVars[db]=t.choice===!0||t.confirmed===!0:r.requestType===ub&&(e.localVars[fb]=t.cardId)}),()=>{}}function cb(e,t){return()=>{}}var lb,ub,db,fb,pb,oie=t((()=>{V(),z(),F(),lb=`固政/确认`,ub=`固政/选牌`,db=`固政/确认结果`,fb=`固政/所选牌`,pb={createSkill:ob,onInit:sb,onMount:cb}})),sie=r({createSkill:()=>hb,default:()=>yb,onInit:()=>gb,onMount:()=>_b});function mb(e){return!!e&&e.suit===`♦`}function hb(e,t){return{id:e,ownerId:t,name:`国色`,description:`你可以将一张方块牌当【乐不思蜀】使用`}}function gb(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n];if(!o?.alive)return`玩家不存在或已死亡`;if(typeof t.cardId!=`string`)return`需要选择一张牌`;let s=t.cardId,c=o.hand.includes(s),l=Object.values(o.equipment).some(e=>e===s);if(!c&&!l)return`牌不在手牌或装备区`;if(!mb(e.cardMap[s]))return`需要一张方块牌`;let u=t.target??t.targets?.[0];if(typeof u!=`number`)return`需要选择目标`;if(u===n)return`不能对自己使用`;let d=e.players[u];return d?.alive?d.pendingTricks.some(e=>e.name===vb)?`目标判定区已有乐不思蜀`:r&&i&&a?null:`国色使用条件不满足`:`目标不存在或已死亡`},async(e,t)=>{let r=n,i=t.cardId,a=t.target??t.targets?.[0];await I(e,`国色`,r,{...t});let o=Object.entries(e.players[r].equipment).find(([,e])=>e===i);o&&await B(e,{type:`卸下`,player:r,slot:o[0]}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`处理区`}}),await B(e,{type:`添加延时锦囊`,player:a,trick:{name:vb,source:r,card:e.cardMap[i]??{id:i,name:vb,suit:`♦`,color:`红`,rank:`A`,type:`锦囊牌`}}}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await L(e)}),()=>{}}function _b(e,t){t.defineAction(`use`,{label:`国色`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`国色:将一张方块牌当乐不思蜀使用`,cardFilter:{filter:e=>mb(e),min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return!(!n||n.alive===!1)}}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>mb(e))??!1?!0:Object.values(t.equipment??{}).some(t=>mb(t?e.view.cardMap[t]:void 0)):!1}})}var vb,yb,cie=t((()=>{V(),z(),J(),F(),vb=`乐不思蜀`,yb={createSkill:hb,onInit:gb,onMount:_b}}));function bb(e){if(!e)return 0;let t=e.rank;if(t===`A`)return 1;if(t===`J`)return 11;if(t===`Q`)return 12;if(t===`K`)return 13;let n=parseInt(t,10);return Number.isFinite(n)?n:0}async function xb(e,t,n,r,i){await B(e,{type:`拼点扣置`,initiator:t,target:n,initiatorCard:r,targetCard:i}),await B(e,{type:`拼点亮出`,initiator:t,target:n,initiatorCard:r,targetCard:i});let a=bb(e.cardMap[r])>bb(e.cardMap[i])?`赢`:`没赢`;return await B(e,{type:`移动牌`,cardId:r,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await B(e,{type:`拼点后`,initiator:t,target:n,initiatorCard:r,targetCard:i,result:a}),a}var Sb=t((()=>{V()})),lie=r({createSkill:()=>Cb,default:()=>Ab,onInit:()=>wb,onMount:()=>Tb});function uie(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function Cb(e,t){return{id:e,ownerId:t,name:`天义`,description:`出牌阶段限一次,与一名角色拼点:赢则本回合攻击范围无限、可额外使用一张杀、杀可额外指定一个目标;没赢则本回合不能使用杀`}}function wb(e,t){let n=e.ownerId,r=$m(t,n,(e,t)=>+(e.turn.vars[Ob]===t)),i=oh(t,n,(e,t)=>e.turn.vars[kb]===t),a=qm(t,n,(e,t,n,r)=>e.turn.vars[Ob]===t),o=qh(t,n,(e,t)=>e.turn.vars[Ob]===t?2:0);j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(X(e,n,`天义`))return`本回合已使用过天义`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;if(typeof i!=`string`)return`需要选择一张拼点牌`;if(!r.hand.includes(i))return`拼点牌不在手牌中`;let a=t.target;if(typeof a!=`number`)return`需要选择拼点目标`;if(a===n)return`不能与自己拼点`;let o=e.players[a];return o?.alive?o.hand.length===0?`目标没有手牌,无法拼点`:null:`目标不存在或已死亡`},async(e,t)=>{let r=n,i=t.cardId,a=t.target;await Z(e,r,`天义`),await I(e,`天义`,r,{...t});let o=e.cardMap[i],s=o?uie(o.rank):0;delete e.localVars[Eb],await B(e,{type:`请求回应`,requestType:Db,target:a,prompt:{type:`useCard`,title:`天义:与 ${e.players[r].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let c=e.localVars[Eb];delete e.localVars[Eb];let l;c&&e.players[a].hand.includes(c)?l=await xb(e,r,a,i,c)===`赢`:(await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`弃牌堆`}}),l=s>0),l?(e.turn.vars[Ob]=r,await B(e,{type:`回合用量`,player:r,key:Ob,value:r}),await B(e,{type:`回合用量`,player:r,key:Jc(`天义`),value:1}),await B(e,{type:`回合用量`,player:r,key:Xc(`天义`),value:1})):(e.turn.vars[kb]=r,await B(e,{type:`回合用量`,player:r,key:Yc(`天义`),value:!0})),await L(e)});for(let n of t.players){let r=n.index;j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return`当前不需要回应`;let i=n.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==Db)return`当前不是天义回应`;if(i.target!==r)return`不是问你的`;let a=t.cardId;return typeof a==`string`?e.players[r].hand.includes(a)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`},async(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return;let i=n.atom;i.type!==`请求回应`||i.requestType!==Db||(e.localVars[Eb]=t.cardId)})}return()=>{r(),i(),a(),o()}}function Tb(e,t){t.defineAction(`use`,{label:`天义`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`天义:选择一张拼点牌和一名目标`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return n?n.alive!==!1&&(n.handCount??0)>0:!1}}},activeWhen:e=>yh(`天义`)(e)&&(e.view.players[e.perspectiveIdx]?.hand?.length??0)>0}),t.defineAction(`respond`,{label:`天义`,style:`primary`,prompt:{type:`useCard`,title:`天义:请出一张拼点牌`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var Eb,Db,Ob,kb,Ab,die=t((()=>{V(),z(),Sb(),Q(),F(),fh(),Xh(),Xm(),W(),Eb=`天义/targetCard`,Db=`天义/拼点`,Ob=Rl,kb=`天义/lost`,Ab={createSkill:Cb,onInit:wb,onMount:Tb}})),fie=r({createSkill:()=>pie,onInit:()=>mie,onMount:()=>hie});function pie(e,t){return{id:e,ownerId:t,name:`天妒`,description:`当你的判定牌生效后,你可以获得此判定牌`}}function mie(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);return t?.atom.type===`请求回应`?t.atom.requestType===jb?null:`当前不是天妒选择`:`当前不需要回应`},async(e,t)=>{e.localVars[Mb]=t.choice===!0}),N(t,e.id,n,`判定牌生效后`,async e=>{if(e.atom.player!==n)return;let t=R(e.state);if(t.length===0||t.length>1)return;let r=t[t.length-1];if(!e.state.cardMap[r])return;delete e.state.localVars[Mb],await B(e.state,{type:`请求回应`,requestType:jb,target:n,prompt:{type:`confirm`,title:`天妒:获得判定牌?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!1,timeout:10});let i=e.state.localVars[Mb]===!0;delete e.state.localVars[Mb],i&&await B(e.state,{type:`移动牌`,cardId:r,from:{zone:`处理区`},to:{zone:`手牌`,player:n}})}),()=>{}}function hie(e,t){t.defineAction(`respond`,{label:`天妒`,style:`default`,prompt:{type:`confirm`,title:`是否发动天妒?`,confirmLabel:`获得判定牌`,cancelLabel:`不获得`}})}var jb,Mb,gie=t((()=>{V(),z(),F(),jb=`天妒/choose`,Mb=`天妒/choice`})),_ie=r({createSkill:()=>Fb,default:()=>Gb,onInit:()=>Ib,onMount:()=>Lb});function Nb(e,t,n){let r=e.cardMap[n];return r?!!(r.suit===`♥`||r.suit===`♠`&&e.players[t]?.skills.includes(`红颜`)):!1}function Pb(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function Fb(e,t){return{id:e,ownerId:t,name:`天香`,description:`受到伤害时,弃一张红桃手牌防止之,令一名其他角色二选一:①受来源1伤害并摸X(X为已损失体力至多5);②失去1体力并获得弃置的牌`}}function Ib(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=Pb(e,n);if(r!==Rb&&r!==zb&&r!==Bb)return`当前不是天香询问`;if(r===Rb||r===Bb)return null;let i=t.cardId,a=t.target;return typeof i==`string`?e.players[n]?.hand.includes(i)?Nb(e,n,i)?typeof a==`number`?a===n?`不能转移给自己`:e.players[a]?.alive?null:`目标无效`:`请选择转移目标`:`必须选择红桃手牌`:`牌不在手牌中`:`请选择一张红桃手牌`},async(e,t)=>{let r=Pb(e,n),i=t.choice===!0||t.confirmed===!0;r===Rb?e.localVars[Vb]=i:r===zb?(e.localVars[Hb]=t.cardId??null,e.localVars[Ub]=t.target??null):r===Bb&&(e.localVars[Wb]=i?`damage`:`lose`)}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.amount??0;if(r<=0)return;let i=e.state.players[n];if(!i?.alive||i.hand.filter(t=>Nb(e.state,n,t)).length===0||!e.state.players.some((e,t)=>t!==n&&e.alive)||(delete e.state.localVars[Vb],await B(e.state,{type:`请求回应`,requestType:Rb,target:n,prompt:{type:`confirm`,title:`是否发动天香?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[Vb]))return;delete e.state.localVars[Hb],delete e.state.localVars[Ub];let a=i.skills.includes(`红颜`);await B(e.state,{type:`请求回应`,requestType:zb,target:n,prompt:{type:`useCardAndTarget`,title:`天香:弃一张红桃手牌,选择一名其他角色`,cardFilter:{filter:e=>e.suit===`♥`||a&&e.suit===`♠`,min:1,max:1},targetFilter:{min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0}},timeout:15});let o=e.state.localVars[Hb],s=e.state.localVars[Ub];if(delete e.state.localVars[Vb],delete e.state.localVars[Hb],delete e.state.localVars[Ub],typeof o!=`string`||typeof s!=`number`||s===n)return;let c=e.state.players[s];if(!c?.alive||!i.hand.includes(o)||!Nb(e.state,n,o))return;delete e.state.localVars[Wb],await B(e.state,{type:`请求回应`,requestType:Bb,target:n,prompt:{type:`confirm`,title:`天香:令 ${c.name} ①受来源1点伤害并摸X张牌?(确认=①,取消=②失去1体力并获得弃牌)`,confirmLabel:`①受伤害+摸牌`,cancelLabel:`②失去体力+获牌`},defaultChoice:!1,timeout:15});let l=e.state.localVars[Wb];delete e.state.localVars[Wb];let u=l===`damage`;if(await B(e.state,{type:`弃置`,player:n,cardIds:[o],voluntary:!0}),u){let i=t.source??n;if(await Dm(e.state,i,s,r,void 0,t.damageType),c.alive){let t=c.maxHealth-p(c),n=Math.min(t,5);n>0&&await B(e.state,{type:`摸牌`,player:s,count:n})}}else await B(e.state,{type:`失去体力`,target:s,amount:1}),c.alive&&e.state.zones.discardPile.includes(o)&&await B(e.state,{type:`移动牌`,cardId:o,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:s}});return{kind:`cancel`}}),()=>{}}function Lb(e,t){t.defineAction(`respond`,{label:`天香`,style:`primary`,prompt:{type:`confirm`,title:`是否发动天香?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var Rb,zb,Bb,Vb,Hb,Ub,Wb,Gb,vie=t((()=>{b(),V(),Om(),F(),Rb=`天香/confirm`,zb=`天香/choose`,Bb=`天香/option`,Vb=`天香/confirmed`,Hb=`天香/cardId`,Ub=`天香/target`,Wb=`天香/option`,Gb={createSkill:Fb,onInit:Ib,onMount:Lb}})),yie=r({createSkill:()=>Kb,default:()=>ix,onInit:()=>Xb,onMount:()=>Zb});function Kb(e,t){return{id:e,ownerId:t,name:Qb,description:`回合内使用非装备牌指定目标后,可弃置另一名角色一张牌并令其摸一张牌`}}function qb(e){return e?e.hand.length>0?!0:Object.values(e.equipment).some(e=>typeof e==`string`):!1}function Jb(e,t){return e.players.some(e=>e.alive&&e.index!==t&&qb(e))}function Yb(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function Xb(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=Yb(e,n);if(r!==$b&&r!==ex&&r!==tx)return`当前不是奇制询问`;if(r===$b)return null;if(r===ex){let r=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);if(typeof r!=`number`)return`请选择一名角色`;if(r===n)return`不能选择自己`;let i=e.players[r];return i?.alive?qb(i)?null:`目标无可弃置的牌`:`目标已死亡`}let i=t.zone;if(i===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(i===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand)`;return null},async(e,t)=>{let r=Yb(e,n);if(r===$b){e.localVars[nx]=t.choice===!0||t.confirmed===!0;return}if(r===ex){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[rx]=n);return}if(r===tx){e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null};return}}),N(t,e.id,n,`指定目标后`,async e=>{let t=e.atom;if(t.type!==`指定目标后`||t.source!==n||e.state.currentPlayerIndex!==n||!e.state.players[n]?.alive||(t.cardId===void 0?void 0:e.state.cardMap[t.cardId])?.type===`装备牌`||!Jb(e.state,n))return;if(delete e.state.localVars[nx],await B(e.state,{type:`请求回应`,requestType:$b,target:n,prompt:{type:`confirm`,title:`是否发动奇制?(弃置另一名角色一张牌,然后令其摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[nx]){delete e.state.localVars[nx];return}if(delete e.state.localVars[nx],!e.state.players[n]?.alive||!Jb(e.state,n))return;delete e.state.localVars[rx],await B(e.state,{type:`请求回应`,requestType:ex,target:n,prompt:{type:`choosePlayer`,title:`奇制:选择要弃置其一张牌的其他角色`,min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0&&qb(e.state.players[r])},timeout:20});let r=e.state.localVars[rx];if(delete e.state.localVars[rx],typeof r!=`number`)return;let i=e.state.players[r];if(!i?.alive||!qb(i))return;await kg(e.state,n,r,i,{mode:`discard`,requestType:tx,title:`奇制:选择要从 ${i.name} 弃置的 1 张牌`,includeJudge:!1}),e.state.players[r]?.alive&&await B(e.state,{type:`摸牌`,player:r,count:1});let a=fl(e.state.turn.vars)??0;e.state.turn.vars[gl]=a+1}),()=>{}}function Zb(e,t){return t.defineAction(`respond`,{label:Qb,style:`default`,prompt:{type:`confirm`,title:`奇制`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var Qb,$b,ex,tx,nx,rx,ix,bie=t((()=>{V(),F(),Ag(),W(),Qb=`奇制`,$b=`${Qb}/confirm`,ex=`${Qb}/选目标`,tx=`${Qb}/选牌`,nx=`${Qb}/confirmed`,rx=`${Qb}/target`,ix={createSkill:Kb,onInit:Xb,onMount:Zb}})),xie=r({QICAI_TAG:()=>ax,createSkill:()=>Sie,onInit:()=>Cie});function Sie(e,t){return{id:e,ownerId:t,name:`奇才`,description:`锁定技:你使用任何锦囊牌无距离限制`,isLocked:!0}}function Cie(e,t){let n=e.ownerId,r=t.players[n];return r&&!r.tags.includes(`奇才/无距离限制`)&&r.tags.push(ax),()=>{let e=t.players[n];e&&(e.tags=e.tags.filter(e=>e!==ax))}}var ax,wie=t((()=>{ax=`奇才/无距离限制`})),Tie=r({createSkill:()=>ox,default:()=>ux,onInit:()=>cx,onMount:()=>lx});function ox(e,t){return{id:e,ownerId:t,name:`奇袭`,description:`你可以将一张黑色牌当【过河拆桥】使用`}}function sx(e){return`${e}#奇袭`}function cx(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=!!u&&u.color===`黑`,f=l&&o.hand.includes(c),p=l&&Object.values(o.equipment).some(e=>e===c);return r&&i&&a&&s&&d&&(f||p)?null:`现在不能使用奇袭`},async(e,t)=>{let r=t.cardId,i=sx(r),a=e.players[n],o=Object.entries(a.equipment).find(([,e])=>e===r);if(o){let r=o[0];t._origSlot=r,await B(e,{type:`卸下`,player:n,slot:r})}await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`过河拆桥`})},(e,t)=>{let r=t.cardId,i=sx(r),a=e.players[n],o=t._origSlot;delete e.cardMap[i];let s=a.hand.indexOf(i);if(s>=0)if(o){if(a.hand.splice(s,1),a.equipment[o]=r,o===`武器`){let t=e.cardMap[r];a.vars[wl]=t?.range??1}}else a.hand[s]=r}),()=>{}}function lx(e,t){t.defineAction(`transform`,{label:`奇袭`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张黑色牌当过河拆桥使用`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1},targetFilter:{min:1,max:1}},transform:t=>({name:`过河拆桥`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.color===`黑`)??!1?!0:Object.values(t.equipment??{}).some(t=>(t?e.view.cardMap[t]:void 0)?.color===`黑`):!1}})}var ux,Eie=t((()=>{F(),V(),J(),W(),ux={createSkill:ox,onInit:cx,onMount:lx}})),Die=r({createSkill:()=>dx,default:()=>bx,onInit:()=>fx,onMount:()=>px});function dx(e,t){return{id:e,ownerId:t,name:`奇谋`,description:`限定技,出牌阶段,你可以失去任意点体力并摸等量的牌,然后本回合你计算与其他角色的距离-X且使用【杀】的限制次数+X(X为失去的体力值)`}}function fx(e,t){let n=e.ownerId,r=[];return r.push(j(t,e.id,n,`use`,(e,t)=>e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:e.players[n]?.alive?e.players[n].vars[mx]?`奇谋已使用过(限定技)`:e.players[n].health<1?`没有体力可失去`:null:`玩家不存在或已死亡`:`只能在出牌阶段发动`:`不是你的回合`,async(e,t)=>{let r=e.players[n],i=r.health;delete e.localVars[gx],await B(e,{type:`请求回应`,requestType:hx,target:n,prompt:{type:`chooseOption`,title:`奇谋:失去几点体力?(1-${i})`,description:`失去 X 点体力并摸 X 张牌,然后本回合你计算与其他角色的距离-X且使用【杀】的限制次数+X`,options:Array.from({length:i},(e,t)=>({value:String(t+1),label:`失去 ${t+1} 点体力`}))},defaultChoice:`1`,timeout:30});let a=e.localVars[gx];if(delete e.localVars[gx],!(typeof a!=`number`||a<1||a>i)){r.vars[mx]=!0,await I(e,`奇谋`,n,{x:a});try{if(await B(e,{type:`失去体力`,target:n,amount:a}),!e.players[n]?.alive)return;await B(e,{type:`摸牌`,player:n,count:a});let t=(il(r.vars)??0)+a;r.vars[Sl]=t,r.vars[vx]=a,await B(e,{type:`加标记`,player:n,mark:{id:yx,scope:n,payload:{x:a}},distanceVars:{attackMod:t}}),e.turn.vars[_x]=a,await B(e,{type:`回合用量`,player:n,key:Jc(`奇谋`),value:a})}finally{await L(e)}}})),r.push(j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`||i.requestType!==hx)return`当前不是奇谋询问`;let a=e.players[n]?.health??0,o=Number(t.option);return!Number.isInteger(o)||o<1||o>a?`请选择 1-${a} 之间的整数`:null},async(e,t)=>{e.localVars[gx]=Number(t.option)})),r.push($m(t,n,(e,t)=>{if(t!==n)return 0;let r=e.turn.vars[_x];return typeof r==`number`?r:0})),r.push(N(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`||t.player!==n)return;let r=e.state.players[n];if(!r)return;let i=r.vars[vx];if(typeof i!=`number`)return;let a=(il(r.vars)??0)-i;a>0?r.vars[Sl]=a:delete r.vars[Sl],delete r.vars[vx],r.marks.some(e=>e.id===yx)&&await B(e.state,{type:`去标记`,player:n,markId:yx,distanceVars:{attackMod:a>0?a:void 0}})})),()=>{for(let e of r)e();let e=t.players[n];if(e){let t=e.vars[vx];if(typeof t==`number`){let n=(il(e.vars)??0)-t;n>0?e.vars[Sl]=n:delete e.vars[Sl],delete e.vars[vx]}e.marks=e.marks.filter(e=>e.id!==yx)}}}function px(e,t){return t.defineAction(`use`,{label:`奇谋`,style:`primary`,prompt:{type:`confirm`,title:`是否发动奇谋?(限定技)`,description:`出牌阶段:失去任意点体力并摸等量的牌,本回合你计算与其他角色的距离-X且使用【杀】的限制次数+X`,confirmLabel:`发动`,cancelLabel:`不发动`},activeWhen:e=>q(e)}),t.defineAction(`respond`,{label:`选择体力值`,style:`default`,prompt:{type:`confirm`,title:`奇谋:选择失去的体力值`}}),()=>{}}var mx,hx,gx,_x,vx,yx,bx,Oie=t((()=>{V(),z(),F(),fh(),J(),W(),mx=`奇谋/used`,hx=`奇谋/选X`,gx=`奇谋/x`,_x=`奇谋/extra`,vx=`奇谋/距离加成`,yx=`奇谋/距离`,bx={createSkill:dx,onInit:fx,onMount:px}})),kie=r({createSkill:()=>xx,default:()=>Mx,onInit:()=>Sx,onMount:()=>Cx});async function Aie(e,t,n,r){if(delete e.localVars[Dx],await B(e,{type:`请求回应`,requestType:Tx,target:t,prompt:{type:`confirm`,title:`是否发动奋威?(限定技:令${n}对任意个目标无效)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.localVars[Dx])return null;delete e.localVars[Ox],await B(e,{type:`请求回应`,requestType:Ex,target:t,prompt:{type:`choosePlayer`,title:`奋威:选择要令其无效的目标(可多选)`,min:1,max:r.length,candidates:r,filter:(e,t)=>r.includes(t)},timeout:30});let i=e.localVars[Ox];return delete e.localVars[Ox],!i||i.length===0?null:(e.players[t].vars[wx]=!0,i)}function xx(e,t){return{id:e,ownerId:t,name:`奋威`,description:`限定技,当一张锦囊牌指定多个目标后,你可以令此牌对任意个目标无效`}}function Sx(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==Tx&&a!==Ex?`当前不是奋威询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===Tx)e.localVars[Dx]=t.choice===!0||t.confirmed===!0;else if(r===Ex){let n=t.targets;Array.isArray(n)&&(e.localVars[Ox]=n)}}),M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.requestType!==`无懈可击`)return;let r=t.cancelTarget;if(typeof r!=`number`)return;let i=e.state,a=Ke(i);if(!a)return;let o=jx[a.skillId],s=a.skillId===`铁索连环`;if(!o&&!s)return;let c=a.params?.cardId,l=c?`${kx}${c}`:null,u=l?i.localVars[l]:void 0;if(o&&u?.includes(r))return a.cancelled=!0,{kind:`cancel`};if(!c||i.localVars[`${Ax}${c}`]||i.players[n]?.vars[wx]||!i.players[n]?.alive)return;let d=a.params?.targets??[];if(d.length<=1)return;i.localVars[`${Ax}${c}`]=!0;let f=await Aie(i,n,a.skillId,d);if(f&&(i.localVars[`${kx}${c}`]=f,o&&f.includes(r)))return a.cancelled=!0,{kind:`cancel`}}),M(t,e.id,n,`设横置`,async e=>{let t=e.state,n=Ke(t);if(n?.skillId!==`铁索连环`)return;let r=e.atom;if(typeof r.player!=`number`)return;let i=n.params?.cardId;if(i&&t.localVars[`${kx}${i}`]?.includes(r.player))return{kind:`cancel`}}),()=>{}}function Cx(e,t){return t.defineAction(`respond`,{label:`奋威`,style:`danger`,prompt:{type:`confirm`,title:`奋威`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var wx,Tx,Ex,Dx,Ox,kx,Ax,jx,Mx,jie=t((()=>{V(),z(),F(),wx=`奋威/used`,Tx=`奋威/confirm`,Ex=`奋威/choose`,Dx=`奋威/confirmed`,Ox=`奋威/chosenTargets`,kx=`奋威/无效/`,Ax=`奋威/已处理/`,jx={南蛮入侵:`allOthers`,万箭齐发:`allOthers`,桃园结义:`allAlive`,五谷丰登:`allAlive`},Mx={createSkill:xx,onInit:Sx,onMount:Cx}})),Mie=r({createSkill:()=>Nx,default:()=>zx,onInit:()=>Px,onMount:()=>Fx});function Nx(e,t){return{id:e,ownerId:t,name:`奋激`,description:`当一名角色的手牌被弃置或获得后,你可以失去1点体力令其摸两张牌`}}function Px(e,t){let n=e.ownerId,r=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType?.startsWith(Ix)?null:`当前不是奋激询问`:`当前不需要回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType??``;r.startsWith(Ix)&&(e.localVars[r]=t.choice===!0||t.confirmed===!0)});async function i(e,t){let r=e.state;if(!r.players[n]?.alive||!r.players[t]?.alive)return;let i=`${Ix}/${t}`;delete r.localVars[i],await B(r,{type:`请求回应`,requestType:i,target:n,prompt:{type:`confirm`,title:`是否发动奋激?(失去1点体力令 ${r.players[t]?.name??`P${t}`} 摸两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10});let a=r.localVars[i];delete r.localVars[i],a&&(await B(r,{type:`失去体力`,target:n,amount:1}),r.players[n]?.alive&&r.players[t]?.alive&&await B(r,{type:`摸牌`,player:t,count:2}))}let a=M(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||typeof t.player!=`number`)return;let n=e.state.players[t.player];n&&(e.state.localVars[Lx]=t.cardIds.filter(e=>n.hand.includes(e)))}),o=N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||typeof t.player!=`number`)return;if(t.voluntary===!0){delete e.state.localVars[Lx];return}let n=e.state.localVars[Lx];delete e.state.localVars[Lx],!(!n||n.length===0)&&await i(e,t.player)}),s=M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.type!==`获得`||t.from===void 0)return;let n=e.state.players[t.from];e.state.localVars[Rx]=n?.hand.includes(t.cardId)??!1}),c=N(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.type!==`获得`)return;if(t.from===void 0||typeof t.from!=`number`){delete e.state.localVars[Rx];return}let n=e.state.localVars[Rx];delete e.state.localVars[Rx],n&&await i(e,t.from)});return()=>{r(),a(),o(),s(),c()}}function Fx(e,t){return()=>{}}var Ix,Lx,Rx,zx,Nie=t((()=>{V(),F(),Ix=`奋激/confirm`,Lx=`奋激/弃置手牌快照`,Rx=`奋激/获得手牌快照`,zx={createSkill:Nx,onInit:Px,onMount:Fx}})),Pie=r({createSkill:()=>Fie,onInit:()=>Iie,onMount:()=>Lie});function Fie(e,t){return{id:e,ownerId:t,name:`奸雄`,description:`当你受到伤害后,你可以获得造成此伤害的牌`}}function Iie(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);return t?.atom.type===`请求回应`?t.atom.requestType===Bx?null:`当前不是奸雄选择`:`当前不需要回应`},async(e,t)=>{e.localVars[Hx]=t.choice===!0}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(delete e.state.localVars[Vx],(t.amount??0)<=0))return;let r=t.cardId;if(typeof r!=`string`||!e.state.cardMap[r])return;let i=e.state.cardMap[r].shadowOf??r;delete e.state.localVars[Hx],await B(e.state,{type:`请求回应`,requestType:Bx,target:n,prompt:{type:`confirm`,title:`奸雄:是否获得造成此伤害的牌?`,confirmLabel:`获得`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[Hx]===!0&&(e.state.localVars[Vx]=i),delete e.state.localVars[Hx]}),N(t,e.id,n,`移动牌`,async e=>{let t=e.state.localVars[Vx];typeof t==`string`&&e.atom.to?.zone===`弃牌堆`&&e.state.zones.discardPile.includes(t)&&e.state.cardMap[t]&&await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}})}),()=>{}}function Lie(e,t){t.defineAction(`respond`,{label:`奸雄`,style:`default`,prompt:{type:`confirm`,title:`是否发动奸雄?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var Bx,Vx,Hx,Rie=t((()=>{V(),F(),Bx=`奸雄/choose`,Vx=`奸雄/wantCard`,Hx=`奸雄/choice`})),zie=r({createSkill:()=>Ux,default:()=>$x,onInit:()=>Wx,onMount:()=>Gx});function Ux(e,t){return{id:e,ownerId:t,name:`好施`,description:`摸牌阶段,你可以额外摸两张牌,若此时你的手牌数超过五张,你必须将一半(向下取整)的手牌交给除你外手牌数最少的一名角色`}}function Wx(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==Kx&&a!==qx&&a!==Jx?`当前不是好施询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n),i=r?.atom?.requestType;if(i===Kx)e.localVars[Yx]=t.choice===!0||t.confirmed===!0;else if(i===qx){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[Zx]=n)}else if(i===Jx){let i=t.cardIds,a=(r?.atom)?.prompt?.cardFilter?.min;Array.isArray(i)&&typeof a==`number`&&i.length===a&&i.every(t=>e.players[n]?.hand.includes(t))&&(e.localVars[Qx]=i)}}),M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive||X(e.state,n,`好施`)||(delete e.state.localVars[Yx],await B(e.state,{type:`请求回应`,requestType:Kx,target:n,prompt:{type:`confirm`,title:`是否发动好施?(额外摸两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[Yx]))return;await Z(e.state,n,`好施`),e.state.localVars[Xx]=!0;let r=t.count??2;return{kind:`modify`,atom:{...e.atom,count:r+2}}}),N(t,e.id,n,`摸牌`,async e=>{if(e.atom.player!==n||!e.state.localVars[Xx])return;delete e.state.localVars[Xx];let t=e.state.players[n];if(!t?.alive)return;let r=t.hand.length;if(r<=5)return;let i=Math.floor(r/2),a=1/0,o=[];for(let t of e.state.players)t.index===n||!t.alive||(t.hand.length<a?(a=t.hand.length,o.length=0,o.push(t.index)):t.hand.length===a&&o.push(t.index));if(o.length===0)return;let s;if(o.length===1)s=o[0];else{delete e.state.localVars[Zx],await B(e.state,{type:`请求回应`,requestType:qx,target:n,prompt:{type:`choosePlayer`,title:`好施:选择手牌最少的角色(给予手牌)`,min:1,max:1,filter:(e,t)=>o.includes(t)},timeout:15});let t=e.state.localVars[Zx];if(delete e.state.localVars[Zx],typeof t!=`number`)return;s=t}delete e.state.localVars[Qx],await B(e.state,{type:`请求回应`,requestType:Jx,target:n,prompt:{type:`useCard`,title:`好施:选择 ${i} 张牌交给 ${e.state.players[s].name}`,cardFilter:{filter:()=>!0,min:i,max:i}},mandatory:!0,timeout:30});let c=e.state.localVars[Qx];if(delete e.state.localVars[Qx],(!c||c.length===0)&&(c=e.state.players[n]?.hand.slice(0,i)??[]),c&&c.length>0)for(let t of c)await B(e.state,{type:`给予`,cardId:t,from:n,to:s})}),()=>{}}function Gx(e,t){return t.defineAction(`respond`,{label:`好施`,style:`primary`,prompt:{type:`confirm`,title:`好施`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var Kx,qx,Jx,Yx,Xx,Zx,Qx,$x,Bie=t((()=>{V(),Q(),F(),Kx=`好施/confirm`,qx=`好施/target`,Jx=`好施/give`,Yx=`好施/confirmed`,Xx=`好施/active`,Zx=`好施/chosenTarget`,Qx=`好施/giveCards`,$x={createSkill:Ux,onInit:Wx,onMount:Gx}})),Vie=r({createSkill:()=>eS,default:()=>nS,onInit:()=>tS});function eS(e,t){return{id:e,ownerId:t,name:`完杀`,description:`锁定技:在你的回合,除你以外,只有处于濒死状态的角色才能使用【桃】`,isLocked:!0}}function tS(e,t){let n=e.ownerId;return M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.requestType!==`桃/求桃`||e.state.currentPlayerIndex!==n)return;let r=t.target;if(typeof r==`number`&&r!==n&&r!==e.state.players.findIndex(e=>e.alive&&e.health<=0))return{kind:`cancel`}}),()=>{}}var nS,Hie=t((()=>{F(),nS={createSkill:eS,onInit:tS}})),Uie=r({createSkill:()=>oS,default:()=>xS,onInit:()=>sS,onMount:()=>cS});function rS(e,t){return e.players[t]?.vars[uS]===`阴`?`阴`:`阳`}async function iS(e,t){await B(e,{type:`回合用量`,player:t,key:dS,value:rS(e,t)})}function Wie(e,t){let n=-1,r=[];for(let i of e.players)i.index===t||!i.alive||(i.hand.length>n?(n=i.hand.length,r.length=0,r.push(i.index)):i.hand.length===n&&r.push(i.index));return r}async function aS(e,t){let n=e.players[t];if(!n?.alive)return;let r=4-n.hand.length;r>0&&await B(e,{type:`摸牌`,player:t,count:r})}function oS(e,t){return{id:e,ownerId:t,name:lS,description:`转换技。阳:出牌阶段限一次,交给手牌数最多的其他角色一张牌并对其造成1点伤害,若其因此死亡,可令一名角色摸至四张。阴:其他角色对你造成伤害后,观看其手牌并交给其一张牌,当前回合结束阶段若其未失去此牌,你将手牌摸至四张`}}function sS(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===fS||a===hS)return null;if(a===pS){let r=t.cardIds??t.cardId,i=Array.isArray(r)?r:typeof r==`string`?[r]:void 0;if(!i||i.length===0)return null;let a=e.players[n];return i.every(e=>a.hand.includes(e))?null:`牌不在手牌中`}if(a===gS){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);return typeof n==`number`?e.players[n]?.alive?null:`目标不合法`:`需要指定一名角色`}return`当前不是审时回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===fS)e.localVars[_S]=t.choice===!0||t.confirmed===!0;else if(r===pS){let n=t.cardIds??t.cardId,r=Array.isArray(n)?n:typeof n==`string`?[n]:void 0;r&&r.length>0&&(e.localVars[vS]=r)}else if(r===hS)e.localVars[yS]=t.choice===!0||t.confirmed===!0;else if(r===gS){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[bS]=n)}}),j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,lS))return`本回合已使用过审时`;if(rS(e,n)!==`阳`)return`当前为阴状态,无法发动阳`;if(r.hand.length===0)return`需要有手牌才能发动审时`;let i=t.target;if(typeof i!=`number`)return`需要指定目标`;if(i===n)return`不能对自己发动审时`;if(!e.players[i]?.alive)return`目标不合法`;let a=Wie(e,n);if(a.length===0)return`没有可选目标`;if(!a.includes(i))return`目标必须是手牌数最多的其他角色`;let o=t.cardId;return typeof o==`string`?r.hand.includes(o)?null:`牌不在手牌中`:`需要选择一张牌`},async(e,t)=>{let r=n,i=t.target,a=t.cardId;if(await Z(e,r,lS),e.players[r].vars[uS]=`阴`,await iS(e,r),await I(e,`${lS}(阳)`,r,{target:i,cardId:a}),e.players[r].hand.includes(a)&&e.players[i]?.alive&&await B(e,{type:`给予`,cardId:a,from:r,to:i}),e.players[i]?.alive&&await Dm(e,r,i,1),!e.players[i]?.alive){if(delete e.localVars[yS],await B(e,{type:`请求回应`,requestType:hS,target:r,prompt:{type:`confirm`,title:`审时:目标因此死亡,是否令一名角色将手牌摸至四张?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:20}),e.localVars[yS]){delete e.localVars[bS],await B(e,{type:`请求回应`,requestType:gS,target:r,prompt:{type:`choosePlayer`,title:`审时:选择一名角色(将手牌摸至四张)`,min:1,max:1,candidates:e.players.filter(e=>e.alive).map(e=>e.index),filter:(t,n)=>!!e.players[n]?.alive},timeout:20});let t=e.localVars[bS];delete e.localVars[bS],typeof t==`number`&&e.players[t]?.alive&&await aS(e,t)}delete e.localVars[yS]}await L(e)}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=t.source;if(r===n||rS(e.state,n)!==`阴`||!e.state.players[n]?.alive)return;let i=e.state.players[r];if(!i?.alive)return;let a=e.state.players[n];if(!a||a.hand.length===0||(delete e.state.localVars[_S],await B(e.state,{type:`请求回应`,requestType:fS,target:n,prompt:{type:`confirm`,title:`审时(阴):是否观看其手牌并交给其一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[_S]))return;delete e.state.localVars[_S],delete e.state.localVars[vS],await B(e.state,{type:`请求回应`,requestType:pS,target:n,prompt:{type:`useCard`,title:`审时(阴):选择一张手牌交给 ${i.name}`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let o=e.state.localVars[vS];if(delete e.state.localVars[vS],!Array.isArray(o)||o.length===0)return;let s=o[0];if(!(!a.hand.includes(s)||!e.state.players[r]?.alive)&&(await B(e.state,{type:`给予`,cardId:s,from:n,to:r}),e.state.players[n].vars[uS]=`阳`,await iS(e.state,n),e.state.players[r]?.hand.includes(s))){let t=e.state.players[n].vars[mS]??[];t.push({source:r,cardId:s}),e.state.players[n].vars[mS]=t}}),N(t,e.id,n,`阶段开始`,async e=>{if(e.atom.type!==`阶段开始`||e.atom.phase!==`回合结束`)return;let t=e.state.players[n],r=t?.vars[mS];if(!(!Array.isArray(r)||r.length===0)&&(t.vars[mS]=[],t?.alive)){for(let t of r)if(e.state.players[t.source]?.hand.includes(t.cardId)){await aS(e.state,n);break}}}),N(t,e.id,n,`回合开始`,async e=>{e.atom.type===`回合开始`&&e.atom.player===n&&await iS(e.state,n)}),()=>{}}function cS(e,t){return t.defineAction(`use`,{label:lS,style:`danger`,prompt:{type:`useCardAndTarget`,title:`审时(阳):交给手牌数最多的其他角色一张牌,对其造成1点伤害`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players.find(e=>e.index===t);if(!r||r.alive===!1)return!1;let i=-1;for(let t of e.players){if(t.index===n||!t.alive)continue;let e=t.handCount??0;e>i&&(i=e)}return(r.handCount??0)===i}}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return!t||t.turnUsage?.[dS]===`阴`||(t.handCount??0)===0?!1:e.view.players.some(t=>t.index!==e.perspectiveIdx&&t.alive)}}),t.defineAction(`respond`,{label:lS,style:`primary`,prompt:{type:`confirm`,title:`审时`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var lS,uS,dS,fS,pS,mS,hS,gS,_S,vS,yS,bS,xS,Gie=t((()=>{V(),z(),Om(),Q(),J(),F(),W(),lS=`审时`,uS=`审时/态`,dS=Ul,fS=`审时/阴/confirm`,pS=`审时/阴/give`,mS=`审时/阴/追踪`,hS=`审时/阳/致死确认`,gS=`审时/阳/致死目标`,_S=`审时/阴/confirmed`,vS=`审时/阴/giveCard`,yS=`审时/阳/致死确认结果`,bS=`审时/阳/致死目标结果`,xS={createSkill:oS,onInit:sS,onMount:cS}})),Kie=r({createSkill:()=>qie,onInit:()=>Jie,onMount:()=>Yie});function qie(e,t){return{id:e,ownerId:t,name:`寒冰剑`,description:`武器:杀造成伤害时可改为依次弃目标2张牌`,isLocked:!0}}function Jie(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===`寒冰剑/confirm`)return null;if(i===`寒冰剑/选牌`){let e=t.zone;if(e===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand)`;return null}return`当前不是寒冰剑回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===`寒冰剑/confirm`?e.localVars[`寒冰剑/confirmed`]=t.choice===!0||t.confirmed===!0:r===`寒冰剑/选牌`&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.source!==n)return;let r=e.state.players[n];if(!r)return;let i=r.equipment.武器;if(!i||e.state.cardMap[i]?.name!==`寒冰剑`)return;let a=t.cardId;if(!a||e.state.cardMap[a]?.name!==`杀`)return;let o=e.state.players[t.target];if(o&&(o.hand.length>0||Object.keys(o.equipment).length>0)&&(delete e.state.localVars[`寒冰剑/confirmed`],await B(e.state,{type:`请求回应`,requestType:`寒冰剑/confirm`,target:n,prompt:{type:`confirm`,title:`寒冰剑:是否改为弃目标2张牌?`,confirmLabel:`弃牌`,cancelLabel:`正常伤害`},defaultChoice:!1,timeout:10}),e.state.localVars[`寒冰剑/confirmed`])){for(let r=0;r<2;r++){let i=e.state.players[t.target];if(!i||!(i.hand.length>0||Object.keys(i.equipment).length>0))break;await kg(e.state,n,t.target,i,{mode:`discard`,requestType:`寒冰剑/选牌`,title:`寒冰剑:选择弃置目标的牌(第${r+1}张)`,includeJudge:!1})}return delete e.state.localVars[`寒冰剑/confirmed`],{kind:`cancel`}}}),()=>{}}function Yie(e,t){t.defineAction(`respond`,{label:`寒冰剑`,style:`default`,prompt:{type:`confirm`,title:`寒冰剑:是否改为弃目标2张?`,confirmLabel:`弃牌`,cancelLabel:`正常伤害`}})}var Xie=t((()=>{V(),F(),Ag(),W()})),Zie=r({createSkill:()=>SS,default:()=>wS,onInit:()=>CS});function SS(e,t){return{id:e,ownerId:t,name:`寸目`,description:`锁定技:当你摸牌时,你改为从牌堆底摸牌`,isLocked:!0}}function CS(e,t){let n=e.ownerId;return M(t,e.id,n,`摸牌`,async e=>{if(e.atom.player===n&&!e.atom.fromBottom)return{kind:`modify`,atom:{...e.atom,fromBottom:!0}}}),()=>{}}var wS,Qie=t((()=>{F(),wS={createSkill:SS,onInit:CS}})),$ie=r({createSkill:()=>TS,default:()=>PS,onInit:()=>DS,onMount:()=>OS});function TS(e,t){return{id:e,ownerId:t,name:`屯田`,description:`回合外失去牌时判定,非红桃则置于武将牌上为田,每张田与其他角色距离 -1`}}function ES(e,t){return e.players[t].marks.filter(e=>e.id.startsWith(NS)).length}function eae(e,t){let n=ES(e,t);n>0?e.players[t].vars[Sl]=n:delete e.players[t].vars[Sl]}function DS(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===kS?null:`当前不是屯田确认`:`当前不需要回应`},async(e,t)=>{e.localVars[AS]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.player!==n||t.judgeType!==`屯田`||!e.state.localVars[AS])return;let r=R(e.state);if(r.length===0)return;let i=r[r.length-1],a=e.state.cardMap[i];if(!a||(e.state.localVars[jS]=a.suit,e.state.localVars[MS]=i,a.suit===`♥`))return;await B(e.state,{type:`收取判定牌`,player:n,cardId:i});let o=ES(e.state,n)+1,s=`${NS}${e.state.seq}`;await B(e.state,{type:`加标记`,player:n,mark:{id:s,scope:n,payload:{cardId:i}},distanceVars:{attackMod:o}}),eae(e.state,n)});async function r(e,t){e.state.currentPlayerIndex!==n&&e.state.players[n]?.alive&&e.state.zones.deck.length!==0&&(delete e.state.localVars[AS],await B(e.state,{type:`请求回应`,requestType:kS,target:n,prompt:{type:`confirm`,title:`是否发动屯田?(回合外因${t}失去牌,判定可能获得田)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[AS]&&(delete e.state.localVars[jS],delete e.state.localVars[MS],await jm(e.state,n,`屯田`),delete e.state.localVars[jS],delete e.state.localVars[MS]))}return N(t,e.id,n,`获得`,async e=>{let t=e.atom;t.type===`获得`&&t.from===n&&t.player!==n&&await r(e,`获得`)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.type===`移动牌`&&t.from.zone===`手牌`&&t.from.player===n&&(t.to.zone===`手牌`&&t.to.player===n||await r(e,`移动牌`))}),N(t,e.id,n,`给予`,async e=>{let t=e.atom;t.type===`给予`&&t.from===n&&t.to!==n&&await r(e,`给予`)}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;t.type===`弃置`&&t.player===n&&await r(e,`弃置`)}),()=>{}}function OS(e,t){t.defineAction(`respond`,{label:`屯田`,style:`primary`,prompt:{type:`confirm`,title:`是否发动屯田?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var kS,AS,jS,MS,NS,PS,tae=t((()=>{V(),z(),Fm(),F(),W(),kS=`屯田/confirm`,AS=`屯田/confirmed`,jS=`屯田/judgeSuit`,MS=`屯田/judgeCardId`,NS=`屯田/田:`,PS={createSkill:TS,onInit:DS,onMount:OS}})),nae=r({createSkill:()=>FS,default:()=>BS,onInit:()=>IS,onMount:()=>LS});function FS(e,t){return{id:e,ownerId:t,name:`崩坏`,description:`锁定技:回合结束阶段,若你的体力不是全场最少的,须减1点体力或1点体力上限`,isLocked:!0}}function IS(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===RS?null:`当前不是崩坏选择`:`当前不需要回应`},async(e,t)=>{e.localVars[zS]=t.choice===!0?`maxHealth`:`health`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`)return;let r=e.state.players[n];if(!r?.alive)return;let i=e.state.players.filter(e=>e.alive).reduce((e,t)=>Math.min(e,p(t)),1/0);if(p(r)<=i)return;delete e.state.localVars[zS],await B(e.state,{type:`请求回应`,requestType:RS,target:n,prompt:{type:`confirm`,title:`崩坏:减1点体力上限,还是减1点体力?`,confirmLabel:`减体力上限`,cancelLabel:`减体力`},defaultChoice:!1,timeout:15});let a=e.state.localVars[zS];delete e.state.localVars[zS],a===`maxHealth`?await B(e.state,{type:`设上限`,player:n,amount:r.maxHealth-1}):await B(e.state,{type:`失去体力`,target:n,amount:1})}),()=>{}}function LS(e,t){t.defineAction(`respond`,{label:`崩坏`,style:`default`,prompt:{type:`confirm`,title:`崩坏:减1点体力上限,还是减1点体力?`,confirmLabel:`减体力上限`,cancelLabel:`减体力`}})}var RS,zS,BS,rae=t((()=>{b(),V(),F(),RS=`崩坏/choose`,zS=`崩坏/choice`,BS={createSkill:FS,onInit:IS,onMount:LS}})),iae=r({createSkill:()=>VS,default:()=>iC,onInit:()=>US,onMount:()=>WS});function VS(e,t){return{id:e,ownerId:t,name:`巧变`,description:`弃一张手牌跳过阶段:摸牌阶段可从至多两名其他角色各获得一张手牌;出牌阶段可移动场上的一张牌`}}function HS(e,t){let n=e.players[t];if(!n)return[];let r=[...n.hand],i=Object.values(n.equipment).filter(e=>!!e),a=n.pendingTricks.map(e=>e.card.id);return[...r,...i,...a]}function US(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return[GS,KS,qS,JS,YS,XS].includes(a)?null:`当前不是巧变询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===GS){e.localVars[ZS]=t.choice===!0;return}if(r===KS){let n=t.cardIds,r=t.cardId,i=(Array.isArray(n)&&n.length>0?n[0]:void 0)??(typeof r==`string`?r:void 0);i&&(e.localVars[QS]=i);return}if(r===qS){let n=t.targets;Array.isArray(n)&&(e.localVars[$S]=n);return}if(r===JS){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[eC]=n);return}if(r===YS){let n=t.cardIds,r=t.cardId,i=(Array.isArray(n)&&n.length>0?n[0]:void 0)??(typeof r==`string`?r:void 0);i&&(e.localVars[tC]=i);return}if(r===XS){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[nC]=n);return}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||e.state.currentPlayerIndex!==n)return;let r=t.phase;if(!rC.includes(r))return;let i=e.state.players[n];if(!i?.alive||i.hand.length===0||E(e.state)||(delete e.state.localVars[ZS],await B(e.state,{type:`请求回应`,requestType:GS,target:n,prompt:{type:`confirm`,title:`是否发动巧变?(弃一张手牌跳过${r}阶段)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[ZS]))return;delete e.state.localVars[QS],await B(e.state,{type:`请求回应`,requestType:KS,target:n,prompt:{type:`distribute`,mode:`select`,title:`巧变:选择一张手牌弃置以跳过${r}阶段`,source:`hand`,minTotal:1,maxTotal:1},timeout:15});let a=e.state.localVars[QS];if(delete e.state.localVars[QS],!(!a||!i.hand.includes(a))){await I(e.state,`巧变`,n,{phase:r,discardCardId:a});try{if(await B(e.state,{type:`弃置`,player:n,cardIds:[a],voluntary:!0}),r===`摸牌`){let t=e.state.players.filter(e=>e.alive&&e.index!==n&&e.hand.length>0);if(t.length>0){delete e.state.localVars[$S],await B(e.state,{type:`请求回应`,requestType:qS,target:n,prompt:{type:`choosePlayer`,title:`巧变:选择至多两名其他角色(各获得其一张手牌)`,min:0,max:Math.min(2,t.length),filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0&&(e.state.players[r]?.hand.length??0)>0},timeout:20});let r=e.state.localVars[$S]??[];delete e.state.localVars[$S];for(let t of r.slice(0,2)){let r=e.state.players[t];if(!r?.alive||r.hand.length===0)continue;let i=Ud(e.state.rngSeed),a=i.nextInt(r.hand.length);e.state.rngSeed=i.getState();let o=r.hand[a];await B(e.state,{type:`获得`,player:n,cardId:o,from:t})}}}else if(r===`出牌`&&e.state.players.filter(t=>t.alive&&HS(e.state,t.index).length>0).length>0){delete e.state.localVars[eC],await B(e.state,{type:`请求回应`,requestType:JS,target:n,prompt:{type:`choosePlayer`,title:`巧变:选择源玩家(从其场上选一张牌移动)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0&&HS(e.state,n).length>0},timeout:15});let t=e.state.localVars[eC];if(delete e.state.localVars[eC],typeof t==`number`){let r=HS(e.state,t);delete e.state.localVars[tC],await B(e.state,{type:`请求回应`,requestType:YS,target:n,prompt:{type:`distribute`,mode:`select`,title:`巧变:选择 ${e.state.players[t]?.name??`P${t}`} 场上的一张牌移动`,cardIds:r,minTotal:1,maxTotal:1},timeout:15});let i=e.state.localVars[tC];if(delete e.state.localVars[tC],typeof i==`string`&&r.includes(i)){delete e.state.localVars[nC],await B(e.state,{type:`请求回应`,requestType:XS,target:n,prompt:{type:`choosePlayer`,title:`巧变:选择目标玩家(将牌移到其场上)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0},timeout:15});let r=e.state.localVars[nC];delete e.state.localVars[nC],typeof r==`number`&&await aae(e.state,t,i,r)}}}}finally{await L(e.state)}return Nh(e.state,{player:n,phase:r})}}),()=>{}}async function aae(e,t,n,r){if(t===r)return;let i=e.players[t];if(!i||!e.cardMap[n])return;let a=i.pendingTricks.find(e=>e.card.id===n);if(a){await B(e,{type:`移除延时锦囊`,player:t,trickName:a.name}),await B(e,{type:`获得`,player:r,cardId:n,from:t});return}await B(e,{type:`获得`,player:r,cardId:n,from:t})}function WS(e,t){t.defineAction(`respond`,{label:`巧变`,style:`primary`,prompt:{type:`confirm`,title:`是否发动巧变?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var GS,KS,qS,JS,YS,XS,ZS,QS,$S,eC,tC,nC,rC,iC,oae=t((()=>{V(),z(),F(),Ph(),Wd(),GS=`巧变/confirm`,KS=`巧变/discard`,qS=`巧变/steal-targets`,JS=`巧变/move-source-player`,YS=`巧变/move-source-card`,XS=`巧变/move-dest-player`,ZS=`巧变/confirmed`,QS=`巧变/discardCardId`,$S=`巧变/stealTargets`,eC=`巧变/moveSourcePlayer`,tC=`巧变/moveSourceCardId`,nC=`巧变/moveDestPlayer`,rC=[`判定`,`摸牌`,`出牌`,`弃牌`],iC={createSkill:VS,onInit:US,onMount:WS}})),sae=r({createSkill:()=>aC,default:()=>cC,onInit:()=>oC,onMount:()=>sC});function aC(e,t){return{id:e,ownerId:t,name:`巨象`,description:`锁定技:南蛮入侵对你无效;其他角色使用的南蛮入侵结算后进入弃牌堆时,你获得它`,isLocked:!0}}function oC(e,t){let n=e.ownerId;return M(t,e.id,n,`询问杀`,async e=>{if(e.atom.target===n&&Ke(e.state)?.skillId===`南蛮入侵`)return{kind:`cancel`}}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target===n&&t.cardId&&e.state.cardMap[t.cardId]?.name===`南蛮入侵`)return{kind:`cancel`}}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(!t.cardId||t.from?.zone!==`处理区`||t.to?.zone!==`弃牌堆`||e.state.cardMap[t.cardId]?.name!==`南蛮入侵`)return;let r=Ke(e.state);r?.skillId===`南蛮入侵`&&r.from!==n&&e.state.players[n]?.alive===!0&&await B(e.state,{type:`移动牌`,cardId:t.cardId,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}})}),()=>{}}function sC(e,t){}var cC,cae=t((()=>{V(),z(),F(),cC={createSkill:aC,onInit:oC,onMount:sC}}));function lC(e,t){if(t)return e.cardMap[t]}function uC(e){let t=Ke(e)?.params?.cardId;return lC(e,typeof t==`string`?t:void 0)}function dC(e,t,n,r){let i=[];return i.push(M(e,t,n,`成为目标`,async e=>{let t=e.atom;if(t.target===n&&r(e.state,lC(e.state,t.cardId),n))return{kind:`cancel`}})),i.push(M(e,t,n,`检测有效性`,async e=>{let t=e.atom;if(t.target===n&&r(e.state,lC(e.state,t.cardId),n))return{kind:`cancel`}})),i.push(M(e,t,n,`询问杀`,async e=>{if(e.atom.target===n&&r(e.state,uC(e.state),n))return{kind:`cancel`}})),i.push(M(e,t,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target===n&&r(e.state,lC(e.state,t.cardId),n))return{kind:`cancel`}})),i.push(M(e,t,n,`获得`,async e=>{let t=e.atom;if(t.from===n&&t.player!==n&&r(e.state,uC(e.state),n))return{kind:`cancel`}})),i.push(M(e,t,n,`弃置`,async e=>{if(e.atom.player===n&&r(e.state,uC(e.state),n))return{kind:`cancel`}})),i.push(M(e,t,n,`设横置`,async e=>{if(e.atom.player===n&&r(e.state,uC(e.state),n))return{kind:`cancel`}})),()=>{for(let e of i)e()}}var fC=t((()=>{z(),F()})),lae=r({createSkill:()=>pC,default:()=>hC,onInit:()=>mC});function pC(e,t){return{id:e,ownerId:t,name:`帷幕`,description:`锁定技:你不能成为黑色锦囊的目标`,isLocked:!0}}function uae(e){return!!e&&e.type===`锦囊牌`&&e.color===`黑`}function mC(e,t){let n=e.ownerId;return dC(t,e.id,n,(e,t)=>uae(t))}var hC,dae=t((()=>{fC(),hC={createSkill:pC,onInit:mC}})),fae=r({createSkill:()=>_C,default:()=>CC,onInit:()=>vC,onMount:()=>yC});function gC(e){let t=new Set;for(let n of e.players)n.alive&&n.faction&&t.add(n.faction);return Math.max(1,t.size)}function _C(e,t){return{id:e,ownerId:t,name:`庸肆`,description:`锁定技,摸牌阶段你多摸X张牌;弃牌阶段开始时你弃置X张牌(X为全场势力数)`,isLocked:!0}}function vC(e,t){let n=e.ownerId,r=M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive)return;let r=gC(e.state),i=t.count??2;return{kind:`modify`,atom:{...e.atom,count:i+r}}}),i=N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`弃牌`||t.player!==n)return;let r=e.state,i=r.players[n];if(!i?.alive)return;let a=gC(r),o=Math.min(a,i.hand.length);if(o<=0)return;delete r.localVars[xC],r.localVars[SC]=o,await B(r,{type:`请求回应`,requestType:bC,target:n,prompt:{type:`useCard`,title:`庸肆:弃置 ${o} 张牌`,cardFilter:{filter:()=>!0,min:o,max:o}},mandatory:!0,timeout:30});let s=r.players[n],c=r.localVars[xC];delete r.localVars[xC],delete r.localVars[SC],await B(r,{type:`弃置`,player:n,cardIds:Array.isArray(c)&&c.length===o&&c.every(e=>s.hand.includes(e))?c:s.hand.slice(0,o)})}),a=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是庸肆弃牌窗口`;let i=r.atom;if(i.requestType!==bC)return`当前不是庸肆弃牌窗口`;if(i.target!==n)return`不是你的庸肆弃牌`;let a=t.cardIds;if(!Array.isArray(a))return`cardIds required`;let o=e.localVars[SC];if(typeof o==`number`&&a.length!==o)return`需弃置 ${o} 张牌`;let s=e.players[n];if(!s)return`target not found`;for(let e of a)if(typeof e!=`string`||!s.hand.includes(e))return`card ${e} not in hand`;return null},async(e,t)=>{e.localVars[xC]=t.cardIds});return()=>{r(),i(),a()}}function yC(e,t){t.defineAction(`respond`,{label:`庸肆`,style:`primary`,prompt:{type:`useCard`,title:`庸肆:选择弃置的牌`,cardFilter:{filter:()=>!0,min:1,max:99}},activeWhen:e=>{let t=e.view.pending;if(!t||t.target!==e.perspectiveIdx)return!1;let n=t.atom;return n.type===`请求回应`&&n.requestType===bC}})}var bC,xC,SC,CC,pae=t((()=>{V(),F(),bC=`庸肆/弃牌`,xC=`庸肆/弃牌选择`,SC=`庸肆/弃牌数`,CC={createSkill:_C,onInit:vC,onMount:yC}}));async function wC(e,t,n){await B(e,{type:`亮身份牌前`,player:t}),await B(e,{type:`亮身份牌`,player:t}),await B(e,{type:`死亡时`,player:t,killer:n}),await B(e,{type:`系统处理牌`,player:t}),await mae(e,t,n),await B(e,{type:`死亡后`,player:t,killer:n})}async function mae(e,t,n){if(n===void 0||n===t)return;let r=e.players[n];if(!r?.alive)return;let i=e.players[t];if(i.identity===`反贼`)await B(e,{type:`摸牌`,player:n,count:3});else if(i.identity===`忠臣`&&r.identity===`主公`){let t=[...r.hand,...Object.values(r.equipment).filter(Boolean)];t.length>0&&await B(e,{type:`弃置`,player:n,cardIds:t})}}var hae=t((()=>{V()})),gae=r({canRescueWith:()=>OC,createSkill:()=>TC,onInit:()=>DC,registerSystemRespondActions:()=>EC});function TC(e,t){return{id:e,ownerId:t,name:`系统规则`,description:`引擎级规则(判定清理/技能生命周期/濒死)`}}function EC(e,t){let n=[];return n.push(j(e,`系统规则`,t,`选将`,(e,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.type!==`选将询问`)return`当前不是选将窗口`;if(r.atom.target!==t)return`不是你的选将回合`;let i=e.players[t];if(!i)return`player ${t} not found`;if(i.character)return`已选择武将,不能重新选将`;let a=n.character;return typeof a==`string`?r.atom.candidates.some(e=>e.name===a)?e.players.some(e=>e.index!==t&&e.character===a)?`该武将已被其他玩家选择`:null:`选择的武将不在候选人中`:`character required`},async(e,n)=>{let r=e.pendingSlots.get(t),i=r.atom.target,a=n.character,o=r.atom.candidates.find(e=>e.name===a);await B(e,{type:`分配武将`,target:i,character:o.name,skills:[...Tp,...o.skills]})})),n.push(j(e,`系统规则`,t,`respond`,(e,n)=>{let r=e.pendingSlots.get(t);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是弃牌窗口`;let i=r.atom;if(i.requestType!==`__弃牌`)return`当前不是弃牌窗口`;if(i.target!==t)return`不是你的弃牌回合`;let a=n.cardIds;if(!Array.isArray(a))return`cardIds required`;if(a.length===0)return`不能弃 0 张牌`;let o=e.players[i.target];if(!o)return`target not found`;for(let e of a)if(typeof e!=`string`||!o.hand.includes(e))return`card ${e} not in hand`;return null},async(e,n)=>{let r=e.pendingSlots.get(t).atom.target,i=n.cardIds;await B(e,{type:`弃置`,player:r,cardIds:i})})),()=>n.forEach(e=>e())}function DC(e,t){return N(t,`系统规则`,-1,`添加技能`,async e=>{let t=e.atom;await f9(e.state,t.skillId,t.player)}),N(t,`系统规则`,-1,`移除技能`,async e=>{let t=e.atom;d9(e.state,t.skillId,t.player)}),N(t,`系统规则`,-1,`弃置`,async e=>{let t=e.atom,n=e.state.players[t.player];if(n)for(let r of t.cardIds){let i=e.state.cardMap[r];i?.type===`装备牌`&&i?.name&&ym(i.name)&&n.skills.includes(i.name)&&await B(e.state,{type:`移除技能`,player:t.player,skillId:i.name})}}),N(t,`系统规则`,-1,`获得`,async e=>{let t=e.atom;if(t.from===void 0)return;let n=e.state.players[t.from];if(!n)return;let r=e.state.cardMap[t.cardId];r?.type===`装备牌`&&r?.name&&ym(r.name)&&n.skills.includes(r.name)&&await B(e.state,{type:`移除技能`,player:t.from,skillId:r.name})}),N(t,`系统规则`,-1,`扣减体力`,async e=>{let t=e.atom;if(typeof t.target!=`number`)return;let n=e.state.players[t.target];n&&n.alive&&n.health<=0&&await kC(e.state,t.target)}),N(t,`系统规则`,-1,`失去体力`,async e=>{let t=e.atom;if(typeof t.target!=`number`)return;let n=e.state.players[t.target];n&&n.alive&&n.health<=0&&(delete e.state.localVars[`死亡/killer`],await kC(e.state,t.target))}),N(t,`系统规则`,-1,`设上限`,async e=>{let t=e.atom;if(typeof t.player!=`number`)return;let n=e.state.players[t.player];n&&n.alive&&n.maxHealth<=0&&(delete e.state.localVars[`死亡/killer`],await wC(e.state,t.player))}),()=>{}}function OC(e,t,n){let r=t===n;return e=>!!(e.name===`桃`||e.name===`酒`&&r)}async function kC(e,t){if(await B(e,{type:`陷入濒死`,target:t}),e.localVars[`不屈/存活`]===t){delete e.localVars[`不屈/存活`];return}if(await B(e,{type:`进入濒死状态时`,target:t}),e.players[t].health>0)return;let n=e.players.length,r=e.currentPlayerIndex,i=new Set;for(;e.players[t].health<=0;){let a=!1;for(let o=0;o<n;o++){let s=(r-o+n)%n;if(!i.has(s)&&e.players[s].alive){if(i.add(s),a=!0,await B(e,{type:`请求回应`,requestType:`桃/求桃`,target:s,prompt:{type:`useCard`,title:`${e.players[t].name} 濒死,使用桃/酒救援`,cardFilter:{filter:OC(e,s,t),min:1,max:1}},timeout:15}),e.localVars[`求桃/已救`]){if(await B(e,{type:`回复体力`,target:t,amount:1,source:s}),delete e.localVars[`求桃/已救`],e.players[t].health>0)return;await B(e,{type:`新的濒死状态时`,target:t}),r=s,i=new Set,i.add(s);break}break}}if(!a)break}if(e.players[t].health<=0){let n=e.localVars[`死亡/killer`];delete e.localVars[`死亡/killer`],await wC(e,t,n)}}var AC=t((()=>{V(),F(),v9(),Np(),Sm(),hae()})),_ae=r({checkIdentityGameOver:()=>jC,default:()=>MC});function jC(e){let t=e.players.find(e=>e.identity===`主公`);if(t&&!t.alive){let t=e.players.find(e=>e.alive&&e.identity===`反贼`);if(t)return{gameOver:!0,winner:t.index};let n=e.players.find(e=>e.alive&&e.identity===`内奸`);return n?{gameOver:!0,winner:n.index}:{gameOver:!0,winner:e.players.find(e=>e.identity===`反贼`)?.index}}return t?.alive&&!e.players.find(e=>e.alive&&(e.identity===`反贼`||e.identity===`内奸`))?{gameOver:!0,winner:t.index}:e.players.filter(e=>e.alive).length<=1?{gameOver:!0,winner:e.players.find(e=>e.alive)?.index}:{gameOver:!1}}var MC,NC=t((()=>{AC(),MC={mode:`身份局`,onInit(e){DC(TC(`系统规则`,-1),e);for(let t of e.players)EC(e,t.index);return()=>{}},checkGameOver:jC,opening:{candidatesPerIdentity:{主公:7,忠臣:5,反贼:4,内奸:5},lordPickEnabled:!0}}})),vae=r({default:()=>PC}),PC,yae=t((()=>{NC(),PC={mode:`1v1`,onInit(e){return MC.onInit(e)},checkGameOver:jC,opening:{candidatesPerIdentity:{主公:5,反贼:5,忠臣:5,内奸:5},lordPickEnabled:!1}}}));function bae(e){let t=FC[e];if(!t)throw Error(`不支持的游戏模式: ${String(e)}`);return t()}var FC,IC=t((()=>{Em(),FC={身份局:async()=>(await Y(async()=>{let{default:e}=await Promise.resolve().then(()=>(NC(),_ae));return{default:e}},void 0,import.meta.url)).default,"1v1":async()=>(await Y(async()=>{let{default:e}=await Promise.resolve().then(()=>(yae(),vae));return{default:e}},void 0,import.meta.url)).default}})),xae=t((()=>{b(),qf()}));function Sae(e){return e.config?.mode??`身份局`}var Cae=t((()=>{b(),xae(),F(),v9(),wp(),Ge(),IC()})),wae=r({createSkill:()=>Dae,onInit:()=>Oae});function Tae(e){let t=new Map;for(let n of e){let e=Dc(n.name),r=t.get(e);r||(r={baseId:e,versions:[]},t.set(e,r)),r.versions.push(n)}return[...t.values()]}function LC(e){return e.flatMap(e=>e.versions.map(t=>({...t,baseId:e.baseId})))}function Eae(e){let t=[],n=[];for(let r of e){if(t.length>=zC&&n.length>=BC)break;r.versions.some(e=>Ac(e.name))?t.length<zC&&t.push(r):n.length<BC&&n.push(r)}let r=[...t,...n];if(r.length<7){let t=new Set(r.map(e=>e.baseId));for(let n of e){if(r.length>=7)break;t.has(n.baseId)||(t.add(n.baseId),r.push(n))}}return r}function Dae(e,t){return{id:e,ownerId:t,name:`开局`,description:`游戏开局:抽身份、选将、洗牌、发牌、启动第一回合`}}function Oae(e,t){return se(t,{skillId:`开局`,ownerId:RC,actionType:`start`,validate:(e,t)=>t.playerCount<2?`至少需要2名玩家`:null,execute:async(e,t)=>{let{characters:n,playerCount:r,seed:i,handSize:a=4}=t;await B(e,{type:`抽身份`,playerCount:r,seed:i});let{candidatesPerIdentity:o,lordPickEnabled:s}=(await bae(Sae(e))).opening,c=e=>o[e??``]??o.反贼??4,l=Ud(i+1),u=[...n].filter(e=>e.name!==`主公`);for(let e=u.length-1;e>0;e--){let t=l.nextInt(e+1),n=u[e];u[e]=u[t],u[t]=n}let d=Tae(u),f=e.players.findIndex(e=>e.identity===`主公`),p=new Set;if(e.charSelecting=!0,s&&f>=0){let t=Eae(d);if(t.length>0){await B(e,{type:`选将询问`,target:f,candidates:LC(t)});let n=e.players[f].character;n&&p.add(Dc(n))}}let m=s?e.players.map((e,t)=>t).filter(e=>e!==f):e.players.map((e,t)=>t);if(m.length>0){let t=d.filter(e=>!p.has(e.baseId)),n=m.map(t=>c(e.players[t].identity)),r=n.reduce((e,t)=>e+t,0);if(t.length<r)throw Error(`武将池不足: 需要 ${r} 个候选组提供给玩家,当前池中只有 ${t.length} 个`);let i=[],a=0;for(let e=0;e<m.length;e++){let r=n[e],o=t.slice(a,a+r);a+=r,i.push({target:m[e],candidates:LC(o)})}i.length>0&&await B(e,{type:`并行选将`,selections:i})}e.charSelecting=!1,await B(e,{type:`亮将`,assignments:e.players.filter(e=>e.character).map(e=>({target:e.index,character:e.character,faction:e.faction,maxHealth:e.maxHealth,health:e.health,skills:[...e.skills]}))});for(let t of e.players)for(let n of t.skills)await f9(e,n,t.index);await B(e,{type:`初始化洗牌`,seed:i}),await B(e,{type:`发牌`,handSize:a});let h=e.players.find(e=>e.identity===`主公`);h&&(await B(e,{type:`回合开始`,player:h.index}),await B(e,{type:`阶段开始`,player:h.index,phase:`准备`}),await B(e,{type:`阶段结束`,player:h.index,phase:`准备`}))}}),()=>D(t,`开局`,RC,`start`)}var RC,zC,BC,kae=t((()=>{V(),Wd(),F(),v9(),Fc(),IC(),Cae(),RC=-1,zC=5,BC=2})),Aae=r({createSkill:()=>VC,default:()=>ZC,onInit:()=>GC,onMount:()=>KC});function VC(e,t){return{id:e,ownerId:t,name:qC,description:`出牌阶段限两次:失去1点体力或弃一张武器牌,对一名本回合未以此法指定过的其他角色造成1点伤害`}}function HC(e){return!!e&&e.type===`装备牌`&&e.subtype===`武器`}function UC(e,t){let n=e.players[t]?.vars[JC];return typeof n==`number`?n:0}function WC(e,t){let n=e.players[t]?.vars[YC];return Array.isArray(n)?n:[]}function GC(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`不是出牌阶段`;if(E(e))return`当前有未回应的询问`;if(UC(e,n)>=XC)return`本阶段强袭已达上限(2次)`;let r=e.players[n];if(!r?.alive)return`已死亡`;let i=t.cost;if(i!==`hp`&&i!==`discard`)return`cost 必须为 hp 或 discard`;let a=t.target;if(typeof a!=`number`)return`需要指定目标`;if(a===n)return`不能以自己为目标`;if(!e.players[a]?.alive)return`目标不合法`;if(WC(e,n).includes(a))return`本回合已对此角色发动过强袭`;if(i===`discard`){let n=t.cardId;if(typeof n!=`string`)return`弃武器需要 cardId`;let i=e.cardMap[n];if(!HC(i))return`不是武器牌`;let a=r.hand.includes(n),o=r.equipment.武器===n;if(!a&&!o)return`武器不在手牌或装备区`}return null},async(e,t)=>{let r=n,i=t.target,a=t.cost,o=UC(e,r)+1;e.players[r].vars[JC]=o,await B(e,{type:`回合用量`,player:r,key:JC,value:o});let s=[...WC(e,r),i];if(e.players[r].vars[YC]=s,await B(e,{type:`回合用量`,player:r,key:YC,value:s}),await I(e,qC,r,{...t}),a===`hp`){if(await B(e,{type:`失去体力`,target:r,amount:1}),!e.players[r]?.alive){await L(e);return}}else{let n=t.cardId;e.players[r].equipment.武器===n&&await B(e,{type:`卸下`,player:r,slot:`武器`}),await B(e,{type:`弃置`,player:r,cardIds:[n],voluntary:!0})}await Dm(e,r,i,1),await L(e)}),()=>{}}function KC(e,t){return t.defineAction(`use`,{label:qC,style:`danger`,prompt:{type:`selectTarget`,title:`强袭:选择一名本回合未以此法指定过的角色(失去1点体力或弃武器,对其造成1点伤害)`,description:`本阶段限两次;每名角色每回合仅能被指定一次`,targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players.find(e=>e.index===t);if(!r||r.alive===!1)return!1;let i=e.players[n]?.turnUsage?.[YC];return!(Array.isArray(i)?i:[]).includes(t)}},paramVariants:[{label:`失去1点体力`,params:{cost:`hp`}},{label:`弃一张武器牌(先选中武器牌)`,params:{cost:`discard`},cardFilter:e=>HC(e)}]},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx]?.turnUsage?.[JC];return(typeof t==`number`?t:0)<XC}}),()=>{}}var qC,JC,YC,XC,ZC,jae=t((()=>{V(),z(),Om(),J(),F(),qC=`强袭`,JC=`${qC}/usedThisTurn`,YC=`${qC}/targets/usedThisTurn`,XC=2,ZC={createSkill:VC,onInit:GC,onMount:KC}})),Mae=r({createSkill:()=>QC,default:()=>sw,onInit:()=>$C,onMount:()=>ew});function Nae(e){return e?e.type===`基本牌`?!0:e.type===`锦囊牌`&&e.trickSubtype!==`延时锦囊`&&e.trickSubtype!==`响应锦囊`:!1}function QC(e,t){return{id:e,ownerId:t,name:`往烈`,description:`你出牌阶段使用的首张牌无距离限制;当你于出牌阶段使用基本牌或普通锦囊牌时,你可以令此牌不能被响应,然后你本阶段不能再使用牌`}}function $C(e,t){let n=e.ownerId,r=Jm(t,n,(e,t,r)=>!(t!==n||e.currentPlayerIndex!==n||e.phase!==`出牌`||e.turn.vars[tw])),i=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===aw?null:`当前不是往烈选择`:`当前不需要回应`},async(e,t)=>{e.localVars[ow]=t.choice===!0});N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`出牌`&&t.player===n&&(e.state.turn.vars[tw]||await B(e.state,{type:`回合用量`,player:n,key:nw,value:!0}))}),N(t,e.id,n,`使用时`,async e=>{let t=e.atom;if(t.type!==`使用时`||t.source!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`出牌`)return;e.state.turn.vars[tw]=!0,await B(e.state,{type:`回合用量`,player:n,key:nw,value:!1});let r=e.state.cardMap[t.cardId];Nae(r)&&(delete e.state.localVars[ow],await B(e.state,{type:`请求回应`,requestType:aw,target:n,prompt:{type:`confirm`,title:`是否发动往烈,令此牌不能被响应,然后本阶段不能再使用牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[ow]===!0&&(e.state.localVars[iw]=t.cardId,e.state.turn.vars[rw]=n),delete e.state.localVars[ow])});let a=M(t,e.id,n,`询问闪`,async e=>{let t=e.params?.cardId;if(t&&e.state.localVars[iw]===t)return{kind:`cancel`}}),o=M(t,e.id,n,`请求回应`,async e=>{if(e.atom.requestType!==`无懈可击`)return;let t=e.params?.cardId;if(t&&e.state.localVars[iw]===t)return{kind:`cancel`}});return N(t,e.id,n,`使用结算结束后`,async e=>{let t=e.atom;t.type===`使用结算结束后`&&t.source===n&&e.state.localVars[iw]===t.cardId&&delete e.state.localVars[iw]}),()=>{r(),i(),a(),o()}}function ew(e,t){t.defineAction(`respond`,{label:`往烈`,style:`default`,prompt:{type:`confirm`,title:`是否发动往烈,令此牌不能被响应,然后本阶段不能再使用牌?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var tw,nw,rw,iw,aw,ow,sw,Pae=t((()=>{V(),F(),Xm(),W(),tw=`往烈/首张已用`,nw=Bl,rw=`往烈/禁出牌`,iw=`往烈/不可响应`,aw=`往烈/choose`,ow=`往烈/choice`,sw={createSkill:QC,onInit:$C,onMount:ew}})),Fae=r({RONG_PREFIX:()=>vw,createSkill:()=>cw,default:()=>bw,onInit:()=>dw,onMount:()=>fw,rongCount:()=>lw});function cw(e,t){return{id:e,ownerId:t,name:`征荣`,description:`使用杀或伤害锦囊牌时,可将一名手牌数不小于你的目标角色的一张牌置于武将牌上为"荣"`}}function lw(e,t){return e.players[t].marks.filter(e=>e.id.startsWith(vw)).length}function uw(e,t){let n=e.players[t];return n.hand.length>0||Object.keys(n.equipment).length>0}function dw(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===pw)return null;if(a===mw)return typeof(t.target??t.choice)==`number`?null:`target required`;if(a===hw){let e=t.zone;if(e===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand)`;return null}return`当前不是征荣回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===pw)e.localVars[gw]=t.choice===!0||t.confirmed===!0;else if(r===mw){let n=t.target??t.choice;typeof n==`number`&&(e.localVars[_w]=n)}else r===hw&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),N(t,e.id,n,`使用时`,async e=>{let t=e.atom;if(t.type!==`使用时`||t.source!==n||!t.cardId)return;let r=e.state.cardMap[t.cardId];if(!r||!(r.name===`杀`||yw.has(r.name)))return;let i=e.state.players[n];if(!i?.alive)return;let a=Ke(e.state),o=a?.params.resolvedTargets??a?.params.targets??[],s=i.hand.length,c=o.filter(t=>t!==n&&e.state.players[t]?.alive&&e.state.players[t].hand.length>=s&&uw(e.state,t));if(c.length===0||(delete e.state.localVars[gw],await B(e.state,{type:`请求回应`,requestType:pw,target:n,prompt:{type:`confirm`,title:`是否发动征荣?(将一名手牌数不小于你的目标的一张牌置为荣)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[gw]))return;let l;if(c.length===1)l=c[0];else{delete e.state.localVars[_w],await B(e.state,{type:`请求回应`,requestType:mw,target:n,prompt:{type:`choosePlayer`,title:`征荣:选择一名目标角色`,min:1,max:1,candidates:[...c]},defaultChoice:c[0],timeout:15});let t=e.state.localVars[_w];if(typeof t!=`number`||!c.includes(t))return;l=t}let u=e.state.players[l];if(!u?.alive||!uw(e.state,l))return;let d=e.state.players[n].hand.length;await kg(e.state,n,l,u,{mode:`obtain`,requestType:hw,title:`征荣:选择该目标的一张牌置为荣`,includeJudge:!1});let f=e.state.players[n].hand[d];f&&(await B(e.state,{type:`弃置`,player:n,cardIds:[f]}),await B(e.state,{type:`加标记`,player:n,mark:{id:`${vw}${e.state.seq}`,scope:n,payload:{cardId:f}}}))}),()=>{}}function fw(e,t){t.defineAction(`respond`,{label:`征荣`,style:`default`,prompt:{type:`confirm`,title:`是否发动征荣?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var pw,mw,hw,gw,_w,vw,yw,bw,xw=t((()=>{V(),z(),F(),Ag(),W(),pw=`征荣/confirm`,mw=`征荣/选目标`,hw=`征荣/选牌`,gw=`征荣/confirmed`,_w=`征荣/目标`,vw=`征荣/荣:`,yw=new Set([`南蛮入侵`,`万箭齐发`,`火攻`,`决斗`]),bw={createSkill:cw,onInit:dw,onMount:fw}})),Iae=r({createSkill:()=>Sw,default:()=>Ow,onInit:()=>Cw,onMount:()=>ww});function Sw(e,t){return{id:e,ownerId:t,name:`志继`,description:`觉醒技:准备阶段且无手牌时,回复1体力或摸2牌,减1体力上限并永久获得"观星"`}}function Cw(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===Tw?null:`当前不是志继选择`:`当前不需要回应`},async(e,t)=>{e.localVars[Ew]=t.choice===!0?`draw`:`heal`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`准备`||t.player!==n||e.state.players[n]?.vars[Dw])return;let r=e.state.players[n];if(!r?.alive||r.hand.length>0)return;if(e.state.players[n].vars[Dw]=!0,delete e.state.localVars[Ew],await B(e.state,{type:`请求回应`,requestType:Tw,target:n,prompt:{type:`confirm`,title:`志继:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`},defaultChoice:!1,timeout:30}),e.state.localVars[Ew]===`draw`)await B(e.state,{type:`摸牌`,player:n,count:2});else{let t=e.state.players[n].health,r=e.state.players[n].maxHealth,i=Math.min(1,Math.max(0,r-t));i>0&&await B(e.state,{type:`回复体力`,target:n,amount:i})}let i=e.state.players[n].maxHealth-1;await B(e.state,{type:`设上限`,player:n,amount:i}),await B(e.state,{type:`添加技能`,player:n,skillId:`观星`})}),()=>{}}function ww(e,t){t.defineAction(`respond`,{label:`志继`,style:`primary`,prompt:{type:`confirm`,title:`志继:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`}})}var Tw,Ew,Dw,Ow,Lae=t((()=>{V(),F(),Tw=`志继/choose`,Ew=`志继/choice`,Dw=`志继/awakened`,Ow={createSkill:Sw,onInit:Cw,onMount:ww}})),Rae=r({JU_PREFIX:()=>Iw,addJu:()=>Aw,createSkill:()=>Mw,default:()=>Rw,juCount:()=>kw,onInit:()=>Nw,onMount:()=>Pw,removeJu:()=>jw});function kw(e,t){return e.players[t]?.marks.filter(e=>e.id.startsWith(Iw)).length??0}async function Aw(e,t){await B(e,{type:`加标记`,player:t,mark:{id:`${Iw}${e.seq}`,scope:t}})}async function jw(e,t,n=1){let r=e.players[t]?.marks??[],i=[];for(let e of r){if(i.length>=n)break;e.id.startsWith(Iw)&&i.push(e.id)}for(let n of i)await B(e,{type:`去标记`,player:t,markId:n})}function Mw(e,t){return{id:e,ownerId:t,name:Fw,description:`锁定技:游戏开始时获得3枚橘标记;有橘的角色受到伤害时防止伤害并移除1枚橘;有橘的角色摸牌阶段多摸一张牌`,isLocked:!0}}function Nw(e,t){let n=e.ownerId;return N(t,e.id,n,`回合开始`,async e=>{let t=e.state;t.players[n]?.alive&&(t.localVars[Lw(n)]||(t.localVars[Lw(n)]=!0,await Aw(t,n),await Aw(t,n),await Aw(t,n)))}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom.target;if(!(kw(e.state,t)<=0))return await jw(e.state,t),{kind:`cancel`}}),M(t,e.id,n,`摸牌`,async e=>{let t=e.atom,n=t.player;if(e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive||kw(e.state,n)<=0)return;let r=t.count??2;return{kind:`modify`,atom:{...t,count:r+1}}}),()=>{}}function Pw(e,t){return()=>{}}var Fw,Iw,Lw,Rw,zw=t((()=>{V(),F(),Fw=`怀橘`,Iw=`${Fw}/橘:`,Lw=e=>`${Fw}/init/${e}`,Rw={createSkill:Mw,onInit:Nw,onMount:Pw}})),zae=r({createSkill:()=>Bae,onInit:()=>Vae,onMount:()=>Hae});function Bae(e,t){return{id:e,ownerId:t,name:`急救`,description:`在你的回合外,你可以将一张红色牌当【桃】使用。`}}function Vae(e,t){let n=e.ownerId,r=de(t,n,`请求回应`,`桃/求桃`);return j(t,e.id,n,`respond`,(e,t)=>{if(e.currentPlayerIndex===n)return`急救只能在回合外使用`;let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.target!==n)return`不是问你的`;if(r.atom.type!==`请求回应`||r.atom.requestType!==`桃/求桃`)return`当前不是求桃`;let i=t.cardId;if(!i)return`cardId required`;if(!e.players[n].hand.includes(i))return`牌不在手牌中`;let a=e.cardMap[i];return a?a.color===`红`?null:`只能使用红色牌`:`牌不存在`},async(e,t)=>{let r=t.cardId;await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:n},to:{zone:`弃牌堆`}}),e.localVars[`求桃/已救`]=!0}),()=>{r()}}function Hae(e,t){t.defineAction(`respond`,{label:`急救`,style:`primary`,respondFor:`桃/求桃`,prompt:{type:`useCard`,title:`急救:将一张红色牌当桃使用`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1}}})}var Uae=t((()=>{V(),F()})),Wae=r({createSkill:()=>Bw,default:()=>qw,onInit:()=>Ww,onMount:()=>Gw});function Bw(e,t){return{id:e,ownerId:t,name:`急袭`,description:`将一张"田"当【顺手牵羊】使用`}}function Vw(e,t){return e.players[t].marks.filter(e=>e.id.startsWith(Kw)).length}function Hw(e,t){let n=Vw(e,t);n>0?e.players[t].vars[Sl]=n:delete e.players[t].vars[Sl]}function Uw(e){return`${e}#急袭`}function Ww(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.markId;if(typeof i!=`string`)return`需要选择一张田`;let a=r.marks.find(e=>e.id===i);return a?.id.startsWith(Kw)?a.payload?.cardId?null:`田缺少卡牌信息`:`指定的田不存在`},async(e,t)=>{let r=t.markId,i=e.players[n],a=i.marks.find(e=>e.id===r);if(!a)return;let o=a.payload?.cardId,s=o?e.cardMap[o]:void 0,c=Uw(r),l=Vw(e,n)-1;await B(e,{type:`去标记`,player:n,markId:r,distanceVars:{attackMod:l>0?l:void 0}});let u={id:c,name:`顺手牵羊`,suit:s?.suit??``,color:s?.color??`无色`,rank:s?.rank??`A`,type:`锦囊牌`,trickSubtype:`普通锦囊`,shadowOf:o};e.cardMap[c]=u,i.hand.push(c),Hw(e,n)},(e,t)=>{let r=t.markId,i=Uw(r),a=e.players[n],o=e.cardMap[i]?.shadowOf;delete e.cardMap[i],a.hand=a.hand.filter(e=>e!==i),a.marks.push({id:r,scope:n,payload:{cardId:o??``}}),Hw(e,n)}),()=>{}}function Gw(e,t){t.defineAction(`transform`,{label:`急袭`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`急袭:选择一张田当顺手牵羊使用`,cardFilter:{min:1,max:1},targetFilter:{min:1,max:1,filter:()=>!0}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?(t.marks??[]).some(e=>e.id.startsWith(Kw)):!1}})}var Kw,qw,Gae=t((()=>{V(),J(),F(),W(),Kw=`屯田/田:`,qw={createSkill:Bw,onInit:Ww,onMount:Gw}})),Kae=r({createSkill:()=>Yw,default:()=>iT,onInit:()=>Xw,onMount:()=>Zw});function Jw(e,t){return e.cardMap[t]?.shadowOf??t}function qae(e,t,n){let r=e.players[t]?.equipment;if(!r)return null;for(let[e,t]of Object.entries(r))if(t===n)return e;return null}function Yw(e,t){return{id:e,ownerId:t,name:Qw,description:`当你每回合首次使用一种类型的牌后,你可以将之置于牌堆顶,然后摸一张牌`}}function Xw(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===rT?null:`当前不是恃才询问`:`当前不需要回应`},async(e,t)=>{e.localVars[tT]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`使用时`,async e=>{let t=e.atom;if(t.type!==`使用时`||t.source!==n)return;let r=e.state.cardMap[t.cardId];if(!r)return;let i=r.type,a=e.state.turn.vars[$w]??[];if(a.includes(i))return;a.push(i),e.state.turn.vars[$w]=a;let o=e.state.turn.vars[eT]??[];o.push(Jw(e.state,t.cardId)),e.state.turn.vars[eT]=o,e.frame.params[nT]=r.shadowOf??t.cardId}),N(t,e.id,n,`使用结算结束后`,async e=>{let t=e.atom;if(t.type!==`使用结算结束后`||t.source!==n||!e.state.players[n]?.alive)return;let r=e.frame.params[nT]??Jw(e.state,t.cardId),i=e.state.turn.vars[eT]??[];if(!i.includes(r))return;if(e.state.turn.vars[eT]=i.filter(e=>e!==r),delete e.state.localVars[tT],await B(e.state,{type:`请求回应`,requestType:rT,target:n,prompt:{type:`confirm`,title:`是否发动恃才?(将此牌置于牌堆顶,然后摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[tT]!==!0){delete e.state.localVars[tT];return}delete e.state.localVars[tT];let a=e.state;if(a.zones.discardPile.includes(r))await B(a,{type:`移动牌`,cardId:r,from:{zone:`弃牌堆`},to:{zone:`牌堆`}});else{let e=qae(a,n,r);e&&(await B(a,{type:`卸下`,player:n,slot:e}),a.players[n]?.hand.includes(r)&&await B(a,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:n},to:{zone:`牌堆`}}))}await B(a,{type:`摸牌`,player:n,count:1})}),()=>{}}function Zw(e,t){return t.defineAction(`respond`,{label:Qw,style:`primary`,prompt:{type:`confirm`,title:`恃才`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var Qw,$w,eT,tT,nT,rT,iT,Jae=t((()=>{V(),F(),Qw=`恃才`,$w=`恃才/已用类型`,eT=`恃才/待触发`,tT=`恃才/confirmed`,nT=`恃才/effectiveCardId`,rT=`恃才/confirm`,iT={createSkill:Yw,onInit:Xw,onMount:Zw}})),Yae=r({createSkill:()=>aT,default:()=>pT,onInit:()=>oT,onMount:()=>sT});function aT(e,t){return{id:e,ownerId:t,name:`悲歌`,description:`一名角色受到杀伤害后,弃一张牌令其判定:♥回血/♦摸二/♣来源弃二/♠来源翻面`}}function oT(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;if(r.atom.requestType!==cT)return`当前不是悲歌询问`;let i=t.cardId;return typeof i==`string`?e.players[n].hand.includes(i)?null:`牌不在手牌中`:`请选择一张手牌弃置`},async(e,t)=>{e.localVars[lT]=t.cardId}),N(t,e.id,n,`判定牌生效后`,async e=>{if(e.atom.judgeType!==`悲歌`)return;let t=R(e.state);if(t.length===0)return;let n=t[t.length-1],r=e.state.cardMap[n];r&&(e.state.localVars[uT]=r.suit)}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if((t.amount??0)<=0)return;let r=t.target;if(r===void 0||!e.state.players[r]?.alive)return;let i=t.cardId;if(!i||e.state.cardMap[i]?.name!==`杀`)return;let a=e.state.players[n];if(!a?.alive||a.hand.length===0)return;delete e.state.localVars[lT],await B(e.state,{type:`请求回应`,requestType:cT,target:n,prompt:{type:`useCard`,title:`悲歌:弃置一张牌,令受伤角色判定`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let o=e.state.localVars[lT];if(delete e.state.localVars[lT],typeof o!=`string`||(await B(e.state,{type:`弃置`,player:n,cardIds:[o],voluntary:!0}),e.state.zones.deck.length===0))return;delete e.state.localVars[uT],await jm(e.state,r,`悲歌`);let s=e.state.localVars[uT];if(delete e.state.localVars[uT],s===void 0)return;let c=t.source;if(s===`♥`)e.state.players[r]?.alive&&await B(e.state,{type:`回复体力`,target:r,amount:1});else if(s===`♦`)await B(e.state,{type:`摸牌`,player:r,count:2});else if(s===`♣`){if(c===void 0)return;let t=e.state.players[c];if(!t?.alive)return;let n=t.hand.slice(0,Math.min(2,t.hand.length));n.length>0&&await B(e.state,{type:`弃置`,player:c,cardIds:n})}else if(s===`♠`){if(c===void 0||!e.state.players[c]?.alive)return;await Ch(e.state,c,`悲歌`)}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`)return;let n=t.player;if(n===void 0)return;let r=e.state.players[n];if(r){if(t.phase===`准备`&&r.tags.includes(dT))return await wh(e.state,n,`悲歌`),e.state.localVars[fT]=n,{kind:`cancel`};if(e.state.localVars[fT]===n)return{kind:`cancel`}}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`)return;let n=t.player;if(n!==void 0&&e.state.localVars[fT]===n)return delete e.state.localVars[fT],await kh(e.state,n),{kind:`cancel`}}),()=>{}}function sT(e,t){t.defineAction(`respond`,{label:`悲歌`,style:`primary`,prompt:{type:`useCard`,title:`悲歌:弃置一张牌发动`,cardFilter:{filter:e=>!0,min:1,max:1}}})}var cT,lT,uT,dT,fT,pT,Xae=t((()=>{V(),z(),Fm(),Mh(),F(),cT=`悲歌/discard`,lT=`悲歌/discardCard`,uT=`悲歌/judgeSuit`,dT=`悲歌/翻面`,fT=`悲歌/skipAll`,pT={createSkill:aT,onInit:oT,onMount:sT}})),Zae=r({createSkill:()=>_T,default:()=>DT,onInit:()=>vT,onMount:()=>yT});function mT(e,t){return e.players[t]?.vars[xT]===`阴`?`阴`:`阳`}async function hT(e,t){await B(e,{type:`回合用量`,player:t,key:ST,value:mT(e,t)})}function gT(e,t){if(!t)return!1;let n=e.cardMap[t];if(!n)return!1;let r=e.turn.vars[CT];return!Array.isArray(r)||r.length===0?!1:r.includes(n.suit)}function _T(e,t){return{id:e,ownerId:t,name:bT,description:`转换技,出牌阶段限一次。阳:摸一张牌并弃置两张手牌;阴:摸两张牌并弃置一张手牌。然后本阶段使用与弃置牌花色相同的牌无距离和次数限制`}}function vT(e,t){let n=e.ownerId,r=sh(t,n,(e,t,r)=>t===n&&gT(e,r)),i=qm(t,n,(e,t,r,i)=>t===n&&gT(e,i)),a=Jm(t,n,(e,t,r,i)=>t===n&&gT(e,i));return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==wT)return`当前不是成略弃牌`;let a=t.cardIds;if(!Array.isArray(a)||a.length===0)return`请选择要弃置的手牌`;let o=e.localVars[ET],s=e.players[n];return s?typeof o==`number`&&a.length!==o?`需弃置 ${o} 张牌`:a.every(e=>s.hand.includes(e))?new Set(a).size===a.length?null:`cardIds 含重复牌`:`牌不在手牌中`:`player not found`},async(e,t)=>{let n=t.cardIds;Array.isArray(n)&&n.length>0&&(e.localVars[TT]=n)}),j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,bT))return`本回合已使用过成略`;let i=mT(e,n),a=i===`阳`?2:1;return r.hand.length+(i===`阳`?1:2)<a?`手牌不足以发动成略`:null},async(e,t)=>{let r=n;await Z(e,r,bT);let i=mT(e,r),a=i===`阳`?1:2,o=i===`阳`?2:1;await I(e,`${bT}(${i})`,r,{drawCount:a,discardCount:o}),await B(e,{type:`摸牌`,player:r,count:a}),delete e.localVars[TT],e.localVars[ET]=o;let s=e.players[r];await B(e,{type:`请求回应`,requestType:wT,target:r,prompt:{type:`useCard`,title:`成略(${i}):选择 ${o} 张手牌弃置(本阶段同花色牌无距离和次数限制)`,cardFilter:{filter:()=>!0,min:o,max:o}},mandatory:!0,timeout:30}),delete e.localVars[ET];let c=e.localVars[TT];if(delete e.localVars[TT],(!Array.isArray(c)||c.length!==o)&&(c=(s?.hand??[]).slice(0,o)),c=c.filter(t=>e.players[r]?.hand.includes(t)),c.length===o){await B(e,{type:`弃置`,player:r,cardIds:c,voluntary:!0});let t=Array.from(new Set(c.map(t=>e.cardMap[t]?.suit).filter(e=>typeof e==`string`&&e!==``)));t.length>0&&(e.turn.vars[CT]=t,await B(e,{type:`回合用量`,player:r,key:CT,value:t}),await B(e,{type:`回合用量`,player:r,key:qc(`成略`),value:!0}))}e.players[r].vars[xT]=i===`阳`?`阴`:`阳`,await hT(e,r),await L(e)}),N(t,e.id,n,`回合开始`,async e=>{e.atom.type===`回合开始`&&e.atom.player===n&&await hT(e.state,n)}),()=>{r(),i(),a()}}function yT(e,t){return t.defineAction(`use`,{label:bT,style:`primary`,prompt:{type:`confirm`,title:`发动成略(摸牌并弃置手牌,本阶段同花色牌无距离和次数限制)`,confirmLabel:`发动`,cancelLabel:`取消`},activeWhen:e=>{if(!yh(bT)(e))return!1;let t=e.view.players[e.perspectiveIdx];return!t||t.turnUsage?.[ST]!==`阴`&&(t.handCount??0)<1?!1:q(e)}}),t.defineAction(`respond`,{label:bT,style:`primary`,prompt:{type:`useCard`,title:`成略:选择要弃置的手牌`,cardFilter:{filter:()=>!0,min:1,max:99}}}),()=>{}}var bT,xT,ST,CT,wT,TT,ET,DT,Qae=t((()=>{V(),z(),F(),Q(),J(),fh(),Xm(),W(),bT=`成略`,xT=`成略/态`,ST=Wl,CT=Pl,wT=`成略/discard`,TT=`成略/discard结果`,ET=`成略/弃牌数`,DT={createSkill:_T,onInit:vT,onMount:yT}})),$ae=r({createSkill:()=>toe,onInit:()=>noe,onMount:()=>roe});function OT(e,t){return e.players[t]?.marks.some(e=>e.id===AT)??!1}function eoe(e){let t=1/0;for(let n of e.players)n.alive&&n.hand.length<t&&(t=n.hand.length);return t}function toe(e,t){return{id:e,ownerId:t,name:`截辎`,description:`当一名角色跳过摸牌阶段后,你可以选择一名角色:若其手牌数全场最少且没有"辎",其获得"辎"标记,否则其摸一张牌。有"辎"的角色于其摸牌阶段结束时移除"辎"并执行一个额外的摸牌阶段`}}function noe(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==NT&&a!==PT?`当前不是截辎询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===NT)e.localVars[jT]=t.choice===!0||t.confirmed===!0;else if(r===PT){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[MT]=n)}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`摸牌`&&(e.state.localVars[kT]=t.player)}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`摸牌`)return;let r=t.player,i=e.state.localVars[kT]===r;if(delete e.state.localVars[kT],i){if(!OT(e.state,r)||!e.state.players[r]?.alive)return;await B(e.state,{type:`去标记`,player:r,markId:AT}),await B(e.state,{type:`阶段开始`,player:r,phase:`摸牌`}),await B(e.state,{type:`摸牌`,player:r,count:2}),delete e.state.localVars[kT];return}if(!e.state.players[n]?.alive||(delete e.state.localVars[jT],await B(e.state,{type:`请求回应`,requestType:NT,target:n,prompt:{type:`confirm`,title:`是否发动截辎?(选择一名角色:若其手牌数全场最少且没有"辎",其获得"辎"标记,否则其摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[jT]))return;delete e.state.localVars[MT],await B(e.state,{type:`请求回应`,requestType:PT,target:n,prompt:{type:`choosePlayer`,title:`截辎:选择一名角色(手牌全场最少且没"辎"→获得"辎";否则其摸一张牌)`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0},timeout:20});let a=e.state.localVars[MT];if(delete e.state.localVars[MT],typeof a!=`number`||!e.state.players[a]?.alive)return;let o=eoe(e.state);if(e.state.players[a].hand.length===o&&!OT(e.state,a)){let t={id:AT,scope:a};await B(e.state,{type:`加标记`,player:a,mark:t})}else await B(e.state,{type:`摸牌`,player:a,count:1})}),()=>{}}function roe(e,t){t.defineAction(`respond`,{label:`截辎`,style:`primary`,prompt:{type:`confirm`,title:`截辎`,confirmLabel:`确认`,cancelLabel:`取消`}})}var kT,AT,jT,MT,NT,PT,ioe=t((()=>{V(),F(),kT=`截辎/normalDrawPhase`,AT=`辎`,jT=`截辎/confirmed`,MT=`截辎/target`,NT=`截辎/confirm`,PT=`截辎/chooseTarget`})),aoe=r({createSkill:()=>ooe,onInit:()=>soe});function ooe(e,t){return{id:e,ownerId:t,name:`护甲`,description:`锁定技:受到【杀】造成的伤害时,若此牌为黑色,伤害 -1`,isLocked:!0}}function soe(e,t){let n=e.ownerId;return M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n||typeof t.cardId!=`string`)return;let r=e.state.cardMap[t.cardId];if(!r||!r.name.includes(`杀`)||r.color!==`黑`)return;let i=t.amount??0;if(!(i<=0))return{kind:`modify`,atom:{...e.atom,amount:i-1}}}),()=>{}}var coe=t((()=>{F()})),loe=r({createSkill:()=>FT,default:()=>RT,onInit:()=>IT,onMount:()=>LT});function FT(e,t){return{id:e,ownerId:t,name:`护驾`,description:`主公技:需要闪时,令其他魏势力角色替你打出闪`}}function IT(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?r.atom.type===`询问闪`?e.players[n]?.alive?e.players.some(e=>e.alive&&e.index!==n&&e.faction===`魏`&&e.hand.length>0)?null:`没有可出闪的魏势力角色`:`玩家不存在或已死亡`:`当前不是出闪窗口`:`当前不需要回应`},async(e,t)=>{let r=e.players.length;for(let t=1;t<r;t++){let i=(n+t)%r,a=e.players[i];if(!a?.alive||a.faction!==`魏`||a.hand.length===0)continue;delete e.localVars[`护驾/闪出`],await B(e,{type:`请求回应`,requestType:`护驾/出闪`,target:i,prompt:{type:`useCard`,title:`护驾:曹操(${e.players[n]?.name??`P${n}`})需要闪,是否打出一张闪?`,cardFilter:{filter:e=>e.name===`闪`,min:1,max:1}},timeout:15});let o=e.localVars[`护驾/闪出`];if(delete e.localVars[`护驾/闪出`],o&&a.hand.includes(o)){await B(e,{type:`移动牌`,cardId:o,from:{zone:`手牌`,player:i},to:{zone:`处理区`}});return}}});for(let r of t.players){let i=r.index;i!==n&&r.faction===`魏`&&j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;if(r.requestType!==`护驾/出闪`)return`当前不是护驾询问`;let a=t.cardId;if(a){if(!e.players[i].hand.includes(a))return`牌不在手牌中`;if(e.cardMap[a]?.name!==`闪`)return`只能打出闪`}return null},async(e,t)=>{let n=t.cardId;n&&(e.localVars[`护驾/闪出`]=n)})}let r=de(t,n,`询问闪`);return()=>{r()}}function LT(e,t){t.defineAction(`respond`,{label:`护驾`,style:`primary`,prompt:{type:`confirm`,title:`护驾:令魏势力角色替你出闪?`,confirmLabel:`护驾`,cancelLabel:`不发动`},activeWhen:e=>{let t=e.view.pending;if(!t||t.target!==e.perspectiveIdx)return!1;let n=t.atom;return n.type===`询问闪`||n.type===`请求回应`&&n.requestType===`护驾/出闪`}})}var RT,uoe=t((()=>{V(),F(),RT={createSkill:FT,onInit:IT,onMount:LT}})),doe=r({createSkill:()=>UT,default:()=>tE,onInit:()=>WT,onMount:()=>GT});function zT(e,t){return e.players[t]?.vars[qT]===`阴`?`阴`:`阳`}async function BT(e,t){await B(e,{type:`回合用量`,player:t,key:JT,value:zT(e,t)})}function foe(e,t,n){return!!e.turn.vars[YT]?.some(e=>e.from===t&&e.to===n)}function VT(e,t,n){let r=e.turn.vars[YT]??[];r.some(e=>e.from===t&&e.to===n)||(r.push({from:t,to:n}),e.turn.vars[YT]=r)}function HT(e,t){return t?e.cardMap[t]?.name===`杀`:!1}function UT(e,t){return{id:e,ownerId:t,name:KT,description:`转换技。阳:成为其他角色杀的目标后,你可与其各摸一张牌,然后其本回合不能再对你使用牌。阴:使用杀指定目标后,你可获得其一张牌,然后你本回合不能再对其使用牌`}}function WT(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===XT||a===ZT)return null;if(a===QT){let e=t.zone;if(e===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand)`;return null}return`当前不是拒战回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===XT?e.localVars[$T]=t.choice===!0||t.confirmed===!0:r===ZT?e.localVars[eE]=t.choice===!0||t.confirmed===!0:r===QT&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),M(t,e.id,n,`成为目标`,async e=>{let t=e.atom,n=t.source,r=t.target;if(!(typeof n!=`number`||typeof r!=`number`)&&n!==r&&foe(e.state,n,r))return{kind:`cancel`}}),N(t,e.id,n,`成为目标后`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.source;r!==n&&HT(e.state,t.cardId)&&zT(e.state,n)===`阳`&&e.state.players[n]?.alive&&e.state.players[r]?.alive&&(delete e.state.localVars[$T],await B(e.state,{type:`请求回应`,requestType:XT,target:n,prompt:{type:`confirm`,title:`拒战(阳):是否与其各摸一张牌,然后其本回合不能再对你使用牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[$T]&&(delete e.state.localVars[$T],await B(e.state,{type:`摸牌`,player:n,count:1}),e.state.players[r]?.alive&&await B(e.state,{type:`摸牌`,player:r,count:1}),VT(e.state,r,n),e.state.players[n].vars[qT]=`阴`,await BT(e.state,n)))}),N(t,e.id,n,`指定目标后`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(typeof r!=`number`||r===n||!HT(e.state,t.cardId)||zT(e.state,n)!==`阴`||!e.state.players[n]?.alive)return;let i=e.state.players[r];i?.alive&&(i.hand.length>0||Object.keys(i.equipment).length>0)&&(delete e.state.localVars[eE],await B(e.state,{type:`请求回应`,requestType:ZT,target:n,prompt:{type:`confirm`,title:`拒战(阴):是否获得其一张牌,然后你本回合不能再对其使用牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[eE]&&(delete e.state.localVars[eE],await kg(e.state,n,r,i,{mode:`obtain`,requestType:QT,title:`拒战(阴):选择从 ${i.name} 获得的一张牌`,includeJudge:!1}),VT(e.state,n,r),e.state.players[n].vars[qT]=`阳`,await BT(e.state,n)))}),N(t,e.id,n,`回合开始`,async e=>{e.atom.player===n&&await BT(e.state,n)}),()=>{}}function GT(e,t){return t.defineAction(`respond`,{label:KT,style:`primary`,prompt:{type:`confirm`,title:`拒战`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var KT,qT,JT,YT,XT,ZT,QT,$T,eE,tE,poe=t((()=>{V(),F(),Ag(),W(),KT=`拒战`,qT=`拒战/态`,JT=Kl,YT=`拒战/禁对`,XT=`拒战/阳/confirm`,ZT=`拒战/阴/confirm`,QT=`拒战/阴/选牌`,$T=`拒战/阳/confirmed`,eE=`拒战/阴/confirmed`,tE={createSkill:UT,onInit:WT,onMount:GT}})),moe=r({createSkill:()=>nE,default:()=>uE,onInit:()=>rE,onMount:()=>iE});function nE(e,t){return{id:e,ownerId:t,name:`挑衅`,description:`出牌阶段限一次:指定一名能用杀攻击到你的角色,其须对你出杀,否则你弃其一张牌`}}async function hoe(e,t,n){let r=e.players[n];if(!r)return;let i=Object.entries(r.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`})),a=r.hand.length;if(i.length===0&&a===0)return;let o=i.length>0?{zone:`equipment`,cardId:i[0].cardId}:{zone:`hand`,handIndex:0};e.localVars[lE]=n,delete e.localVars[cE];let s={type:`请求回应`,requestType:sE,target:t,prompt:{type:`pickTargetCard`,mode:`discard`,title:`挑衅:弃置 ${r.name} 的一张牌`,target:n,equipment:i,judge:[],handCount:a},defaultChoice:o,timeout:20};await B(e,s);let c=e.localVars[cE];delete e.localVars[cE],delete e.localVars[lE];let l=s.prompt.equipment??[],u=o;u.zone===`equipment`&&(l.some(e=>e.cardId===u.cardId)||(u=l.length>0?{zone:`equipment`,cardId:l[0].cardId}:{zone:`hand`,handIndex:0}));let d=c?.zone??u.zone,f;if(d===`equipment`)f=c?.cardId??u.cardId??void 0;else{let e=c?.handIndex??0;f=r.hand[e]??r.hand[0]}f&&await B(e,{type:`弃置`,player:n,cardIds:[f]})}function rE(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`挑衅`))return`本回合已使用过挑衅`;if(!e.players[n]?.alive)return`玩家不存在或已死亡`;let r=t.target;return typeof r==`number`?r===n?`不能选择自己`:e.players[r]?.alive?Gm(e,r,n)?null:`目标无法用杀攻击到你`:`目标不存在或已死亡`:`需要选择目标`},async(e,t)=>{let r=n,i=t.target;await Z(e,r,`挑衅`),await I(e,`挑衅`,r,{...t});try{await B(e,{type:`请求回应`,requestType:aE,target:i,prompt:{type:`useCardAndTarget`,title:`挑衅:对 ${e.players[r].name} 使用一张杀,否则其弃你一张牌`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>t===r}},timeout:15});let t=e.localVars[oE];delete e.localVars[oE],t?.cardId?await Lh(e,i,t.cardId,[t.target],`杀`):await hoe(e,r,i)}finally{await L(e)}});let r=[];for(let i of t.players){let a=i.index;r.push(j(t,e.id,a,`respond`,(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是挑衅询问`;let i=r.atom.requestType;if(i===aE){let r=t.cardId,i=Array.isArray(t.targets)?t.targets[0]:t.target,o=typeof i==`number`?i:void 0;return typeof r==`string`?typeof o==`number`?e.players[a]?.hand.includes(r)?e.cardMap[r]?.name===`杀`?o===n?Gm(e,a,n,r)?null:`目标不在攻击范围内`:`只能对姜维使用杀`:`只能使用杀`:`牌不在手牌中`:`请选择目标`:`请选择一张杀`}if(i===sE){let n=e.localVars[lE];if(typeof n!=`number`)return`无弃牌目标`;let i=e.players[n];if(!i)return`弃牌目标不存在`;let a=t.zone;if(a===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`;let e=r.atom?.prompt?.equipment;return e&&!e.some(e=>e.cardId===t.cardId)?`该装备不可选`:Object.values(i.equipment).includes(t.cardId)?null:`该牌不在目标装备区`}return a===`hand`?typeof t.handIndex==`number`?t.handIndex<0||t.handIndex>=i.hand.length?`handIndex 越界`:null:`handIndex required`:`zone required (equipment|hand)`}return`当前不是挑衅询问`},async(e,t)=>{let n=e.pendingSlots.get(a)?.atom?.requestType;if(n===aE){let n=Array.isArray(t.targets)?t.targets[0]:t.target;e.localVars[oE]={cardId:t.cardId,target:n}}else n===sE&&(e.localVars[cE]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}))}return()=>{for(let e of r)e()}}function iE(e,t){t.defineAction(`use`,{label:`挑衅`,style:`danger`,prompt:{type:`selectTarget`,title:`挑衅:选择一名能用杀攻击到你的角色`,description:`其须对你出杀,否则你弃其一张牌`,targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players[t];return!r||r.alive===!1?!1:lm(e.players,e.cardMap,t,n)}}},activeWhen:e=>yh(`挑衅`)(e)}),t.defineAction(`respond`,{label:`挑衅`,style:`primary`,prompt:{type:`pickTargetCard`,title:`挑衅:选择弃置的牌`,target:0,equipment:[],judge:[],handCount:0}})}var aE,oE,sE,cE,lE,uE,goe=t((()=>{V(),z(),Gh(),Q(),F(),Xm(),um(),aE=`挑衅/出杀`,oE=`挑衅/出杀选择`,sE=`挑衅/选牌`,cE=`挑衅/选牌`,lE=`挑衅/弃牌目标`,uE={createSkill:nE,onInit:rE,onMount:iE}})),_oe=r({createSkill:()=>dE,default:()=>_E,onInit:()=>fE,onMount:()=>pE});function voe(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function dE(e,t){return{id:e,ownerId:t,name:`据守`,description:`结束阶段:翻面并摸四张牌,然后弃置一张手牌(装备牌改为使用之)`}}function fE(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`弃牌`||e.phase===`回合结束`,a=!E(e),o=e.players[n]?.alive===!0,s=!X(e,n,`据守`);return r&&i&&a&&o&&s?null:`现在不能发动据守`},async(e,t)=>{await Z(e,n,`据守`),await I(e,`据守`,n,{});try{await B(e,{type:`摸牌`,player:n,count:4});let t=e.players[n];if(t.hand.length>0){delete e.localVars[gE],await B(e,{type:`请求回应`,requestType:hE,target:n,prompt:{type:`useCard`,title:`据守:选择一张手牌弃置(装备牌将改为使用)`,cardFilter:{filter:()=>!0,min:1,max:1}},mandatory:!0,timeout:20});let r=e.localVars[gE];if(delete e.localVars[gE],(!r||!t.hand.includes(r))&&(r=t.hand[0]),r&&t.hand.includes(r)){let t=e.cardMap[r],i=voe(t);if(t?.type===`装备牌`&&i){let a=e.players[n].equipment[i];if(a){let t=e.cardMap[a];t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:n,skillId:t.name}),await B(e,{type:`卸下`,player:n,slot:i}),await B(e,{type:`移动牌`,cardId:a,from:{zone:`手牌`,player:n},to:{zone:`弃牌堆`}})}await B(e,{type:`装备`,player:n,cardId:r}),t?.name&&ym(t.name)&&await B(e,{type:`添加技能`,player:n,skillId:t.name})}else await B(e,{type:`弃置`,player:n,cardIds:[r],voluntary:!0})}}}finally{await L(e)}}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?r.atom.type===`请求回应`?r.atom.requestType===hE?null:`当前不是据守弃牌窗口`:`当前不是选牌窗口`:`当前不需要回应`},async(e,t)=>{let r=Array.isArray(t.cardIds)?t.cardIds[0]:t.cardId,i=e.players[n];typeof r==`string`&&i?.hand.includes(r)&&(e.localVars[gE]=r)}),()=>{}}function pE(e,t){t.defineAction(`use`,{label:`据守`,style:`primary`,prompt:{type:`confirm`,title:`是否发动据守?(翻面摸四张,然后弃置一张手牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},activeWhen:e=>{if(e.view.currentPlayerIndex!==e.perspectiveIdx)return!1;let t=e.view.phase;if(t!==`弃牌`&&t!==`回合结束`)return!1;let n=e.view.players[e.perspectiveIdx];return!(!n||n.turnUsage?.[mE])}})}var mE,hE,gE,_E,yoe=t((()=>{V(),z(),Q(),F(),Sm(),mE=`据守/usedThisTurn`,hE=`据守/弃牌`,gE=`据守/discardChoice`,_E={createSkill:dE,onInit:fE,onMount:pE}})),boe=r({createSkill:()=>vE,default:()=>wE,onInit:()=>yE,onMount:()=>bE});function vE(e,t){return{id:e,ownerId:t,name:`掣政`,description:`锁定技:防止你出牌阶段对攻击范围内不含你的角色造成的伤害;出牌阶段结束时若用牌数少于这些角色数,弃置其中一名角色一张牌`,isLocked:!0}}function xoe(e,t){let n=[];for(let r of e.players)r.index===t||!r.alive||Gm(e,r.index,t)||n.push(r.index);return n}function Soe(e,t){let n=e.players[t];return n?n.hand.length>0?!0:Object.values(n.equipment).some(e=>!!e):!1}function yE(e,t){let n=e.ownerId;return M(t,e.id,n,`伤害结算开始时`,async e=>{let t=e.atom;if(t.source!==n)return;let r=e.state;if(r.phase===`出牌`&&r.currentPlayerIndex===n&&!Gm(r,t.target,n))return{kind:`cancel`}}),N(t,e.id,n,`使用时`,async e=>{let t=e.state;if(t.phase!==`出牌`||e.atom.source!==n)return;let r=t.turn.vars[CE]??0;t.turn.vars[CE]=r+1}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.phase!==`出牌`||t.player!==n)return;let r=e.state;if(!r.players[n]?.alive)return;let i=r.turn.vars[CE]??0,a=xoe(r,n);if(i>=a.length)return;let o=a.filter(e=>Soe(r,e));if(o.length===0)return;await I(r,`掣政`,n,{});let s;if(o.length===1)s=o[0];else{delete r.localVars[SE],await B(r,{type:`请求回应`,requestType:xE,target:n,prompt:{type:`choosePlayer`,title:`掣政:你本阶段用牌数不足,选择一名角色弃置其一张牌`,min:1,max:1,candidates:o,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:30});let e=r.localVars[SE];if(delete r.localVars[SE],typeof e!=`number`||!o.includes(e)){await L(r);return}s=e}let c=r.players[s];if(c?.alive){let e;if(c.hand.length>0){let t=Ud(r.rngSeed);e=c.hand[t.nextInt(c.hand.length)],r.rngSeed=t.getState()}else{let t=Object.values(c.equipment).filter(e=>!!e);t.length>0&&(e=t[0])}e&&await B(r,{type:`弃置`,player:s,cardIds:[e]})}await L(r)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`||r.atom.requestType!==xE)return`当前不是掣政窗口`;let i=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);return typeof i==`number`?i===n?`不能选择自己`:e.players[i]?.alive?Gm(e,i,n)?`只能选择攻击范围内不包含你的角色`:null:`目标不合法`:`请选择一名角色`},async(e,t)=>{let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[SE]=n)}),()=>{}}function bE(e,t){return()=>{}}var xE,SE,CE,wE,Coe=t((()=>{V(),z(),Xm(),F(),Wd(),xE=`掣政/选目标`,SE=`掣政/所选目标`,CE=`掣政/出牌数`,wE={createSkill:vE,onInit:yE,onMount:bE}})),woe=r({createSkill:()=>TE,default:()=>ME,onInit:()=>EE,onMount:()=>DE});function TE(e,t){return{id:e,ownerId:t,name:`攻心`,description:`出牌阶段限一次,观看一名其他角色手牌,可展示其中一张♥牌,弃置之或将之置于牌堆顶`}}function EE(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`攻心`))return`本回合已使用过攻心`;let i=t.targets;if(!Array.isArray(i)||i.length!==1)return`需要指定一名目标`;let a=i[0];if(a===n)return`不能对自己使用攻心`;let o=e.players[a];return o?.alive?o.hand.length===0?`目标没有手牌`:null:`目标不合法`},async(e,t)=>{let r=n,i=t.targets[0];await Z(e,r,`攻心`),await I(e,`攻心`,r,{target:i});let a=e.players[i].hand.map(t=>{let n=e.cardMap[t];return n?.suit===`♥`?{cardId:t,cardName:n.name,suit:n.suit,rank:n.rank}:null}).filter(e=>e!==null);if(a.length===0){await L(e);return}delete e.localVars[kE],await B(e,{type:`请求回应`,requestType:OE,target:r,prompt:{type:`pickProcessingCard`,title:`攻心:选择目标一张♥牌展示(放弃则不展示)`,cards:a},timeout:30});let o=e.localVars[kE];if(delete e.localVars[kE],!o||!e.players[i]?.hand.includes(o)){await L(e);return}await B(e,{type:`展示`,player:i,cardId:o}),delete e.localVars[jE],await B(e,{type:`请求回应`,requestType:AE,target:r,prompt:{type:`confirm`,title:`攻心:弃置此♥牌,还是将之置于牌堆顶?`,confirmLabel:`弃置`,cancelLabel:`置牌堆顶`},defaultChoice:!1,timeout:30});let s=e.localVars[jE];delete e.localVars[jE],s===`discard`?e.players[i]?.hand.includes(o)&&await B(e,{type:`弃置`,player:i,cardIds:[o]}):e.players[i]?.hand.includes(o)&&await B(e,{type:`移动牌`,cardId:o,from:{zone:`手牌`,player:i},to:{zone:`牌堆`}}),await L(e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===OE){let n=t.cardId;if(n!==void 0){let t=e.settlementStack[e.settlementStack.length-1]?.params.target;if(t===void 0||!e.players[t]?.hand.includes(n))return`该牌不在可选范围`;if(e.cardMap[n]?.suit!==`♥`)return`只能选择♥牌`}return null}return a===AE?null:`当前不是攻心回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===OE){let n=t.cardId;typeof n==`string`&&(e.localVars[kE]=n)}else r===AE&&(e.localVars[jE]=t.choice===!0?`discard`:`top`)}),()=>{}}function DE(e,t){t.defineAction(`use`,{label:`攻心`,style:`primary`,prompt:{type:`selectTarget`,title:`攻心:观看一名其他角色的手牌`,targetFilter:{min:1,max:1,filter:(t,n)=>n!==e.ownerId&&(t.players[n]?.handCount??0)>0}},activeWhen:t=>yh(`攻心`)(t)?t.view.players.some(t=>t.index!==e.ownerId&&t.alive&&(t.handCount??0)>0):!1}),t.defineAction(`respond`,{label:`攻心`,style:`primary`,prompt:{type:`pickProcessingCard`,title:`攻心:选择目标一张♥牌展示`,cards:[]}})}var OE,kE,AE,jE,ME,Toe=t((()=>{V(),z(),Q(),F(),OE=`攻心/选牌`,kE=`攻心/cardId`,AE=`攻心/选效果`,jE=`攻心/effect`,ME={createSkill:TE,onInit:EE,onMount:DE}})),Eoe=r({createSkill:()=>PE,default:()=>GE,onInit:()=>FE,onMount:()=>IE});function NE(e){e.turn.vars={};for(let t of e.players)t.marks=t.marks.filter(e=>e.duration!==`turn`),t.vars=Object.fromEntries(Object.entries(t.vars).filter(([e])=>!e.endsWith(`/usedThisTurn`)&&!e.endsWith(`/healed`)&&!e.endsWith(`/givenCount`)))}function PE(e,t){return{id:e,ownerId:t,name:`放权`,description:`跳过出牌阶段,回合结束时弃一张手牌,令一名其他角色进行一个额外回合`}}function FE(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===LE)return null;if(i===RE){let r=t.cardId;return typeof r==`string`?e.players[n].hand.includes(r)?null:`牌不在手牌中`:`请选择一张手牌弃置`}if(i===zE){let r=t.target;return typeof r==`number`?r===n?`不能选择自己`:e.players[r]?.alive?null:`目标已死亡`:`请选择一名其他角色`}return`当前不是放权回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===LE?e.localVars[BE]=t.choice===!0||t.confirmed===!0:r===RE?e.localVars[HE]=t.cardId:r===zE&&(e.localVars[UE]=t.target)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`出牌`&&e.state.currentPlayerIndex===n&&e.state.players[n]?.alive&&(delete e.state.localVars[BE],await B(e.state,{type:`请求回应`,requestType:LE,target:n,prompt:{type:`confirm`,title:`是否发动放权?(跳过出牌阶段,回合结束时弃一张手牌令其他角色额外回合)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[BE]===!0))return e.state.localVars[VE]=!0,await B(e.state,{type:`阶段结束`,player:n,phase:`出牌`}),{kind:`cancel`}}),M(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`)return;let r=e.state,i=t.player;if(typeof i==`number`){if(i===n&&r.localVars[VE]===!0){delete r.localVars[VE];let e=r.players[n];if(!e?.alive||e.hand.length===0)return;delete r.localVars[HE],await B(r,{type:`请求回应`,requestType:RE,target:n,prompt:{type:`useCard`,title:`放权:弃置一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let t=r.localVars[HE];if(delete r.localVars[HE],!t||!e.hand.includes(t))return;await B(r,{type:`弃置`,player:n,cardIds:[t],voluntary:!0}),delete r.localVars[UE],await B(r,{type:`请求回应`,requestType:zE,target:n,prompt:{type:`choosePlayer`,title:`放权:选择一名其他角色进行一个额外回合`,min:1,max:1,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:15});let i=r.localVars[UE];if(typeof i!=`number`||i===n||!r.players[i]?.alive)return;let a=r.currentPlayerIndex;return r.localVars[UE]=i,r.localVars[WE]=a,NE(r),r.currentPlayerIndex=i,await Oy(r,i),{kind:`cancel`}}if(i===r.localVars[UE]){let e=r.localVars[WE];return delete r.localVars[UE],delete r.localVars[WE],typeof e!=`number`||!r.players[e]?.alive?void 0:(NE(r),r.currentPlayerIndex=e,await Oy(r,e),{kind:`cancel`})}}}),()=>{}}function IE(e,t){t.defineAction(`respond`,{label:`放权`,style:`primary`,prompt:{type:`confirm`,title:`是否发动放权?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var LE,RE,zE,BE,VE,HE,UE,WE,GE,Doe=t((()=>{V(),ky(),F(),LE=`放权/trigger`,RE=`放权/discard`,zE=`放权/chooseTarget`,BE=`放权/triggered`,VE=`放权/active`,HE=`放权/discardCard`,UE=`放权/extraTarget`,WE=`放权/originalNext`,GE={createSkill:PE,onInit:FE,onMount:IE}})),Ooe=r({createSkill:()=>KE,default:()=>tD,onInit:()=>qE,onMount:()=>JE});function KE(e,t){return{id:e,ownerId:t,name:`放逐`,description:`受到伤害后,令一名其他角色摸 X 张牌(X=已损失体力)并翻面`}}function qE(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==YE&&a!==XE?`当前不是放逐询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===YE)e.localVars[ZE]=t.choice===!0;else if(r===XE){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[QE]=n)}}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=e.state.players[n];if(!r?.alive)return;let i=r.maxHealth-p(r);if(i<=0||!e.state.players.some(e=>e.alive&&e.index!==n)||(delete e.state.localVars[ZE],await B(e.state,{type:`请求回应`,requestType:YE,target:n,prompt:{type:`confirm`,title:`是否发动放逐?(令一名其他角色摸 ${i} 张牌并翻面)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[ZE]))return;delete e.state.localVars[QE],await B(e.state,{type:`请求回应`,requestType:XE,target:n,prompt:{type:`choosePlayer`,title:`放逐:选择一名其他角色(摸牌并翻面)`,min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0},timeout:15});let a=e.state.localVars[QE];delete e.state.localVars[QE],typeof a==`number`&&e.state.players[a]?.alive&&(await B(e.state,{type:`摸牌`,player:a,count:i}),await Ch(e.state,a,`放逐`))}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`)return;let n=t.player;if(n===void 0)return;let r=e.state.players[n];if(r){if(t.phase===`准备`&&r.tags.includes($E))return await wh(e.state,n,`放逐`),e.state.localVars[eD]=n,{kind:`cancel`};if(e.state.localVars[eD]===n)return{kind:`cancel`}}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`)return;let n=t.player;if(n!==void 0&&e.state.localVars[eD]===n)return delete e.state.localVars[eD],await kh(e.state,n),{kind:`cancel`}}),()=>{}}function JE(e,t){t.defineAction(`respond`,{label:`放逐`,style:`primary`,prompt:{type:`confirm`,title:`是否发动放逐?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var YE,XE,ZE,QE,$E,eD,tD,koe=t((()=>{b(),V(),Mh(),F(),YE=`放逐/confirm`,XE=`放逐/target`,ZE=`放逐/confirmed`,QE=`放逐/target`,$E=`放逐/翻面`,eD=`放逐/skipAll`,tD={createSkill:KE,onInit:qE,onMount:JE}})),Aoe=r({createSkill:()=>nD,default:()=>iD,onInit:()=>rD});function nD(e,t){return{id:e,ownerId:t,name:`救援`,description:`主公技,锁定技:其他吴势力角色对你使用【桃】的回复值+1`,isLocked:!0}}function rD(e,t){let n=e.ownerId;return N(t,e.id,n,`回复体力`,async e=>{let t=e.atom;if(t.target!==n||n!==0)return;let r=t.source;if(typeof r!=`number`||r===n||e.state.localVars[`求桃/已救`]!==!0)return;let i=e.state.players[r];i?.alive&&i.faction===`吴`&&await B(e.state,{type:`回复体力`,target:n,amount:1})}),()=>{}}var iD,joe=t((()=>{V(),F(),iD={createSkill:nD,onInit:rD}})),Moe=r({createSkill:()=>aD,default:()=>dD,onInit:()=>oD,onMount:()=>sD});function aD(e,t){return{id:e,ownerId:t,name:cD,description:`若你没有橘,你可以跳过摸牌阶段并获得1枚橘`}}function Noe(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function oD(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>Noe(e,n)===lD?null:`当前不是整论询问`,async(e,t)=>{e.localVars[uD]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`摸牌`||t.player!==n)return;let r=e.state;if(r.players[n]?.alive&&!(kw(r,n)>0)){if(delete r.localVars[uD],await B(r,{type:`请求回应`,requestType:lD,target:n,prompt:{type:`confirm`,title:`整论:你没有橘标记,是否跳过摸牌阶段并获得 1 枚橘?`,confirmLabel:`跳过并获橘`,cancelLabel:`正常摸牌`},defaultChoice:!1,timeout:20}),!r.localVars[uD]){delete r.localVars[uD];return}return delete r.localVars[uD],await Aw(r,n),Nh(r,{player:n,phase:`摸牌`})}}),()=>{}}function sD(e,t){return()=>{}}var cD,lD,uD,dD,Poe=t((()=>{V(),F(),Ph(),zw(),cD=`整论`,lD=`${cD}/confirm`,uD=`${cD}/confirmed`,dD={createSkill:aD,onInit:oD,onMount:sD}})),Foe=r({createSkill:()=>Ioe,onInit:()=>Loe,onMount:()=>Roe});function fD(e){return!e||e.color!==`黑`?!1:e.type===`基本牌`||e.type===`装备牌`}function Ioe(e,t){return{id:e,ownerId:t,name:`断粮`,description:`将一张黑色基本牌或装备牌当【兵粮寸断】使用;对手牌数不小于你的角色无距离限制`}}function Loe(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n];if(!o?.alive)return`玩家不存在或已死亡`;if(typeof t.cardId!=`string`)return`需要选择一张牌`;if(typeof t.target!=`number`)return`需要选择目标`;if(!o.hand.includes(t.cardId))return`牌不在手牌中`;if(!fD(e.cardMap[t.cardId]))return`需要黑色基本牌或装备牌`;let s=t.target;if(s===n)return`不能对自己使用`;let c=e.players[s];if(!c?.alive)return`目标不存在或已死亡`;if(c.pendingTricks.some(e=>e.name===pD))return`目标判定区已有兵粮寸断`;let l=c.hand.length>=o.hand.length||Wm(e,n,s)<=1;return r&&i&&a&&l?null:`断粮使用条件不满足`},async(e,t)=>{let r=n,i=t.cardId,a=t.target;await I(e,`断粮`,r,{...t}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`处理区`}}),await B(e,{type:`添加延时锦囊`,player:a,trick:{name:pD,source:r,card:e.cardMap[i]??{id:i,name:pD,suit:`♣`,color:`黑`,rank:`A`,type:`锦囊牌`}}}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await L(e)}),()=>{}}function Roe(e,t){t.defineAction(`use`,{label:`断粮`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`断粮:将黑色基本牌/装备牌当兵粮寸断使用`,cardFilter:{filter:e=>fD(e),min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players[t];if(!r||r.alive===!1)return!1;let i=e.players[n]?.handCount??0;return(r.handCount??0)>=i?!0:cm(e.players,n,t)<=1}}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>fD(e))??!1:!1}})}var pD,zoe=t((()=>{V(),z(),J(),F(),Xm(),um(),pD=`兵粮寸断`})),Boe=r({createSkill:()=>mD,default:()=>_D,onInit:()=>hD});function mD(e,t){return{id:e,ownerId:t,name:`断肠`,description:`杀死你的角色立即失去所有技能直到游戏结束(装备仍生效)`,isLocked:!0}}function hD(e,t){let n=e.ownerId;return N(t,e.id,n,`死亡时`,async e=>{let t=e.atom;if(t.type!==`死亡时`||t.player!==n)return;let r=t.killer;if(r===void 0||r===n)return;let i=e.state.players[r];if(!i?.alive)return;let a=new Set;for(let t of Object.values(i.equipment)){if(!t)continue;let n=e.state.cardMap[t]?.name;n&&a.add(n)}let o=i.skills.filter(e=>!gD.has(e)&&!a.has(e));for(let t of o)await B(e.state,{type:`移除技能`,player:r,skillId:t})}),()=>{}}var gD,_D,Voe=t((()=>{V(),F(),Np(),gD=new Set(Tp),_D={createSkill:mD,onInit:hD}})),Hoe=r({createSkill:()=>yD,default:()=>wD,onInit:()=>bD,onMount:()=>xD});function vD(e){let t=new Set;for(let n of e.players)n.character&&t.add(n.character);return t}function Uoe(e,t){let n=vD(e),r=ll(e.players[t]?.vars)??[],i=new Set([...n,...r]),a=wc.map(e=>e.name).filter(e=>!i.has(e));if(a.length===0)return null;let o=Ud(e.rngSeed),s=o.nextInt(a.length);return e.rngSeed=o.getState(),a[s]}function yD(e,t){return{id:e,ownerId:t,name:`新生`,description:`每当你受到 1 点伤害后,你可以获得一张新的化身牌`}}function bD(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===SD?typeof t.choice==`boolean`?null:`需要 choice(布尔)`:`当前不是新生询问`:`当前不需要回应`},async(e,t)=>{e.localVars[CD]=t.choice===!0}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=e.state;if(!r.players[n]?.alive||Woe(r,n)===null)return;delete r.localVars[CD],await B(r,{type:`请求回应`,requestType:SD,target:n,prompt:{type:`confirm`,title:`新生:是否获得一张新的化身牌?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!1,timeout:30});let i=r.localVars[CD];if(delete r.localVars[CD],i!==!0)return;let a=Uoe(r,n);if(a===null)return;let o=r.players[n],s=ll(o.vars)??[];s.push(a),o.vars[bl]=s}),()=>{}}function Woe(e,t){let n=vD(e),r=ll(e.players[t]?.vars)??[],i=new Set([...n,...r]),a=wc.map(e=>e.name).filter(e=>!i.has(e));return a.length>0?a[0]:null}function xD(e,t){t.defineAction(`respond`,{label:`新生`,style:`passive`,prompt:{type:`confirm`,title:`新生:是否获得一张新的化身牌?`,confirmLabel:`获得`,cancelLabel:`不获得`}})}var SD,CD,wD,Goe=t((()=>{V(),F(),Ec(),Wd(),W(),SD=`新生/confirm`,CD=`新生/choice`,wD={createSkill:yD,onInit:bD,onMount:xD}})),Koe=r({createSkill:()=>qoe,onInit:()=>Joe});function qoe(e,t){return{id:e,ownerId:t,name:`方天画戟`,description:`武器:最后一张手牌为杀时可指定最多3个目标`,isLocked:!0}}function Joe(e,t){let n=e.ownerId;return qh(t,n,(e,t,r)=>{let i=e.players[n]?.equipment.武器;return!i||e.cardMap[i]?.name!==`方天画戟`||e.players[n]?.hand?.length!==1?0:3})}var Yoe=t((()=>{Xh()})),Xoe=r({createSkill:()=>TD,default:()=>DD,onInit:()=>ED});function TD(e,t){return{id:e,ownerId:t,name:`无双`,description:`锁定技:你使用【杀】的目标需连续出两张【闪】才能抵消;与你【决斗】的角色每次需连续打出两张【杀」`,isLocked:!0}}function Zoe(e,t){return`无双/dodgeCount/${e}/${t}`}function Qoe(e,t){return`无双/duelCount/${e}/${t}`}function ED(e,t){let n=e.ownerId;return N(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n||!e.state.players[n]?.skills.includes(`无双`))return;let r=t.target,i=$oe(e.state);if(e.state.cardMap[i]?.name!==`杀`||!Je(e.state,i,r))return;let a=Zoe(i,r),o=e.state.localVars[a]??0;if(o>=1){delete e.state.localVars[a];return}Ye(e.state,i,r),e.state.localVars[a]=o+1,await B(e.state,{type:`询问闪`,target:r,source:n}),delete e.state.localVars[a]}),N(t,e.id,n,`询问杀`,async e=>{let t=e.atom;if(t.source!==n||!e.state.players[n]?.skills.includes(`无双`))return;let r=e.state.settlementStack[e.state.settlementStack.length-1]?.params?.cardId;if(!r||e.state.cardMap[r]?.name!==`决斗`)return;let i=t.target,a=Qoe(r,i),o=e.state.localVars[a]??0;if(o>=1){delete e.state.localVars[a];return}(await og(e.state)).length!==0&&(e.state.localVars[a]=o+1,await B(e.state,{type:`询问杀`,target:i,source:n}),delete e.state.localVars[a])}),()=>{}}function $oe(e){return e.settlementStack[e.settlementStack.length-1]?.params?.cardId??``}var DD,ese=t((()=>{V(),F(),z(),ug(),DD={createSkill:TD,onInit:ED}})),tse=r({REN_MARK_ID:()=>PD,createSkill:()=>AD,default:()=>BD,getRenCardId:()=>OD,getRenColor:()=>kD,onInit:()=>jD,onMount:()=>MD});function OD(e,t){let n=e.players[t]?.marks.find(e=>e.id===PD)?.payload?.cardId;return typeof n==`string`?n:void 0}function kD(e,t){let n=OD(e,t);if(n)return e.cardMap[n]?.color}async function nse(e,t){let n=e.players[t];if(!n?.alive||n.hand.length===0)return;delete e.localVars[RD],await B(e,{type:`请求回应`,requestType:ID,target:t,prompt:{type:`useCard`,title:`明任:选择一张手牌置为"任"`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let r=e.localVars[RD];if(delete e.localVars[RD],!Array.isArray(r)||r.length===0)return;let i=r[0];n.hand.includes(i)&&(await B(e,{type:`弃置`,player:t,cardIds:[i]}),await B(e,{type:`加标记`,player:t,mark:{id:PD,scope:t,payload:{cardId:i}}}))}function AD(e,t){return{id:e,ownerId:t,name:ND,description:`游戏开始时摸两张牌并将一张手牌置为"任";结束阶段可用手牌替换"任"`}}function jD(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===LD)return null;if(a===ID){let r=t.cardIds??t.cardId,i=Array.isArray(r)?r:typeof r==`string`?[r]:void 0;if(!i||i.length===0)return null;let a=e.players[n];return i.every(e=>a.hand.includes(e))?null:`牌不在手牌中`}return`当前不是明任回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===LD)e.localVars[zD]=t.choice===!0||t.confirmed===!0;else if(r===ID){let n=t.cardIds??t.cardId,r=Array.isArray(n)?n:typeof n==`string`?[n]:void 0;r&&r.length>0&&(e.localVars[RD]=r)}}),N(t,e.id,n,`回合开始`,async e=>{let t=e.state;t.localVars[FD(n)]||t.players[n]?.alive&&(t.localVars[FD(n)]=!0,await B(t,{type:`摸牌`,player:n,count:2}),await nse(t,n))}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n)return;let r=e.state,i=r.players[n];if(!i?.alive||!OD(r,n)||i.hand.length===0||(delete r.localVars[zD],await B(r,{type:`请求回应`,requestType:LD,target:n,prompt:{type:`confirm`,title:`明任:是否用手牌替换"任"?`,confirmLabel:`替换`,cancelLabel:`不替换`},defaultChoice:!1,timeout:15}),!r.localVars[zD]))return;delete r.localVars[zD],delete r.localVars[RD],await B(r,{type:`请求回应`,requestType:ID,target:n,prompt:{type:`useCard`,title:`明任:选择一张手牌替换"任"`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let a=r.localVars[RD];if(delete r.localVars[RD],!Array.isArray(a)||a.length===0)return;let o=a[0];i.hand.includes(o)&&(await B(r,{type:`去标记`,player:n,markId:PD}),await B(r,{type:`弃置`,player:n,cardIds:[o]}),await B(r,{type:`加标记`,player:n,mark:{id:PD,scope:n,payload:{cardId:o}}}))}),()=>{}}function MD(e,t){return t.defineAction(`respond`,{label:ND,style:`primary`,prompt:{type:`useCard`,title:`明任:选择一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}}}),()=>{}}var ND,PD,FD,ID,LD,RD,zD,BD,VD=t((()=>{V(),F(),ND=`明任`,PD=`明任/任`,FD=e=>`${ND}/init/${e}`,ID=`${ND}/选牌`,LD=`${ND}/confirm`,RD=`${ND}/选牌结果`,zD=`${ND}/confirmed`,BD={createSkill:AD,onInit:jD,onMount:MD}})),rse=r({createSkill:()=>HD,default:()=>qD,onInit:()=>UD,onMount:()=>WD});function HD(e,t){return{id:e,ownerId:t,name:`暴虐`,description:`主公技:其他群雄角色造成伤害后,可判定,黑桃则回复1点体力`}}function UD(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===GD?null:`当前不是暴虐确认`:`当前不需要回应`},async(e,t)=>{e.localVars[KD]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom,r=e.state.players[n];if(!r?.alive||r.identity!==`主公`||(t.amount??0)<=0)return;let i=t.source;if(typeof i!=`number`||i===n||i<0)return;let a=e.state.players[i];a?.alive&&a.faction===`群`&&(delete e.state.localVars[KD],await B(e.state,{type:`请求回应`,requestType:GD,target:n,prompt:{type:`confirm`,title:`暴虐:${a.name} 造成伤害,是否进行判定?(黑桃回复1点体力)`,confirmLabel:`判定`,cancelLabel:`不判定`},defaultChoice:!1,timeout:10}),e.state.localVars[KD]&&await jm(e.state,n,`暴虐`))}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.judgeType!==`暴虐`||t.player!==n)return;let r=R(e.state);if(r.length===0)return;let i=r[r.length-1],a=e.state.cardMap[i];a&&a.suit===`♠`&&e.state.players[n]?.alive&&await B(e.state,{type:`回复体力`,target:n,amount:1})}),()=>{}}function WD(e,t){t.defineAction(`respond`,{label:`暴虐`,style:`default`,prompt:{type:`confirm`,title:`是否发动暴虐?(判定,黑桃回复1点体力)`,confirmLabel:`判定`,cancelLabel:`不发动`}})}var GD,KD,qD,ise=t((()=>{V(),z(),Fm(),F(),GD=`暴虐/confirm`,KD=`暴虐/confirmed`,qD={createSkill:HD,onInit:UD,onMount:WD}})),ase=r({createSkill:()=>QD,default:()=>iO,onInit:()=>$D,onMount:()=>eO});function JD(e){return!!e&&e.name===`杀`&&(!e.damageType||e.damageType===`普通`)}function YD(e){return`${e}#朱雀羽扇`}function XD(e){return`${rO}${e}`}function ZD(e,t){let n=XD(t);if(!(n in e.localVars))return;let r=e.localVars[n];delete e.localVars[n];let i=e.cardMap[t];i&&(r===null?delete i.damageType:i.damageType=r)}function QD(e,t){return{id:e,ownerId:t,name:`朱雀羽扇`,description:`你可将一张普通杀当火杀使用或打出。`}}function $D(e,t){let n=e.ownerId,r=[];return r.push(j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o?.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&!!o&&o.hand.includes(c);return r&&i&&a&&s&&d&&JD(u)?null:`现在不能使用朱雀羽扇`},async(e,t)=>{let r=t.cardId,i=YD(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`杀`,outputDamageType:`火焰`})},(e,t)=>{let r=t.cardId,i=YD(r);delete e.cardMap[i],e.players[n].hand=e.players[n].hand.map(e=>e===i?r:e)})),r.push(j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===tO?null:`当前不是朱雀羽扇询问`:`当前不需要回应`},async(e,t)=>{e.localVars[nO]=t.choice===!0})),r.push(N(t,e.id,n,`使用时`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.cardId;if(!r)return;let i=e.state.cardMap[r];if(!JD(i))return;let a=e.state.players[n];if(!a)return;let o=a.equipment.武器;if(!o||e.state.cardMap[o]?.name!==`朱雀羽扇`)return;delete e.state.localVars[nO],await B(e.state,{type:`请求回应`,requestType:tO,target:n,prompt:{type:`confirm`,title:`朱雀羽扇:是否发动,将此【杀】改为火【杀】?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10});let s=e.state.localVars[nO]===!0;delete e.state.localVars[nO],s&&(e.state.localVars[XD(r)]=i.damageType??null,i.damageType=`火焰`)})),r.push(N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.from?.zone!==`处理区`)return;let n=t.cardId;typeof n==`string`&&ZD(e.state,n)})),()=>{for(let e of r)e();for(let e of Object.keys(t.localVars))e.startsWith(rO)&&ZD(t,e.slice(14))}}function eO(e,t){t.defineAction(`transform`,{label:`朱雀羽扇`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`朱雀羽扇:将普通【杀】当火【杀】使用`,cardFilter:{filter:e=>e.name===`杀`&&(!e.damageType||e.damageType===`普通`),min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>t!==e.currentPlayerIndex}},activeWhen:e=>q(e)&&sm(e.view,e.perspectiveIdx)}),t.defineAction(`respond`,{label:`朱雀羽扇`,style:`default`,prompt:{type:`confirm`,title:`朱雀羽扇:是否发动,将此【杀】改为火【杀】?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var tO,nO,rO,iO,ose=t((()=>{V(),F(),J(),tO=`朱雀羽扇/confirm`,nO=`朱雀羽扇/confirmed`,rO=`朱雀羽扇/origType:`,iO={createSkill:QD,onInit:$D,onMount:eO}})),sse=r({createSkill:()=>aO,default:()=>lO,onInit:()=>sO,onMount:()=>cO});function aO(e,t){return{id:e,ownerId:t,name:`枭姬`,description:`失去装备区的牌时,你可以摸两张牌`}}async function oO(e,t,n){for(let r=0;r<n;r++){if(!e.players[t]?.alive)return;delete e.localVars[`枭姬/confirmed`],await B(e,{type:`请求回应`,requestType:`枭姬/confirm`,target:t,prompt:{type:`confirm`,title:`是否发动枭姬?(摸两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!0,timeout:10}),e.localVars[`枭姬/confirmed`]&&await B(e,{type:`摸牌`,player:t,count:2})}}function sO(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?r.atom.type!==`请求回应`||r.atom.requestType!==`枭姬/confirm`?`当前不是枭姬窗口`:null:`当前不需要回应`},async(e,t)=>{e.localVars[`枭姬/confirmed`]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`卸下`,async e=>{e.atom.player===n&&await oO(e.state,n,1)}),M(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.player!==n)return;let r=new Set(Object.values(e.state.players[n].equipment).filter(e=>typeof e==`string`)),i=(t.cardIds??[]).filter(e=>r.has(e)).length;i>0&&(e.state.localVars[`枭姬/弃置loss`]=i)}),N(t,e.id,n,`弃置`,async e=>{if(e.atom.player!==n)return;let t=e.state.localVars[`枭姬/弃置loss`];t&&(delete e.state.localVars[`枭姬/弃置loss`],await oO(e.state,n,t))}),M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.from!==n)return;let r=new Set(Object.values(e.state.players[n].equipment).filter(e=>typeof e==`string`));t.cardId&&r.has(t.cardId)&&(e.state.localVars[`枭姬/获得loss`]=1)}),N(t,e.id,n,`获得`,async e=>{if(e.atom.from!==n)return;let t=e.state.localVars[`枭姬/获得loss`];t&&(delete e.state.localVars[`枭姬/获得loss`],await oO(e.state,n,t))}),()=>{}}function cO(e,t){t.defineAction(`respond`,{label:`枭姬`,style:`default`,prompt:{type:`confirm`,title:`是否发动枭姬?(摸两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var lO,cse=t((()=>{V(),F(),lO={createSkill:aO,onInit:sO,onMount:cO}})),lse=r({createSkill:()=>use,onInit:()=>dse,onMount:()=>fse});function use(e,t){return{id:e,ownerId:t,name:`武圣`,description:`你可以将一张红色牌当【杀】使用或打出`}}function uO(e){return`${e}#武圣`}function dse(e,t){let n=e.ownerId,r=j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a),l=!!s&&s.color===`红`,u=e.currentPlayerIndex===n,d=!E(e),f=e.pendingSlots.get(n),p=f?.atom?.type,m=f?.atom?.requestType,h=f?.atom?.target;return i&&c&&l&&(u&&d||f&&h===n&&(p===`询问杀`||p===`请求回应`&&m===`杀/respondKill`))?null:`现在不能使用武圣`},async(e,t)=>{let r=t.cardId,i=uO(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`杀`})},(e,t)=>{let r=t.cardId,i=uO(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),i=de(t,n,`询问杀`);return()=>{i(),r()}}function fse(e,t){t.defineAction(`transform`,{label:`武圣`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张红色牌当杀使用`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t?.alive||!(t.hand?.some(e=>e.color===`红`)??!1))return!1;let n=q(e)&&sm(e.view,e.perspectiveIdx),r=e.view.pending,i=r?.atom?.type,a=r?.atom?.requestType,o=!!r&&r.target===e.perspectiveIdx&&(i===`询问杀`||i===`请求回应`&&a===`杀/respondKill`);return n||o}})}var pse=t((()=>{F(),V(),um(),J()})),mse=r({createSkill:()=>dO,default:()=>SO,onInit:()=>fO,onMount:()=>pO});function dO(e,t){return{id:e,ownerId:t,name:`武烈`,description:`限定技,结束阶段,你可以失去任意点体力,令等量的其他角色各获得1个「烈」标记。有「烈」的角色受到伤害时,防止此伤害,然后移去「烈」`}}function fO(e,t){let n=e.ownerId,r=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==hO&&a!==gO&&a!==_O)return`当前不是武烈询问`;if(a===gO){let r=typeof t.option==`string`?Number(t.option):t.hpCount,i=e.players[n]?.health??0,a=typeof r==`number`?r:NaN;if(!Number.isInteger(a)||a<1||a>i)return`请选择 1-${i} 之间的整数`}if(a===_O){let n=e.localVars[yO],r=t.targets;if(!Array.isArray(r)||typeof n!=`number`||r.length!==n)return`请选择 ${n??`?`} 名其他角色`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===hO)e.localVars[vO]=t.choice===!0||t.confirmed===!0;else if(r===gO){let n=typeof t.option==`string`?Number(t.option):t.hpCount;typeof n==`number`&&Number.isInteger(n)&&n>=1&&(e.localVars[yO]=n)}else if(r===_O){let n=t.targets;Array.isArray(n)&&(e.localVars[bO]=n)}}),i=N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`)return;let r=e.state,i=r.players[n];if(!i?.alive||i.vars[mO]||i.health<1)return;let a=r.players.filter(e=>e.alive&&e.index!==n);if(a.length===0)return;if(delete r.localVars[vO],await B(r,{type:`请求回应`,requestType:hO,target:n,prompt:{type:`confirm`,title:`是否发动武烈?(限定技)`,description:`结束阶段:失去任意点体力,令等量其他角色各获得1个「烈」标记`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!r.localVars[vO]){delete r.localVars[vO];return}delete r.localVars[vO];let o=Math.min(i.health,a.length);delete r.localVars[yO],await B(r,{type:`请求回应`,requestType:gO,target:n,prompt:{type:`chooseOption`,title:`武烈:失去几点体力?(1-${o})`,description:`失去 N 点体力,令 N 名其他角色各获得1个「烈」标记`,options:Array.from({length:o},(e,t)=>({value:String(t+1),label:`失去 ${t+1} 点体力`}))},defaultChoice:!1,timeout:20});let s=r.localVars[yO];if(delete r.localVars[yO],typeof s!=`number`||s<1||s>o)return;let c=Math.min(s,a.length);delete r.localVars[bO],r.localVars[yO]=c,await B(r,{type:`请求回应`,requestType:_O,target:n,prompt:{type:`choosePlayer`,title:`武烈:选择 ${c} 名其他角色(各获1个「烈」标记)`,min:c,max:c,filter:(e,t)=>t!==n&&r.players[t]?.alive===!0},timeout:30});let l=r.localVars[bO];if(delete r.localVars[bO],delete r.localVars[yO],!(!Array.isArray(l)||l.length!==c)&&(r.players[n].vars[mO]=!0,await B(r,{type:`失去体力`,target:n,amount:s}),r.players[n]?.alive))for(let e of l)r.players[e]?.alive&&await B(r,{type:`加标记`,player:e,mark:{id:xO,scope:e,payload:{source:n}}})}),a=M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(typeof t.target!=`number`||(t.amount??0)<=0)return;let n=e.state,r=t.target,i=n.players[r];if(i?.alive&&i.marks.some(e=>e.id===xO))return await B(n,{type:`去标记`,player:r,markId:xO}),{kind:`cancel`}});return()=>{r(),i(),a()}}function pO(e,t){return()=>{}}var mO,hO,gO,_O,vO,yO,bO,xO,SO,hse=t((()=>{V(),F(),mO=`武烈/used`,hO=`武烈/confirm`,gO=`武烈/hp`,_O=`武烈/choose`,vO=`武烈/confirmed`,yO=`武烈/hpCount`,bO=`武烈/targets`,xO=`武烈/烈`,SO={createSkill:dO,onInit:fO,onMount:pO}})),gse=r({createSkill:()=>_se,onInit:()=>yse,onMount:()=>bse});function _se(e,t){return{id:e,ownerId:t,name:`洛神`,description:`准备阶段判定:黑色获得判定牌并重复,直到红色或停止`}}function vse(e){return!!e&&(e.suit===`♠`||e.suit===`♣`)}function yse(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{if(e.pendingSlots.get(n)?.atom.type!==`请求回应`)return`当前不需要回应`;let r=e.pendingSlots.get(n).atom.requestType;return r!==`洛神/confirm`&&r!==`洛神/continue`?`当前不是洛神询问`:null},async(e,t)=>{e.localVars[`洛神/confirmed`]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.player!==n||t.judgeType!==`洛神`)return;let r=R(e.state);if(r.length===0){e.state.localVars[`洛神/lastResult`]=`red`;return}let i=r[r.length-1],a=e.state.cardMap[i];e.state.localVars[`洛神/lastJudgeCardId`]=i,e.state.localVars[`洛神/lastResult`]=vse(a)?`black`:`red`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||!e.state.players[n]?.alive||e.state.zones.deck.length===0||(delete e.state.localVars[`洛神/confirmed`],await B(e.state,{type:`请求回应`,requestType:`洛神/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动洛神?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`洛神/confirmed`]))return;let r=!0;for(;r&&e.state.zones.deck.length!==0;){await jm(e.state,n,`洛神`);let t=e.state.localVars[`洛神/lastResult`],i=e.state.localVars[`洛神/lastJudgeCardId`];if(delete e.state.localVars[`洛神/lastResult`],delete e.state.localVars[`洛神/lastJudgeCardId`],t!==`black`||!i)break;await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}}),delete e.state.localVars[`洛神/confirmed`],await B(e.state,{type:`请求回应`,requestType:`洛神/continue`,target:n,prompt:{type:`confirm`,title:`判定为黑色,是否继续洛神?`,confirmLabel:`继续`,cancelLabel:`停止`},defaultChoice:!0,timeout:10}),r=e.state.localVars[`洛神/confirmed`]!==!1}delete e.state.localVars[`洛神/confirmed`]}),()=>{}}function bse(e,t){t.defineAction(`respond`,{label:`洛神`,style:`default`,prompt:{type:`confirm`,title:`是否发动洛神?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var xse=t((()=>{V(),z(),Fm(),F()})),Sse=r({createSkill:()=>Cse,onInit:()=>wse,onMount:()=>Tse});function Cse(e,t){return{id:e,ownerId:t,name:`流离`,description:`当你成为杀的目标时,可弃一张牌,将此杀转移给攻击范围内一名其他角色`}}function wse(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{if(e.pendingSlots.get(n)?.atom.type!==`请求回应`)return`当前不需要回应`;let r=e.pendingSlots.get(n).atom.requestType;if(r!==`流离/confirm`&&r!==`流离/chooseTarget`&&r!==`流离/pickDiscard`)return`当前不是流离回应`;if(r===`流离/chooseTarget`){let r=t.target;if(typeof r!=`number`)return`请选择转移目标`;if(r===n)return`不能转移给自己`;if(r===e.localVars[`流离/来源`])return`不能转移给杀的来源`;if(!e.players[r]?.alive)return`目标不存活`;if(!Gm(e,n,r))return`目标不在你的攻击范围内`}if(r===`流离/pickDiscard`){let r=t.cardIds??t.cardId,i=Array.isArray(r)?r:typeof r==`string`?[r]:void 0;if(!i||i.length===0)return null;if(i.length!==1)return`请选择弃置的 1 张手牌`;let a=i[0];if(typeof a!=`string`||!e.players[n].hand.includes(a))return`弃置牌不在你的手牌中`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===`流离/confirm`)e.localVars[`流离/confirmed`]=t.choice===!0||t.confirmed===!0;else if(r===`流离/pickDiscard`){let n=t.cardIds??t.cardId,r=Array.isArray(n)?n:typeof n==`string`?[n]:void 0;e.localVars[`流离/discard`]=r?.[0]}else e.localVars[`流离/target`]=t.target}),N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.cardId;if(!r||e.state.cardMap[r]?.name!==`杀`)return;let i=e.state.players[n];if(!i||i.hand.length===0||(delete e.state.localVars[`流离/confirmed`],e.state.localVars[`流离/来源`]=t.source,await B(e.state,{type:`请求回应`,requestType:`流离/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动流离?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`流离/confirmed`]))return;delete e.state.localVars[`流离/target`],await B(e.state,{type:`请求回应`,requestType:`流离/chooseTarget`,target:n,prompt:{type:`choosePlayer`,title:`流离:选择转移目标`,min:1,max:1,filter:(r,i)=>i!==n&&i!==t.source&&r.players[i]?.alive===!0&&Gm(e.state,n,i)},timeout:15});let a=e.state.localVars[`流离/target`];if(typeof a!=`number`||a===n)return;delete e.state.localVars[`流离/discard`],await B(e.state,{type:`请求回应`,requestType:`流离/pickDiscard`,target:n,prompt:{type:`useCard`,title:`流离:弃置 1 张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let o=e.state.players[n],s=e.state.localVars[`流离/discard`];if(delete e.state.localVars[`流离/discard`],typeof s!=`string`||!o.hand.includes(s)){delete e.state.localVars[`流离/target`],delete e.state.localVars[`流离/来源`];return}let c=s;await B(e.state,{type:`弃置`,player:n,cardIds:[c],voluntary:!0});let l=e.frame.params.resolvedTargets;if(l){let e=l.indexOf(n);e>=0&&(l[e]=a)}delete e.state.localVars[`流离/confirmed`],delete e.state.localVars[`流离/target`],delete e.state.localVars[`流离/来源`]}),()=>{}}function Tse(e,t){t.defineAction(`respond`,{label:`流离`,style:`default`,prompt:{type:`confirm`,title:`是否发动流离?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var Ese=t((()=>{V(),F(),Xm()})),Dse=r({createSkill:()=>CO,default:()=>AO,onInit:()=>wO,onMount:()=>TO});function CO(e,t){return{id:e,ownerId:t,name:`涅槃`,description:`限定技:濒死时弃置所有牌和判定区牌,重置武将牌,摸三张并回复至3点体力`}}function wO(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===EO?null:`当前不是涅槃确认`:`当前不需要回应`},async(e,t)=>{e.localVars[DO]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`陷入濒死`,async e=>{if(e.atom.target!==n||e.state.players[n]?.vars[OO])return;let t=e.state.players[n];if(!t||t.health>0||(delete e.state.localVars[DO],await B(e.state,{type:`请求回应`,requestType:EO,target:n,prompt:{type:`confirm`,title:`是否发动涅槃?(限定技:弃所有牌,摸3张,回复至3体力)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[DO]))return;e.state.players[n].vars[OO]=!0;let r=e.state.players[n],i=[...r.hand],a=Object.values(r.equipment).filter(e=>typeof e==`string`),o=r.pendingTricks.map(e=>({trickName:e.name,cardId:e.card.id}));for(let{trickName:t}of o)await B(e.state,{type:`移除延时锦囊`,player:n,trickName:t});let s=o.map(e=>e.cardId).filter(t=>et(e.state,t)===null),c=[...i,...a,...s];c.length>0&&await B(e.state,{type:`弃置`,player:n,cardIds:c}),e.state.players[n].marks.some(e=>e.id===`chained`)&&await Th(e.state,n,!1),await B(e.state,{type:`摸牌`,player:n,count:3});let l=e.state.players[n].health,u=Math.max(0,kO-l);u>0&&await B(e.state,{type:`回复体力`,target:n,amount:u})}),()=>{}}function TO(e,t){t.defineAction(`respond`,{label:`涅槃`,style:`primary`,prompt:{type:`confirm`,title:`是否发动涅槃?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var EO,DO,OO,kO,AO,Ose=t((()=>{V(),Mh(),rt(),F(),EO=`涅槃/confirm`,DO=`涅槃/confirmed`,OO=`涅槃/used`,kO=3,AO={createSkill:CO,onInit:wO,onMount:TO}})),kse=r({createSkill:()=>MO,default:()=>BO,onInit:()=>NO,onMount:()=>PO});function jO(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function MO(e,t){return{id:e,ownerId:t,name:`涯角`,description:`每当你于回合外使用或打出手牌时,你可以展示牌堆顶的一张牌,若这两张牌的类别相同,你可以将牌堆顶的一张牌交给一名角色;若不同,你可以弃置攻击范围内包含你的一名角色区域里的一张牌。`}}function NO(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=jO(e,n);if(r!==LO&&r!==RO&&r!==zO)return`当前不是涯角询问`;if(r===zO){let e=t.zone;if(e===`equipment`||e===`judge`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|judge|hand)`}return null},async(e,t)=>{let r=jO(e,n);r===LO?e.localVars[FO]=t.choice===!0||t.confirmed===!0:r===RO?e.localVars[IO]=t.target??null:r===zO&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.from.zone!==`手牌`||t.from.player!==n||t.to.zone!==`处理区`||e.state.currentPlayerIndex===n||!e.state.players[n]?.alive)return;let r=e.state.zones.deck;if(r.length===0||(delete e.state.localVars[FO],await B(e.state,{type:`请求回应`,requestType:LO,target:n,prompt:{type:`confirm`,title:`是否发动涯角?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[FO]))return;let i=r[r.length-1];await B(e.state,{type:`展示`,player:n,cardId:i});let a=e.state.cardMap[t.cardId],o=e.state.cardMap[i];if(a?.type===o?.type){delete e.state.localVars[IO],await B(e.state,{type:`请求回应`,requestType:RO,target:n,prompt:{type:`choosePlayer`,title:`涯角:将牌堆顶牌交给一名角色`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0},timeout:15});let t=e.state.localVars[IO];typeof t==`number`&&await B(e.state,{type:`摸牌`,player:t,count:1})}else{delete e.state.localVars[IO],await B(e.state,{type:`请求回应`,requestType:RO,target:n,prompt:{type:`choosePlayer`,title:`涯角:选择攻击范围内包含你的一名角色,弃其一张牌`,min:1,max:1,filter:(t,r)=>e.state.players[r]?.alive===!0&&Gm(e.state,r,n)},timeout:20});let t=e.state.localVars[IO];if(delete e.state.localVars[IO],typeof t!=`number`)return;let r=e.state.players[t];if(!r?.alive)return;await kg(e.state,n,t,r,{mode:`discard`,requestType:zO,title:`涯角:选择要从 ${r.name} 区域弃置的一张牌`})}delete e.state.localVars[FO],delete e.state.localVars[IO]}),()=>{}}function PO(e,t){t.defineAction(`respond`,{label:`涯角`,style:`primary`,prompt:{type:`confirm`,title:`是否发动涯角?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var FO,IO,LO,RO,zO,BO,Ase=t((()=>{V(),F(),Xm(),Ag(),W(),FO=`涯角/confirmed`,IO=`涯角/target`,LO=`涯角/confirm`,RO=`涯角/target`,zO=`涯角/discard`,BO={createSkill:MO,onInit:NO,onMount:PO}})),jse=r({createSkill:()=>VO,default:()=>tk,onInit:()=>HO,onMount:()=>UO});function VO(e,t){return{id:e,ownerId:t,name:`溃诛`,description:`弃牌阶段结束时,选择一项:令至多X名角色各摸一张牌,或对体力值之和为X的角色各造成1点伤害(X为本阶段弃牌数)`}}function HO(e,t){let n=e.ownerId;return N(t,e.id,n,`弃置`,async e=>{if(e.state.phase!==`弃牌`||e.atom.player!==n)return;let t=e.state.localVars[ZO]??0;e.state.localVars[ZO]=t+e.atom.cardIds.length}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.phase!==`弃牌`||t.player!==n)return;let r=e.state;if(!r.players[n]?.alive)return;let i=r.localVars[ZO]??0;if(delete r.localVars[ZO],i<=0)return;r.localVars[XO]=i,await I(r,`溃诛`,n,{X:i}),delete r.localVars[qO],await B(r,{type:`请求回应`,requestType:WO,target:n,prompt:{type:`chooseOption`,title:`溃诛:你本阶段弃置了 ${i} 张牌,选择一项`,options:[{value:QO,label:`令至多 ${i} 名角色各摸一张牌`},{value:$O,label:`对体力值之和为 ${i} 的角色各造成 1 点伤害`},{value:ek,label:`不发动`}]},timeout:30});let a=r.localVars[qO];if(delete r.localVars[qO],a!==QO&&a!==$O){delete r.localVars[XO],await L(r);return}if(a===QO){delete r.localVars[JO],await B(r,{type:`请求回应`,requestType:GO,target:n,prompt:{type:`choosePlayer`,title:`溃诛:选择 1 至 ${i} 名角色各摸一张牌`,min:1,max:i,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:30});let e=r.localVars[JO]??[];delete r.localVars[JO];for(let t of e)r.players[t]?.alive&&await B(r,{type:`摸牌`,player:t,count:1})}else{delete r.localVars[YO],await B(r,{type:`请求回应`,requestType:KO,target:n,prompt:{type:`choosePlayer`,title:`溃诛:选择体力值之和为 ${i} 的角色(各造成 1 点伤害)`,min:1,max:i,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:30});let e=r.localVars[YO]??[];delete r.localVars[YO];for(let t of e)r.players[t]?.alive&&await Dm(r,n,t,1)}delete r.localVars[XO],await L(r)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是溃诛窗口`;let i=r.atom,a=e.localVars[XO]??0;if(i.requestType===WO){let e=t.option;return e!==QO&&e!==$O&&e!==ek?`请选择一项`:null}if(i.requestType===GO){let r=t.targets;if(!Array.isArray(r)||r.length===0)return`请选择至少一名角色`;if(r.length>a)return`至多选择 ${a} 名角色`;if(new Set(r).size!==r.length)return`targets 含重复座次`;for(let t of r){if(t===n)return`不能选择自己`;if(!e.players[t]?.alive)return`目标不合法`}return null}if(i.requestType===KO){let r=t.targets;if(!Array.isArray(r)||r.length===0)return`请选择至少一名角色`;if(r.length>a)return`至多选择 ${a} 名角色`;if(new Set(r).size!==r.length)return`targets 含重复座次`;let i=0;for(let t of r){if(t===n)return`不能选择自己`;if(!e.players[t]?.alive)return`目标不合法`;i+=p(e.players[t])}return i===a?null:`所选角色体力值之和(${i})须等于 ${a}`}return`当前不是溃诛窗口`},async(e,t)=>{let r=e.pendingSlots.get(n).atom;r.requestType===WO?e.localVars[qO]=t.option:r.requestType===GO?e.localVars[JO]=t.targets:r.requestType===KO&&(e.localVars[YO]=t.targets)}),()=>{}}function UO(e,t){return()=>{}}var WO,GO,KO,qO,JO,YO,XO,ZO,QO,$O,ek,tk,Mse=t((()=>{V(),z(),Om(),F(),b(),WO=`溃诛/选择`,GO=`溃诛/摸牌选目标`,KO=`溃诛/伤害选目标`,qO=`溃诛/选项`,JO=`溃诛/摸牌目标`,YO=`溃诛/伤害目标`,XO=`溃诛/X`,ZO=`溃诛/弃牌数`,QO=`摸牌`,$O=`伤害`,ek=`不发动`,tk={createSkill:VO,onInit:HO,onMount:UO}})),Nse=r({createSkill:()=>Pse,onInit:()=>Fse,onMount:()=>Ise});function Pse(e,t){return{id:e,ownerId:t,name:`激将`,description:`主公技,其他蜀势力角色可以在你需要时代替你使用或打出【杀】(视为由你使用或打出)`}}function Fse(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n].alive===!0,s=n===0,c=t.target,l=typeof c==`number`&&!!e.players[c],u=l?e.players[c]:null,d=c!==n,f=u?.alive===!0,p=u?.faction===`蜀`,m=t.killTarget,h=m===void 0||e.players[m]?.alive===!0&&m!==c;return r&&i&&a&&o&&s&&l&&d&&f&&p&&h?null:`现在不能使用激将`},async(e,t)=>{let r=n,i=t.target,a=t.killTarget;await I(e,`激将`,r,{...t}),typeof a==`number`&&(e.localVars[ik]=a),await B(e,{type:`请求回应`,requestType:nk,target:i,prompt:{type:`useCardAndTarget`,title:`激将:对 ${typeof a==`number`?e.players[a]?.name??`?`:`?`} 使用一张杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>typeof a==`number`?t===a:t!==i}},timeout:15});let o=e.localVars[rk];delete e.localVars[rk],delete e.localVars[ik],o?.cardId&&Array.isArray(o.targets)&&o.targets.length>0&&await Lh(e,i,o.cardId,o.targets,`杀`),await L(e)});let r=[];r.push(de(t,n,`询问杀`));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type===`询问杀`)return e.players[i]?.alive?i===0?e.players.some(e=>e.alive&&e.index!==i&&e.faction===`蜀`&&e.hand.length>0)?null:`没有可出杀的蜀势力角色`:`仅主公可用`:`玩家不存在或已死亡`;if(r.requestType===nk){let n=t.cardId,r=t.targets;if(typeof n!=`string`)return`请选择一张杀`;if(!Array.isArray(r)||r.length===0)return`请选择目标`;if(!e.players[i]?.hand.includes(n))return`牌不在手牌中`;if(e.cardMap[n]?.name!==`杀`)return`只能使用杀`;let a=e.localVars[ik];if(typeof a==`number`&&!r.includes(a))return`必须包含激将指定的目标`;for(let t of r)if(!Gm(e,i,t,n))return`目标不在攻击范围内`;return null}return`当前不是激将询问`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom;if(n?.type===`询问杀`){let t=e.players.length;for(let n=1;n<t;n++){let r=(i+n)%t,a=e.players[r];if(a?.alive&&a.faction===`蜀`&&a.hand.length!==0&&(await B(e,{type:`请求回应`,requestType:`杀/respondKill`,target:r,prompt:{type:`useCard`,title:`激将:主公(${e.players[i]?.name??`P${i}`})需要杀,是否打出一张杀?`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},timeout:15}),R(e).find(t=>e.cardMap[t]?.name===`杀`)))return}return}n?.requestType===nk&&(e.localVars[rk]={cardId:t.cardId,targets:t.targets})}))}return()=>{for(let e of r)e()}}function Ise(e,t){return t.defineAction(`use`,{label:`激将`,style:`primary`,prompt:{type:`choosePlayer`,title:`激将:选择一名蜀势力角色出杀`,min:1,max:1,filter:(t,n)=>n!==e.ownerId&&t.players[n]?.alive===!0&&t.players[n]?.faction===`蜀`},activeWhen:t=>q(t)&&im(e.ownerId)}),t.defineAction(`respond`,{label:`激将`,style:`primary`,prompt:{type:`confirm`,title:`激将:令蜀势力角色替你打出杀?`,confirmLabel:`激将`,cancelLabel:`不发动`},activeWhen:e=>{let t=e.view.pending;if(!t||t.target!==e.perspectiveIdx)return!1;let n=t.atom;return n.type===`询问杀`||n.requestType===nk}}),()=>{}}var nk,rk,ik,Lse=t((()=>{V(),z(),Gh(),F(),Xm(),J(),nk=`激将/出杀`,rk=`激将/出杀选择`,ik=`激将/killTarget`})),Rse=r({createSkill:()=>ak,default:()=>uk,onInit:()=>ok,onMount:()=>sk});function zse(e){return`激昂/src/${e}`}function Bse(e,t){let n=t?e.cardMap[t]:void 0;if(n?.name===`决斗`||n?.name===`杀`&&n.color===`红`)return!0;let r=Ke(e)?.skillId;return r===`决斗`||r===`离间`}function ak(e,t){return{id:e,ownerId:t,name:`激昂`,description:`使用或被使用【决斗】或红色【杀】时,你可以摸一张牌`}}function ok(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===ck?null:`当前不是激昂确认`:`当前不需要回应`},async(e,t)=>{e.localVars[lk]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if((t.source===n||t.target===n)&&e.state.players[n]?.alive&&Bse(e.state,t.cardId)){if(t.source===n){let n=zse(t.cardId??`__virtual__`);if(e.state.localVars[n])return;e.state.localVars[n]=!0}delete e.state.localVars[lk],await B(e.state,{type:`请求回应`,requestType:ck,target:n,prompt:{type:`confirm`,title:`是否发动激昂?(摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[lk]&&await B(e.state,{type:`摸牌`,player:n,count:1})}}),()=>{}}function sk(e,t){t.defineAction(`respond`,{label:`激昂`,style:`primary`,prompt:{type:`confirm`,title:`是否发动激昂?(摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var ck,lk,uk,Vse=t((()=>{V(),z(),F(),ck=`激昂/confirm`,lk=`激昂/confirmed`,uk={createSkill:ak,onInit:ok,onMount:sk}})),Hse=r({createSkill:()=>dk,default:()=>hk,onInit:()=>pk,onMount:()=>mk});function dk(e,t){return{id:e,ownerId:t,name:`火计`,description:`你可以将一张红色手牌当【火攻】使用`}}function fk(e){return`${e}#火计`}function pk(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=!!u&&u.color===`红`;return r&&i&&a&&s&&d&&f?null:`现在不能使用火计`},async(e,t)=>{let r=t.cardId,i=fk(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`火攻`})},(e,t)=>{let r=t.cardId,i=fk(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),()=>{}}function mk(e,t){t.defineAction(`transform`,{label:`火计`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张红色牌当火攻使用`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>(e.players[t]?.handCount??0)>0}},transform:t=>({name:`火攻`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.color===`红`)??!1:!1}})}var hk,Use=t((()=>{F(),V(),J(),hk={createSkill:dk,onInit:pk,onMount:mk}})),Wse=r({createSkill:()=>gk,default:()=>Tk,onInit:()=>_k,onMount:()=>vk});function Gse(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function gk(e,t){return{id:e,ownerId:t,name:`烈刃`,description:`使用杀造成伤害后,可与受害者拼点,赢则获得对方一张牌`}}function _k(e,t){let n=e.ownerId,r=[];for(let i of t.players){let a=i.index,o=j(t,e.id,a,`respond`,(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let o=i.requestType;if(o===yk)return a===n?null:`只有祝融可以确认`;if(o===xk){if(a!==n)return`只有祝融可以选择拼点牌`;let r=t.cardId;return typeof r==`string`?e.players[a].hand.includes(r)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`}if(o===Ck){let n=t.cardId;return typeof n==`string`?e.players[a].hand.includes(n)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`}return`当前不是烈刃回应`},async(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return;let r=n.atom.requestType;r===yk?e.localVars[bk]=t.choice===!0||t.confirmed===!0:r===xk?e.localVars[Sk]=t.cardId:r===Ck&&(e.localVars[wk]=t.cardId)});r.push(o)}return N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0||t.target===void 0||t.target===n)return;let r=t.cardId;if(!r||e.state.cardMap[r]?.name!==`杀`)return;let i=t.target,a=e.state.players[i];if(!a?.alive)return;let o=e.state.players[n];if(!o||o.hand.length===0||a.hand.length===0||(delete e.state.localVars[bk],await B(e.state,{type:`请求回应`,requestType:yk,target:n,prompt:{type:`confirm`,title:`是否发动烈刃,与 ${a.name} 拼点?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[bk])||e.state.players[n].hand.length===0||e.state.players[i].hand.length===0)return;delete e.state.localVars[Sk],await B(e.state,{type:`请求回应`,requestType:xk,target:n,prompt:{type:`useCard`,title:`烈刃:请选择一张拼点牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let s=e.state.localVars[Sk];if(!s||!e.state.players[n].hand.includes(s))return;delete e.state.localVars[wk],await B(e.state,{type:`请求回应`,requestType:Ck,target:i,prompt:{type:`useCard`,title:`烈刃:与 ${e.state.players[n].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let c=e.state.localVars[wk];delete e.state.localVars[wk],await I(e.state,`烈刃`,n,{victim:i});let l=e.state.cardMap[s],u=l?Gse(l.rank):0,d;if(c&&e.state.players[i].hand.includes(c)?d=await xb(e.state,n,i,s,c)===`赢`:(await B(e.state,{type:`移动牌`,cardId:s,from:{zone:`手牌`,player:n},to:{zone:`弃牌堆`}}),d=u>0),await L(e.state),!d)return;let f=e.state.players[i];if(f)if(f.hand.length>0){let t=Ud(e.state.rngSeed),r=f.hand[t.nextInt(f.hand.length)];e.state.rngSeed=t.getState(),await B(e.state,{type:`获得`,player:n,cardId:r,from:i})}else{let t=Object.keys(f.equipment)[0];if(t){let r=f.equipment[t];r&&await B(e.state,{type:`获得`,player:n,cardId:r,from:i})}}}),()=>{r.forEach(e=>e())}}function vk(e,t){t.defineAction(`respond`,{label:`烈刃`,style:`danger`,prompt:{type:`confirm`,title:`是否发动烈刃?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var yk,bk,xk,Sk,Ck,wk,Tk,Kse=t((()=>{V(),z(),Sb(),F(),Wd(),yk=`烈刃/confirm`,bk=`烈刃/confirmed`,xk=`烈刃/选牌`,Sk=`烈刃/ownerCard`,Ck=`烈刃/拼点`,wk=`烈刃/victimCard`,Tk={createSkill:gk,onInit:_k,onMount:vk}})),qse=r({createSkill:()=>Jse,onInit:()=>Yse,onMount:()=>Xse});function Jse(e,t){return{id:e,ownerId:t,name:`烈弓`,description:`使用杀指定目标后,若其手牌数不小于你的体力值或不大于你的攻击范围,可令其不能抵消此杀`}}function Yse(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===`烈弓/confirm`?null:`当前不是烈弓确认`:`当前不是请求回应`},async(e,t)=>{e.localVars[Dk]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0)return;let r=t.target;if(t.cardId!==void 0&&e.state.cardMap[t.cardId]?.name!==`杀`)return;let i=e.state.players[n],a=e.state.players[r];if(!i?.alive||!a?.alive)return;let o=ol(i.vars)??1;(a.hand.length>=p(i)||a.hand.length<=o)&&(delete e.state.localVars[Dk],await B(e.state,{type:`请求回应`,requestType:`烈弓/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动烈弓(令目标不能出闪)?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[Dk]&&await B(e.state,{type:`加标签`,player:r,tag:Ek}))}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r!==void 0&&e.state.players[r]?.tags.includes(Ek))return await B(e.state,{type:`去标签`,player:r,tag:Ek}),{kind:`cancel`}}),()=>{}}function Xse(e,t){t.defineAction(`respond`,{label:`烈弓`,style:`default`,prompt:{type:`confirm`,title:`是否发动烈弓?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var Ek,Dk,Zse=t((()=>{b(),V(),F(),W(),Ek=`烈弓/禁闪`,Dk=`烈弓/confirmed`})),Qse=r({createSkill:()=>Ok,default:()=>Mk,onInit:()=>kk,onMount:()=>Ak});function Ok(e,t){return{id:e,ownerId:t,name:jk,description:`锁定技:每回合首次成为其他角色杀或决斗的目标后,若其手牌数不小于你,此牌对你无效`,isLocked:!0}}function kk(e,t){let n=e.ownerId;return M(t,e.id,n,`检测有效性`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.source;if(r===void 0||r===n)return;let i=t.cardId;if(!i)return;let a=e.state.cardMap[i];if(!a||a.name!==`杀`&&a.name!==`决斗`||X(e.state,n,jk))return;await Z(e.state,n,jk);let o=e.state.players[r],s=e.state.players[n];if(!(!o||!s)&&o.hand.length>=s.hand.length)return{kind:`cancel`}}),()=>{}}function Ak(e,t){return()=>{}}var jk,Mk,$se=t((()=>{F(),Q(),jk=`父荫`,Mk={createSkill:Ok,onInit:kk,onMount:Ak}})),ece=r({createSkill:()=>Nk,default:()=>Bk,onInit:()=>Pk,onMount:()=>Fk});function Nk(e,t){return{id:e,ownerId:t,name:`狂骨`,description:`对距离1以内的角色每造成1点伤害后,你可以回复1点体力或摸一张牌`}}function Pk(e,t){let n=e.ownerId,r=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==Ik&&a!==Lk?`当前不是狂骨询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===Ik?e.localVars[Rk]=t.choice===!0||t.confirmed===!0:r===Lk&&(e.localVars[zk]=t.choice===!0?`heal`:`draw`)});return N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.amount??0;if(r<=0||t.target===void 0)return;let i=t.target;if(e.state.players[i]?.alive&&!(Wm(e.state,n,i)>1))for(let t=0;t<r;t++){if(!e.state.players[n]?.alive)return;delete e.state.localVars[Rk],await B(e.state,{type:`请求回应`,requestType:Ik,target:n,prompt:{type:`confirm`,title:`是否发动狂骨?(第 ${t+1}/${r} 点伤害)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),e.state.localVars[Rk]===!0&&(delete e.state.localVars[zk],await B(e.state,{type:`请求回应`,requestType:Lk,target:n,prompt:{type:`confirm`,title:`狂骨:回复1点体力,或摸一张牌?`,confirmLabel:`回复1点体力`,cancelLabel:`摸一张牌`},defaultChoice:!1,timeout:30}),e.state.localVars[zk]===`heal`?await B(e.state,{type:`回复体力`,target:n,amount:1}):await B(e.state,{type:`摸牌`,player:n,count:1}))}}),()=>{r()}}function Fk(e,t){}var Ik,Lk,Rk,zk,Bk,tce=t((()=>{V(),F(),Xm(),Ik=`狂骨/confirm`,Lk=`狂骨/choose`,Rk=`狂骨/confirmed`,zk=`狂骨/choice`,Bk={createSkill:Nk,onInit:Pk,onMount:Fk}})),nce=r({createSkill:()=>Vk,default:()=>Kk,onInit:()=>Hk});function Vk(e,t){return{id:e,ownerId:t,name:`界不屈`,description:`锁定技:濒死时翻牌堆顶作"创"牌置于武将牌上,点数与已有创均不同则回复至1体力,相同则移去此牌;武将牌上有"创"时手牌上限为"创"的数量`,isLocked:!0}}function Hk(e,t){let n=e.ownerId,r=N(t,e.id,n,`陷入濒死`,async e=>{if(e.atom.target!==n||!e.state.players[n]?.alive||e.state.zones.deck.length===0)return;delete e.state.localVars[Gk],await B(e.state,{type:`置创牌`,player:n,varsKey:Wk,resultKey:Gk});let t=e.state.localVars[Gk];if(delete e.state.localVars[Gk],t)return;let r=e.state.players[n].health,i=Math.max(0,1-r);i>0&&await B(e.state,{type:`回复体力`,target:n,amount:i}),e.state.localVars[Uk]=n}),i=rp(t,n,(e,t)=>{if(t!==n)return;let r=e.players[t]?.vars[Wk]??[];return r.length>0?r.length:void 0});return()=>{r(),i()}}var Uk,Wk,Gk,Kk,rce=t((()=>{V(),F(),op(),Uk=`不屈/存活`,Wk=`不屈/创牌`,Gk=`不屈/重复`,Kk={createSkill:Vk,onInit:Hk}})),ice=r({createSkill:()=>qk,default:()=>$k,onInit:()=>Yk,onMount:()=>Xk});function qk(e,t){return{id:e,ownerId:t,name:`界义从`,description:`锁定技:你计算与其他角色的距离-1;若你的体力值不大于2,其他角色计算与你的距离+1`,isLocked:!0}}async function Jk(e,t){let n=e.players[t];if(!n)return;let r=n.alive&&n.health>0&&n.health<=Zk,i=n.marks.some(e=>e.id===Qk);r&&!i?(n.vars[Cl]=1,await B(e,{type:`加标记`,player:t,mark:{id:Qk,scope:t,payload:{}},distanceVars:{defenseMod:1}})):!r&&i&&(delete n.vars[Cl],await B(e,{type:`去标记`,player:t,markId:Qk,distanceVars:{defenseMod:void 0}}))}function Yk(e,t){let n=e.ownerId;t.players[n].vars[Sl]=1;let r=t.players[n];return r.alive&&r.health>0&&r.health<=Zk&&(r.vars[Cl]=1,r.marks.push({id:Qk,scope:n,payload:{}})),N(t,e.id,n,`扣减体力后`,async e=>{e.atom.target===n&&await Jk(e.state,n)}),N(t,e.id,n,`回复体力`,async e=>{e.atom.target===n&&await Jk(e.state,n)}),N(t,e.id,n,`失去体力`,async e=>{e.atom.target===n&&await Jk(e.state,n)}),()=>{delete t.players[n]?.vars[Sl],delete t.players[n]?.vars[Cl];let e=t.players[n];e&&(e.marks=e.marks.filter(e=>e.id!==Qk))}}function Xk(e,t){}var Zk,Qk,$k,ace=t((()=>{V(),F(),W(),Zk=2,Qk=`义从/低血`,$k={createSkill:qk,onInit:Yk,onMount:Xk}})),oce=r({createSkill:()=>sce,default:()=>dce,onInit:()=>lce,onMount:()=>uce});function sce(e,t){return{id:e,ownerId:t,name:tA,description:`你可以将两张花色相同的手牌当【万箭齐发】使用;你使用【万箭齐发】可以少选一个目标`}}function cce(e,t){return`${e}#${t}#界乱击`}function lce(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardIds;if(!Array.isArray(c)||c.length!==2)return`需要选择 2 张手牌`;let[l,u]=c;if(typeof l!=`string`||typeof u!=`string`)return`cardIds 必须为字符串`;if(l===u)return`不能选择同一张牌`;let d=!!o&&o.hand.includes(l)&&o.hand.includes(u),f=e.cardMap[l],p=e.cardMap[u],m=!!f&&!!p,h=!!f&&!!p&&f.suit!==``&&f.suit===p.suit;return r&&i&&a&&s&&d&&m&&h?null:`界乱击需要两张同花色的手牌`},async(e,t)=>{let r=t.cardIds,[i,a]=r;await B(e,{type:`当作`,player:n,cardIds:r,shadowId:cce(i,a),outputName:`万箭齐发`})},(e,t)=>{let r=t.cardIds,[i,a]=Array.isArray(r)?r:[],o=i&&a?cce(i,a):void 0;if(o){delete e.cardMap[o];let t=e.players[n],r=t.hand.indexOf(o);r>=0&&t.hand.splice(r,1),t.hand.push(i,a)}}),j(t,`万箭齐发`,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`不是出牌阶段`;if(E(e))return`当前有等待响应`;let r=e.players[n];if(!r?.alive)return`你已死亡`;let i=t.cardId;return typeof i==`string`?r.hand.includes(i)?e.cardMap[i]?.name===`万箭齐发`?null:`不是万箭齐发`:`牌不在手牌中`:`cardId required`},async(e,t)=>{let r=n,i=t.cardId,a=e.players.filter(e=>e.alive),o=a.length,s=[];if(o>1){let e=a.findIndex(e=>e.index===r);if(e>=0)for(let t=1;t<o;t++)s.push(a[(e+t)%o].index)}let c=s;if(s.length>=1){delete e.localVars[rA],await B(e,{type:`请求回应`,requestType:nA,target:r,prompt:{type:`choosePlayer`,title:`界乱击:可少选一个目标(选 0 或 1 名排除)`,description:`可放弃(不排除任何目标)`,min:0,max:1,filter:(e,t)=>s.includes(t)},timeout:20});let t=e.localVars[rA];delete e.localVars[rA],typeof t==`number`&&(c=s.filter(e=>e!==t))}await Lh(e,r,i,c,`万箭齐发`,{onSettle:Hh(e,r,i)})}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`||i.requestType!==nA)return`当前不是界乱击询问`;let a=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);return a==null?null:typeof a==`number`?e.players[a]?.alive?null:`目标不存在或已死亡`:`target 必须为数字`},async(e,t)=>{let n=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);e.localVars[rA]=typeof n==`number`?n:null}),()=>{}}function uce(e,t){t.defineAction(`transform`,{label:tA,style:`danger`,prompt:{type:`useCardAndTarget`,title:`选择 2 张同花色的手牌当万箭齐发使用(界版:可少选一个目标)`,cardFilter:{filter:()=>!0,min:2,max:2,comboFilter:e=>e[0]?.suit===e[1]?.suit},targetFilter:{min:0,max:0}},transform:t=>({name:`万箭齐发`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];if(!t?.hand)return!1;let n={};for(let e of t.hand)if(e.suit&&(n[e.suit]=(n[e.suit]??0)+1,n[e.suit]>=2))return!0;return!1}}),t.defineAction(`respond`,{label:tA,style:`danger`,prompt:{type:`choosePlayer`,title:`界乱击:少选一个目标(可选)`,min:0,max:1}})}var eA,tA,nA,rA,dce,fce=t((()=>{F(),V(),Gh(),J(),eA=`界乱击`,tA=`乱击`,nA=`${eA}/skipTarget`,rA=`${eA}/skipTargetChoice`,dce={createSkill:sce,onInit:lce,onMount:uce}})),pce=r({createSkill:()=>mce,default:()=>yce,onInit:()=>gce,onMount:()=>_ce});function mce(e,t){return{id:e,ownerId:t,name:vce,description:`限定技:出牌阶段令所有其他角色依次对距离最小者出杀,无法如此做者失去1点体力;结算后可视为使用一张无距离限制的【杀】`}}function iA(e,t){let n=1/0,r=new Map;for(let i=0;i<e.players.length;i++){if(i===t||!e.players[i]?.alive)continue;let a=Wm(e,t,i);r.set(i,a),a<n&&(n=a)}let i=[];for(let[e,t]of r)t===n&&i.push(e);return i}async function hce(e,t,n){if(!e.players[n]?.alive)return;let r=`界乱武:杀:${t}:${n}:${e.seq}`;e.cardMap[r]={id:r,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,r,[n],`杀`,{virtual:!0,onSettle:Hh(e,t,r)}),delete e.cardMap[r]}function gce(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`use`,(e,t)=>e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:e.players[n]?.vars[aA]?`乱武已使用过(限定技)`:e.players[n]?.alive?e.players.filter(e=>e.alive&&e.index!==n).length===0?`场上没有其他角色`:null:`玩家不存在或已死亡`:`只能在出牌阶段发动`:`不是你的回合`,async(e,r)=>{let i=n;e.players[i].vars[aA]=!0,await I(t,`界乱武`,i,{});try{let t=e.players.length;for(let n=1;n<t;n++){let r=(i+n)%t;if(r===i||!e.players[r]?.alive)continue;let a=iA(e,r);if(a.length===0){await B(e,{type:`失去体力`,target:r,amount:1});continue}delete e.localVars[oA],await B(e,{type:`请求回应`,requestType:sA,target:r,prompt:{type:`useCardAndTarget`,title:`乱武:对距离最近的角色使用一张【杀】,否则失去1点体力`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>a.includes(t)}},timeout:20});let o=e.localVars[oA];delete e.localVars[oA],o&&e.players[r].hand.includes(o.cardId)&&iA(e,r).includes(o.target)&&e.players[o.target]?.alive?await Lh(e,r,o.cardId,[o.target],`杀`):await B(e,{type:`失去体力`,target:r,amount:1})}if(e.players[i]?.alive&&lh(e,i)&&e.players.filter(e=>e.alive&&e.index!==i).length>0){delete e.localVars[cA],await B(e,{type:`请求回应`,requestType:lA,target:i,prompt:{type:`choosePlayer`,title:`界乱武:视为使用一张无距离限制的【杀】,选择目标(pass 则不使用)`,min:1,max:1,filter:(t,n)=>n!==i&&e.players[n]?.alive===!0},timeout:20});let t=e.localVars[cA];delete e.localVars[cA],typeof t==`number`&&e.players[t]?.alive&&await hce(e,i,t)}}finally{await L(t)}}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.requestType!==sA&&r.requestType!==lA)return`当前不是乱武询问`;if(r.requestType===lA){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);return typeof n==`number`?n===i?`不能以自己为目标`:e.players[n]?.alive?null:`目标不存在或已死亡`:`请选择目标`}let a=t.cardId,o=t.target;return typeof a==`string`?typeof o==`number`?e.players[i]?.hand.includes(a)?e.cardMap[a]?.name===`杀`?iA(e,i).includes(o)?null:`目标不是距离最近的角色`:`只能使用杀`:`牌不在手牌中`:`请选择目标`:`请选择一张杀`},async(e,t)=>{if(e.pendingSlots.get(i)?.atom?.requestType===lA){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[cA]=n);return}e.localVars[oA]={cardId:t.cardId,target:t.target}}))}return()=>{for(let e of r)e()}}function _ce(e,t){return t.defineAction(`use`,{label:`乱武`,style:`primary`,prompt:{type:`confirm`,title:`乱武(限定技):令所有其他角色依次对距离最近者出杀,无法如此做者失去1点体力;结算后可视为使用一张无距离限制的【杀】`},activeWhen:e=>q(e)}),t.defineAction(`respond`,{label:`出杀`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`乱武:对距离最近的角色使用一张【杀】,否则失去1点体力`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1}}}),()=>{}}var vce,aA,oA,sA,cA,lA,yce,bce=t((()=>{V(),z(),J(),Gh(),F(),Xm(),fh(),vce=`乱武`,aA=`乱武/used`,oA=`乱武/出杀`,sA=`界乱武/出杀`,cA=`界乱武/最终杀目标`,lA=`界乱武/最终杀目标`,yce={createSkill:mce,onInit:gce,onMount:_ce}})),xce=r({createSkill:()=>Sce,default:()=>kce,onInit:()=>Dce,onMount:()=>Oce});function Sce(e,t){return{id:e,ownerId:t,name:`界仁德`,description:`出牌阶段:每名角色限一次,将任意张手牌交给一名其他角色;本阶段给出第二张时,可视为使用一张基本牌`}}function uA(e,t,n,r){return`仁德:${e}:${t}:${n}:${r}`}async function Cce(e,t,n){if(!e.players[n]?.alive)return;let r=uA(`杀`,t,n,e.seq);e.cardMap[r]={id:r,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,r,[n],`杀`,{virtual:!0,onSettle:Hh(e,t,r)}),delete e.cardMap[r]}async function wce(e,t,n){let r=e.players[n];if(!r?.alive||r.health>=r.maxHealth)return;let i=uA(`桃`,t,n,e.seq);e.cardMap[i]={id:i,name:`桃`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,i,[n],`桃`,{virtual:!0}),delete e.cardMap[i]}async function Tce(e,t){let n=uA(`酒`,t,t,e.seq);e.cardMap[n]={id:n,name:`酒`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,n,[t],`酒`,{virtual:!0}),delete e.cardMap[n]}function Ece(e,t){let n=e.allocation,r=e.targets,i=e.cardId,a=e.targets;return Array.isArray(n)&&n.length>0&&Array.isArray(n[0].cardIds)?n:Array.isArray(r)&&r.length>0&&Array.isArray(r[0].cardIds)?r:i&&Array.isArray(a)&&a.length>0?[{target:a[0],cardIds:[i]}]:null}function Dce(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=Ece(t,n);if(!c)return`需要指定牌和目标`;let l=c.reduce((e,t)=>e+t.cardIds.length,0)>0,u=[],d=!0,f=!0;if(l)for(let e of c){if(!Array.isArray(e.cardIds)){f=!1;continue}for(let t of e.cardIds)u.includes(t)&&(d=!1),u.push(t),o.hand.includes(t)||(f=!1)}let p=l&&c.every(t=>t.target!==n&&e.players[t.target]?.alive===!0),m=new Set(c.map(e=>e.target)).size===1,h=!(Array.isArray(o.vars[`仁德/givenTargets`])?o.vars[`仁德/givenTargets`]:[]).includes(c[0].target);return r&&i&&a&&s&&l&&d&&f&&p&&m&&h?null:`现在不能使用界仁德`},async(e,t)=>{let r=n,i=e.players[r];await I(e,`仁德`,r,{...t});let a=Ece(t,r),o=(typeof i.vars[`仁德/givenCount`]==`number`?i.vars[`仁德/givenCount`]:0)+a.reduce((e,t)=>e+t.cardIds.length,0),s=o>=2&&!i.vars[`仁德/basicUsed`];for(let t of a)for(let n of t.cardIds)await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:r},to:{zone:`手牌`,player:t.target}});i.vars[`仁德/givenCount`]=o;let c=Array.isArray(i.vars[`仁德/givenTargets`])?i.vars[`仁德/givenTargets`]:[];for(let e of a)c.includes(e.target)||c.push(e.target);if(i.vars[`仁德/givenTargets`]=c,s){i.vars[`仁德/basicUsed`]=!0,delete e.localVars[dA],await B(e,{type:`请求回应`,requestType:pA,target:r,prompt:{type:`chooseOption`,title:`界仁德:视为使用一张基本牌?`,options:[{value:`杀`,label:`杀`},{value:`桃`,label:`桃`},{value:`酒`,label:`酒`},{value:`不使用`,label:`不使用`}]},defaultChoice:`不使用`,timeout:30});let t=e.localVars[dA];if(delete e.localVars[dA],t===`杀`){if(lh(e,r)){delete e.localVars[fA],await B(e,{type:`请求回应`,requestType:mA,target:r,prompt:{type:`choosePlayer`,title:`界仁德:选择【杀】的目标(攻击范围内一名其他角色)`,min:1,max:1,filter:(t,n)=>n!==r&&e.players[n]?.alive===!0&&Gm(e,r,n)},timeout:30});let t=e.localVars[fA];delete e.localVars[fA],typeof t==`number`&&e.players[t]?.alive&&await Cce(e,r,t)}}else if(t===`桃`){delete e.localVars[fA],await B(e,{type:`请求回应`,requestType:mA,target:r,prompt:{type:`choosePlayer`,title:`界仁德:选择【桃】的目标(一名已受伤角色,可对自己)`,min:1,max:1,filter:(t,n)=>{let r=e.players[n];return!!r?.alive&&r.health<r.maxHealth}},timeout:30});let t=e.localVars[fA];delete e.localVars[fA],typeof t==`number`&&e.players[t]?.alive&&await wce(e,r,t)}else t===`酒`&&(X(e,r,`酒`)&&!e.players[r]?.tags.includes(`酒/无次数限制`)||await Tce(e,r))}await L(e)}),j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let r=t.atom.requestType??``;return r!==pA&&r!==mA?`当前不是仁德询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType??``;if(r===pA){let n=t.option;n===`杀`||n===`桃`||n===`酒`?e.localVars[dA]=n:e.localVars[dA]=`不使用`}else if(r===mA){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[fA]=n)}}),()=>{}}function Oce(e,t){return t.defineAction(`use`,{label:`界仁德`,style:`primary`,prompt:{type:`distribute`,mode:`allocate`,title:`界仁德:选择要送出的手牌和目标角色(每名角色每回合限一次)`,source:`hand`,minPerTarget:1,maxPerTarget:99,minTotal:1,maxTotal:99,allowSelf:!1}}),t.defineAction(`respond`,{label:`界仁德`,style:`default`,prompt:{type:`confirm`,title:`界仁德`}}),()=>{}}var dA,fA,pA,mA,kce,Ace=t((()=>{V(),z(),F(),Xm(),fh(),Q(),Gh(),dA=`仁德/basicChoice`,fA=`仁德/basicTarget`,pA=`界仁德/basicChoice`,mA=`界仁德/basicTarget`,kce={createSkill:Sce,onInit:Dce,onMount:Oce}})),jce=r({createSkill:()=>Nce,default:()=>Lce,onInit:()=>Pce,onMount:()=>Fce});function Mce(e){return!!e&&e.type===`装备牌`}function hA(e,t){let n=[],r=e.players[t];if(!r)return n;for(let t of r.hand)Mce(e.cardMap[t])&&n.push(t);for(let t of[`武器`,`防具`,`进攻马`,`防御马`,`宝物`]){let i=r.equipment[t];i&&Mce(e.cardMap[i])&&n.push(i)}return n}function Nce(e,t){return{id:e,ownerId:t,name:gA,description:`其他角色进入濒死时,可弃置一张装备牌并翻面,令其回复至1点体力`}}function Pce(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==`界仁心/confirm`&&a!==`界仁心/selectCard`)return`当前不是仁心询问`;if(a===`界仁心/selectCard`){let r=t.cardId;if(typeof r!=`string`)return`请选择一张装备牌`;if(!hA(e,n).includes(r))return`该牌不是你可弃置的装备牌`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===`界仁心/confirm`)e.localVars[_A]=t.choice===!0||t.confirmed===!0;else if(r===`界仁心/selectCard`){let n=t.cardId;typeof n==`string`&&(e.localVars[vA]=n)}}),N(t,e.id,n,`陷入濒死`,async e=>{let t=e.atom;if(typeof t.target!=`number`)return;let r=t.target;if(r===n)return;let i=e.state.players[r];if(!i?.alive||i.health>0||!e.state.players[n]?.alive||hA(e.state,n).length===0)return;delete e.state.localVars[_A],await B(e.state,{type:`请求回应`,requestType:`界仁心/confirm`,target:n,prompt:{type:`confirm`,title:`仁心:是否弃置一张装备牌并翻面,令 ${i.name} 回复至1点体力?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15});let a=e.state.localVars[_A]===!0;if(delete e.state.localVars[_A],!a||e.state.players[r]?.health>0)return;let o=hA(e.state,n);if(o.length===0)return;let s;if(o.length===1)s=o[0];else if(delete e.state.localVars[vA],await B(e.state,{type:`请求回应`,requestType:`界仁心/selectCard`,target:n,prompt:{type:`pickProcessingCard`,title:`仁心:选择一张装备牌弃置`,cards:o.map(t=>{let n=e.state.cardMap[t];return{cardId:t,cardName:n?.name??t,suit:n?.suit??``,rank:n?.rank??``}})},defaultChoice:o[0],timeout:20}),s=e.state.localVars[vA],delete e.state.localVars[vA],typeof s!=`string`&&(s=o[0]),!hA(e.state,n).includes(s))return;await B(e.state,{type:`弃置`,player:n,cardIds:[s],voluntary:!0}),await Ch(e.state,n,`仁心`);let c=e.state.players[r]?.health??0,l=Math.max(1,1-c);await B(e.state,{type:`回复体力`,target:r,amount:l})}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n)return;let r=e.state.players[n];if(t.phase===`准备`&&r?.tags.includes(Ice))return await wh(e.state,n,`仁心`),e.state.localVars[yA]=n,{kind:`cancel`};if(e.state.localVars[yA]===n)return{kind:`cancel`}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type===`阶段结束`&&t.player===n&&e.state.localVars[yA]===n)return delete e.state.localVars[yA],await kh(e.state,n),{kind:`cancel`}}),()=>{}}function Fce(e,t){t.defineAction(`respond`,{label:gA,style:`primary`,prompt:{type:`confirm`,title:`是否发动仁心?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var gA,_A,vA,Ice,yA,Lce,Rce=t((()=>{V(),Mh(),F(),gA=`仁心`,_A=`仁心/confirmed`,vA=`仁心/cardChoice`,Ice=`仁心/翻面`,yA=`仁心/skipAll`,Lce={createSkill:Nce,onInit:Pce,onMount:Fce}})),zce=r({createSkill:()=>Bce,default:()=>DA,onInit:()=>Hce,onMount:()=>Uce});function Bce(e,t){return{id:e,ownerId:t,name:bA,description:`限定技:濒死时,将体力回复至X点且手牌摸至X张(X为全场势力数);然后若X大于你造成的伤害数,你翻面`}}function Vce(e){let t=new Set;for(let n of e.players)n.alive&&n.faction&&t.add(n.faction);return t.size}function Hce(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===wA?null:`当前不是伏枥询问`:`当前不需要回应`},async(e,t)=>{e.localVars[CA]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`陷入濒死`,async e=>{if(e.atom.target!==n||e.state.players[n]?.vars[xA])return;let t=e.state.players[n];if(!t?.alive||t.health>0||(delete e.state.localVars[CA],await B(e.state,{type:`请求回应`,requestType:wA,target:n,prompt:{type:`confirm`,title:`是否发动伏枥?(限定技:回复至X体力并摸至X张手牌;X=全场势力数;若X>你造成的伤害数则翻面)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[CA]))return;e.state.players[n].vars[xA]=!0;let r=Vce(e.state),i=e.state.players[n].health,a=Math.max(0,r-i);a>0&&await B(e.state,{type:`回复体力`,target:n,amount:a});let o=e.state.players[n].hand.length,s=Math.max(0,r-o);s>0&&await B(e.state,{type:`摸牌`,player:n,count:s}),r>(e.state.players[n].vars[SA]??0)&&(Dh(e.state,n)||await Ch(e.state,n,`伏枥`))}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0)return;let r=e.state.players[n].vars[SA]??0;e.state.players[n].vars[SA]=r+(t.amount??0)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n)return;let r=e.state.players[n];if(r){if(t.phase===`准备`&&r.tags.includes(TA))return await wh(e.state,n,`伏枥`),e.state.localVars[EA]=n,{kind:`cancel`};if(e.state.localVars[EA]===n)return{kind:`cancel`}}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type===`阶段结束`&&t.player===n&&e.state.localVars[EA]===n)return delete e.state.localVars[EA],await kh(e.state,n),{kind:`cancel`}}),()=>{}}function Uce(e,t){t.defineAction(`respond`,{label:bA,style:`primary`,prompt:{type:`confirm`,title:`是否发动伏枥?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var bA,xA,SA,CA,wA,TA,EA,DA,Wce=t((()=>{V(),Mh(),F(),bA=`伏枥`,xA=`伏枥/used`,SA=`伏枥/damageDealt`,CA=`伏枥/confirmed`,wA=`界伏枥/confirm`,TA=`伏枥/翻面`,EA=`伏枥/skipAll`,DA={createSkill:Bce,onInit:Hce,onMount:Uce}})),Gce=r({createSkill:()=>kA,default:()=>PA,onInit:()=>AA,onMount:()=>jA});function Kce(e,t){let n=e.players[t];return n?Math.max(0,n.maxHealth-p(n)):0}async function OA(e,t){let n=e.players[t];if(!n?.alive)return;let r=Kce(e,t),i=n.hand.length;if(r<=0||i>=r||(delete e.localVars[NA],await B(e,{type:`请求回应`,requestType:MA,target:t,prompt:{type:`confirm`,title:`伤逝:是否将手牌摸至 ${r} 张?(当前 ${i} 张,已损失 ${r} 体力)`,confirmLabel:`摸牌`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.localVars[NA]!==!0))return;let a=r-i,o=e.zones.deck.length+e.zones.discardPile.length;a>o&&(a=o),a>0&&await B(e,{type:`摸牌`,player:t,count:a})}function kA(e,t){return{id:e,ownerId:t,name:`伤逝`,description:`当你的手牌数小于X后,你可以将手牌摸至X张(X为你已损失体力值)`}}function AA(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===MA?null:`当前不是伤逝确认`:`当前不需要回应`},async(e,t)=>{e.localVars[NA]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`扣减体力后`,async e=>{let t=e.atom;t.target===n&&((t.amount??0)<=0||await OA(e.state,n))}),N(t,e.id,n,`失去体力`,async e=>{let t=e.atom;t.target===n&&((t.amount??0)<=0||await OA(e.state,n))}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;t.player===n&&(t.cardIds??[]).length!==0&&await OA(e.state,n)}),N(t,e.id,n,`获得`,async e=>{e.atom.from===n&&await OA(e.state,n)}),N(t,e.id,n,`给予`,async e=>{let t=e.atom;t.from===n&&t.to!==n&&await OA(e.state,n)}),N(t,e.id,n,`移出至暂存区`,async e=>{e.atom.target===n&&await OA(e.state,n)}),N(t,e.id,n,`拼点扣置`,async e=>{let t=e.atom;t.initiator!==n&&t.target!==n||await OA(e.state,n)}),N(t,e.id,n,`装备`,async e=>{e.atom.player===n&&await OA(e.state,n)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.from?.zone===`手牌`&&t.from?.player===n&&!(t.to?.zone===`手牌`&&t.to?.player===n)){if(t.to?.zone===`处理区`&&t.cardId){let n=e.state.cardMap[t.cardId],r=n&&Wg(n.name);if(r&&!r.delayed)return}await OA(e.state,n)}}),N(t,e.id,n,`使用结算结束后`,async e=>{e.atom.source===n&&await OA(e.state,n)}),()=>{}}function jA(e,t){t.defineAction(`respond`,{label:`伤逝`,style:`default`,prompt:{type:`confirm`,title:`是否发动伤逝?`,confirmLabel:`摸牌`,cancelLabel:`不发动`}})}var MA,NA,PA,qce=t((()=>{b(),V(),Yg(),F(),MA=`界伤逝/confirm`,NA=`伤逝/confirmed`,PA={createSkill:kA,onInit:AA,onMount:jA}})),Jce=r({createSkill:()=>FA,default:()=>VA,onInit:()=>IA,onMount:()=>LA});function FA(e,t){return{id:e,ownerId:t,name:`界克己`,description:`若你未于本回合出牌阶段使用或打出过【杀】,你可以跳过弃牌阶段`}}function IA(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===BA?null:`当前不是界克己确认`:`当前不需要回应`},async(e,t)=>{e.localVars[zA]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.from.zone!==`手牌`||t.from.player!==n||t.to.zone===`处理区`&&e.state.phase===`出牌`&&e.state.cardMap[t.cardId]?.name===`杀`&&(e.state.turn.vars[RA]=!0)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`弃牌`&&!e.state.turn.vars[RA]&&(delete e.state.localVars[zA],await B(e.state,{type:`请求回应`,requestType:BA,target:n,prompt:{type:`confirm`,title:`界克己:本回合出牌阶段未出杀,是否跳过弃牌阶段?`,confirmLabel:`跳过`,cancelLabel:`不跳过`},defaultChoice:!1,timeout:15}),e.state.localVars[zA]))return await B(e.state,{type:`阶段结束`,player:n,phase:`弃牌`}),{kind:`cancel`}}),()=>{}}function LA(e,t){t.defineAction(`respond`,{label:`界克己`,style:`primary`,prompt:{type:`confirm`,title:`界克己:是否跳过弃牌阶段?`,confirmLabel:`跳过`,cancelLabel:`不跳过`}})}var RA,zA,BA,VA,Yce=t((()=>{V(),F(),RA=`界克己/playedSlash`,zA=`界克己/confirmed`,BA=`界克己/confirm`,VA={createSkill:FA,onInit:IA,onMount:LA}})),Xce=r({createSkill:()=>HA,default:()=>$A,onInit:()=>UA,onMount:()=>WA});function HA(e,t){return{id:e,ownerId:t,name:`界再起`,description:`结束阶段,你可以令至多X名角色各选一项(X=本回合置入弃牌堆的红色牌数):1.摸一张牌;2.令你回复1点体力`}}function UA(e,t){let n=e.ownerId,r=N(t,e.id,n,`回合开始`,async e=>{let t=e.atom;t.type===`回合开始`&&t.player===n&&(e.state.turn.vars[GA]=e.state.zones.discardPile.length)}),i=[];for(let r of t.players){let a=r.index,o=j(t,e.id,a,`respond`,(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let o=i.requestType;if(o===qA||o===JA){if(a!==n)return`当前不是你的询问`;if(o===JA){let n=e.localVars[KA],r=t.targets;if(!Array.isArray(r))return`需选择目标(可为空)`;let i=typeof n==`number`?n:0;if(r.length>i)return`至多选择 ${i} 名角色`;for(let t of r)if(typeof t!=`number`||!e.players[t]?.alive)return`目标不合法`}return null}return typeof o==`string`&&o===YA+a?null:`当前不是界再起询问`},async(e,t)=>{let n=e.pendingSlots.get(a)?.atom?.requestType;if(n===qA)e.localVars[XA]=t.choice===!0||t.confirmed===!0;else if(n===JA){let n=t.targets;e.localVars[ZA]=Array.isArray(n)?n.filter(e=>typeof e==`number`):[]}else if(n===YA+a){let n=t.choice===!0||t.confirmed===!0?1:2,r=e.localVars[QA]??{};r[String(a)]=n,e.localVars[QA]=r}});i.push(o)}let a=N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`)return;let r=e.state;if(!r.players[n]?.alive)return;let i=r.turn.vars[GA];if(typeof i!=`number`||r.zones.discardPile.length<i)return;let a=r.zones.discardPile.slice(i).filter(e=>r.cardMap[e]?.color===`红`).length;if(a<=0)return;let o=r.players.filter(e=>e.alive).length;if(o===0)return;let s=Math.min(a,o);delete r.localVars[XA],await B(r,{type:`请求回应`,requestType:qA,target:n,prompt:{type:`confirm`,title:`界再起:本回合置入弃牌堆 ${a} 张红色牌。是否令至多 ${s} 名角色各选一项?`,description:`选项:1.摸一张牌;2.令孟获回复1点体力`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:20});let c=r.localVars[XA]===!0;if(delete r.localVars[XA],!c)return;r.localVars[KA]=s,delete r.localVars[ZA],await B(r,{type:`请求回应`,requestType:JA,target:n,prompt:{type:`choosePlayer`,title:`界再起:选择至多 ${s} 名角色(各选一项:摸一张牌 或 令你回复1点体力)`,min:0,max:s,filter:(e,t)=>r.players[t]?.alive===!0},timeout:30}),delete r.localVars[KA];let l=r.localVars[ZA];delete r.localVars[ZA];let u=Array.isArray(l)?l.filter((e,t,n)=>r.players[e]?.alive&&n.indexOf(e)===t).slice(0,s):[];if(u.length!==0){for(let e of u)if(r.players[e]?.alive)if(delete r.localVars[QA],await B(r,{type:`请求回应`,requestType:YA+e,target:e,prompt:{type:`confirm`,title:`界再起(孟获):选择一项——1.摸一张牌;2.令孟获回复1点体力`,confirmLabel:`1·摸一张牌`,cancelLabel:`2·令孟获回复1点体力`},defaultChoice:!0,timeout:20}),(r.localVars[QA]?.[String(e)]===2?2:1)==1)await B(r,{type:`摸牌`,player:e,count:1});else{let e=r.players[n];e?.alive&&e.health<e.maxHealth&&await B(r,{type:`回复体力`,target:n,amount:1})}delete r.localVars[QA]}});return()=>{r(),i.forEach(e=>e()),a()}}function WA(e,t){}var GA,KA,qA,JA,YA,XA,ZA,QA,$A,Zce=t((()=>{V(),F(),GA=`界再起/base`,KA=`界再起/x`,qA=`界再起/trigger`,JA=`界再起/chooseTargets`,YA=`界再起/option/`,XA=`界再起/confirmed`,ZA=`界再起/targets`,QA=`界再起/optionResults`,$A={createSkill:HA,onInit:UA,onMount:WA}})),Qce=r({createSkill:()=>ej,default:()=>oj,onInit:()=>tj,onMount:()=>nj});function $ce(e){e.turn.vars={};for(let t of e.players)t.marks=t.marks.filter(e=>e.duration!==`turn`),t.vars=Object.fromEntries(Object.entries(t.vars).filter(([e])=>!e.endsWith(`/usedThisTurn`)&&!e.endsWith(`/healed`)&&!e.endsWith(`/givenCount`)&&!e.endsWith(`/givenTargets`)&&!e.endsWith(`/basicUsed`)))}function ej(e,t){return{id:e,ownerId:t,name:`界凿险`,description:`觉醒技:准备阶段田≥3时,减1体力上限、获得"急袭",且本回合结束后进行一个额外回合`}}function tj(e,t){let n=e.ownerId;return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`准备`||t.player!==n||e.state.players[n]?.vars[rj])return;let r=e.state.players[n];if(!r?.alive||r.marks.filter(e=>e.id.startsWith(aj)).length<3)return;e.state.players[n].vars[rj]=!0;let i=r.maxHealth-1;await B(e.state,{type:`设上限`,player:n,amount:i}),await B(e.state,{type:`添加技能`,player:n,skillId:`急袭`}),e.state.localVars[ij]=!0}),M(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`||t.player!==n)return;let r=e.state;if(r.localVars[ij]===!0&&(delete r.localVars[ij],r.players[n]?.alive))return $ce(r),r.currentPlayerIndex=n,await Oy(r,n),{kind:`cancel`}}),()=>{}}function nj(e,t){}var rj,ij,aj,oj,ele=t((()=>{V(),ky(),F(),rj=`凿险/awakened`,ij=`凿险/extraTurn`,aj=`屯田/田:`,oj={createSkill:ej,onInit:tj,onMount:nj}})),tle=r({createSkill:()=>sj,default:()=>pj,onInit:()=>cj,onMount:()=>lj});function sj(e,t){return{id:e,ownerId:t,name:`界刚烈`,description:`受到伤害后判定,红色对其造成1点伤害,黑色弃置其一张牌`}}function cj(e,t){let n=e.ownerId,r=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===uj)return null;if(a!==dj)return`当前不是界刚烈回应`;let o=t.zone;if(o===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(o===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else if(o===`judge`){if(typeof t.cardId!=`string`)return`cardId required`}else return`zone required (equipment|hand|judge)`;return null},async(e,t)=>{if(e.pendingSlots.get(n)?.atom?.requestType===uj){e.localVars[`界刚烈/confirmed`]=t.choice===!0;return}e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null}});return N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.judgeType!==`界刚烈`||t.player!==n)return;let r=R(e.state);if(r.length===0)return;let i=r[r.length-1],a=e.state.cardMap[i];a&&(e.state.localVars[fj]=a.color)}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0||t.source===void 0||t.source===n)return;let r=t.source;if(!e.state.players[r]?.alive||e.state.zones.deck.length===0||(delete e.state.localVars[`界刚烈/confirmed`],await B(e.state,{type:`请求回应`,requestType:uj,target:n,prompt:{type:`confirm`,title:`是否发动界刚烈?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`界刚烈/confirmed`]))return;delete e.state.localVars[fj],await jm(e.state,n,`界刚烈`);let i=e.state.localVars[fj];if(delete e.state.localVars[fj],i===void 0)return;if(i===`红`){await Dm(e.state,n,r,1);return}let a=e.state.players[r];a?.alive&&(a.hand.length>0||Object.keys(a.equipment).length>0||a.pendingTricks.length>0)&&await kg(e.state,n,r,a,{mode:`discard`,requestType:dj,title:`界刚烈:选择弃置来源的一张牌`})}),()=>{r()}}function lj(e,t){t.defineAction(`respond`,{label:`界刚烈`,style:`danger`,prompt:{type:`pickTargetCard`,title:`界刚烈:选择弃置来源的一张牌`,target:-1,equipment:[],judge:[],handCount:0}})}var uj,dj,fj,pj,nle=t((()=>{V(),z(),Fm(),Om(),F(),Ag(),W(),uj=`界刚烈/confirm`,dj=`界刚烈/选牌`,fj=`界刚烈/judgeColor`,pj={createSkill:sj,onInit:cj,onMount:lj}})),rle=r({createSkill:()=>mj,default:()=>wj,onInit:()=>hj,onMount:()=>gj});function mj(e,t){return{id:e,ownerId:t,name:vj,description:`当你使用【杀】对其他角色造成伤害后,你可以获得其区域里的一张牌;获得的牌不为装备牌,其摸一张牌;为装备牌,你视为对由其指定的另一名角色使用一张【决斗】`}}function hj(e,t){let n=e.ownerId,r=[];for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n||n.atom.type!==`请求回应`)return`当前不需要回应`;let r=n.atom.requestType;if(r===xj)return null;if(r===Sj){let e=t.zone;if(e===`equipment`||e===`judge`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand|judge)`;return null}return r===Cj?typeof t.target==`number`?null:`target required`:`当前不是利驭回应`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;n===xj?e.localVars[yj]=t.choice===!0||t.confirmed===!0:n===Sj?e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null}:n===Cj&&(e.localVars[bj]=t.target)}))}return r.push(N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0||t.target===n||(t.amount??0)<=0||typeof t.cardId!=`string`||e.state.cardMap[t.cardId]?.name!==`杀`)return;let r=t.target,i=e.state.players[r];if(!i?.alive||!e.state.players[n]?.alive||!(i.hand.length>0||Object.keys(i.equipment).length>0||i.pendingTricks.length>0)||(delete e.state.localVars[yj],await B(e.state,{type:`请求回应`,requestType:xj,target:n,prompt:{type:`confirm`,title:`是否发动利驭?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[yj]))return;delete e.state.localVars[yj];let a=e.state.players[r];if(!a)return;await kg(e.state,n,r,a,{mode:`obtain`,requestType:Sj,title:`利驭:选择获得受伤目标区域里的一张牌`,includeJudge:!0});let o=e.state.players[n];if(!o)return;let s=o.hand[o.hand.length-1]??null;if(s===null)return;let c=e.state.cardMap[s];if(!c)return;if(c.type!==`装备牌`){await B(e.state,{type:`摸牌`,player:r,count:1});return}let l=e.state.players.filter(e=>e.alive&&e.index!==n&&e.index!==r).map(e=>e.index);if(l.length===0)return;delete e.state.localVars[bj],await B(e.state,{type:`请求回应`,requestType:Cj,target:r,prompt:{type:`choosePlayer`,title:`利驭:选择另一名角色,界吕布视为对其使用决斗`,min:1,max:1,filter:(e,t)=>t!==n&&t!==r&&e.players[t]?.alive===!0},defaultChoice:l[0],timeout:15});let u=e.state.localVars[bj];if(delete e.state.localVars[bj],typeof u==`number`&&!(u===n||u===r)&&e.state.players[u]?.alive){await I(e.state,_j,n,{duelTarget:u,source:r});try{if(e.state.players[n]?.alive&&e.state.players[u]?.alive){let t=`${_j}:决斗:${n}:${u}:${e.state.seq}`;e.state.cardMap[t]={id:t,name:`决斗`,suit:``,color:`无色`,rank:`A`,type:`锦囊牌`},await Lh(e.state,n,t,[u],`决斗`,{virtual:!0}),delete e.state.cardMap[t]}}finally{await L(e.state)}}})),()=>{for(let e of r)e()}}function gj(e,t){t.defineAction(`respond`,{label:vj,style:`default`,prompt:{type:`confirm`,title:`是否发动利驭?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var _j,vj,yj,bj,xj,Sj,Cj,wj,ile=t((()=>{V(),z(),F(),Ag(),Gh(),W(),_j=`界利驭`,vj=`利驭`,yj=`${_j}/confirmed`,bj=`${_j}/duelTarget`,xj=`${_j}/confirm`,Sj=`${_j}/选牌`,Cj=`${_j}/chooseDuelTarget`,wj={createSkill:mj,onInit:hj,onMount:gj}})),ale=r({createSkill:()=>Tj,default:()=>Oj,onInit:()=>Ej,onMount:()=>Dj});function Tj(e,t){return{id:e,ownerId:t,name:`界制衡`,description:`出牌阶段限一次:弃任意张牌(手牌/装备),摸等量张;若弃置了所有手牌,额外摸一张`}}function Ej(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=t.cardIds??(typeof t.cardId==`string`?[t.cardId]:void 0);if(!Array.isArray(r)||r.length===0)return`cardIds required (at least 1)`;if(X(e,n,`界制衡`))return`本回合已使用过界制衡`;let i=e.players[n];if(!i)return`player not found`;for(let e of r){let t=i.hand.includes(e),n=Object.values(i.equipment).includes(e);if(!t&&!n)return`牌不在手牌或装备区中`}return null},async(e,t)=>{await Z(e,n,`界制衡`);let r=n;await I(e,`界制衡`,r,{...t});let i=t.cardIds??(typeof t.cardId==`string`?[t.cardId]:[]),a=e.players[r].hand,o=a.length>0&&a.every(e=>i.includes(e));await B(e,{type:`弃置`,player:r,cardIds:i,voluntary:!0}),await B(e,{type:`摸牌`,player:r,count:i.length+ +!!o}),await L(e)}),()=>{}}function Dj(e,t){return t.defineAction(`use`,{label:`界制衡`,style:`primary`,prompt:{type:`distribute`,mode:`select`,title:`界制衡:选择要弃置的牌(手牌+装备均可;若弃置所有手牌,额外多摸一张)`,source:`handAndEquip`,minTotal:1,maxTotal:99},activeWhen:e=>yh(`界制衡`)(e)}),()=>{}}var Oj,ole=t((()=>{V(),z(),Q(),F(),Oj={createSkill:Tj,onInit:Ej,onMount:Dj}})),sle=r({createSkill:()=>Aj,default:()=>Wj,onInit:()=>jj,onMount:()=>Nj});function kj(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function Aj(e,t){return{id:e,ownerId:t,name:Fj,description:`主公技:你与其他吴势力角色可互相拼点;若发起方没赢,你可以获得两张拼点牌;觉醒后可拒绝盟友发起的拼点`}}function jj(e,t){let n=e.ownerId,r=[];for(let i of t.players){let a=i.index;if(a===n||i.faction!==`吴`)continue;let o=j(t,e.id,a,`use`,(e,t)=>{if(n!==0)return`制霸为主公技,孙策非主公`;let r=e.players[n];if(!r?.alive)return`主公不存在或已死亡`;if(r.hand.length===0)return`孙策没有手牌,无法拼点`;let i=e.players[a];if(!i?.alive)return`已死亡`;let o=e.currentPlayerIndex===a,s=e.phase===`出牌`,c=!E(e);if(!o||!s||!c)return`现在不能使用制霸`;if(X(e,a,Ij))return`本回合已使用过制霸`;let l=t.cardId;return typeof l==`string`?i.hand.includes(l)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`},async(e,t)=>{let r=t.cardId;await Z(e,a,Ij);let i=e.players[n];if(!(cl(i.vars)&&(delete e.localVars[Vj],await B(e,{type:`请求回应`,requestType:Rj,target:n,prompt:{type:`confirm`,title:`${e.players[a].name} 欲与你制霸拼点,是否接受?`,confirmLabel:`接受`,cancelLabel:`拒绝`},defaultChoice:!0,timeout:20}),e.localVars[Vj]===!1))){await I(e,Pj,a,{...t});try{await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:a},to:{zone:`处理区`}}),delete e.localVars[Hj],await B(e,{type:`请求回应`,requestType:zj,target:n,prompt:{type:`useCard`,title:`制霸:与 ${e.players[a].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let t=e.localVars[Hj];if(!t||!e.players[n].hand.includes(t)){await B(e,{type:`移动牌`,cardId:r,from:{zone:`处理区`},to:{zone:`弃牌堆`}});return}await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:n},to:{zone:`处理区`}}),await Mj(e,n,r,t,kj(e.cardMap[r]?.rank??``)>kj(e.cardMap[t]?.rank??``))}finally{await L(e)}}});r.push(o)}let i=j(t,e.id,n,`use`,(e,t)=>{if(n!==0)return`制霸为主公技,孙策非主公`;let r=e.players[n];if(!r?.alive)return`已死亡`;let i=e.currentPlayerIndex===n,a=e.phase===`出牌`,o=!E(e);if(!i||!a||!o)return`现在不能主动使用制霸`;if(X(e,n,Lj))return`本回合已主动使用过制霸`;let s=t.cardId;if(typeof s!=`string`)return`请选择一张拼点牌`;if(!r.hand.includes(s))return`拼点牌不在手牌中`;let c=t.target;if(typeof c!=`number`)return`请选择一名其他吴势力角色`;if(c===n)return`不能与自己拼点`;let l=e.players[c];return l?.alive?l.faction===`吴`?l.hand.length===0?`目标没有手牌,无法拼点`:null:`目标非吴势力`:`目标不存在或已死亡`},async(e,t)=>{let r=t.cardId,i=t.target;await Z(e,n,Lj),await I(e,Pj,n,{...t});try{await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:n},to:{zone:`处理区`}}),delete e.localVars[Hj],await B(e,{type:`请求回应`,requestType:zj,target:i,prompt:{type:`useCard`,title:`制霸:${e.players[n].name} 与你拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let t=e.localVars[Hj];if(!t||!e.players[i].hand.includes(t)){await B(e,{type:`移动牌`,cardId:r,from:{zone:`处理区`},to:{zone:`弃牌堆`}});return}await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:i},to:{zone:`处理区`}}),await Mj(e,n,r,t,kj(e.cardMap[r]?.rank??``)>kj(e.cardMap[t]?.rank??``))}finally{await L(e)}});r.push(i);for(let i of t.players){let a=i.index,o=j(t,e.id,a,`respond`,(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let o=i.requestType;if(o===Rj||o===Bj)return a===n?null:`只有孙策可以回应`;if(o===zj){let n=t.cardId;return typeof n==`string`?e.players[a].hand.includes(n)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`}return`当前不是制霸回应`},async(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return;let r=n.atom.requestType;r===Rj?e.localVars[Vj]=t.choice===!0||t.confirmed===!0:r===zj?e.localVars[Hj]=t.cardId:r===Bj&&(e.localVars[Uj]=t.choice===!0||t.confirmed===!0)});r.push(o)}return()=>{r.forEach(e=>e())}}async function Mj(e,t,n,r,i){if(i){for(let t of[n,r])await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}});return}delete e.localVars[Uj],await B(e,{type:`请求回应`,requestType:Bj,target:t,prompt:{type:`confirm`,title:`制霸:对方拼点没赢,是否获得两张拼点牌?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!0,timeout:20});let a=e.localVars[Uj]!==!1;for(let i of[n,r])await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:a?{zone:`手牌`,player:t}:{zone:`弃牌堆`}})}function Nj(e,t){let n=e.ownerId;t.defineAction(`use`,{label:Fj,style:`primary`,prompt:{type:`useCardAndTarget`,title:`制霸:选择一张拼点牌和一名其他吴势力角色`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return n?n.alive!==!1&&(n.handCount??0)>0:!1}}},activeWhen:e=>{let t=e.perspectiveIdx;return t===n&&!im(n)||(e.view.players[t]?.hand?.length??0)===0?!1:yh(t===n?Lj:Ij)(e)}}),t.defineAction(`respond`,{label:Fj,style:`primary`,prompt:{type:`confirm`,title:`制霸`,confirmLabel:`确认`,cancelLabel:`取消`}})}var Pj,Fj,Ij,Lj,Rj,zj,Bj,Vj,Hj,Uj,Wj,cle=t((()=>{V(),z(),Q(),F(),W(),J(),Pj=`界制霸`,Fj=`制霸`,Ij=Pj,Lj=`${Pj}/主动`,Rj=`${Pj}/refuse`,zj=`${Pj}/respCard`,Bj=`${Pj}/take`,Vj=`${Pj}/refuseResult`,Hj=`${Pj}/respCardId`,Uj=`${Pj}/takeResult`,Wj={createSkill:Aj,onInit:jj,onMount:Nj}})),lle=r({createSkill:()=>Gj,default:()=>$j,onInit:()=>qj,onMount:()=>Jj});function Gj(e,t){return{id:e,ownerId:t,name:Xj,description:`出牌阶段限两次,令一名其他角色视为对你使用一张决斗`}}function Kj(e,t){let n=e.players[t]?.vars[Zj];return typeof n==`number`?n:0}function qj(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(Kj(e,n)>=Qj)return`本阶段势斩已达上限(2次)`;if(!e.players[n]?.alive)return`玩家不存在或已死亡`;let r=t.target;return typeof r==`number`?r===n?`不能以自己为目标`:e.players[r]?.alive?null:`目标不合法`:`需要指定一名目标`},async(e,t)=>{let r=n,i=t.target,a=Kj(e,r)+1;e.players[r].vars[Zj]=a,await B(e,{type:`回合用量`,player:r,key:Zj,value:a}),await I(e,Yj,r,{...t});try{if(e.players[r]?.alive&&e.players[i]?.alive){let t=`${Yj}:决斗:${i}:${r}:${e.seq}`;e.cardMap[t]={id:t,name:`决斗`,suit:``,color:`无色`,rank:`A`,type:`锦囊牌`},await Lh(e,i,t,[r],`决斗`,{virtual:!0}),delete e.cardMap[t]}}finally{await L(e)}}),()=>{}}function Jj(e,t){t.defineAction(`use`,{label:Xj,style:`danger`,prompt:{type:`selectTarget`,title:`势斩:选择一名其他角色,令其视为对你使用一张决斗(限两次/阶段)`,description:`本阶段限两次`,targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players.find(e=>e.index===t);return!(!n||n.alive===!1)}}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx]?.turnUsage?.[Zj];return(typeof t==`number`?t:0)<Qj}})}var Yj,Xj,Zj,Qj,$j,ule=t((()=>{V(),z(),J(),F(),Gh(),Yj=`界势斩`,Xj=`势斩`,Zj=`${Yj}/usedThisTurn`,Qj=2,$j={createSkill:Gj,onInit:qj,onMount:Jj}})),dle=r({createSkill:()=>eM,default:()=>fM,onInit:()=>nM,onMount:()=>rM});function eM(e,t){return{id:e,ownerId:t,name:iM,description:`摸牌阶段结束时弃置一张牌,本回合可将与之颜色不同的牌当决斗使用;结束阶段获得本回合对你造成伤害的牌`}}function tM(e){return`${e}#界双雄`}function nM(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==uM&&a!==dM)return`当前不是双雄询问`;if(a===dM){let r=t.cardId;if(typeof r!=`string`)return`请选择一张手牌`;if(!e.players[n].hand.includes(r))return`牌不在手牌中`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===uM?e.localVars[oM]=t.choice===!0:r===dM&&typeof t.cardId==`string`&&(e.localVars[sM]=t.cardId)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`摸牌`&&t.player===n&&(e.state.localVars[aM]=n)}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`摸牌`||t.player!==n||e.state.localVars[aM]!==n)return;delete e.state.localVars[aM];let r=e.state.players[n];if(!r?.alive||r.hand.length===0||(delete e.state.localVars[oM],await B(e.state,{type:`请求回应`,requestType:uM,target:n,prompt:{type:`confirm`,title:`是否发动双雄?(弃置一张牌,本回合可将与之颜色不同的牌当决斗使用)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[oM]!==!0))return;delete e.state.localVars[sM],await B(e.state,{type:`请求回应`,requestType:dM,target:n,prompt:{type:`useCard`,title:`双雄:选择一张手牌弃置(本回合与之颜色不同的牌当决斗)`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let i=e.state.localVars[sM];if(delete e.state.localVars[sM],!i||!r.hand.includes(i))return;let a=e.state.cardMap[i];if(!a)return;await B(e.state,{type:`弃置`,player:n,cardIds:[i],voluntary:!0});let o=a.color;e.state.turn.vars[cM]=o,await B(e.state,{type:`回合用量`,player:n,key:cM,value:o})}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=t.cardId;if(!r)return;let i=e.state.cardMap[r];if(!i)return;let a=i.shadowOf??r,o=e.state.turn.vars[lM]??[];o.includes(a)||(o.push(a),e.state.turn.vars[lM]=o)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n||!e.state.players[n]?.alive)return;let r=e.state.turn.vars[lM]??[];if(r.length!==0){for(let t of r)e.state.zones.discardPile.includes(t)&&e.state.cardMap[t]&&await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}});delete e.state.turn.vars[lM]}}),j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=e.turn.vars[cM],l=typeof c==`string`&&c!==``,u=t.cardId,d=typeof u==`string`,f=d&&o.hand.includes(u),p=d?e.cardMap[u]:void 0,m=!!p,h=!!p&&!!c&&p.color!==c;return r&&i&&a&&s&&l&&f&&m&&h?null:`双雄:需要一张与本回合弃置牌颜色不同的手牌`},async(e,t)=>{let r=t.cardId,i=tM(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`决斗`})},(e,t)=>{let r=t.cardId,i=tM(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),()=>{}}function rM(e,t){t.defineAction(`respond`,{label:iM,style:`primary`,prompt:{type:`confirm`,title:`是否发动双雄?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),t.defineAction(`transform`,{label:iM,style:`danger`,prompt:{type:`useCardAndTarget`,title:`选择一张与本回合弃置牌颜色不同的手牌当决斗使用`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1}},transform:t=>({name:`决斗`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];if(!t?.hand)return!1;let n=t.turnUsage?.[cM];return typeof n!=`string`||n===``?!1:t.hand.some(e=>e.color!==n)}})}var iM,aM,oM,sM,cM,lM,uM,dM,fM,fle=t((()=>{V(),F(),J(),W(),iM=`双雄`,aM=`界双雄/normalDrawPhase`,oM=`界双雄/activate`,sM=`界双雄/discardCard`,cM=Hl,lM=`界双雄/damageCards`,uM=`界双雄/activate`,dM=`界双雄/pick`,fM={createSkill:eM,onInit:nM,onMount:rM}})),ple=r({createSkill:()=>pM,default:()=>vM,onInit:()=>mM,onMount:()=>hM});function pM(e,t){return{id:e,ownerId:t,name:`界反间`,description:`出牌阶段限一次,展示并交给一名其他角色一张手牌,其选择:弃置同色牌或失去1点体力`}}function mM(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`反间`))return`本回合已使用过反间`;if(r.hand.length===0)return`需要有手牌才能发动反间`;let i=t.cardId;if(typeof i!=`string`||!r.hand.includes(i))return`需要选择一张手牌`;let a=t.targets;if(!Array.isArray(a)||a.length!==1)return`需要指定一名目标`;let o=a[0];return o===n?`不能对自己使用反间`:e.players[o]?.alive?null:`目标不合法`},async(e,t)=>{let r=n,i=t.targets[0],a=t.cardId;if(await Z(e,r,`反间`),await I(e,`界反间`,r,{...t}),await B(e,{type:`移动牌`,cardId:a,from:{zone:`手牌`,player:r},to:{zone:`手牌`,player:i}}),delete e.localVars[_M],await B(e,{type:`请求回应`,requestType:gM,target:i,prompt:{type:`confirm`,title:`反间:展示所有手牌弃置同色牌,或失去1点体力`,confirmLabel:`展示并弃置同色牌`,cancelLabel:`失去1点体力`},defaultChoice:!1,timeout:30}),e.localVars[_M]===!0){let t=e.cardMap[a]?.suit,n=e.players[i];if(t&&n?.alive){let r=n.hand.filter(n=>e.cardMap[n]?.suit===t);r.length>0&&await B(e,{type:`弃置`,player:i,cardIds:r})}}else e.players[i]?.alive&&await B(e,{type:`失去体力`,target:i,amount:1});await L(e)});let r=[];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;return r.type===`请求回应`?r.requestType===gM?typeof t.choice==`boolean`?null:`需要选择一项`:`当前不是反间二选一`:`当前不需要回应`},async(e,t)=>{e.localVars[_M]=t.choice===!0});r.push(a)}return()=>{r.forEach(e=>e())}}function hM(e,t){return t.defineAction(`use`,{label:`界反间`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`反间:选一张手牌展示并交给一名其他角色`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(t,n)=>n!==e.ownerId}},activeWhen:e=>yh(`反间`)(e)&&(e.view.players[e.perspectiveIdx]?.hand?.length??0)>0}),t.defineAction(`respond`,{label:`界反间`,style:`danger`,prompt:{type:`confirm`,title:`反间:展示所有手牌弃置同色牌,或失去1点体力`,confirmLabel:`展示并弃置同色牌`,cancelLabel:`失去1点体力`}}),()=>{}}var gM,_M,vM,mle=t((()=>{V(),z(),Q(),F(),gM=`界反间/choice`,_M=`反间/choice`,vM={createSkill:pM,onInit:mM,onMount:hM}})),hle=r({createSkill:()=>yM,default:()=>xM,onInit:()=>bM});function yM(e,t){return{id:e,ownerId:t,name:`界咆哮`,description:`锁定技:出牌阶段使用【杀】无次数限制;杀被【闪】抵消时摸一张牌`,isLocked:!0}}function bM(e,t){let n=e.ownerId,r=eh(t,n,()=>!0),i=N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`出牌`&&t.player===n&&await B(e.state,{type:`回合用量`,player:n,key:qc(`界咆哮`),value:!0})}),a=N(t,e.id,n,`被抵消`,async e=>{e.frame.skillId===`杀`&&e.atom.source===n&&await B(e.state,{type:`摸牌`,player:n,count:1})});return()=>{r(),i(),a()}}var xM,gle=t((()=>{V(),F(),fh(),W(),xM={createSkill:yM,onInit:bM}})),_le=r({createSkill:()=>SM,default:()=>NM,onInit:()=>CM,onMount:()=>wM});function vle(e){return`界固政/弃牌/${e}`}function yle(e){for(let t of[...Object.keys(e.localVars)])t.startsWith(`界固政/`)&&delete e.localVars[t]}function SM(e,t){return{id:e,ownerId:t,name:TM,description:`每阶段限一次,其他角色≥2张牌因弃置置入弃牌堆后,可将其中一张交给该角色,然后可获其余`}}function CM(e,t){let n=e.ownerId;return N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.player===n)return;let r=e.state;if(!r.players[n]?.alive)return;let i=vle(t.player),a=[...r.localVars[i]??[],...t.cardIds];if(r.localVars[i]=a,r.localVars[MM]||a.length<2)return;r.localVars[MM]=!0;let o=t.player,s=[...a];if(await I(r,TM,n,{target:o,cardIds:s}),delete r.localVars[kM],await B(r,{type:`请求回应`,requestType:EM,target:n,prompt:{type:`confirm`,title:`是否发动界固政?(${r.players[o]?.name??``} 弃置了 ${s.length} 张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),r.localVars[kM]!==!0){await L(r);return}let c=s.filter(e=>r.zones.discardPile.includes(e));if(c.length===0){await L(r);return}let l;if(c.length===1)l=c[0];else{delete r.localVars[AM],await B(r,{type:`请求回应`,requestType:DM,target:n,prompt:{type:`pickProcessingCard`,title:`界固政:选择一张牌交给该角色(其余你可获得)`,cards:c.map(e=>{let t=r.cardMap[e];return{cardId:e,cardName:t?.name??`?`,suit:t?.suit??``,rank:t?.rank??``}})},defaultChoice:c[0],timeout:30});let e=r.localVars[AM];l=e&&c.includes(e)?e:c[0]}await B(r,{type:`移动牌`,cardId:l,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:o}});let u=c.filter(e=>e!==l);if(u.length>0&&(delete r.localVars[jM],await B(r,{type:`请求回应`,requestType:OM,target:n,prompt:{type:`confirm`,title:`是否获得其余 ${u.length} 张牌?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!1,timeout:30}),r.localVars[jM]===!0))for(let e of u)await B(r,{type:`移动牌`,cardId:e,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}});await L(r)}),N(t,e.id,n,`阶段结束`,async e=>{yle(e.state)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是界固政窗口`;let i=r.atom;return i.requestType===EM||i.requestType===OM?null:i.requestType===DM?typeof t.cardId==`string`?null:`需要选择一张牌`:`当前不是界固政窗口`},async(e,t)=>{let r=e.pendingSlots.get(n).atom;r.requestType===EM?e.localVars[kM]=t.choice===!0||t.confirmed===!0:r.requestType===DM?e.localVars[AM]=t.cardId:r.requestType===OM&&(e.localVars[jM]=t.choice===!0||t.confirmed===!0)}),()=>{}}function wM(e,t){return()=>{}}var TM,EM,DM,OM,kM,AM,jM,MM,NM,ble=t((()=>{V(),z(),F(),TM=`界固政`,EM=`界固政/确认`,DM=`界固政/选牌`,OM=`界固政/获其余`,kM=`界固政/确认结果`,AM=`界固政/所选牌`,jM=`界固政/获其余结果`,MM=`界固政/已触发`,NM={createSkill:SM,onInit:CM,onMount:wM}})),xle=r({createSkill:()=>LM,default:()=>YM,onInit:()=>RM,onMount:()=>zM});function PM(e){return!!e&&e.suit===`♦`}function FM(e,t){return e.hand.includes(t)?!0:Object.values(e.equipment).some(e=>e===t)}function IM(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function LM(e,t){return{id:e,ownerId:t,name:`界国色`,description:`出牌阶段限一次,选一项后摸一张牌:①方片牌当乐不思蜀使用;②弃方片牌和场上乐不思蜀`}}function RM(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`界国色`))return`本回合已使用过界国色`;let r=e.players[n];return r?.alive?[...r.hand,...Object.values(r.equipment).filter(e=>typeof e==`string`)].some(t=>PM(e.cardMap[t]))?null:`需要一张方片牌`:`玩家不存在或已死亡`},async(e,t)=>{await Z(e,n,`界国色`),await I(e,`界国色`,n,{}),delete e.localVars[GM],await B(e,{type:`请求回应`,requestType:VM,target:n,prompt:{type:`confirm`,title:`界国色:选择一项(然后摸一张牌)`,confirmLabel:`①方片当乐使用`,cancelLabel:`②弃方片+弃场上乐`},defaultChoice:!1,timeout:15});let r=e.localVars[GM];delete e.localVars[GM],r===`use`?await Sle(e,n):await Cle(e,n),e.players[n]?.alive&&await B(e,{type:`摸牌`,player:n,count:1}),await L(e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=IM(e,n);if(r!==VM&&r!==HM&&r!==UM&&r!==WM)return`当前不是界国色询问`;if(r===VM)return null;let i=e.players[n];if(!i?.alive)return`玩家不可用`;if(r===HM){let r=t.cardId;if(typeof r!=`string`)return`请选择一张方片牌`;if(!FM(i,r))return`牌不在手牌或装备区`;if(!PM(e.cardMap[r]))return`需要一张方片牌`;let a=t.target??t.targets?.[0];return typeof a==`number`?a===n?`不能对自己使用`:e.players[a]?.alive?e.players[a].pendingTricks.some(e=>e.name===BM)?`目标判定区已有乐不思蜀`:null:`目标不存在或已死亡`:`请选择目标`}if(r===UM){let n=t.cardId;return typeof n==`string`?FM(i,n)?PM(e.cardMap[n])?null:`需要一张方片牌`:`牌不在手牌或装备区`:`请选择一张方片牌弃置`}let a=t.target;if(typeof a!=`number`)return`请选择一名角色`;let o=e.players[a];return o?.alive?o.pendingTricks.some(e=>e.name===BM)?null:`该角色判定区没有乐不思蜀`:`目标无效`},async(e,t)=>{let r=IM(e,n),i=t.choice===!0||t.confirmed===!0;r===VM?e.localVars[GM]=i?`use`:`remove`:r===HM?(e.localVars[KM]=t.cardId??null,e.localVars[qM]=t.target??t.targets?.[0]??null):r===UM?e.localVars[KM]=t.cardId??null:r===WM&&(e.localVars[JM]=t.target??null)}),()=>{}}async function Sle(e,t){if(!e.players[t]?.alive)return;delete e.localVars[KM],delete e.localVars[qM],await B(e,{type:`请求回应`,requestType:HM,target:t,prompt:{type:`useCardAndTarget`,title:`界国色:选一张方片牌当乐不思蜀,选一名其他角色(无距离限制)`,cardFilter:{filter:e=>e.suit===`♦`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,n)=>n!==t&&e.players[n]?.alive===!0}},timeout:20});let n=e.localVars[KM],r=e.localVars[qM];if(delete e.localVars[KM],delete e.localVars[qM],typeof n!=`string`||typeof r!=`number`||!e.players[r]?.alive)return;let i=Object.entries(e.players[t].equipment).find(([,e])=>e===n);i&&await B(e,{type:`卸下`,player:t,slot:i[0]}),await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:t},to:{zone:`处理区`}}),await B(e,{type:`添加延时锦囊`,player:r,trick:{name:BM,source:t,card:e.cardMap[n]??{id:n,name:BM,suit:`♦`,color:`红`,rank:`A`,type:`锦囊牌`}}}),await B(e,{type:`移动牌`,cardId:n,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}async function Cle(e,t){if(!e.players[t]?.alive)return;delete e.localVars[KM],await B(e,{type:`请求回应`,requestType:UM,target:t,prompt:{type:`useCard`,title:`界国色:选一张方片牌弃置`,cardFilter:{filter:e=>e.suit===`♦`,min:1,max:1}},timeout:20});let n=e.localVars[KM];if(delete e.localVars[KM],typeof n!=`string`)return;delete e.localVars[JM],await B(e,{type:`请求回应`,requestType:WM,target:t,prompt:{type:`choosePlayer`,title:`界国色:选择要弃置其乐不思蜀的角色`,min:1,max:1,candidates:e.players.map((e,t)=>({p:e,i:t})).filter(({p:e,i:n})=>n!==t&&e.alive&&e.pendingTricks.some(e=>e.name===BM)).map(({i:e})=>e)},timeout:20});let r=e.localVars[JM];if(delete e.localVars[JM],typeof r!=`number`)return;let i=e.players[r];i?.alive&&i.pendingTricks.some(e=>e.name===BM)&&(await B(e,{type:`弃置`,player:t,cardIds:[n],voluntary:!0}),await B(e,{type:`移除延时锦囊`,player:r,trickName:BM}))}function zM(e,t){return t.defineAction(`use`,{label:`界国色`,style:`primary`,prompt:{type:`confirm`,title:`界国色:选一项后摸一张牌`,confirmLabel:`发动`,cancelLabel:`不发动`},activeWhen:e=>{if(!yh(`界国色`)(e))return!1;let t=e.view.players[e.perspectiveIdx],n=(t?.hand??[]).some(e=>e.suit===`♦`),r=Object.values(t?.equipment??{}).some(t=>e.view.cardMap[t]?.suit===`♦`);return n||r}}),t.defineAction(`respond`,{label:`界国色`,style:`primary`,prompt:{type:`confirm`,title:`界国色`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var BM,VM,HM,UM,WM,GM,KM,qM,JM,YM,wle=t((()=>{V(),z(),Q(),F(),BM=`乐不思蜀`,VM=`界国色/option`,HM=`界国色/use`,UM=`界国色/removeCard`,WM=`界国色/removeTarget`,GM=`界国色/option`,KM=`界国色/cardId`,qM=`界国色/target`,JM=`界国色/trickTarget`,YM={createSkill:LM,onInit:RM,onMount:zM}})),Tle=r({createSkill:()=>$M,default:()=>lN,onInit:()=>eN,onMount:()=>tN});function XM(e,t,n){let r=e.cardMap[n];if(!r)return!1;if(r.suit===`♥`)return!0;let i=e.players[t]?.skills??[];return!!(r.suit===`♠`&&(i.includes(`红颜`)||i.includes(`界红颜`)))}function Ele(e){let t=Object.values(e.equipment).filter(e=>typeof e==`string`);return[...e.hand,...t]}function ZM(e,t){return e.hand.includes(t)?!0:Object.values(e.equipment).some(e=>e===t)}function QM(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function $M(e,t){return{id:e,ownerId:t,name:`界天香`,description:`受到伤害时,弃一张红桃牌防止之,令一名其他角色二选一:①受来源1伤害并摸X(X为已损失体力至多5);②失去1体力并获得弃置的牌`}}function eN(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=QM(e,n);if(r!==nN&&r!==rN&&r!==iN)return`当前不是界天香询问`;if(r===nN||r===iN)return null;let i=t.cardId,a=t.target;if(typeof i!=`string`)return`请选择一张红桃牌`;let o=e.players[n];return o?.alive?ZM(o,i)?XM(e,n,i)?typeof a==`number`?a===n?`不能选择自己`:e.players[a]?.alive?null:`目标无效`:`请选择一名其他角色`:`必须选择红桃牌`:`牌不在手牌或装备区`:`玩家不可用`},async(e,t)=>{let r=QM(e,n),i=t.choice===!0||t.confirmed===!0;r===nN?e.localVars[aN]=i:r===rN?(e.localVars[oN]=t.cardId??null,e.localVars[sN]=t.target??null):r===iN&&(e.localVars[cN]=i?`damage`:`lose`)}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=e.state.players[n];if(!r?.alive)return;let i=Ele(r).filter(t=>XM(e.state,n,t));if(i.length===0||!e.state.players.some((e,t)=>t!==n&&e.alive)||(delete e.state.localVars[aN],await B(e.state,{type:`请求回应`,requestType:nN,target:n,prompt:{type:`confirm`,title:`是否发动界天香(弃红桃牌防止伤害)?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[aN]))return;delete e.state.localVars[oN],delete e.state.localVars[sN];let a=r.skills,o=a.includes(`红颜`)||a.includes(`界红颜`);await B(e.state,{type:`请求回应`,requestType:rN,target:n,prompt:{type:`useCardAndTarget`,title:`界天香:弃一张红桃牌(手牌或装备区),选择一名其他角色`,cardFilter:{filter:e=>e.suit===`♥`||o&&e.suit===`♠`,candidates:i,min:1,max:1},targetFilter:{min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0}},timeout:15});let s=e.state.localVars[oN],c=e.state.localVars[sN];if(delete e.state.localVars[aN],delete e.state.localVars[oN],delete e.state.localVars[sN],typeof s!=`string`||typeof c!=`number`||c===n)return;let l=e.state.players[c];if(!l?.alive||!ZM(r,s)||!XM(e.state,n,s))return;delete e.state.localVars[cN],await B(e.state,{type:`请求回应`,requestType:iN,target:n,prompt:{type:`confirm`,title:`界天香:令 ${l.name} ①受来源1点伤害并摸X张牌?(确认=①,取消=②失去1体力并获得弃牌)`,confirmLabel:`①受伤害+摸牌`,cancelLabel:`②失去体力+获牌`},defaultChoice:!1,timeout:15});let u=e.state.localVars[cN];delete e.state.localVars[cN];let d=u===`damage`;if(await B(e.state,{type:`弃置`,player:n,cardIds:[s],voluntary:!0}),d){let r=t.source??n;if(await Dm(e.state,r,c,1,void 0,t.damageType),l.alive){let t=l.maxHealth-p(l),n=Math.min(t,5);n>0&&await B(e.state,{type:`摸牌`,player:c,count:n})}}else await B(e.state,{type:`失去体力`,target:c,amount:1}),l.alive&&e.state.zones.discardPile.includes(s)&&await B(e.state,{type:`移动牌`,cardId:s,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:c}});return{kind:`cancel`}}),()=>{}}function tN(e,t){t.defineAction(`respond`,{label:`界天香`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界天香?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var nN,rN,iN,aN,oN,sN,cN,lN,Dle=t((()=>{b(),V(),Om(),F(),nN=`界天香/confirm`,rN=`界天香/choose`,iN=`界天香/option`,aN=`界天香/confirmed`,oN=`界天香/cardId`,sN=`界天香/target`,cN=`界天香/option`,lN={createSkill:$M,onInit:eN,onMount:tN}})),Ole=r({QICAI_ARMOR_TAG:()=>mN,QICAI_TAG:()=>pN,QICAI_TREASURE_TAG:()=>hN,createSkill:()=>uN,default:()=>gN,onInit:()=>dN,onMount:()=>fN});function uN(e,t){return{id:e,ownerId:t,name:`界奇才`,description:`锁定技:你使用任何锦囊牌无距离限制;其他角色不能弃置你装备区的防具或宝物`,isLocked:!0}}function dN(e,t){let n=e.ownerId,r=t.players[n];r&&(r.tags.includes(`奇才/无距离限制`)||r.tags.push(pN),r.tags.includes(`奇才/防具保护`)||r.tags.push(mN),r.tags.includes(`奇才/宝物保护`)||r.tags.push(hN));let i=M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.prompt?.type!==`pickTargetCard`||t.prompt?.mode!==`discard`)return;let r=t.prompt?.target;typeof r==`number`&&r===n&&t.prompt?.equipment&&(t.prompt.equipment=t.prompt.equipment.filter(e=>!(e.slot===`防具`||e.slot===`宝物`)))});return()=>{i();let e=t.players[n];e&&(e.tags=e.tags.filter(e=>e!==`奇才/无距离限制`&&e!==`奇才/防具保护`&&e!==`奇才/宝物保护`))}}function fN(){}var pN,mN,hN,gN,kle=t((()=>{F(),pN=`奇才/无距离限制`,mN=`奇才/防具保护`,hN=`奇才/宝物保护`,gN={createSkill:uN,onInit:dN,onMount:fN}})),Ale=r({createSkill:()=>_N,default:()=>CN,onInit:()=>vN,onMount:()=>yN});function _N(e,t){return{id:e,ownerId:t,name:`界奸雄`,description:`当你受到伤害后,你可以摸一张牌,并获得造成此伤害的牌`}}function vN(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);return t?.atom.type===`请求回应`?t.atom.requestType===bN?null:`当前不是奸雄选择`:`当前不需要回应`},async(e,t)=>{e.localVars[SN]=t.choice===!0}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(delete e.state.localVars[xN],(t.amount??0)<=0))return;let r=t.cardId,i=typeof r==`string`&&!!e.state.cardMap[r],a=i?e.state.cardMap[r].shadowOf??r:r;if(delete e.state.localVars[SN],await B(e.state,{type:`请求回应`,requestType:bN,target:n,prompt:{type:`confirm`,title:i?`界奸雄:是否发动?(摸一张牌并获得造成此伤害的牌)`:`界奸雄:是否发动?(无伤害牌可获得,仅摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[SN]!==!0){delete e.state.localVars[SN];return}await B(e.state,{type:`摸牌`,player:n,count:1}),i&&(e.state.localVars[xN]=a),delete e.state.localVars[SN]}),N(t,e.id,n,`移动牌`,async e=>{let t=e.state.localVars[xN];typeof t==`string`&&e.atom.to?.zone===`弃牌堆`&&e.state.zones.discardPile.includes(t)&&e.state.cardMap[t]&&await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}})}),()=>{}}function yN(e,t){t.defineAction(`respond`,{label:`界奸雄`,style:`default`,prompt:{type:`confirm`,title:`是否发动奸雄?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var bN,xN,SN,CN,jle=t((()=>{V(),F(),bN=`界奸雄/choose`,xN=`奸雄/wantCard`,SN=`奸雄/choice`,CN={createSkill:_N,onInit:vN,onMount:yN}}));function wN(e){return e.type===`锦囊牌`&&e.trickSubtype===`延时锦囊`}function Mle(e){return e.name===`闪`||e.trickSubtype===`响应锦囊`}function Nle(){return TN}var TN,EN=t((()=>{G(),Sm(),TN=new Set(Sd.map(e=>e.name).filter(e=>ym(e)))})),Ple=r({createSkill:()=>DN,default:()=>WN,onInit:()=>kN,onMount:()=>AN});function DN(e,t){return{id:e,ownerId:t,name:UN,description:`摸牌阶段多摸两张,手牌>5时分半给最少者;给牌后直到下回合开始,成为杀/普通锦囊目标时其可给你一张牌`}}async function ON(e,t,n){delete e.localVars[zN],await B(e,{type:`请求回应`,requestType:RN,target:n,prompt:{type:`useCard`,title:`好施:是否交给${e.players[t].name}一张手牌?(可不打=不交)`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let r=e.localVars[zN];delete e.localVars[zN],r&&e.players[n]?.hand.includes(r)&&await B(e,{type:`给予`,cardId:r,from:n,to:t})}function kN(e,t){let n=e.ownerId,r=[];for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;return r.type===`请求回应`?r.requestType?.startsWith(`界好施/`)?null:`当前不是界好施询问`:`当前不需要回应`},async(e,t)=>{let n=e.pendingSlots.get(i),r=n?.atom?.requestType;if(r===jN)e.localVars[PN]=t.choice===!0||t.confirmed===!0;else if(r===MN){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[IN]=n)}else if(r===NN){let r=t.cardIds,a=(n?.atom)?.prompt?.cardFilter?.min;Array.isArray(r)&&typeof a==`number`&&r.length===a&&new Set(r).size===r.length&&r.every(t=>e.players[i]?.hand.includes(t))&&(e.localVars[LN]=r)}else if(r===RN){let n=t.cardIds??t.cardId,r=Array.isArray(n)?n:typeof n==`string`?[n]:void 0;r&&r.length>0&&(e.localVars[zN]=r[0])}}))}return r.push(M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive||X(e.state,n,`界好施`)||(delete e.state.localVars[PN],await B(e.state,{type:`请求回应`,requestType:jN,target:n,prompt:{type:`confirm`,title:`是否发动好施?(额外摸两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[PN]))return;await Z(e.state,n,`界好施`),e.state.localVars[FN]=!0;let r=t.count??2;return{kind:`modify`,atom:{...e.atom,count:r+2}}})),r.push(N(t,e.id,n,`摸牌`,async e=>{if(e.atom.player!==n||!e.state.localVars[FN])return;delete e.state.localVars[FN];let t=e.state,r=t.players[n];if(!r?.alive)return;let i=r.hand.length;if(i<=5)return;let a=Math.floor(i/2),o=1/0,s=[];for(let e of t.players)e.index===n||!e.alive||(e.hand.length<o?(o=e.hand.length,s.length=0,s.push(e.index)):e.hand.length===o&&s.push(e.index));if(s.length===0)return;let c;if(s.length===1)c=s[0];else{delete t.localVars[IN],await B(t,{type:`请求回应`,requestType:MN,target:n,prompt:{type:`choosePlayer`,title:`好施:选择手牌最少的角色(给予手牌)`,min:1,max:1,filter:(e,t)=>s.includes(t)},timeout:15});let e=t.localVars[IN];if(delete t.localVars[IN],typeof e!=`number`)return;c=e}delete t.localVars[LN],await B(t,{type:`请求回应`,requestType:NN,target:n,prompt:{type:`useCard`,title:`好施:选择 ${a} 张牌交给 ${t.players[c].name}`,cardFilter:{filter:()=>!0,min:a,max:a}},mandatory:!0,timeout:30});let l=t.localVars[LN];if(delete t.localVars[LN],(!l||l.length===0)&&(l=t.players[n]?.hand.slice(0,a)??[]),l&&l.length>0){for(let e of l)await B(t,{type:`给予`,cardId:e,from:n,to:c});t.localVars[BN]=!0,t.localVars[VN]=c}})),r.push(N(t,e.id,n,`回合开始`,async e=>{e.atom.player===n&&(delete e.state.localVars[BN],delete e.state.localVars[VN])})),r.push(N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n)return;let r=e.state;if(!r.localVars[BN])return;let i=r.localVars[VN];if(typeof i!=`number`||!r.players[i]?.alive||r.players[i].hand.length===0)return;let a=t.cardId;if(!a||!r.cardMap[a]?.name.includes(`杀`))return;let o=`${HN}${a}`;r.localVars[o]||(r.localVars[o]=!0,await ON(r,n,i))})),r.push(M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.requestType!==`无懈可击`||t.cancelTarget!==n)return;let r=e.state;if(!r.localVars[BN])return;let i=r.localVars[VN];if(typeof i!=`number`||!r.players[i]?.alive||r.players[i].hand.length===0)return;let a=Ke(r);if(!a)return;let o=a.params?.cardId;if(!o)return;let s=r.cardMap[o];if(!s||wN(s)||Mle(s))return;let c=`${HN}${o}`;r.localVars[c]||(r.localVars[c]=!0,await ON(r,n,i))})),()=>r.forEach(e=>e())}function AN(e,t){return t.defineAction(`respond`,{label:UN,style:`primary`,prompt:{type:`confirm`,title:UN,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var jN,MN,NN,PN,FN,IN,LN,RN,zN,BN,VN,HN,UN,WN,Fle=t((()=>{V(),z(),Q(),EN(),F(),jN=`界好施/confirm`,MN=`界好施/target`,NN=`界好施/give`,PN=`界好施/confirmed`,FN=`界好施/active`,IN=`界好施/chosenTarget`,LN=`界好施/giveCards`,RN=`界好施/passiveGive`,zN=`界好施/passiveCard`,BN=`界好施/被动激活`,VN=`界好施/受益者`,HN=`界好施/被动已触发/`,UN=`好施`,WN={createSkill:DN,onInit:kN,onMount:AN}})),Ile=r({createSkill:()=>GN,default:()=>XN,onInit:()=>qN});function GN(e,t){return{id:e,ownerId:t,name:JN,description:`锁定技,在你的回合内,只有你和处于濒死状态的角色才能使用【桃】;任意濒死结算中,除你和濒死者外其他角色的非锁定技失效`,isLocked:!0}}function Lle(e){return e.players.some(e=>e.alive&&e.health<=0)}function KN(e){if(!Lle(e))for(let t of e.players)t&&t.tags.includes(YN)&&(t.tags=t.tags.filter(e=>e!==YN))}function qN(e,t){let n=e.ownerId,r=[];return r.push(je(t,(e,t,n)=>e.players[t]?.tags.includes(YN)===!0)),r.push(M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.requestType!==`桃/求桃`||e.state.currentPlayerIndex!==n)return;let r=t.target;if(typeof r!=`number`||r===n)return;let i=e.state.players[r];if(!(i?.alive&&i.health<=0))return{kind:`cancel`}})),r.push(M(t,e.id,n,`陷入濒死`,async e=>{if(e.state.currentPlayerIndex===n&&typeof e.atom.target==`number`)for(let t=0;t<e.state.players.length;t++){if(t===n)continue;let r=e.state.players[t];r?.alive&&(r.health<=0||r.tags.includes(YN)||r.tags.push(YN))}})),r.push(N(t,e.id,n,`死亡后`,async e=>{KN(t)})),r.push(N(t,e.id,n,`回复体力`,async e=>{KN(t)})),()=>{for(let e of r)e()}}var JN,YN,XN,Rle=t((()=>{F(),Pe(),JN=`完杀`,YN=`完杀/非锁定技失效`,XN={createSkill:GN,onInit:qN}})),zle=r({createSkill:()=>ZN,default:()=>nP,onInit:()=>QN,onMount:()=>$N});function ZN(e,t){return{id:e,ownerId:t,name:eP,description:`锁定技:手牌上限+X(X为全场势力数);其他角色对你造成伤害时,防止此伤害改为令其摸一张牌,每种势力限一次`,isLocked:!0}}function Ble(e){let t=new Set;for(let n of e.players)n.alive&&n.faction&&t.add(n.faction);return t.size}function Vle(e,t,n){return e.players[t]?.vars[tP+n]===!0}function Hle(e,t,n){let r=e.players[t];r&&(r.vars[tP+n]=!0)}function QN(e,t){let n=e.ownerId,r=rp(t,n,(e,t)=>{if(t!==n)return;let r=e.players[t];if(!r)return;let i=sl(e.turn.vars,t)??0;return p(r)+i+Ble(e)}),i=M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=t.source;if(r===void 0||r===n)return;let i=e.state.players[n],a=e.state.players[r];if(!i?.alive||!a?.alive)return;let o=a.faction;if(o&&!Vle(e.state,n,o))return Hle(e.state,n,o),await B(e.state,{type:`摸牌`,player:r,count:1}),{kind:`cancel`}});return()=>{r(),i()}}function $N(e,t){return()=>{}}var eP,tP,nP,Ule=t((()=>{b(),V(),F(),op(),W(),eP=`宗室`,tP=`宗室/防伤/`,nP={createSkill:ZN,onInit:QN,onMount:$N}}));async function rP(e,t,n){await B(e,{type:`弃置`,player:t,cardIds:[n],voluntary:!0}),await B(e,{type:`摸牌`,player:t,count:1})}var iP=t((()=>{V()})),Wle=r({createSkill:()=>aP,default:()=>yP,onInit:()=>sP,onMount:()=>cP});function aP(e,t){return{id:e,ownerId:t,name:lP,description:`摸牌阶段结束时选择一项:①摸一张牌,本回合杀次数-1且杀不计入手牌上限;②重铸一张牌,本回合杀次数+1且杀无距离限制`}}function oP(e,t){return e.pendingSlots.get(t)?.atom?.requestType}function sP(e,t){let n=e.ownerId,r=oh(t,n,(e,t)=>e.turn.vars[_P]===t),i=ate(t,n,(e,t)=>e.turn.vars[vP]===t?2:0),a=qm(t,n,(e,t,n,r)=>e.turn.vars[vP]===t),o=rp(t,n,(e,t)=>{if(e.turn.vars[_P]!==t)return;let n=e.players[t];if(!n)return;let r=n.hand.filter(t=>e.cardMap[t]?.name===`杀`).length;if(r===0)return;let i=sl(e.turn.vars,t)??0;return p(n)+i+r});return j(t,e.id,n,`respond`,e=>{let t=oP(e,n);return t!==mP&&t!==hP&&t!==gP?`当前不是将驰询问`:null},async(e,t)=>{let r=oP(e,n);r===mP?e.localVars[dP]=t.choice===!0:r===hP?e.localVars[fP]=t.choice===!0:r===gP&&typeof t.cardId==`string`&&(e.localVars[pP]=t.cardId)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`摸牌`&&t.player===n&&(e.state.localVars[uP]=n)}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`摸牌`||t.player!==n||e.state.localVars[uP]!==n)return;delete e.state.localVars[uP];let r=e.state.players[n];if(!r?.alive||(delete e.state.localVars[dP],await B(e.state,{type:`请求回应`,requestType:mP,target:n,prompt:{type:`confirm`,title:`将驰:是否发动?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[dP]!==!0))return;let i=!0;if(r.hand.length>0&&(delete e.state.localVars[fP],await B(e.state,{type:`请求回应`,requestType:hP,target:n,prompt:{type:`confirm`,title:`将驰:选择一项 ①摸一张(杀次数-1,杀不计入手牌上限) ②重铸一张(杀次数+1,杀无距离限制)`,confirmLabel:`①摸一张`,cancelLabel:`②重铸一张`},defaultChoice:!0,timeout:10}),i=e.state.localVars[fP]!==!1),i){await B(e.state,{type:`摸牌`,player:n,count:1}),e.state.turn.vars[_P]=n,await B(e.state,{type:`回合用量`,player:n,key:Yc(`界将驰`),value:!0});return}if(r.hand.length===0)return;delete e.state.localVars[pP],await B(e.state,{type:`请求回应`,requestType:gP,target:n,prompt:{type:`useCard`,title:`将驰:选择一张手牌重铸`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:10});let a=e.state.localVars[pP];delete e.state.localVars[pP],!(!a||!r.hand.includes(a))&&(await rP(e.state,n,a),e.state.turn.vars[vP]=n,await B(e.state,{type:`回合用量`,player:n,key:vP,value:!0}),await B(e.state,{type:`回合用量`,player:n,key:Jc(`界将驰`),value:1}))}),()=>{r(),i(),a(),o()}}function cP(e,t){}var lP,uP,dP,fP,pP,mP,hP,gP,_P,vP,yP,Gle=t((()=>{b(),V(),iP(),F(),fh(),op(),Xm(),W(),lP=`将驰`,uP=`将驰/normalDrawPhase`,dP=`将驰/activateChoice`,fP=`将驰/optionChoice`,pP=`将驰/cardId`,mP=`界将驰/activate`,hP=`界将驰/choose`,gP=`界将驰/pick`,_P=`将驰/choice1`,vP=Fl,yP={createSkill:aP,onInit:sP,onMount:cP}})),Kle=r({createSkill:()=>bP,default:()=>kP,onInit:()=>SP,onMount:()=>CP});function bP(e,t){return{id:e,ownerId:t,name:`界屯田`,description:`回合外失去牌或回合内弃置杀时判定,非红桃则置于武将牌上为田,每张田与其他角色距离 -1`}}function xP(e,t){return e.players[t].marks.filter(e=>e.id.startsWith(OP)).length}function qle(e,t){let n=xP(e,t);n>0?e.players[t].vars[Sl]=n:delete e.players[t].vars[Sl]}function SP(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===wP?null:`当前不是屯田确认`:`当前不需要回应`},async(e,t)=>{e.localVars[TP]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.player!==n||t.judgeType!==`屯田`||!e.state.localVars[TP])return;let r=R(e.state);if(r.length===0)return;let i=r[r.length-1],a=e.state.cardMap[i];if(!a||(e.state.localVars[EP]=a.suit,e.state.localVars[DP]=i,a.suit===`♥`))return;await B(e.state,{type:`收取判定牌`,player:n,cardId:i});let o=xP(e.state,n)+1,s=`${OP}${e.state.seq}`;await B(e.state,{type:`加标记`,player:n,mark:{id:s,scope:n,payload:{cardId:i}},distanceVars:{attackMod:o}}),qle(e.state,n)});async function r(e,t){e.state.players[n]?.alive&&e.state.zones.deck.length!==0&&(delete e.state.localVars[TP],await B(e.state,{type:`请求回应`,requestType:wP,target:n,prompt:{type:`confirm`,title:`是否发动屯田?(因${t}失去牌,判定可能获得田)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[TP]&&(delete e.state.localVars[EP],delete e.state.localVars[DP],await jm(e.state,n,`屯田`),delete e.state.localVars[EP],delete e.state.localVars[DP]))}async function i(e,t){e.state.currentPlayerIndex!==n&&await r(e,t)}return N(t,e.id,n,`获得`,async e=>{let t=e.atom;t.type===`获得`&&t.from===n&&t.player!==n&&await i(e,`获得`)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.type===`移动牌`&&t.from.zone===`手牌`&&t.from.player===n&&(t.to.zone===`手牌`&&t.to.player===n||await i(e,`移动牌`))}),N(t,e.id,n,`给予`,async e=>{let t=e.atom;t.type===`给予`&&t.from===n&&t.to!==n&&await i(e,`给予`)}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type===`弃置`&&t.player===n)if(e.state.currentPlayerIndex===n){if(!(t.cardIds??[]).some(t=>e.state.cardMap[t]?.name===`杀`))return;await r(e,`回合内弃置杀`)}else await i(e,`弃置`)}),()=>{}}function CP(e,t){t.defineAction(`respond`,{label:`界屯田`,style:`primary`,prompt:{type:`confirm`,title:`是否发动屯田?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var wP,TP,EP,DP,OP,kP,Jle=t((()=>{V(),z(),Fm(),F(),W(),wP=`界屯田/confirm`,TP=`屯田/confirmed`,EP=`屯田/judgeSuit`,DP=`屯田/judgeCardId`,OP=`屯田/田:`,kP={createSkill:bP,onInit:SP,onMount:CP}})),Yle=r({createSkill:()=>AP,default:()=>IP,onInit:()=>jP,onMount:()=>MP});function AP(e,t){return{id:e,ownerId:t,name:`崩坏`,description:`锁定技:回合结束阶段,若你的体力不是全场最少的,须减1点体力或1点体力上限;界酒池酒杀造成伤害后本回合失效`,isLocked:!0}}function jP(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===NP?null:`当前不是崩坏选择`:`当前不需要回应`},async(e,t)=>{e.localVars[PP]=t.choice===!0?`maxHealth`:`health`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`)return;let r=e.state.players[n];if(!r?.alive||e.state.turn.vars[FP]===!0)return;let i=e.state.players.filter(e=>e.alive).reduce((e,t)=>Math.min(e,p(t)),1/0);if(p(r)<=i)return;delete e.state.localVars[PP],await B(e.state,{type:`请求回应`,requestType:NP,target:n,prompt:{type:`confirm`,title:`崩坏:减1点体力上限,还是减1点体力?`,confirmLabel:`减体力上限`,cancelLabel:`减体力`},defaultChoice:!1,timeout:15});let a=e.state.localVars[PP];delete e.state.localVars[PP],a===`maxHealth`?await B(e.state,{type:`设上限`,player:n,amount:r.maxHealth-1}):await B(e.state,{type:`失去体力`,target:n,amount:1})}),()=>{}}function MP(e,t){t.defineAction(`respond`,{label:`崩坏`,style:`default`,prompt:{type:`confirm`,title:`崩坏:减1点体力上限,还是减1点体力?`,confirmLabel:`减体力上限`,cancelLabel:`减体力`}})}var NP,PP,FP,IP,Xle=t((()=>{b(),V(),F(),NP=`界崩坏/choose`,PP=`崩坏/choice`,FP=`崩坏/disabled`,IP={createSkill:AP,onInit:jP,onMount:MP}})),Zle=r({createSkill:()=>LP,default:()=>sF,onInit:()=>VP,onMount:()=>HP});function LP(e,t){return{id:e,ownerId:t,name:`界巧变`,description:`游戏开始获得2枚"变"标记;弃一张牌或移除1枚"变"跳过阶段(摸牌:至多两名角色各获得一张手牌;出牌:移动场上的一张牌);结束阶段手牌数与历史均不相等则获得1枚"变"`}}function Qle(e,t){return e.players[t].marks.filter(e=>e.id.startsWith(iF)).length}async function RP(e,t){await B(e,{type:`加标记`,player:t,mark:{id:`${iF}${e.seq}`,scope:t}})}async function $le(e,t){let n=e.players[t].marks.find(e=>e.id.startsWith(iF));n&&await B(e,{type:`去标记`,player:t,markId:n.id})}function zP(e,t){let n=e.players[t].vars[rF];return Array.isArray(n)?n.filter(e=>typeof e==`number`):[]}function eue(e,t,n){let r=zP(e,t);e.players[t].vars[rF]=[...r,n]}function BP(e,t){let n=e.players[t];if(!n)return[];let r=[...n.hand],i=Object.values(n.equipment).filter(e=>!!e),a=n.pendingTricks.map(e=>e.card.id);return[...r,...i,...a]}function VP(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return[UP,WP,GP,KP,qP,JP,YP].includes(a)?null:`当前不是界巧变询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===UP){e.localVars[XP]=t.choice===!0;return}if(r===WP){e.localVars[ZP]=t.choice===!0?`变`:`discard`;return}if(r===GP){let n=t.cardIds,r=t.cardId,i=(Array.isArray(n)&&n.length>0?n[0]:void 0)??(typeof r==`string`?r:void 0);i&&(e.localVars[QP]=i);return}if(r===KP){let n=t.targets;Array.isArray(n)&&(e.localVars[$P]=n);return}if(r===qP){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[eF]=n);return}if(r===JP){let n=t.cardIds,r=t.cardId,i=(Array.isArray(n)&&n.length>0?n[0]:void 0)??(typeof r==`string`?r:void 0);i&&(e.localVars[tF]=i);return}if(r===YP){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[nF]=n);return}}),N(t,e.id,n,`回合开始`,async e=>{let t=e.state;t.players[n]?.alive&&(t.localVars[aF(n)]||(t.localVars[aF(n)]=!0,await RP(t,n),await RP(t,n)))}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||e.state.currentPlayerIndex!==n)return;let r=t.phase;if(!oF.includes(r))return;let i=e.state.players[n];if(!i?.alive||E(e.state))return;let a=i.hand.length>0,o=Qle(e.state,n)>0;if(!a&&!o||(delete e.state.localVars[XP],await B(e.state,{type:`请求回应`,requestType:UP,target:n,prompt:{type:`confirm`,title:`是否发动界巧变?(跳过${r}阶段)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[XP]))return;let s;a&&o?(delete e.state.localVars[ZP],await B(e.state,{type:`请求回应`,requestType:WP,target:n,prompt:{type:`confirm`,title:`界巧变:以何种方式跳过${r}阶段?`,description:`确认 = 移除1枚"变"标记;取消 = 弃置一张手牌`,confirmLabel:`移除1枚变`,cancelLabel:`弃置手牌`},defaultChoice:!1,timeout:10}),s=e.state.localVars[ZP]===`变`?`变`:`discard`,delete e.state.localVars[ZP]):s=o?`变`:`discard`;let c;if(!(s===`discard`&&(delete e.state.localVars[QP],await B(e.state,{type:`请求回应`,requestType:GP,target:n,prompt:{type:`distribute`,mode:`select`,title:`界巧变:选择一张手牌弃置以跳过${r}阶段`,source:`hand`,minTotal:1,maxTotal:1},timeout:15}),c=e.state.localVars[QP],delete e.state.localVars[QP],!c||!i.hand.includes(c)))){await I(e.state,`界巧变`,n,{phase:r,mode:s,discardCardId:c??null});try{if(s===`discard`&&c?await B(e.state,{type:`弃置`,player:n,cardIds:[c],voluntary:!0}):await $le(e.state,n),r===`摸牌`){let t=e.state.players.filter(e=>e.alive&&e.index!==n&&e.hand.length>0);if(t.length>0){delete e.state.localVars[$P],await B(e.state,{type:`请求回应`,requestType:KP,target:n,prompt:{type:`choosePlayer`,title:`界巧变:选择至多两名其他角色(各获得其一张手牌)`,min:0,max:Math.min(2,t.length),filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0&&(e.state.players[r]?.hand.length??0)>0},timeout:20});let r=e.state.localVars[$P]??[];delete e.state.localVars[$P];for(let t of r.slice(0,2)){let r=e.state.players[t];if(!r?.alive||r.hand.length===0)continue;let i=Ud(e.state.rngSeed),a=i.nextInt(r.hand.length);e.state.rngSeed=i.getState();let o=r.hand[a];await B(e.state,{type:`获得`,player:n,cardId:o,from:t})}}}else if(r===`出牌`&&e.state.players.filter(t=>t.alive&&BP(e.state,t.index).length>0).length>0){delete e.state.localVars[eF],await B(e.state,{type:`请求回应`,requestType:qP,target:n,prompt:{type:`choosePlayer`,title:`界巧变:选择源玩家(从其场上选一张牌移动)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0&&BP(e.state,n).length>0},timeout:15});let t=e.state.localVars[eF];if(delete e.state.localVars[eF],typeof t==`number`){let r=BP(e.state,t);delete e.state.localVars[tF],await B(e.state,{type:`请求回应`,requestType:JP,target:n,prompt:{type:`distribute`,mode:`select`,title:`界巧变:选择 ${e.state.players[t]?.name??`P${t}`} 场上的一张牌移动`,cardIds:r,minTotal:1,maxTotal:1},timeout:15});let i=e.state.localVars[tF];if(delete e.state.localVars[tF],typeof i==`string`&&r.includes(i)){delete e.state.localVars[nF],await B(e.state,{type:`请求回应`,requestType:YP,target:n,prompt:{type:`choosePlayer`,title:`界巧变:选择目标玩家(将牌移到其场上)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0},timeout:15});let r=e.state.localVars[nF];delete e.state.localVars[nF],typeof r==`number`&&await tue(e.state,t,i,r)}}}}finally{await L(e.state)}return Nh(e.state,{player:n,phase:r})}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`)return;let r=e.state,i=r.players[n];if(!i?.alive)return;let a=i.hand.length;zP(r,n).includes(a)||(await RP(r,n),eue(r,n,a))}),()=>{}}async function tue(e,t,n,r){if(t===r)return;let i=e.players[t];if(!i||!e.cardMap[n])return;let a=i.pendingTricks.find(e=>e.card.id===n);if(a){await B(e,{type:`移除延时锦囊`,player:t,trickName:a.name}),await B(e,{type:`获得`,player:r,cardId:n,from:t});return}await B(e,{type:`获得`,player:r,cardId:n,from:t})}function HP(e,t){t.defineAction(`respond`,{label:`界巧变`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界巧变?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var UP,WP,GP,KP,qP,JP,YP,XP,ZP,QP,$P,eF,tF,nF,rF,iF,aF,oF,sF,nue=t((()=>{V(),z(),F(),Ph(),Wd(),UP=`界巧变/confirm`,WP=`界巧变/mode`,GP=`界巧变/discard`,KP=`界巧变/steal-targets`,qP=`界巧变/move-source-player`,JP=`界巧变/move-source-card`,YP=`界巧变/move-dest-player`,XP=`界巧变/confirmed`,ZP=`界巧变/mode`,QP=`界巧变/discardCardId`,$P=`界巧变/stealTargets`,eF=`界巧变/moveSourcePlayer`,tF=`界巧变/moveSourceCardId`,nF=`界巧变/moveDestPlayer`,rF=`界巧变/历史手牌数`,iF=`界巧变/变:`,aF=e=>`界巧变/init/${e}`,oF=[`判定`,`摸牌`,`出牌`,`弃牌`],sF={createSkill:LP,onInit:VP,onMount:HP}})),rue=r({createSkill:()=>cF,default:()=>vF,onInit:()=>lF,onMount:()=>uF});function iue(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function cF(e,t){return{id:e,ownerId:t,name:fF,description:`出牌阶段限一次拼点:赢则本回合下一张牌可多/少指定一个目标;没赢则本回合不能使用锦囊牌`}}function lF(e,t){let n=e.ownerId,r=S(t,n,(e,t)=>e.turn.vars[gF]===t),i=qh(t,n,(e,t)=>e.turn.vars[hF]===t?2:0);j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(X(e,n,dF))return`本回合已使用过巧说`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;if(typeof i!=`string`)return`需要选择一张拼点牌`;if(!r.hand.includes(i))return`拼点牌不在手牌中`;let a=t.target;if(typeof a!=`number`)return`需要选择拼点目标`;if(a===n)return`不能与自己拼点`;let o=e.players[a];return o?.alive?o.hand.length===0?`目标没有手牌,无法拼点`:null:`目标不存在或已死亡`},async(e,t)=>{let r=n,i=t.cardId,a=t.target;await Z(e,r,dF),await I(e,dF,r,{...t});let o=e.cardMap[i],s=o?iue(o.rank):0;delete e.localVars[pF],await B(e,{type:`请求回应`,requestType:mF,target:a,prompt:{type:`useCard`,title:`巧说:与 ${e.players[r].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let c=e.localVars[pF];delete e.localVars[pF];let l;c&&e.players[a].hand.includes(c)?l=await xb(e,r,a,i,c)===`赢`:(await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`弃牌堆`}}),l=s>0),l?(e.turn.vars[hF]=r,await B(e,{type:`回合用量`,player:r,key:_F,value:1})):(e.turn.vars[gF]=r,await B(e,{type:`回合用量`,player:r,key:gF,value:!0})),await L(e)});for(let n of t.players){let r=n.index;j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return`当前不需要回应`;let i=n.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==mF)return`当前不是巧说回应`;if(i.target!==r)return`不是问你的`;let a=t.cardId;return typeof a==`string`?e.players[r].hand.includes(a)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`},async(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return;let i=n.atom;i.type!==`请求回应`||i.requestType!==mF||(e.localVars[pF]=t.cardId)})}return N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.type===`移动牌`&&t.from.zone===`手牌`&&t.from.player===n&&t.to.zone===`处理区`&&e.state.turn.vars[hF]===n&&(delete e.state.turn.vars[hF],await B(e.state,{type:`回合用量`,player:n,key:_F,value:!1}))}),()=>{r(),i()}}function uF(e,t){t.defineAction(`use`,{label:fF,style:`primary`,prompt:{type:`useCardAndTarget`,title:`巧说:选择一张拼点牌和一名目标`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return n?n.alive!==!1&&(n.handCount??0)>0:!1}}},activeWhen:e=>yh(dF)(e)&&(e.view.players[e.perspectiveIdx]?.hand?.length??0)>0}),t.defineAction(`respond`,{label:fF,style:`primary`,prompt:{type:`useCard`,title:`巧说:请出一张拼点牌`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var dF,fF,pF,mF,hF,gF,_F,vF,aue=t((()=>{V(),z(),Sb(),Q(),F(),ne(),Xh(),W(),dF=`界巧说`,fF=`巧说`,pF=`${dF}/targetCard`,mF=`${dF}/拼点`,hF=`巧说/winNext`,gF=`巧说/lost`,_F=Xc(`界巧说`),vF={createSkill:cF,onInit:lF,onMount:uF}})),oue=r({createSkill:()=>yF,default:()=>wF,onInit:()=>SF});function yF(e,t){return{id:e,ownerId:t,name:CF,description:`锁定技,你不能成为黑色锦囊牌的目标;你防止回合内受到的伤害并摸所防止伤害值两倍数量的牌`,isLocked:!0}}function bF(e){return!!e&&e.type===`锦囊牌`&&e.color===`黑`}function sue(e){let t=Ke(e)?.params?.cardId;return typeof t==`string`?t:void 0}function xF(e){let t=sue(e);return t!==void 0&&bF(e.cardMap[t])}function SF(e,t){let n=e.ownerId,r=[];return r.push(M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n||e.state.currentPlayerIndex!==n)return;let r=typeof t.amount==`number`?t.amount:0;if(!(r<=0))return await B(e.state,{type:`摸牌`,player:n,count:r*2}),{kind:`cancel`}})),r.push(M(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target===n&&t.cardId&&bF(e.state.cardMap[t.cardId]))return{kind:`cancel`}})),r.push(M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.from===n&&t.player!==n&&xF(e.state))return{kind:`cancel`}})),r.push(M(t,e.id,n,`弃置`,async e=>{if(e.atom.player===n&&xF(e.state))return{kind:`cancel`}})),r.push(M(t,e.id,n,`设横置`,async e=>{if(e.atom.player===n&&xF(e.state))return{kind:`cancel`}})),r.push(M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target===n&&t.cardId&&bF(e.state.cardMap[t.cardId]))return{kind:`cancel`}})),()=>{for(let e of r)e()}}var CF,wF,cue=t((()=>{V(),z(),F(),CF=`帷幕`,wF={createSkill:yF,onInit:SF}})),lue=r({createSkill:()=>TF,default:()=>BF,onInit:()=>OF,onMount:()=>kF});function TF(e,t){return{id:e,ownerId:t,name:jF,description:`出牌阶段限一次,弃一张牌使本回合攻击范围无限,且同花色杀无次数限制;弃装备可再弃一名其他角色一张牌`}}function uue(e,t){return e.players[t]?.vars[MF]===!0}function EF(e){return e?e.hand.length>0?!0:Object.values(e.equipment).some(e=>typeof e==`string`):!1}function DF(e,t){return e.players.some(e=>e.alive&&e.index!==t&&EF(e))}function OF(e,t){let n=e.ownerId,r=qm(t,n,(e,t,n,r)=>e.turn.vars[NF]===t),i=sh(t,n,(e,t,n)=>{if(e.turn.vars[NF]!==t||!n)return!1;let r=e.turn.vars[PF];return typeof r==`string`?e.cardMap[n]?.suit===r:!1});return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(uue(e,n))return`本回合已发动过弓骑`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;return typeof i==`string`?r.hand.includes(i)?null:`牌不在手牌中`:`需要选择一张要弃置的手牌`},async(e,t)=>{let r=n,i=t.cardId,a=e.players[r],o=e.cardMap[i];e.players[r].vars[MF]=!0,await B(e,{type:`回合用量`,player:r,key:MF,value:!0}),await I(e,AF,r,{...t}),await B(e,{type:`弃置`,player:r,cardIds:[i],voluntary:!0}),e.turn.vars[NF]=r,await B(e,{type:`回合用量`,player:r,key:NF,value:!0}),o?.suit&&(e.turn.vars[PF]=o.suit,await B(e,{type:`回合用量`,player:r,key:Dl,value:o.suit})),o?.type===`装备牌`&&a.alive&&DF(e,r)&&await due(e,r),await L(e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不是请求回应`;let a=i.requestType;return!a||![FF,IF,LF].includes(a)?`当前不是弓骑询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===FF){e.localVars[RF]=t.choice===!0||t.confirmed===!0;return}if(r===IF){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[zF]=n);return}if(r===LF){let n=t.zone;if(n===`equipment`){if(typeof t.cardId!=`string`)return}else if(n===`hand`){if(typeof t.handIndex!=`number`)return}else return;e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null};return}}),()=>{r(),i()}}async function due(e,t){if(delete e.localVars[RF],await B(e,{type:`请求回应`,requestType:FF,target:t,prompt:{type:`confirm`,title:`弓骑:弃置的牌为装备,是否弃一名其他角色一张牌?`,confirmLabel:`弃牌`,cancelLabel:`不弃`},defaultChoice:!1,timeout:10}),!e.localVars[RF]){delete e.localVars[RF];return}if(delete e.localVars[RF],!e.players[t]?.alive||!DF(e,t))return;delete e.localVars[zF],await B(e,{type:`请求回应`,requestType:IF,target:t,prompt:{type:`choosePlayer`,title:`弓骑:选择要弃置其一张牌的其他角色`,min:1,max:1,filter:(n,r)=>r!==t&&e.players[r]?.alive===!0&&EF(e.players[r])},timeout:20});let n=e.localVars[zF];if(delete e.localVars[zF],typeof n!=`number`)return;let r=e.players[n];!r?.alive||!EF(r)||await kg(e,t,n,r,{mode:`discard`,requestType:LF,title:`弓骑:选择要从 ${r.name} 弃置的 1 张牌`,includeJudge:!1})}function kF(e,t){t.defineAction(`use`,{label:jF,style:`primary`,prompt:{type:`useCard`,title:`弓骑:选择一张手牌弃置(本回合攻击范围无限,同花色杀无次数限制;装备牌可再弃他人一张牌)`,cardFilter:{filter:()=>!0,min:1,max:1}},activeWhen:e=>q(e)?e.view.players[e.perspectiveIdx]?.turnUsage?.[MF]!==!0:!1}),t.defineAction(`respond`,{label:jF,style:`default`,prompt:{type:`confirm`,title:`弓骑`}})}var AF,jF,MF,NF,PF,FF,IF,LF,RF,zF,BF,fue=t((()=>{V(),z(),F(),J(),Ag(),Xm(),fh(),W(),AF=`界弓骑`,jF=`弓骑`,MF=`${AF}/usedThisTurn`,NF=Il,PF=`${AF}/suit`,FF=`${AF}/confirm`,IF=`${AF}/选目标`,LF=`${AF}/选牌`,RF=`${AF}/confirmed`,zF=`${AF}/target`,BF={createSkill:TF,onInit:OF,onMount:kF}})),pue=r({createSkill:()=>VF,default:()=>QF,onInit:()=>GF,onMount:()=>KF});function VF(e,t){return{id:e,ownerId:t,name:JF,description:`出牌阶段限两次:受到1点伤害或弃一张武器牌,对一名本回合未以此法指定过的其他角色造成1点伤害`}}function HF(e){return!!e&&e.type===`装备牌`&&e.subtype===`武器`}function UF(e,t){let n=e.players[t]?.vars[YF];return typeof n==`number`?n:0}function WF(e,t){let n=e.players[t]?.vars[XF];return Array.isArray(n)?n:[]}function GF(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(UF(e,n)>=ZF)return`本阶段强袭已达上限(2次)`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cost;if(i!==`damage`&&i!==`discard`)return`cost 必须为 damage 或 discard`;let a=t.target;if(typeof a!=`number`)return`需要指定目标`;if(a===n)return`不能以自己为目标`;if(!e.players[a]?.alive)return`目标不合法`;if(WF(e,n).includes(a))return`本回合已对此角色发动过强袭`;if(i===`discard`){let n=t.cardId;if(typeof n!=`string`)return`弃武器需要 cardId`;let i=e.cardMap[n];if(!HF(i))return`不是武器牌`;let a=r.hand.includes(n),o=r.equipment.武器===n;if(!a&&!o)return`武器不在手牌或装备区`}return null},async(e,t)=>{let r=n,i=t.target,a=t.cost,o=UF(e,r)+1;e.players[r].vars[YF]=o,await B(e,{type:`回合用量`,player:r,key:YF,value:o});let s=[...WF(e,r),i];if(e.players[r].vars[XF]=s,await B(e,{type:`回合用量`,player:r,key:XF,value:s}),await I(e,qF,r,{...t}),a===`damage`){if(await Dm(e,r,r,1),!e.players[r]?.alive){await L(e);return}}else{let n=t.cardId;e.players[r].equipment.武器===n&&await B(e,{type:`卸下`,player:r,slot:`武器`}),await B(e,{type:`弃置`,player:r,cardIds:[n],voluntary:!0})}await Dm(e,r,i,1),await L(e)}),()=>{}}function KF(e,t){t.defineAction(`use`,{label:JF,style:`danger`,prompt:{type:`selectTarget`,title:`强袭:选择一名本回合未以此法指定过的角色(受到1点伤害或弃武器,对其造成1点伤害)`,description:`本阶段限两次;每名角色每回合仅能被指定一次`,targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players.find(e=>e.index===t);if(!r||r.alive===!1)return!1;let i=e.players[n]?.turnUsage?.[XF];return!(Array.isArray(i)?i:[]).includes(t)}},paramVariants:[{label:`受到1点伤害`,params:{cost:`damage`}},{label:`弃一张武器牌(先选中武器牌)`,params:{cost:`discard`},cardFilter:e=>HF(e)}]},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx]?.turnUsage?.[YF];return(typeof t==`number`?t:0)<ZF}})}var qF,JF,YF,XF,ZF,QF,mue=t((()=>{V(),z(),Om(),J(),F(),qF=`界强袭`,JF=`强袭`,YF=`${qF}/usedThisTurn`,XF=`${qF}/targets/usedThisTurn`,ZF=2,QF={createSkill:VF,onInit:GF,onMount:KF}})),hue=r({createSkill:()=>$F,default:()=>mI,onInit:()=>eI,onMount:()=>tI});function $F(e,t){return{id:e,ownerId:t,name:rI,description:`出牌阶段开始时,你可观看一名其他角色的手牌并展示其中一张牌;本阶段你使用此类别的牌后可摸一张牌`}}function eI(e,t){let n=e.ownerId,r=async e=>{if(delete e.localVars[pI],await B(e,{type:`请求回应`,requestType:lI,target:n,prompt:{type:`confirm`,title:`强识:是否摸一张牌?(本阶段使用同类别的牌)`,confirmLabel:`摸牌`,cancelLabel:`不摸`},defaultChoice:!0,timeout:15}),e.localVars[pI]===!1){delete e.localVars[pI];return}delete e.localVars[pI],await B(e,{type:`摸牌`,player:n,count:1})};return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===oI||i===lI)return null;if(i===sI){let r=t.target;return typeof r==`number`?r===n?`不能观看自己的手牌`:e.players[r]?.alive?e.players[r].hand.length===0?`目标无手牌`:null:`目标不合法`:`需要指定一名目标`}if(i===cI){let n=t.cardId;if(typeof n!=`string`)return`需要选择一张牌展示`;let r=e.localVars[dI];return typeof r==`number`?e.players[r]?.hand.includes(n)?null:`该牌不在目标手牌中`:`目标未确定`}return`当前不是强识询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===oI?e.localVars[uI]=t.choice===!0||t.confirmed===!0:r===lI?e.localVars[pI]=t.choice===!0||t.confirmed===!0:r===sI?e.localVars[dI]=t.target:r===cI&&(e.localVars[fI]=t.cardId)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`出牌`||t.player!==n)return;let r=e.state;if(!r.players[n]?.alive||(delete r.players[n].vars[iI],delete r.players[n].vars[aI],!r.players.some((e,t)=>t!==n&&e.alive&&e.hand.length>0)))return;if(delete r.localVars[uI],await B(r,{type:`请求回应`,requestType:oI,target:n,prompt:{type:`confirm`,title:`是否发动强识?(观看一名其他角色的手牌并展示其中一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!r.localVars[uI]){delete r.localVars[uI];return}delete r.localVars[uI],await I(r,nI,n,{}),delete r.localVars[dI],await B(r,{type:`请求回应`,requestType:sI,target:n,prompt:{type:`choosePlayer`,title:`强识:选择一名其他角色(观看其手牌)`,min:1,max:1,filter:(e,t)=>t!==n&&r.players[t]?.alive===!0&&(r.players[t]?.hand.length??0)>0},timeout:20});let i=r.localVars[dI];if(typeof i!=`number`||i===n){delete r.localVars[dI],await L(r);return}if(!r.players[i]?.alive||r.players[i].hand.length===0){delete r.localVars[dI],await L(r);return}delete r.localVars[fI],await B(r,{type:`请求回应`,requestType:cI,target:n,prompt:{type:`pickProcessingCard`,title:`强识:选择一张牌展示(本阶段使用此类别的牌可摸一张)`,cards:r.players[i].hand.map(e=>{let t=r.cardMap[e];return{cardId:e,cardName:t?.name??`?`,suit:t?.suit??``,rank:t?.rank??``}})},timeout:30});let a=r.localVars[fI];if(delete r.localVars[fI],delete r.localVars[dI],typeof a!=`string`||!r.players[i].hand.includes(a)){await L(r);return}await B(r,{type:`展示`,player:i,cardId:a});let o=r.cardMap[a];o&&(r.players[n].vars[iI]=o.type,r.players[n].vars[aI]=a),await L(r)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.state;if(t.currentPlayerIndex!==n||t.phase!==`出牌`)return;let i=t.players[n]?.vars[iI];if(typeof i!=`string`)return;let a=e.atom;if(!a.cardId||a.from?.zone!==`手牌`||a.from.player!==n||!a.to||a.to.zone!==`处理区`&&a.to.zone!==`弃牌堆`)return;let o=t.cardMap[a.cardId];o&&o.type===i&&o.type!==`装备牌`&&t.players[n]?.alive&&await r(t)}),N(t,e.id,n,`装备`,async e=>{let t=e.state;if(t.currentPlayerIndex!==n||t.phase!==`出牌`)return;let i=t.players[n]?.vars[iI];if(typeof i!=`string`)return;let a=e.atom;if(a.player!==n||!t.players[n]?.alive)return;let o=t.cardMap[a.cardId];o&&o.type===i&&await r(t)}),N(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`出牌`||t.player!==n)return;let r=e.state;delete r.players[n]?.vars[iI],delete r.players[n]?.vars[aI]}),()=>{}}function tI(e,t){t.defineAction(`respond`,{label:rI,style:`primary`,prompt:{type:`confirm`,title:`是否发动强识?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var nI,rI,iI,aI,oI,sI,cI,lI,uI,dI,fI,pI,mI,gue=t((()=>{V(),z(),F(),nI=`界强识`,rI=`强识`,iI=`${nI}/category`,aI=`${nI}/revealedCard`,oI=`${nI}/confirm`,sI=`${nI}/target`,cI=`${nI}/pick`,lI=`${nI}/draw`,uI=`${nI}/confirmed`,dI=`${nI}/targetChoice`,fI=`${nI}/pickedCard`,pI=`${nI}/drawConfirmed`,mI={createSkill:$F,onInit:eI,onMount:tI}})),_ue=r({createSkill:()=>hI,default:()=>kI,onInit:()=>gI,onMount:()=>_I});function hI(e,t){return{id:e,ownerId:t,name:vI,description:`锁定技:回合开始时执行一个额外的出牌阶段;此阶段开始时可获得一张无距离限制的杀;若未于此阶段造成过伤害,阶段结束时受1点伤害`,isLocked:!0}}function gI(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==DI&&a!==OI?`当前不是当先询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===DI)e.localVars[TI]=t.choice===!0||t.confirmed===!0;else if(r===OI){let n=t.choice===!0||t.confirmed===!0;e.localVars[EI]=n?`deck`:`discard`}}),j(t,e.id,n,`end`,(e,t)=>e.turn.vars[yI]!==!0||e.phase!==`出牌`?`当前不处于当先额外出牌阶段`:E(e)?`请先处理待响应事件`:e.players[n]?.alive?null:`玩家已死亡`,async(e,t)=>{e.turn.vars[yI]=!1});let r=qm(t,n,(e,t,n,r)=>r?r===e.turn.vars[SI]:!1);return N(t,e.id,n,`回合开始`,async e=>{if(e.atom.player===n&&e.state.players[n]?.alive){if(e.state.turn.vars[yI]=!0,e.state.turn.vars[xI]=0,delete e.state.turn.vars[bI],await B(e.state,{type:`回合用量`,player:n,key:wI,value:!0}),await B(e.state,{type:`阶段开始`,player:n,phase:`出牌`}),delete e.state.localVars[TI],await B(e.state,{type:`请求回应`,requestType:DI,target:n,prompt:{type:`confirm`,title:`当先:是否从牌堆或弃牌堆获得一张无距离限制的杀?`,confirmLabel:`获得杀`,cancelLabel:`不获得`},defaultChoice:!1,timeout:15}),e.state.localVars[TI]===!0){delete e.state.localVars[EI],await B(e.state,{type:`请求回应`,requestType:OI,target:n,prompt:{type:`confirm`,title:`当先:从哪个区域获得杀?`,confirmLabel:`牌堆`,cancelLabel:`弃牌堆`},defaultChoice:!1,timeout:15});let t=e.state.localVars[EI],r=t===`discard`?`弃牌堆`:`牌堆`,i=(t===`discard`?e.state.zones.discardPile:e.state.zones.deck).filter(t=>e.state.cardMap[t]?.name===`杀`),a;if(i.length>0){let t=Ud(e.state.rngSeed);a=i[t.nextInt(i.length)],e.state.rngSeed=t.getState()}a&&(await B(e.state,{type:`移动牌`,cardId:a,from:{zone:r},to:{zone:`手牌`,player:n}}),e.state.turn.vars[SI]=a,e.state.turn.vars[CI]=!0,await B(e.state,{type:`回合用量`,player:n,key:CI,value:!0}))}for(;e.state.turn.vars[yI]===!0&&e.state.players[n]?.alive===!0;)await B(e.state,{type:`出牌窗口`,player:n,timeout:50});e.state.turn.vars[xI]===0&&e.state.players[n]?.alive===!0&&await Dm(e.state,n,n,1),e.state.turn.vars[CI]!==void 0&&await B(e.state,{type:`回合用量`,player:n,key:CI,value:!1}),await B(e.state,{type:`回合用量`,player:n,key:wI,value:!1}),delete e.state.turn.vars[yI],delete e.state.turn.vars[xI],delete e.state.turn.vars[bI],delete e.state.turn.vars[SI],delete e.state.turn.vars[CI]}}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0||e.state.turn.vars[yI]!==!0)return;let r=e.state.turn.vars[xI]??0;e.state.turn.vars[xI]=r+(t.amount??0)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom,r=e.state.turn.vars[SI];typeof r==`string`&&t.cardId===r&&t.from?.zone===`手牌`&&(delete e.state.turn.vars[SI],delete e.state.turn.vars[CI],await B(e.state,{type:`回合用量`,player:n,key:CI,value:!1}))}),M(t,e.id,n,`阶段结束`,async e=>{if(e.atom.player===n){if(e.state.turn.vars[bI]===!0)return{kind:`cancel`};if(e.state.turn.vars[yI]===!0)return e.state.turn.vars[yI]=!1,e.state.turn.vars[bI]=!0,{kind:`cancel`}}}),M(t,e.id,n,`清过期标记`,async e=>{if(e.atom.player===n&&e.state.turn.vars[bI]===!0)return{kind:`cancel`}}),M(t,e.id,n,`下一玩家`,async e=>{if(e.state.turn.vars[bI]===!0)return{kind:`cancel`}}),M(t,e.id,n,`回合结束`,async e=>{if(e.atom.player===n&&e.state.turn.vars[bI]===!0)return delete e.state.turn.vars[bI],{kind:`cancel`}}),()=>{r()}}function _I(e,t){t.defineAction(`respond`,{label:vI,style:`passive`,prompt:{type:`confirm`,title:`当先:是否获得一张无距离限制的杀?`,confirmLabel:`获得杀`,cancelLabel:`不获得`}}),t.defineAction(`end`,{label:`当先·结束额外阶段`,style:`default`,prompt:{type:`confirm`,title:`结束当先额外出牌阶段?`,confirmLabel:`结束`,cancelLabel:`继续出牌`},activeWhen:e=>e.view.currentPlayerIndex===e.perspectiveIdx&&e.view.phase===`出牌`&&e.view.players[e.perspectiveIdx]?.turnUsage?.[wI]===!0})}var vI,yI,bI,xI,SI,CI,wI,TI,EI,DI,OI,kI,vue=t((()=>{V(),Om(),F(),Xm(),W(),Wd(),vI=`当先`,yI=`当先/active`,bI=`当先/exiting`,xI=`当先/damageInPhase`,SI=`当先/noRangeKillCardId`,CI=Ll,wI=Gl,TI=`当先/confirmed`,EI=`当先/sourceChoice`,DI=`界当先/confirm`,OI=`界当先/source`,kI={createSkill:hI,onInit:gI,onMount:_I}})),yue=r({createSkill:()=>AI,default:()=>II,onInit:()=>jI,onMount:()=>MI});function AI(e,t){return{id:e,ownerId:t,name:`志继`,description:`觉醒技:准备阶段或结束阶段且无手牌时,回复1体力或摸2牌,减1体力上限并永久获得"观星"`}}async function bue(e,t){if(e.players[t]?.vars[FI])return;let n=e.players[t];if(n?.alive&&!(n.hand.length>0)){if(e.players[t].vars[FI]=!0,delete e.localVars[PI],await B(e,{type:`请求回应`,requestType:NI,target:t,prompt:{type:`confirm`,title:`志继:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`},defaultChoice:!1,timeout:30}),e.localVars[PI]===`draw`)await B(e,{type:`摸牌`,player:t,count:2});else{let n=e.players[t].health,r=e.players[t].maxHealth,i=Math.min(1,Math.max(0,r-n));i>0&&await B(e,{type:`回复体力`,target:t,amount:i})}await B(e,{type:`设上限`,player:t,amount:e.players[t].maxHealth-1}),await B(e,{type:`添加技能`,player:t,skillId:`观星`})}}function jI(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===NI?null:`当前不是志继选择`:`当前不需要回应`},async(e,t)=>{e.localVars[PI]=t.choice===!0?`draw`:`heal`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&(t.phase!==`准备`&&t.phase!==`回合结束`||t.player===n&&await bue(e.state,n))}),()=>{}}function MI(e,t){t.defineAction(`respond`,{label:`志继`,style:`primary`,prompt:{type:`confirm`,title:`志继:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`}})}var NI,PI,FI,II,xue=t((()=>{V(),F(),NI=`界志继/choose`,PI=`志继/choice`,FI=`志继/awakened`,II={createSkill:AI,onInit:jI,onMount:MI}})),Sue=r({createSkill:()=>LI,default:()=>GI,onInit:()=>RI,onMount:()=>zI});function LI(e,t){return{id:e,ownerId:t,name:BI,description:`对其他角色造成1点伤害后,或受到其他角色1点伤害后,摸两张牌并交给该角色其中一张`}}function RI(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==VI&&a!==HI)return`当前不是忘隙询问`;if(a===HI){let e=i.prompt?.cardIds??[],n=new Set(e),r=t.cardIds??[];if(r.length!==1)return`忘隙:必须选择 1 张牌交给该角色`;if(!n.has(r[0]))return`忘隙:所选牌不在刚摸到的牌中`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===VI)e.localVars[UI]=t.choice===!0||t.confirmed===!0;else if(r===HI){let n=t.cardIds??[];e.localVars[WI]=n[0]??null}});async function r(e,t){if(!e.players[n]?.alive||!e.players[t]?.alive)return;if(delete e.localVars[UI],await B(e,{type:`请求回应`,requestType:VI,target:n,prompt:{type:`confirm`,title:`忘隙:是否摸两张牌并交给 P${t} 一张?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.localVars[UI]){delete e.localVars[UI];return}delete e.localVars[UI];let r=e.zones.deck.length+e.zones.discardPile.length;if(r===0)return;let i=new Set(e.players[n].hand);await B(e,{type:`摸牌`,player:n,count:Math.min(2,r)});let a=e.players[n].hand.filter(e=>!i.has(e));if(a.length===0||!e.players[t]?.alive)return;if(a.length===1){await B(e,{type:`给予`,cardId:a[0],from:n,to:t});return}delete e.localVars[WI],await B(e,{type:`请求回应`,requestType:HI,target:n,prompt:{type:`distribute`,mode:`select`,title:`忘隙:选择 1 张牌交给 P${t}`,cardIds:a,minTotal:1,maxTotal:1},defaultChoice:!1,timeout:15});let o=e.localVars[WI];delete e.localVars[WI];let s=typeof o==`string`?o:a[0];e.players[t]?.alive&&e.players[n]?.alive&&await B(e,{type:`给予`,cardId:s,from:n,to:t})}return N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0||t.target===n)return;let i=t.amount??0;if(!(i<=0))for(let n=0;n<i&&e.state.players[t.target]?.alive;n++)await r(e.state,t.target)}),N(t,e.id,n,`伤害结算结束后`,async e=>{let t=e.atom;if(t.target!==n)return;let i=t.source;if(typeof i!=`number`||i===n||i<0)return;let a=t.amount??0;if(!(a<=0))for(let t=0;t<a&&e.state.players[i]?.alive;t++)await r(e.state,i)}),()=>{}}function zI(e,t){t.defineAction(`respond`,{label:BI,style:`primary`,prompt:{type:`confirm`,title:`是否发动忘隙?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var BI,VI,HI,UI,WI,GI,Cue=t((()=>{V(),F(),BI=`忘隙`,VI=`界忘隙/confirm`,HI=`界忘隙/pick`,UI=`忘隙/confirmed`,WI=`忘隙/pickChoice`,GI={createSkill:LI,onInit:RI,onMount:zI}})),wue=r({createSkill:()=>KI,default:()=>tL,onInit:()=>qI,onMount:()=>JI});function KI(e,t){return{id:e,ownerId:t,name:YI,description:`摸牌阶段开始时,观看牌堆顶4张牌,将其中2张置于牌堆顶,其余置于牌堆底`}}function qI(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==XI&&a!==ZI)return`当前不是恂恂询问`;if(a===ZI){if(!Array.isArray(t.top)||!Array.isArray(t.bottom))return`恂恂:需要 top/bottom 划分`;let e=i.prompt?.cardIds??[],n=new Set(e),r=t.top,a=t.bottom,o=[...r,...a];if(o.length!==e.length)return`恂恂:必须划分全部观察的牌`;let s=Math.min(2,e.length);if(r.length!==s)return`恂恂:须将 ${s} 张置于牌堆顶`;let c=new Set;for(let e of o){if(!n.has(e))return`恂恂:牌不在观察范围内`;if(c.has(e))return`恂恂:存在重复的牌`;c.add(e)}}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===XI?e.localVars[QI]=t.choice===!0||t.confirmed===!0:r===ZI&&(e.localVars[$I]={top:t.top??[],bottom:t.bottom??[]})}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`摸牌`||!e.state.players[n]?.alive)return;let r=e.state.zones.deck;if(r.length===0)return;let i=Math.min(eL,r.length);if(i===0)return;if(delete e.state.localVars[QI],await B(e.state,{type:`请求回应`,requestType:XI,target:n,prompt:{type:`confirm`,title:`是否发动恂恂?`,description:`观看牌堆顶 ${i} 张牌,选择置顶与置底`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[QI]){delete e.state.localVars[QI];return}let a=r.slice(-i),o=Math.min(2,i);delete e.state.localVars[$I],await B(e.state,{type:`请求回应`,requestType:ZI,target:n,prompt:{type:`distribute`,mode:`select`,title:`恂恂:选择 ${o} 张置于牌堆顶(顺序即摸牌顺序),其余置于牌堆底`,cardIds:a,minTotal:o,maxTotal:o},defaultChoice:!1,timeout:30});let s=e.state.localVars[$I];delete e.state.localVars[$I],delete e.state.localVars[QI];let c=s?.top??[],l=s?.bottom??[],u=new Set(a),d=[...c,...l];if(!(c.length===o&&d.length===a.length&&new Set(d).size===d.length&&d.every(e=>u.has(e))))return;let f=r.slice(0,r.length-i),p=[...l,...f,...[...c].reverse()];await B(e.state,{type:`整理牌堆`,cards:p,topCount:c.length,bottomCount:l.length})}),()=>{}}function JI(e,t){t.defineAction(`respond`,{label:YI,style:`default`,prompt:{type:`confirm`,title:`是否发动恂恂?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var YI,XI,ZI,QI,$I,eL,tL,Tue=t((()=>{V(),F(),YI=`恂恂`,XI=`界恂恂/confirm`,ZI=`界恂恂/arrange`,QI=`恂恂/confirmed`,$I=`恂恂/arrangement`,eL=4,tL={createSkill:KI,onInit:qI,onMount:JI}})),Eue=r({createSkill:()=>nL,default:()=>hL,onInit:()=>rL,onMount:()=>iL});function nL(e,t){return{id:e,ownerId:t,name:oL,description:`获得一名其他角色≥2张牌后可令其摸1张;受到1点伤害后令来源选:交红色手牌或失去1点体力`}}function Due(e){return`${aL}/gainCount/${e}`}function Oue(e){return`${aL}/gainBatch/${e}`}function kue(e,t){let n=e.settlementStack,r=n[n.length-1],i=Oue(t),a=Due(t),o=r??n.length;if(e.localVars[i]!==o)return e.localVars[i]=o,e.localVars[a]=1,!1;let s=(e.localVars[a]??0)+1;return e.localVars[a]=s,s===2}function Aue(e,t){return(e.players[t]?.hand??[]).some(t=>e.cardMap[t]?.color===`红`)}function jue(e,t){let n=e;if(n.type===`获得`){let e=n.player,r=n.from;return e===t&&typeof r==`number`&&r!==t?{from:r}:null}if(n.type===`给予`){let e=n.to,r=n.from;return e===t&&typeof r==`number`&&r!==t?{from:r}:null}if(n.type===`移动牌`){let e=n.to,r=n.from;return e?.zone===`手牌`&&e.player===t&&typeof r?.player==`number`&&r.player!==t?{from:r.player}:null}return null}function rL(e,t){let n=e.ownerId,r=[];for(let i of t.players){let a=i.index,o=a===n,s=j(t,e.id,a,`respond`,e=>{let t=e.pendingSlots.get(a);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let n=t.atom.requestType??``,r=[dL,fL],i=[pL,mL];return o&&r.includes(n)||i.includes(n)?null:`当前不是恩怨询问`},async(e,t)=>{let n=e.pendingSlots.get(a)?.atom?.requestType;if(n===dL)e.localVars[sL]=t.choice===!0;else if(n===fL)e.localVars[cL]=t.choice===!0;else if(n===pL)e.localVars[lL]=t.choice===!0?`card`:`lose`;else if(n===mL){let n=typeof t.cardId==`string`?t.cardId:``;e.localVars[uL]=n}});r.push(s)}let i=async e=>{let t=jue(e.atom,n);if(!t)return;let r=t.from;e.state.players[r]?.alive&&kue(e.state,r)&&(delete e.state.localVars[sL],await B(e.state,{type:`请求回应`,requestType:dL,target:n,prompt:{type:`confirm`,title:`恩怨:获得 ${e.state.players[r].name??`P${r}`} 至少 2 张牌,是否令其摸 1 张?`,confirmLabel:`令其摸 1 张`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[sL]===!0&&e.state.players[r]?.alive&&await B(e.state,{type:`摸牌`,player:r,count:1}))};return N(t,e.id,n,`获得`,i),N(t,e.id,n,`给予`,i),N(t,e.id,n,`移动牌`,i),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0||t.source===void 0||t.source===n)return;let r=t.source;if(e.state.players[r]?.alive&&(delete e.state.localVars[cL],await B(e.state,{type:`请求回应`,requestType:fL,target:n,prompt:{type:`confirm`,title:`恩怨:受到伤害后,是否令来源选交红牌或失去 1 体力?`,confirmLabel:`令来源选择`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[cL]===!0&&e.state.players[r]?.alive)){await I(e.state,aL,n,{source:r});try{let t=Aue(e.state,r),i=!1;if(t&&(delete e.state.localVars[lL],await B(e.state,{type:`请求回应`,requestType:pL,target:r,prompt:{type:`confirm`,title:`恩怨:选择一项(确认=交给法正一张红色手牌,取消=失去 1 点体力)`,confirmLabel:`交红色手牌`,cancelLabel:`失去 1 点体力`},defaultChoice:!1,timeout:15}),i=e.state.localVars[lL]===`card`),i){delete e.state.localVars[uL],await B(e.state,{type:`请求回应`,requestType:mL,target:r,prompt:{type:`useCard`,title:`恩怨:选择一张红色手牌交给法正`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1}},timeout:15});let t=e.state.localVars[uL];typeof t==`string`&&t&&e.state.players[r]?.hand.includes(t)&&e.state.cardMap[t]?.color===`红`?await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:r},to:{zone:`手牌`,player:n}}):await B(e.state,{type:`失去体力`,target:r,amount:1})}else await B(e.state,{type:`失去体力`,target:r,amount:1})}finally{await L(e.state)}}}),()=>{r.forEach(e=>e())}}function iL(e,t){t.defineAction(`respond`,{label:oL,style:`default`,prompt:{type:`confirm`,title:`是否发动恩怨?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var aL,oL,sL,cL,lL,uL,dL,fL,pL,mL,hL,Mue=t((()=>{V(),z(),F(),aL=`界恩怨`,oL=`恩怨`,sL=`${aL}/aConfirmed`,cL=`${aL}/bConfirmed`,lL=`${aL}/bSourceChoice`,uL=`${aL}/bCardId`,dL=`${aL}/aConfirm`,fL=`${aL}/bConfirm`,pL=`${aL}/bSource`,mL=`${aL}/bCard`,hL={createSkill:nL,onInit:rL,onMount:iL}})),Nue=r({createSkill:()=>gL,default:()=>OL,onInit:()=>_L,onMount:()=>vL});function gL(e,t){return{id:e,ownerId:t,name:`悲歌`,description:`受杀伤害后令其判定,可弃一张牌按花色执行;花色同获判定牌,点数同获弃置牌`}}function _L(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i!==yL&&i!==bL)return`当前不是界悲歌询问`;if(i===bL){let r=t.cardId;if(typeof r==`string`&&!e.players[n].hand.includes(r))return`牌不在手牌中`}return null},async(e,t)=>{let r=(e.pendingSlots.get(n)?.atom).requestType;r===yL?e.localVars[xL]=t.choice===!0:r===bL&&(e.localVars[SL]=t.cardId)}),N(t,e.id,n,`判定牌生效后`,async e=>{if(e.atom.judgeType!==`界悲歌`)return;let t=R(e.state);if(t.length===0)return;let n=t[t.length-1],r=e.state.cardMap[n];r&&(e.state.localVars[CL]=r.suit,e.state.localVars[wL]=r.rank,e.state.localVars[TL]=n)}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if((t.amount??0)<=0)return;let r=t.target;if(r===void 0||!e.state.players[r]?.alive)return;let i=t.cardId;if(!i||e.state.cardMap[i]?.name!==`杀`)return;let a=e.state.players[n];if(!a?.alive||a.hand.length===0)return;delete e.state.localVars[xL],await B(e.state,{type:`请求回应`,requestType:yL,target:n,prompt:{type:`confirm`,title:`界悲歌:是否令受伤角色判定?`,confirmLabel:`发动(判定)`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15});let o=e.state.localVars[xL]===!0;if(delete e.state.localVars[xL],!o||e.state.zones.deck.length===0)return;delete e.state.localVars[CL],delete e.state.localVars[wL],delete e.state.localVars[TL],await jm(e.state,r,`界悲歌`);let s=e.state.localVars[CL];e.state.localVars[wL];let c=e.state.localVars[TL];if(delete e.state.localVars[CL],delete e.state.localVars[wL],delete e.state.localVars[TL],s===void 0)return;let l=t.source,u;if(e.state.players[n].hand.length>0&&(delete e.state.localVars[SL],await B(e.state,{type:`请求回应`,requestType:bL,target:n,prompt:{type:`useCard`,title:`界悲歌:是否弃置一张牌?(花色同获判定牌,点数同获弃置牌)`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15}),u=e.state.localVars[SL],delete e.state.localVars[SL],typeof u==`string`&&await B(e.state,{type:`弃置`,player:n,cardIds:[u],voluntary:!0})),s===`♥`)e.state.players[r]?.alive&&await B(e.state,{type:`回复体力`,target:r,amount:1});else if(s===`♦`)await B(e.state,{type:`摸牌`,player:r,count:2});else if(s===`♣`){if(l===void 0)return;let t=e.state.players[l];if(!t?.alive)return;let n=t.hand.slice(0,Math.min(2,t.hand.length));n.length>0&&await B(e.state,{type:`弃置`,player:l,cardIds:n})}else if(s===`♠`){if(l===void 0||!e.state.players[l]?.alive)return;await Ch(e.state,l,`界悲歌`)}if(typeof u==`string`&&c){let t=e.state.cardMap[c],r=e.state.cardMap[u];t&&r&&(t.suit===r.suit&&e.state.zones.discardPile.includes(c)&&await B(e.state,{type:`移动牌`,cardId:c,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}}),t.rank===r.rank&&e.state.zones.discardPile.includes(u)&&await B(e.state,{type:`移动牌`,cardId:u,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}}))}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`)return;let n=t.player;if(n===void 0)return;let r=e.state.players[n];if(r){if(t.phase===`准备`&&r.tags.includes(EL))return await wh(e.state,n,`界悲歌`),e.state.localVars[DL]=n,{kind:`cancel`};if(e.state.localVars[DL]===n)return{kind:`cancel`}}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`)return;let n=t.player;if(n!==void 0&&e.state.localVars[DL]===n)return delete e.state.localVars[DL],await B(e.state,{type:`清过期标记`,player:n}),await B(e.state,{type:`下一玩家`}),await B(e.state,{type:`回合结束`,player:n})&&await B(e.state,{type:`回合结束后`,player:n}),{kind:`cancel`}}),()=>{}}function vL(e,t){t.defineAction(`respond`,{label:`悲歌`,style:`primary`,prompt:{type:`useCard`,title:`界悲歌:弃置一张牌(可选)`,cardFilter:{filter:e=>!0,min:1,max:1}}})}var yL,bL,xL,SL,CL,wL,TL,EL,DL,OL,Pue=t((()=>{V(),z(),Fm(),Mh(),F(),yL=`界悲歌/chooseStart`,bL=`界悲歌/chooseDiscard`,xL=`界悲歌/start`,SL=`界悲歌/discardCard`,CL=`界悲歌/judgeSuit`,wL=`界悲歌/judgeRank`,TL=`界悲歌/judgeCardId`,EL=`界悲歌/翻面`,DL=`界悲歌/skipAll`,OL={createSkill:gL,onInit:_L,onMount:vL}})),Fue=r({createSkill:()=>kL,default:()=>VL,onInit:()=>AL,onMount:()=>jL});function kL(e,t){return{id:e,ownerId:t,name:NL,description:`其他角色的回合开始时,若你已受伤,你可以与其拼点:赢则其本回合不能对除其以外的角色使用牌;没赢则你获得其拼点牌,然后其视为对你使用一张杀`}}async function Iue(e,t,n){if(!e.players[n]?.alive)return;let r=`${ML}:杀:${t}:${n}:${e.seq}`;e.cardMap[r]={id:r,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,r,[n],`杀`,{virtual:!0}),delete e.cardMap[r]}function AL(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===PL)return null;if(i===FL){let r=t.cardId;return typeof r==`string`?e.players[n]?.hand.includes(r)?null:`拼点牌不在你的手牌中`:`请选择一张拼点牌`}return`当前不是惴恐询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===PL?e.localVars[LL]=t.choice===!0:r===FL&&(e.localVars[RL]=t.cardId)}));for(let i of t.players){if(i.index===n)continue;let a=i.index;r.push(j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(n?.atom.type!==`请求回应`)return`当前不需要回应`;if(n.atom.requestType!==IL)return`当前不是惴恐拼点询问`;let r=t.cardId;return typeof r==`string`?e.players[a]?.hand.includes(r)?null:`拼点牌不在你的手牌中`:`请选择一张拼点牌`},async(e,t)=>{e.pendingSlots.get(a)?.atom?.requestType===IL&&(e.localVars[zL]=t.cardId)}))}return r.push(M(t,e.id,n,`成为目标`,async e=>{let t=e.atom,n=t.source,r=t.target;if(!(typeof n!=`number`||typeof r!=`number`)&&n!==r&&e.state.players[n]?.vars[BL])return{kind:`cancel`}})),r.push(N(t,e.id,n,`回合开始`,async e=>{let t=e.state,r=e.atom.player;if(typeof r!=`number`||r===n)return;let i=t.players[n];if(!i?.alive||i.health>=i.maxHealth)return;let a=t.players[r];if(!a?.alive||i.hand.length===0||a.hand.length===0||(delete t.localVars[LL],await B(t,{type:`请求回应`,requestType:PL,target:n,prompt:{type:`confirm`,title:`惴恐:是否与 ${a.name} 拼点?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!t.localVars[LL])||(delete t.localVars[LL],a.hand.length===0))return;delete t.localVars[RL],await B(t,{type:`请求回应`,requestType:FL,target:n,prompt:{type:`useCard`,title:`惴恐:选择一张拼点牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:20});let o=t.localVars[RL];if(delete t.localVars[RL],!o||!i.hand.includes(o))return;delete t.localVars[zL];let s=a.hand[0];await B(t,{type:`请求回应`,requestType:IL,target:r,prompt:{type:`useCard`,title:`惴恐:与 ${i.name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:20});let c=t.localVars[zL];delete t.localVars[zL],(!c||!a.hand.includes(c))&&(c=s),!(!c||!a.hand.includes(c))&&(await xb(t,n,r,o,c)===`赢`?(t.players[r].vars[BL]=!0,await B(t,{type:`回合用量`,player:r,key:BL,value:!0})):(t.zones.discardPile.includes(c)&&await B(t,{type:`移动牌`,cardId:c,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}}),await Iue(t,r,n)))})),()=>r.forEach(e=>e())}function jL(e,t){return t.defineAction(`respond`,{label:NL,style:`primary`,prompt:{type:`confirm`,title:NL,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var ML,NL,PL,FL,IL,LL,RL,zL,BL,VL,Lue=t((()=>{V(),Sb(),Gh(),F(),ML=`界惴恐`,NL=`惴恐`,PL=`${ML}/confirm`,FL=`${ML}/ownerCard`,IL=`${ML}/targetCard`,LL=`${ML}/confirmed`,RL=`${ML}/ownerCardId`,zL=`${ML}/targetCardId`,BL=`${ML}/restricted/usedThisTurn`,VL={createSkill:kL,onInit:AL,onMount:jL}})),Rue=r({createSkill:()=>HL,default:()=>YL,onInit:()=>UL,onMount:()=>WL});function HL(e,t){return{id:e,ownerId:t,name:`界护驾`,description:`主公技:魏势力角色可代你使用或打出闪;每回合限一次,魏角色回合外用闪时可令你摸1张`}}function UL(e,t){let n=e.ownerId,r=[];r.push(de(t,n,`询问闪`)),r.push(j(t,e.id,n,`respond`,(e,t)=>{if(n!==0)return`非主公不能发动护驾`;let r=e.pendingSlots.get(n);return r?r.atom.type===`询问闪`?e.players[n]?.alive?e.players.some(e=>e.alive&&e.index!==n&&e.faction===`魏`&&e.hand.length>0)?null:`没有可出闪的魏势力角色`:`玩家不存在或已死亡`:`当前不是出闪窗口`:`当前不需要回应`},async(e,t)=>{let r=e.players.length;for(let t=1;t<r;t++){let i=(n+t)%r,a=e.players[i];if(!a?.alive||a.faction!==`魏`||a.hand.length===0)continue;delete e.localVars[GL],await B(e,{type:`请求回应`,requestType:`界护驾/出闪`,target:i,prompt:{type:`useCard`,title:`护驾:曹操(${e.players[n]?.name??`P${n}`})需要闪,是否打出一张闪?`,cardFilter:{filter:e=>e.name===`闪`,min:1,max:1}},timeout:15});let o=e.localVars[GL];if(delete e.localVars[GL],o&&a.hand.includes(o)){await B(e,{type:`移动牌`,cardId:o,from:{zone:`手牌`,player:i},to:{zone:`处理区`}});return}}})),r.push(N(t,e.id,n,`移动牌`,async e=>{if(n!==0)return;let t=e.atom;if(t.from.zone!==`手牌`||t.to.zone!==`处理区`)return;let r=t.from.player;if(typeof r!=`number`||r===n)return;let i=e.state.players[r];if(!i?.alive||i.faction!==`魏`||e.state.cardMap[t.cardId]?.name!==`闪`||e.state.currentPlayerIndex===r)return;let a=e.state.players[n];a?.alive&&e.state.turn.vars[JL]!==!0&&(e.state.turn.vars[JL]=!0,await B(e.state,{type:`回合用量`,player:n,key:JL,value:!0}),delete e.state.localVars[qL],await B(e.state,{type:`请求回应`,requestType:KL,target:r,prompt:{type:`confirm`,title:`界护驾:是否令${a.name}摸一张牌?`,confirmLabel:`令曹操摸牌`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),e.state.localVars[qL]===!0&&await B(e.state,{type:`摸牌`,player:n,count:1}))}));for(let i of t.players){let a=i.index;if(a===n||i.faction!==`魏`)continue;let o=j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let i=r.requestType;if(i===`界护驾/出闪`){let n=t.cardId;if(n){if(!e.players[a].hand.includes(n))return`牌不在手牌中`;if(e.cardMap[n]?.name!==`闪`)return`只能打出闪`}return null}return i===KL?null:`当前不是界护驾询问`},async(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return;let r=n.atom.requestType;if(r===`界护驾/出闪`){let n=t.cardId;n&&(e.localVars[GL]=n)}else r===KL&&(e.localVars[qL]=t.choice===!0||t.confirmed===!0)});r.push(o)}return()=>{for(let e of r)e()}}function WL(e,t){t.defineAction(`respond`,{label:`界护驾`,style:`primary`,prompt:{type:`confirm`,title:`护驾:令魏势力角色替你出闪?`,confirmLabel:`护驾`,cancelLabel:`不发动`},activeWhen:e=>{let t=e.view.pending;if(!t||t.target!==e.perspectiveIdx)return!1;let n=t.atom;return n.type===`询问闪`||n.type===`请求回应`&&n.requestType===`界护驾/出闪`||n.type===`请求回应`&&n.requestType===KL}})}var GL,KL,qL,JL,YL,zue=t((()=>{V(),F(),GL=`界护驾/闪出`,KL=`界护驾/drawChoice`,qL=`界护驾/confirmed`,JL=`界护驾/triggered`,YL={createSkill:HL,onInit:UL,onMount:WL}})),Bue=r({createSkill:()=>XL,default:()=>lR,onInit:()=>QL,onMount:()=>$L});function XL(e,t){return{id:e,ownerId:t,name:tR,description:`出牌阶段限两次:指定一名攻击范围包含你的角色,其须对你出杀且造成伤害,否则你弃其一张牌`}}function ZL(e,t){let n=e.players[t]?.vars[nR];return typeof n==`number`?n:0}async function Vue(e,t,n){let r=e.players[n];if(!r)return;let i=Object.entries(r.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`})),a=r.hand.length;if(i.length===0&&a===0)return;let o=i.length>0?{zone:`equipment`,cardId:i[0].cardId}:{zone:`hand`,handIndex:0};e.localVars[oR]=n,delete e.localVars[sR];let s={type:`请求回应`,requestType:aR,target:t,prompt:{type:`pickTargetCard`,mode:`discard`,title:`挑衅:弃置 ${r.name} 的一张牌`,target:n,equipment:i,judge:[],handCount:a},defaultChoice:o,timeout:20};await B(e,s);let c=e.localVars[sR];delete e.localVars[sR],delete e.localVars[oR];let l=s.prompt.equipment??[],u=o;u.zone===`equipment`&&(l.some(e=>e.cardId===u.cardId)||(u=l.length>0?{zone:`equipment`,cardId:l[0].cardId}:{zone:`hand`,handIndex:0}));let d=c?.zone??u.zone,f;if(d===`equipment`)f=c?.cardId??u.cardId??void 0;else{let e=c?.handIndex??0;f=r.hand[e]??r.hand[0]}f&&await B(e,{type:`弃置`,player:n,cardIds:[f]})}function QL(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(ZL(e,n)>=cR)return`本阶段挑衅已达上限(2次)`;if(!e.players[n]?.alive)return`玩家不存在或已死亡`;let r=t.target;return typeof r==`number`?r===n?`不能选择自己`:e.players[r]?.alive?Gm(e,r,n)?null:`目标无法用杀攻击到你`:`目标不存在或已死亡`:`需要选择目标`},async(e,t)=>{let r=n,i=t.target,a=ZL(e,r)+1;e.players[r].vars[nR]=a,await B(e,{type:`回合用量`,player:r,key:nR,value:a}),await I(e,eR,r,{...t});try{await B(e,{type:`请求回应`,requestType:rR,target:i,prompt:{type:`useCardAndTarget`,title:`挑衅:对 ${e.players[r].name} 使用一张杀(需造成伤害,否则其弃你一张牌)`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>t===r}},timeout:15});let t=e.localVars[iR];delete e.localVars[iR];let n=e.players[r]?.health??0,a=!1;t?.cardId&&(await Lh(e,i,t.cardId,[t.target],`杀`),a=!0);let o=(e.players[r]?.health??n)<n;!(a&&o)&&e.players[i]?.alive&&await Vue(e,r,i)}finally{await L(e)}});let r=[];for(let i of t.players){let a=i.index;r.push(j(t,e.id,a,`respond`,(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是挑衅询问`;let i=r.atom.requestType;if(i===rR){let r=t.cardId,i=t.target;return typeof r==`string`?typeof i==`number`?e.players[a]?.hand.includes(r)?e.cardMap[r]?.name===`杀`?i===n?Gm(e,a,n,r)?null:`目标不在攻击范围内`:`只能对姜维使用杀`:`只能使用杀`:`牌不在手牌中`:`请选择目标`:`请选择一张杀`}if(i===aR){let n=e.localVars[oR];if(typeof n!=`number`)return`无弃牌目标`;let i=e.players[n];if(!i)return`弃牌目标不存在`;let a=t.zone;if(a===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`;let e=r.atom?.prompt?.equipment;return e&&!e.some(e=>e.cardId===t.cardId)?`该装备不可选`:Object.values(i.equipment).includes(t.cardId)?null:`该牌不在目标装备区`}return a===`hand`?typeof t.handIndex==`number`?t.handIndex<0||t.handIndex>=i.hand.length?`handIndex 越界`:null:`handIndex required`:`zone required (equipment|hand)`}return`当前不是挑衅询问`},async(e,t)=>{let n=e.pendingSlots.get(a)?.atom?.requestType;n===rR?e.localVars[iR]={cardId:t.cardId,target:t.target}:n===aR&&(e.localVars[sR]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}))}return()=>{for(let e of r)e()}}function $L(e,t){t.defineAction(`use`,{label:tR,style:`danger`,prompt:{type:`selectTarget`,title:`挑衅:选择一名攻击范围包含你的角色`,description:`其须对你出杀且造成伤害,否则你弃其一张牌(本阶段限两次)`,targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players[t];return!r||r.alive===!1?!1:lm(e.players,e.cardMap,t,n)}}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx]?.turnUsage?.[nR];return(typeof t==`number`?t:0)<cR}}),t.defineAction(`respond`,{label:tR,style:`primary`,prompt:{type:`pickTargetCard`,title:`挑衅:选择弃置的牌`,target:0,equipment:[],judge:[],handCount:0}})}var eR,tR,nR,rR,iR,aR,oR,sR,cR,lR,Hue=t((()=>{V(),z(),Gh(),J(),F(),Xm(),um(),eR=`界挑衅`,tR=`挑衅`,nR=`${eR}/usedThisTurn`,rR=`${eR}/出杀`,iR=`${eR}/出杀选择`,aR=`${eR}/选牌`,oR=`${eR}/弃牌目标`,sR=`${eR}/选牌结果`,cR=2,lR={createSkill:XL,onInit:QL,onMount:$L}})),Uue=r({createSkill:()=>uR,default:()=>vR,onInit:()=>dR,onMount:()=>fR});function Wue(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function uR(e,t){return{id:e,ownerId:t,name:`界据守`,description:`结束阶段:翻面并摸四张牌,然后弃置一张手牌(装备牌改为使用之)`}}function dR(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`弃牌`||e.phase===`回合结束`,a=!E(e),o=e.players[n],s=o?.alive===!0,c=!o.tags.includes(pR),l=!X(e,n,`据守`);return r&&i&&a&&s&&c&&l?null:`现在不能发动据守`},async(e,t)=>{await Z(e,n,`据守`),await I(e,`界据守`,n,{});try{await Ch(e,n,`据守`),await B(e,{type:`摸牌`,player:n,count:4});let t=e.players[n];if(t.hand.length>0){delete e.localVars[_R],await B(e,{type:`请求回应`,requestType:gR,target:n,prompt:{type:`useCard`,title:`界据守:选择一张手牌弃置(装备牌将改为使用)`,cardFilter:{filter:()=>!0,min:1,max:1}},mandatory:!0,timeout:20});let r=e.localVars[_R];if(delete e.localVars[_R],(!r||!t.hand.includes(r))&&(r=t.hand[0]),r&&t.hand.includes(r)){let t=e.cardMap[r],i=Wue(t);if(t?.type===`装备牌`&&i){let a=e.players[n].equipment[i];if(a){let t=e.cardMap[a];t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:n,skillId:t.name}),await B(e,{type:`卸下`,player:n,slot:i}),await B(e,{type:`移动牌`,cardId:a,from:{zone:`手牌`,player:n},to:{zone:`弃牌堆`}})}await B(e,{type:`装备`,player:n,cardId:r}),t?.name&&ym(t.name)&&await B(e,{type:`添加技能`,player:n,skillId:t.name})}else await B(e,{type:`弃置`,player:n,cardIds:[r],voluntary:!0})}}}finally{await L(e)}}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?r.atom.type===`请求回应`?r.atom.requestType===gR?null:`当前不是据守弃牌窗口`:`当前不是选牌窗口`:`当前不需要回应`},async(e,t)=>{let r=Array.isArray(t.cardIds)?t.cardIds[0]:t.cardId,i=e.players[n];typeof r==`string`&&i?.hand.includes(r)&&(e.localVars[_R]=r)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n)return;let r=e.state.players[n];if(t.phase===`准备`&&r?.tags.includes(pR))return await wh(e.state,n,`据守`),e.state.localVars[mR]=n,{kind:`cancel`};if(e.state.localVars[mR]===n)return{kind:`cancel`}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type===`阶段结束`&&t.player===n&&e.state.localVars[mR]===n)return delete e.state.localVars[mR],await kh(e.state,n),{kind:`cancel`}}),()=>{}}function fR(e,t){t.defineAction(`use`,{label:`界据守`,style:`primary`,prompt:{type:`confirm`,title:`是否发动据守?(翻面摸四张,然后弃置一张手牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},activeWhen:e=>{if(e.view.currentPlayerIndex!==e.perspectiveIdx)return!1;let t=e.view.phase;if(t!==`弃牌`&&t!==`回合结束`)return!1;let n=e.view.players[e.perspectiveIdx];return!(!n||n.turnUsage?.[hR])}})}var pR,mR,hR,gR,_R,vR,Gue=t((()=>{V(),z(),Mh(),Q(),F(),Sm(),pR=`据守/翻面`,mR=`据守/skipAll`,hR=`据守/usedThisTurn`,gR=`界据守/弃牌`,_R=`据守/discardChoice`,vR={createSkill:uR,onInit:dR,onMount:fR}})),Kue=r({createSkill:()=>bR,default:()=>jR,onInit:()=>xR,onMount:()=>SR});function yR(e){e.turn.vars={};for(let t of e.players)t.marks=t.marks.filter(e=>e.duration!==`turn`),t.vars=Object.fromEntries(Object.entries(t.vars).filter(([e])=>!e.endsWith(`/usedThisTurn`)&&!e.endsWith(`/healed`)&&!e.endsWith(`/givenCount`)&&!e.endsWith(`/givenTargets`)&&!e.endsWith(`/basicUsed`)))}function bR(e,t){return{id:e,ownerId:t,name:`界放权`,description:`跳过出牌阶段,弃牌阶段开始时弃一张手牌,令一名其他角色进行一个额外回合`}}function xR(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===CR)return null;if(i===wR){let r=t.cardId;return typeof r==`string`?e.players[n].hand.includes(r)?null:`牌不在手牌中`:`请选择一张手牌弃置`}if(i===TR){let r=t.target;return typeof r==`number`?r===n?`不能选择自己`:e.players[r]?.alive?null:`目标已死亡`:`请选择一名其他角色`}return`当前不是放权回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===CR?e.localVars[ER]=t.choice===!0||t.confirmed===!0:r===wR?e.localVars[OR]=t.cardId:r===TR&&(e.localVars[kR]=t.target)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`出牌`&&e.state.currentPlayerIndex===n&&e.state.players[n]?.alive&&(delete e.state.localVars[ER],await B(e.state,{type:`请求回应`,requestType:CR,target:n,prompt:{type:`confirm`,title:`是否发动放权?(跳过出牌阶段,弃牌阶段开始时弃一张手牌令一名角色额外回合)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[ER]===!0))return e.state.localVars[DR]=!0,await B(e.state,{type:`阶段结束`,player:n,phase:`出牌`}),{kind:`cancel`}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`弃牌`||e.state.currentPlayerIndex!==n)return;let r=e.state;if(r.localVars[DR]!==!0)return;delete r.localVars[DR];let i=r.players[n];if(!i?.alive||i.hand.length===0)return;delete r.localVars[OR],await B(r,{type:`请求回应`,requestType:wR,target:n,prompt:{type:`useCard`,title:`放权:弃置一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let a=r.localVars[OR];if(delete r.localVars[OR],!a||!i.hand.includes(a))return;await B(r,{type:`弃置`,player:n,cardIds:[a],voluntary:!0}),delete r.localVars[kR],await B(r,{type:`请求回应`,requestType:TR,target:n,prompt:{type:`choosePlayer`,title:`放权:选择一名其他角色进行一个额外回合`,min:1,max:1,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:15});let o=r.localVars[kR];(typeof o!=`number`||!r.players[o]?.alive)&&delete r.localVars[kR]}),M(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`)return;let r=e.state,i=t.player;if(typeof i==`number`){if(i===n){let e=r.localVars[kR];if(typeof e!=`number`||!r.players[e]?.alive)return;if(!r.players[n]?.alive){delete r.localVars[kR];return}let t=r.currentPlayerIndex;return r.localVars[AR]=t,yR(r),r.currentPlayerIndex=e,await Oy(r,e),{kind:`cancel`}}if(i===r.localVars[kR]){let e=r.localVars[AR];return delete r.localVars[kR],delete r.localVars[AR],typeof e!=`number`||!r.players[e]?.alive?void 0:(yR(r),r.currentPlayerIndex=e,await Oy(r,e),{kind:`cancel`})}}}),()=>{}}function SR(e,t){t.defineAction(`respond`,{label:`界放权`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界放权?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var CR,wR,TR,ER,DR,OR,kR,AR,jR,que=t((()=>{V(),ky(),F(),CR=`界放权/trigger`,wR=`界放权/discard`,TR=`界放权/chooseTarget`,ER=`放权/triggered`,DR=`放权/active`,OR=`放权/discardCard`,kR=`放权/extraTarget`,AR=`放权/originalNext`,jR={createSkill:bR,onInit:xR,onMount:SR}})),Jue=r({createSkill:()=>MR,default:()=>VR,onInit:()=>NR,onMount:()=>PR});function MR(e,t){return{id:e,ownerId:t,name:`界放逐`,description:`受到伤害后,令一名其他角色翻面,并摸 X 张牌(X=已损失体力)`}}function NR(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==FR&&a!==IR?`当前不是放逐询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===FR)e.localVars[LR]=t.choice===!0;else if(r===IR){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[RR]=n)}}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=e.state.players[n];if(!r?.alive)return;let i=r.maxHealth-p(r);if(i<=0||!e.state.players.some(e=>e.alive&&e.index!==n)||(delete e.state.localVars[LR],await B(e.state,{type:`请求回应`,requestType:FR,target:n,prompt:{type:`confirm`,title:`是否发动界放逐?(令一名其他角色翻面并摸 ${i} 张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[LR]))return;delete e.state.localVars[RR],await B(e.state,{type:`请求回应`,requestType:IR,target:n,prompt:{type:`choosePlayer`,title:`界放逐:选择一名其他角色(翻面并摸牌)`,min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0},timeout:15});let a=e.state.localVars[RR];delete e.state.localVars[RR],typeof a==`number`&&e.state.players[a]?.alive&&(await Ch(e.state,a,`放逐`),await B(e.state,{type:`摸牌`,player:a,count:i}))}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`)return;let n=t.player;if(n===void 0)return;let r=e.state.players[n];if(r){if(t.phase===`准备`&&r.tags.includes(zR))return await wh(e.state,n,`放逐`),e.state.localVars[BR]=n,{kind:`cancel`};if(e.state.localVars[BR]===n)return{kind:`cancel`}}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`)return;let n=t.player;if(n!==void 0&&e.state.localVars[BR]===n)return delete e.state.localVars[BR],await kh(e.state,n),{kind:`cancel`}}),()=>{}}function PR(e,t){t.defineAction(`respond`,{label:`界放逐`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界放逐?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var FR,IR,LR,RR,zR,BR,VR,Yue=t((()=>{b(),V(),Mh(),F(),FR=`界放逐/confirm`,IR=`界放逐/target`,LR=`放逐/confirmed`,RR=`放逐/target`,zR=`放逐/翻面`,BR=`放逐/skipAll`,VR={createSkill:MR,onInit:NR,onMount:PR}})),Xue=r({createSkill:()=>HR,default:()=>KR,onInit:()=>UR});function HR(e,t){return{id:e,ownerId:t,name:`界救援`,description:`主公技:其他吴势力角色于其回合内回复体力时,若其体力≥你,其可改为令你回复1点体力,然后其摸一张牌`}}function UR(e,t){let n=e.ownerId;M(t,e.id,n,`回复体力`,async e=>{let t=e.atom;if(n!==0)return;let r=t.target;if(typeof r!=`number`||r===n||e.state.currentPlayerIndex!==r)return;let i=e.state.players[r],a=e.state.players[n];if(!(!i?.alive||!a?.alive)&&i.faction===`吴`&&!(p(i)<p(a))&&(delete e.state.localVars[GR],await B(e.state,{type:`请求回应`,requestType:WR,target:r,prompt:{type:`confirm`,title:`界救援:是否改为令${a.name}回复1点体力,然后你摸一张牌?`,confirmLabel:`改为救援`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),e.state.localVars[GR]===!0))return await B(e.state,{type:`回复体力`,target:n,amount:1}),await B(e.state,{type:`摸牌`,player:r,count:1}),{kind:`cancel`}});let r=[];for(let i of t.players){let a=i.index;if(a===n||i.faction!==`吴`)continue;let o=j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return`当前不需要回应`;let r=n.atom;return r.type===`请求回应`?r.requestType===WR?null:`当前不是界救援询问`:`当前不需要回应`},async(e,t)=>{e.localVars[GR]=t.choice===!0||t.confirmed===!0});r.push(o)}return()=>{for(let e of r)e()}}var WR,GR,KR,Zue=t((()=>{b(),V(),F(),WR=`界救援/choose`,GR=`界救援/confirmed`,KR={createSkill:HR,onInit:UR}})),Que=r({createSkill:()=>$ue,onInit:()=>ede,onMount:()=>tde});function qR(e){return!e||e.color!==`黑`?!1:e.type===`基本牌`||e.type===`装备牌`}function $ue(e,t){return{id:e,ownerId:t,name:`界断粮`,description:`将一张黑色基本牌或黑色装备牌当【兵粮寸断】使用;若本回合未造成过伤害,使用时无距离限制`}}function ede(e,t){let n=e.ownerId;return N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;t.source===n&&((t.amount??0)<=0||e.state.turn.vars[YR]||(e.state.turn.vars[YR]=!0,await B(e.state,{type:`回合用量`,player:n,key:YR,value:!0})))}),j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n];if(!o?.alive)return`玩家不存在或已死亡`;if(typeof t.cardId!=`string`)return`需要选择一张牌`;if(typeof t.target!=`number`)return`需要选择目标`;if(!o.hand.includes(t.cardId))return`牌不在手牌中`;if(!qR(e.cardMap[t.cardId]))return`需要黑色基本牌或装备牌`;let s=t.target;if(s===n)return`不能对自己使用`;let c=e.players[s];if(!c?.alive)return`目标不存在或已死亡`;if(c.pendingTricks.some(e=>e.name===JR))return`目标判定区已有兵粮寸断`;let l=!e.turn.vars[YR]||Wm(e,n,s)<=1;return r&&i&&a&&l?null:`界断粮使用条件不满足`},async(e,t)=>{let r=n,i=t.cardId,a=t.target;await I(e,`界断粮`,r,{...t}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`处理区`}}),await B(e,{type:`添加延时锦囊`,player:a,trick:{name:JR,source:r,card:e.cardMap[i]??{id:i,name:JR,suit:`♣`,color:`黑`,rank:`A`,type:`锦囊牌`}}}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await L(e)}),()=>{}}function tde(e,t){t.defineAction(`use`,{label:`界断粮`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`界断粮:将黑色基本牌或装备牌当兵粮寸断使用`,cardFilter:{filter:e=>qR(e),min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.currentPlayerIndex;if(t===n)return!1;let r=e.players[t];return!r||r.alive===!1?!1:e.players[n]?.turnUsage?.[YR]?cm(e.players,n,t)<=1:!0}}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>qR(e))??!1:!1}})}var JR,YR,nde=t((()=>{V(),z(),J(),F(),Xm(),um(),JR=`兵粮寸断`,YR=`界断粮/damageDealt`})),rde=r({createSkill:()=>XR,default:()=>mz,onInit:()=>tz,onMount:()=>nz});function XR(e,t){return{id:e,ownerId:t,name:rz,description:`失去装备区里的牌,或一次性失去至少两张牌后,可依次弃置至多两名其他角色共计至多两张牌`}}function ZR(e){return e?e.hand.length>0?!0:Object.values(e.equipment).some(e=>typeof e==`string`):!1}function QR(e,t){return e.players.some(e=>e.alive&&e.index!==t&&ZR(e))}async function $R(e,t,n){delete e.localVars[uz],await B(e,{type:`请求回应`,requestType:oz,target:t,prompt:{type:`choosePlayer`,title:`旋风:选择第 ${n} 名要弃置其牌的其他角色`,min:1,max:1,filter:(n,r)=>r!==t&&e.players[r]?.alive===!0&&ZR(e.players[r])},timeout:20});let r=e.localVars[uz];if(delete e.localVars[uz],typeof r!=`number`)return!1;let i=e.players[r];return!i?.alive||!ZR(i)?!1:(await kg(e,t,r,i,{mode:`discard`,requestType:sz,title:`旋风:选择要从 ${i.name} 弃置的 1 张牌`,includeJudge:!1}),!0)}async function ez(e,t){let n=e.players[t];n?.alive&&QR(e,t)&&(delete e.localVars[cz],await B(e,{type:`请求回应`,requestType:iz,target:t,prompt:{type:`confirm`,title:`是否发动旋风?(依次弃至多 2 名角色至多 2 张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.localVars[cz]&&(!n.alive||!QR(e,t)||(await $R(e,t,1),!(!n.alive||!QR(e,t))&&(delete e.localVars[lz],await B(e,{type:`请求回应`,requestType:az,target:t,prompt:{type:`confirm`,title:`是否继续弃置第二张牌?`,confirmLabel:`继续`,cancelLabel:`结束`},defaultChoice:!1,timeout:10}),e.localVars[lz]&&(!n.alive||!QR(e,t)||await $R(e,t,2))))))}function tz(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不是请求回应`;let a=i.requestType;return!a||![iz,az,oz,sz].includes(a)?`当前不是旋风询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===iz){e.localVars[cz]=t.choice===!0||t.confirmed===!0;return}if(r===az){e.localVars[lz]=t.choice===!0||t.confirmed===!0;return}if(r===oz){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[uz]=n);return}if(r===sz){let n=t.zone;if(n===`equipment`){if(typeof t.cardId!=`string`)return}else if(n===`hand`){if(typeof t.handIndex!=`number`)return}else return;e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null};return}}),N(t,e.id,n,`卸下`,async e=>{e.atom.player===n&&await ez(e.state,n)}),M(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.player!==n)return;let r=new Set(Object.values(e.state.players[n].equipment).filter(e=>typeof e==`string`)),i=t.cardIds??[],a=i.filter(e=>r.has(e)).length;e.state.localVars[dz]=a,e.state.localVars[fz]=i.length}),N(t,e.id,n,`弃置`,async e=>{if(e.atom.player!==n)return;let t=e.state.localVars[dz],r=e.state.localVars[fz];delete e.state.localVars[dz],delete e.state.localVars[fz],!(!((t??0)>0)&&!((r??0)>=2))&&await ez(e.state,n)}),M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.from!==n)return;let r=new Set(Object.values(e.state.players[n].equipment).filter(e=>typeof e==`string`));t.cardId&&r.has(t.cardId)&&(e.state.localVars[pz]=1)}),N(t,e.id,n,`获得`,async e=>{if(e.atom.from!==n)return;let t=e.state.localVars[pz];delete e.state.localVars[pz],t&&await ez(e.state,n)}),()=>{}}function nz(e,t){t.defineAction(`respond`,{label:rz,style:`default`,prompt:{type:`confirm`,title:`是否发动旋风?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var rz,iz,az,oz,sz,cz,lz,uz,dz,fz,pz,mz,ide=t((()=>{V(),F(),Ag(),W(),rz=`旋风`,iz=`界旋风/confirm`,az=`界旋风/continue`,oz=`界旋风/选目标`,sz=`界旋风/选牌`,cz=`界旋风/confirmed`,lz=`界旋风/continue`,uz=`界旋风/target`,dz=`界旋风/弃置equipLoss`,fz=`界旋风/弃置totalLoss`,pz=`界旋风/获得equipLoss`,mz={createSkill:XR,onInit:tz,onMount:nz}})),ade=r({createSkill:()=>hz,default:()=>Tz,onInit:()=>yz,onMount:()=>bz});function hz(e,t){return{id:e,ownerId:t,name:Sz,description:`出牌阶段限一次:交给一名其他角色一张杀或装备牌,其选择一项:①视为对你指定的另一名角色出杀(若造成伤害,执行另一项);②你与其各摸一张牌`}}function gz(e){return!!e&&e.name===`杀`}function _z(e){return!!e&&e.type===`装备牌`}function ode(e,t,n){return`明策:杀:${e}:${t}:${n}`}async function sde(e,t,n){if(!e.players[n]?.alive)return!1;let r=e.players[n].health,i=ode(t,n,e.seq);return e.cardMap[i]={id:i,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,i,[n],`杀`,{virtual:!0}),delete e.cardMap[i],e.players[n].health<r}async function vz(e,t,n){e.players[t]?.alive&&await B(e,{type:`摸牌`,player:t,count:1}),e.players[n]?.alive&&await B(e,{type:`摸牌`,player:n,count:1})}function yz(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,xz))return`本回合已使用过明策`;let r=e.players[n];if(!r?.alive)return`角色不可用`;let i=t.cardId;if(typeof i!=`string`)return`需要选择一张牌`;let a=e.cardMap[i];if(!gz(a)&&!_z(a))return`只能给出杀或装备牌`;let o=r.hand.includes(i),s=Object.values(r.equipment).includes(i);if(!o&&!s)return`牌不在你的手牌或装备区`;let c=t.targets;if(!Array.isArray(c)||c.length!==2)return`需要选择给牌目标与可能的杀目标`;let[l,u]=c;return l===n?`给牌目标不能是自己`:e.players[l]?.alive?u===l?`杀目标不能与给牌目标相同`:e.players[u]?.alive?null:`杀目标不合法`:`给牌目标不合法`},async(e,t)=>{let r=n,i=t.cardId,[a,o]=t.targets;await Z(e,r,xz),await I(e,xz,r,{...t});try{if(Object.values(e.players[r].equipment).includes(i)){let t=Object.entries(e.players[r].equipment).find(([,e])=>e===i)?.[0];t&&await B(e,{type:`卸下`,player:r,slot:t})}if(await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`手牌`,player:a}}),!e.players[a]?.alive)return;delete e.localVars[Cz],await B(e,{type:`请求回应`,requestType:wz,target:a,prompt:{type:`confirm`,title:`明策:选择一项(确认=对 ${o+1} 号视为使用一张杀,若造成伤害再各摸一张;取消=你与陈宫各摸一张)`,confirmLabel:`①视为出杀`,cancelLabel:`②双方各摸一张`},defaultChoice:!1,timeout:20});let t=e.localVars[Cz]===!0;delete e.localVars[Cz],t?await sde(e,a,o)&&await vz(e,r,a):await vz(e,r,a)}finally{await L(e)}}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);return n?n.atom.requestType===wz?null:`当前不是明策询问`:`当前不需要回应`},async(e,t)=>{e.pendingSlots.get(i)?.atom?.requestType===wz&&(e.localVars[Cz]=t.choice===!0||t.confirmed===!0)}))}return()=>{for(let e of r)e()}}function bz(e,t){return t.defineAction(`use`,{label:Sz,style:`primary`,prompt:{type:`useCardAndTarget`,title:`明策:交给一名其他角色一张杀或装备牌;并选择可能的杀目标`,description:`出牌阶段限一次。给牌后该角色选择:①视为对你指定的另一名角色出杀(若造成伤害再各摸一张);②你与其各摸一张`,cardFilter:{filter:e=>gz(e)||_z(e),min:1,max:1},targetFilter:{min:2,max:2,slots:[{label:`给牌目标`,filter:(e,t)=>t!==e.currentPlayerIndex&&!!e.players[t]?.alive},{label:`杀目标(选项①)`,filter:(e,t,n)=>!!e.players[t]?.alive&&!n.selected.includes(t)}]}},activeWhen:e=>q(e)&&yh(xz)(e)}),()=>{}}var xz,Sz,Cz,wz,Tz,cde=t((()=>{V(),z(),Gh(),F(),J(),Q(),xz=`界明策`,Sz=`明策`,Cz=`明策/choice`,wz=`界明策/choice`,Tz={createSkill:hz,onInit:yz,onMount:bz}})),lde=r({createSkill:()=>Ez,default:()=>Az,onInit:()=>Dz});function ude(e){return!!e&&e.name===`杀`}function dde(e){return!!e&&e.type===`锦囊牌`&&e.trickSubtype!==`延时锦囊`&&e.trickSubtype!==`响应锦囊`}function fde(e){return ude(e)||dde(e)}function pde(e,t){return e.turn.vars[kz]===t}function Ez(e,t){return{id:e,ownerId:t,name:Oz,description:`锁定技:回合外受到伤害后,本回合【杀】和普通锦囊牌对你无效`,isLocked:!0}}function Dz(e,t){let n=e.ownerId,r=[];return r.push(N(t,e.id,n,`受到伤害后`,async e=>{e.atom.target===n&&e.state.currentPlayerIndex!==n&&e.state.players[n]?.alive&&(e.state.turn.vars[kz]=n)})),r.push(dC(t,e.id,n,(e,t)=>pde(e,n)?fde(t):!1)),()=>{for(let e of r)e()}}var Oz,kz,Az,mde=t((()=>{F(),fC(),Oz=`智迟`,kz=`智迟/active`,Az={createSkill:Ez,onInit:Dz}})),hde=r({createSkill:()=>jz,default:()=>Iz,onInit:()=>Mz,onMount:()=>Nz});function jz(e,t){return{id:e,ownerId:t,name:`暴虐`,description:`主公技:其他群势力角色造成1点伤害后可判定,黑桃则回复1点体力并获得此判定牌`}}function Mz(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===Pz?null:`当前不是暴虐确认`:`当前不需要回应`},async(e,t)=>{e.localVars[Fz]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom,r=e.state.players[n];if(!r?.alive||r.identity!==`主公`||t.amount!==1)return;let i=t.source;if(typeof i!=`number`||i===n||i<0)return;let a=e.state.players[i];if(!a?.alive||a.faction!==`群`||(delete e.state.localVars[Fz],await B(e.state,{type:`请求回应`,requestType:Pz,target:n,prompt:{type:`confirm`,title:`暴虐:${a.name} 造成 1 点伤害,是否进行判定?(黑桃回复1点体力并获得判定牌)`,confirmLabel:`判定`,cancelLabel:`不判定`},defaultChoice:!1,timeout:10}),!e.state.localVars[Fz]))return;let o=e.state.zones.discardPile.length;await jm(e.state,n,`暴虐`);let s=e.state.zones.discardPile;if(s.length<=o)return;let c=s[s.length-1],l=e.state.cardMap[c];l&&l.suit===`♠`&&(await B(e.state,{type:`移动牌`,cardId:c,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}}),await B(e.state,{type:`回复体力`,target:n,amount:1}))}),()=>{}}function Nz(e,t){t.defineAction(`respond`,{label:`暴虐`,style:`default`,prompt:{type:`confirm`,title:`是否发动暴虐?(判定,黑桃回复1点体力并获得判定牌)`,confirmLabel:`判定`,cancelLabel:`不发动`}})}var Pz,Fz,Iz,gde=t((()=>{V(),Fm(),F(),Pz=`界暴虐/confirm`,Fz=`暴虐/confirmed`,Iz={createSkill:jz,onInit:Mz,onMount:Nz}})),_de=r({createSkill:()=>Lz,default:()=>Gz,onInit:()=>Rz,onMount:()=>zz});function Lz(e,t){return{id:e,ownerId:t,name:Vz,description:`每个结束阶段,你可以与当前回合角色各摸一张牌;然后若其与你手牌数不相等,此技能本轮失效`}}function vde(e,t){return e.localVars[Wz(t)]===e.turn.round}function Rz(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===Hz?null:`当前不是樵拾确认`:`当前不需要回应`},async(e,t)=>{e.localVars[Uz]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`)return;let r=t.player;if(typeof r!=`number`)return;let i=e.state;i.players[n]?.alive&&i.players[r]?.alive&&(vde(i,n)||(delete i.localVars[Uz],await B(i,{type:`请求回应`,requestType:Hz,target:n,prompt:{type:`confirm`,title:`是否发动樵拾?(你与当前回合角色各摸一张牌;若手牌数不相等,本轮失效)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),i.localVars[Uz]&&(delete i.localVars[Uz],await B(i,{type:`摸牌`,player:n,count:1}),r!==n&&i.players[r]?.alive&&await B(i,{type:`摸牌`,player:r,count:1}),(i.players[n]?.hand.length??0)!==(i.players[r]?.hand.length??0)&&(i.localVars[Wz(n)]=i.turn.round))))}),()=>{}}function zz(e,t){return t.defineAction(`respond`,{label:Vz,style:`primary`,prompt:{type:`confirm`,title:`是否发动樵拾?(你与当前回合角色各摸一张牌;若手牌数不相等,本轮失效)`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var Bz,Vz,Hz,Uz,Wz,Gz,yde=t((()=>{V(),F(),Bz=`界樵拾`,Vz=`樵拾`,Hz=`${Bz}/confirm`,Uz=`${Bz}/confirmed`,Wz=e=>`${Bz}/disabledRound/${e}`,Gz={createSkill:Lz,onInit:Rz,onMount:zz}})),bde=r({createSkill:()=>Kz,default:()=>Xz,onInit:()=>Jz,onMount:()=>Yz});function Kz(e,t){return{id:e,ownerId:t,name:`界武圣`,description:`你可以将一张红色牌(手牌或装备区)当【杀】使用或打出`}}function qz(e){return`${e}#界武圣`}function Jz(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a),l=o&&Object.values(r.equipment).some(e=>e===a),u=!!s&&s.color===`红`,d=e.currentPlayerIndex===n,f=!E(e),p=e.pendingSlots.get(n),m=p?.atom?.type,h=p?.atom?.requestType,g=p?.atom?.target;return i&&(c||l)&&u&&(d&&f||p&&g===n&&(m===`询问杀`||m===`请求回应`&&h===`杀/respondKill`))?null:`现在不能使用武圣`},async(e,t)=>{let r=t.cardId,i=qz(r),a=e.players[n],o=Object.entries(a.equipment).find(([,e])=>e===r);if(o){let r=o[0];t._origSlot=r,await B(e,{type:`卸下`,player:n,slot:r})}await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`杀`})},(e,t)=>{let r=t.cardId,i=qz(r),a=e.players[n],o=t._origSlot;delete e.cardMap[i];let s=a.hand.indexOf(i);if(s>=0)if(o){if(a.hand.splice(s,1),a.equipment[o]=r,o===`武器`){let t=e.cardMap[r];a.vars[wl]=t?.range??1}}else a.hand[s]=r});let r=de(t,n,`询问杀`),i=qm(t,n,(e,t,n,r)=>r?e.cardMap[r]?.suit===`♦`:!1);return()=>{r(),i()}}function Yz(e,t){t.defineAction(`transform`,{label:`界武圣`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张红色牌当杀使用`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t?.alive)return!1;let n=t.hand?.some(e=>e.color===`红`)??!1,r=Object.values(t.equipment??{}).some(t=>(t?e.view.cardMap[t]:void 0)?.color===`红`);if(!n&&!r)return!1;let i=q(e)&&sm(e.view,e.perspectiveIdx),a=e.view.pending,o=a?.atom?.type,s=a?.atom?.requestType,c=!!a&&a.target===e.perspectiveIdx&&(o===`询问杀`||o===`请求回应`&&s===`杀/respondKill`);return i||c}})}var Xz,xde=t((()=>{F(),V(),um(),J(),Xm(),W(),Xz={createSkill:Kz,onInit:Jz,onMount:Yz}})),Sde=r({createSkill:()=>Zz,default:()=>aB,onInit:()=>Qz,onMount:()=>$z});function Zz(e,t){return{id:e,ownerId:t,name:tB,description:`当你受到伤害后,你可摸X张牌,然后修改"矫诏"(X为你修改"矫诏"的次数)`}}function Cde(e,t){let n=e.players[t]?.vars[iB];return typeof n==`number`?n:0}function Qz(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(!t)return`当前不需要回应`;let r=t.atom;return r.type===`请求回应`?r.requestType===nB?null:`当前不是殚心询问`:`当前不需要回应`},async(e,t)=>{e.localVars[rB]=t.choice===!0}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0||!e.state.players[n]?.alive)return;delete e.state.localVars[rB],await B(e.state,{type:`请求回应`,requestType:nB,target:n,prompt:{type:`confirm`,title:`殚心:是否发动?(摸X张牌并修改"矫诏",X为已修改次数)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15});let r=e.state.localVars[rB]===!0;if(delete e.state.localVars[rB],!r)return;let i=Cde(e.state,n);i>0&&await B(e.state,{type:`摸牌`,player:n,count:i});let a=i+1;e.state.players[n].vars[iB]=a}),()=>{}}function $z(e,t){t.defineAction(`respond`,{label:tB,style:`primary`,prompt:{type:`confirm`,title:`是否发动殚心?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var eB,tB,nB,rB,iB,aB,wde=t((()=>{V(),F(),eB=`界殚心`,tB=`殚心`,nB=`${eB}/confirm`,rB=`${eB}/confirmed`,iB=`${eB}/修改次数`,aB={createSkill:Zz,onInit:Qz,onMount:$z}})),Tde=r({createSkill:()=>oB,default:()=>dB,onInit:()=>cB,onMount:()=>lB});function oB(e,t){return{id:e,ownerId:t,name:uB,description:`锁定技,体力值大于等于你的角色的黑色【杀】对你无效;手牌数小于等于你的角色无法响应你的黑色【杀】`,isLocked:!0}}function Ede(e){let t=e.settlementStack[e.settlementStack.length-1];if(!t)return;let n=t.params.cardId;return typeof n==`string`?n:void 0}function sB(e,t){if(!t)return!1;let n=e.cardMap[t];return!n||n.name!==`杀`?!1:n.color===`黑`}function cB(e,t){let n=e.ownerId;return M(t,e.id,n,`检测有效性`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.source;if(r!==void 0&&!(p(e.state.players[r])<p(e.state.players[n]))&&sB(e.state,t.cardId))return{kind:`cancel`}}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r!==void 0&&sB(e.state,Ede(e.state))&&!((e.state.players[r]?.hand.length??0)>(e.state.players[n]?.hand.length??0)))return{kind:`cancel`}}),()=>{}}function lB(e,t){}var uB,dB,Dde=t((()=>{b(),F(),uB=`毅重`,dB={createSkill:oB,onInit:cB,onMount:lB}})),Ode=r({createSkill:()=>pB,default:()=>AB,onInit:()=>gB,onMount:()=>_B});function fB(e){return e?e.name===`杀`?!0:kB.has(e.name):!1}function pB(e,t){return{id:e,ownerId:t,name:yB,description:`当你成为杀或伤害锦囊的目标时,可令另一名其他角色选一项:1.交给你一张同类型不同牌名的牌;2.成为此牌的额外目标`}}async function mB(e,t,n){if(!e.players[n]?.alive)return;let r=`${vB}:杀:${t}:${n}:${e.seq}`;e.cardMap[r]={id:r,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,r,[n],`杀`,{virtual:!0}),delete e.cardMap[r]}async function hB(e,t,n,r){let i=e.players[t];if(!i?.alive)return;let a=e.cardMap[r];if(!a||e.players.filter(e=>e.alive&&e.index!==t&&e.index!==n).map(e=>e.index).length===0||(delete e.localVars[wB],await B(e,{type:`请求回应`,requestType:bB,target:t,prompt:{type:`confirm`,title:`求援:是否发动?(被 ${a.name} 指定)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.localVars[wB]))return;delete e.localVars[wB],delete e.localVars[TB],await B(e,{type:`请求回应`,requestType:xB,target:t,prompt:{type:`choosePlayer`,title:`求援:选择一名其他角色`,min:1,max:1,filter:(r,i)=>i!==t&&i!==n&&e.players[i]?.alive===!0},timeout:15});let o=e.localVars[TB];if(delete e.localVars[TB],typeof o!=`number`||!e.players[o]?.alive||o===t||o===n)return;delete e.localVars[EB],await B(e,{type:`请求回应`,requestType:SB,target:o,prompt:{type:`confirm`,title:`求援:1.交给 ${i.name} 一张同类型不同牌名的牌 2.成为此牌的额外目标`,confirmLabel:`给牌`,cancelLabel:`成为额外目标`},defaultChoice:!1,timeout:15});let s=e.localVars[EB];if(delete e.localVars[EB],s===1){let r=e.players[o].hand.filter(t=>{let n=e.cardMap[t];return n?.type===a.type&&n.name!==a.name});if(r.length===0){await mB(e,n,o);return}delete e.localVars[DB],await B(e,{type:`请求回应`,requestType:CB,target:o,prompt:{type:`useCard`,title:`求援:交给 ${i.name} 一张同类型不同牌名的牌`,cardFilter:{filter:e=>e.type===a.type&&e.name!==a.name,min:1,max:1}},timeout:20});let s=e.localVars[DB];delete e.localVars[DB],(!s||!r.includes(s))&&(s=r[0]),await B(e,{type:`给予`,cardId:s,from:o,to:t})}else await mB(e,n,o)}function gB(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;return i===bB?null:i===xB?typeof t.target==`number`?null:`请选择一名角色`:`当前不是求援询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===bB?e.localVars[wB]=t.choice===!0:r===xB&&(e.localVars[TB]=t.target)}));for(let i of t.players){if(i.index===n)continue;let a=i.index;r.push(j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(n?.atom.type!==`请求回应`)return`当前不需要回应`;let r=n.atom.requestType;if(r===SB)return null;if(r===CB){let n=t.cardId;return typeof n==`string`?e.players[a]?.hand.includes(n)?null:`牌不在你的手牌中`:`请选择一张牌`}return`当前不是求援询问`},async(e,t)=>{let n=e.pendingSlots.get(a)?.atom?.requestType;n===SB?e.localVars[EB]=t.choice===!0?1:2:n===CB&&(e.localVars[DB]=t.cardId)}))}return r.push(N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n)return;let r=e.state,i=t.cardId;if(!i)return;let a=r.cardMap[i];if(!fB(a))return;let o=t.source;if(typeof o!=`number`)return;let s=`${OB}${i}`;r.localVars[s]||(r.localVars[s]=!0,await hB(r,n,o,i))})),r.push(M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.requestType!==`无懈可击`||t.cancelTarget!==n)return;let r=e.state,i=Ke(r);if(!i)return;let a=i.params?.cardId;if(!a)return;let o=r.cardMap[a];if(!fB(o)||o.name===`杀`||o.name===`决斗`)return;let s=`${OB}${a}`;if(r.localVars[s])return;r.localVars[s]=!0;let c=i.from;await hB(r,n,c,a)})),()=>r.forEach(e=>e())}function _B(e,t){return t.defineAction(`respond`,{label:yB,style:`primary`,prompt:{type:`confirm`,title:yB,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var vB,yB,bB,xB,SB,CB,wB,TB,EB,DB,OB,kB,AB,kde=t((()=>{V(),z(),Gh(),F(),vB=`界求援`,yB=`求援`,bB=`${vB}/confirm`,xB=`${vB}/chooseTarget`,SB=`${vB}/option`,CB=`${vB}/giveCard`,wB=`${vB}/confirmed`,TB=`${vB}/target`,EB=`${vB}/option`,DB=`${vB}/cardId`,OB=`${vB}/processed/`,kB=new Set([`决斗`,`南蛮入侵`,`万箭齐发`,`火攻`]),AB={createSkill:pB,onInit:gB,onMount:_B}})),Ade=r({createSkill:()=>jB,default:()=>IB,onInit:()=>NB,onMount:()=>PB});function jB(e,t){return{id:e,ownerId:t,name:`界洛神`,description:`准备阶段判定:黑色获得判定牌并重复;以此法获得的牌本回合不计入手牌上限`}}function jde(e){return!!e&&(e.suit===`♠`||e.suit===`♣`)}function MB(e){let t=e.turn.vars[FB];return Array.isArray(t)?t:[]}function NB(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{if(e.pendingSlots.get(n)?.atom.type!==`请求回应`)return`当前不需要回应`;let r=e.pendingSlots.get(n).atom.requestType;return r!==`界洛神/confirm`&&r!==`界洛神/continue`?`当前不是洛神询问`:null},async(e,t)=>{e.localVars[`洛神/confirmed`]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.player!==n||t.judgeType!==`洛神`)return;let r=R(e.state);if(r.length===0){e.state.localVars[`洛神/lastResult`]=`red`;return}let i=r[r.length-1],a=e.state.cardMap[i];e.state.localVars[`洛神/lastJudgeCardId`]=i,e.state.localVars[`洛神/lastResult`]=jde(a)?`black`:`red`});let r=rp(t,n,(e,t)=>{if(t!==n)return;let r=MB(e);if(r.length===0)return;let i=e.players[t]?.hand??[],a=r.filter(e=>i.includes(e)).length;if(a===0)return;let o=sl(e.turn.vars,t)??0;return p(e.players[t])+o+a});return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||!e.state.players[n]?.alive||e.state.zones.deck.length===0||(delete e.state.localVars[`洛神/confirmed`],await B(e.state,{type:`请求回应`,requestType:`界洛神/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动洛神?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[`洛神/confirmed`]))return;let r=!0;for(;r&&e.state.zones.deck.length!==0;){await jm(e.state,n,`洛神`);let t=e.state.localVars[`洛神/lastResult`],i=e.state.localVars[`洛神/lastJudgeCardId`];if(delete e.state.localVars[`洛神/lastResult`],delete e.state.localVars[`洛神/lastJudgeCardId`],t!==`black`||!i)break;await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}});let a=MB(e.state);a.includes(i)||(a.push(i),e.state.turn.vars[FB]=a),delete e.state.localVars[`洛神/confirmed`],await B(e.state,{type:`请求回应`,requestType:`界洛神/continue`,target:n,prompt:{type:`confirm`,title:`判定为黑色,是否继续洛神?`,confirmLabel:`继续`,cancelLabel:`停止`},defaultChoice:!0,timeout:10}),r=e.state.localVars[`洛神/confirmed`]!==!1}delete e.state.localVars[`洛神/confirmed`]}),()=>{r()}}function PB(e,t){t.defineAction(`respond`,{label:`界洛神`,style:`default`,prompt:{type:`confirm`,title:`是否发动洛神?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var FB,IB,Mde=t((()=>{b(),V(),z(),Fm(),F(),op(),W(),FB=`界洛神/豁免牌`,IB={createSkill:jB,onInit:NB,onMount:PB}})),Nde=r({createSkill:()=>LB,default:()=>GB,onInit:()=>RB,onMount:()=>zB});function LB(e,t){return{id:e,ownerId:t,name:`界涅槃`,description:`限定技:濒死时弃置所有牌,复原武将牌,摸三张并回复至3点体力,然后获得八阵/火计/看破中的一个`}}function RB(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===BB?null:`当前不是界涅槃询问`:`当前不需要回应`},async(e,t)=>{e.pendingSlots.get(n).atom.requestType===BB&&(e.localVars[VB]=t.choice===!0||t.confirmed===!0)}),N(t,e.id,n,`陷入濒死`,async e=>{if(e.atom.target!==n||e.state.players[n]?.vars[HB])return;let t=e.state.players[n];if(!t||t.health>0||(delete e.state.localVars[VB],await B(e.state,{type:`请求回应`,requestType:BB,target:n,prompt:{type:`confirm`,title:`是否发动界涅槃?(限定技:弃所有牌,摸3张,回复至3体力,获八阵/火计/看破之一)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[VB]))return;e.state.players[n].vars[HB]=!0;let r=e.state.players[n],i=[...r.hand],a=Object.values(r.equipment).filter(e=>typeof e==`string`),o=r.pendingTricks.map(e=>({trickName:e.name,cardId:e.card.id}));for(let{trickName:t}of o)await B(e.state,{type:`移除延时锦囊`,player:n,trickName:t});let s=o.map(e=>e.cardId).filter(t=>et(e.state,t)===null),c=[...i,...a,...s];c.length>0&&await B(e.state,{type:`弃置`,player:n,cardIds:c}),e.state.players[n].marks.some(e=>e.id===`chained`)&&await Th(e.state,n,!1),await B(e.state,{type:`摸牌`,player:n,count:3});let l=e.state.players[n].health,u=Math.max(0,UB-l);u>0&&await B(e.state,{type:`回复体力`,target:n,amount:u});let d;for(let t of WB){if(delete e.state.localVars[VB],await B(e.state,{type:`请求回应`,requestType:BB,target:n,prompt:{type:`confirm`,title:`界涅槃:是否获得「${t}」?`,confirmLabel:`获得`,cancelLabel:`不要`},defaultChoice:!1,timeout:15}),e.state.localVars[VB]){d=t,delete e.state.localVars[VB];break}delete e.state.localVars[VB]}d??=WB[0],await B(e.state,{type:`添加技能`,player:n,skillId:d})}),()=>{}}function zB(e,t){t.defineAction(`respond`,{label:`界涅槃`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界涅槃?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var BB,VB,HB,UB,WB,GB,Pde=t((()=>{V(),Mh(),rt(),F(),BB=`界涅槃/confirm`,VB=`界涅槃/confirmed`,HB=`界涅槃/used`,UB=3,WB=[`八阵`,`火计`,`看破`],GB={createSkill:LB,onInit:RB,onMount:zB}})),Fde=r({createSkill:()=>KB,default:()=>lV,onInit:()=>ZB,onMount:()=>$B});function KB(e,t){return{id:e,ownerId:t,name:tV,description:`出牌阶段用牌若与上一张花色或点数相同,可摸一张;每阶段限一次,可将一张牌当任意基本牌使用(若有上一张花色则继承)`}}function qB(e){return`${e}#${eV}`}function JB(e){let t=e.turn.vars[nV];return typeof t==`string`?t:``}function Ide(e){let t=e.turn.vars[rV];return typeof t==`string`?t:``}function YB(e,t,n){e.turn.vars[nV]=t,e.turn.vars[rV]=n}function Lde(e){YB(e,``,``)}function XB(e,t){return e.currentPlayerIndex===t&&e.phase===`出牌`}function Rde(e,t){return!!e.players[t]?.vars[iV]}function ZB(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===aV?null:`当前不是渐营询问`:`当前不需要回应`},async(e,t)=>{e.localVars[oV]=t.choice===!0||t.confirmed===!0});let r=r=>j(t,e.id,n,`${cV}${r}`,(e,t)=>{if(!XB(e,n))return`只能在你的出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(Rde(e,n))return`本阶段渐营转化已用过`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;return typeof i==`string`?r.hand.includes(i)?null:`牌不在手牌中`:`需要选择一张牌`},async(e,t)=>{let i=t.cardId,a=qB(i),o=JB(e);if(e.players[n].vars[iV]=!0,await B(e,{type:`回合用量`,player:n,key:iV,value:!0}),await B(e,{type:`当作`,player:n,cardIds:[i],shadowId:a,outputName:r}),o!==``){let t=e.cardMap[a];t&&(t.suit=o,t.color=o===`♥`||o===`♦`?`红`:`黑`)}},(e,t)=>{let r=t.cardId,i=qB(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r),delete a.vars[iV]}),i=[...sV].map(r);return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`出牌`&&t.player===n&&Lde(e.state)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.state;if(!XB(t,n))return;let r=e.atom;if(r.from?.zone!==`手牌`||r.from.player!==n||r.to?.zone!==`处理区`)return;let i=r.cardId;if(typeof i!=`string`)return;let a=t.cardMap[i];a&&await QB(t,n,a)}),N(t,e.id,n,`装备`,async e=>{let t=e.state;if(!XB(t,n))return;let r=e.atom;if(r.player!==n)return;let i=r.cardId;if(typeof i!=`string`)return;let a=t.cardMap[i];a&&await QB(t,n,a)}),()=>{for(let e of i)e()}}async function QB(e,t,n){let r=JB(e),i=Ide(e),a=r!==``||i!==``,o=a&&n.suit!==``&&n.suit===r,s=a&&n.rank!==``&&n.rank===i;YB(e,n.suit,n.rank),!(!o&&!s)&&(delete e.localVars[oV],await B(e,{type:`请求回应`,requestType:aV,target:t,prompt:{type:`confirm`,title:`是否发动渐营?(此牌与上一张花色或点数相同,可摸一张)`,confirmLabel:`摸一张`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.localVars[oV]===!0&&await B(e,{type:`摸牌`,player:t,count:1}),delete e.localVars[oV])}function zde(e,t){let n=Wg(t);return n?n.timing===`生效前`?!1:!n.activeWhen||n.activeWhen(e):!0}function $B(e,t){let n=e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return!t||t.turnUsage?.[iV]?!1:(t.handCount??0)>0},r=e=>t=>n(t)&&zde(t,e);for(let e of sV)t.defineAction(`${cV}${e}`,{label:`${tV}·${e}`,style:`primary`,prompt:{type:`useCard`,title:`渐营:将一张牌当【${e}】使用`,description:`出牌阶段限一次;若上一张牌有花色,此牌视为与之同花色`,cardFilter:{filter:()=>!0,min:1,max:1}},transform:t=>({name:e,sourceCardId:t.id,fromSkill:eV}),activeWhen:r(e)});t.defineAction(`respond`,{label:tV,style:`default`,prompt:{type:`confirm`,title:`是否发动渐营?`,confirmLabel:`摸一张`,cancelLabel:`不发动`}})}var eV,tV,nV,rV,iV,aV,oV,sV,cV,lV,Bde=t((()=>{V(),F(),J(),Yg(),eV=`界渐营`,tV=`渐营`,nV=`${eV}/lastSuit`,rV=`${eV}/lastRank`,iV=`${eV}/transform/usedThisTurn`,aV=`${eV}/confirm`,oV=`${eV}/confirmed`,sV=new Set([`杀`,`闪`,`桃`,`酒`]),cV=`transform:`,lV={createSkill:KB,onInit:ZB,onMount:$B}})),Vde=r({createSkill:()=>uV,default:()=>_V,onInit:()=>dV,onMount:()=>fV});function uV(e,t){return{id:e,ownerId:t,name:mV,description:`觉醒技:造成伤害后,若你已受伤,你减少1点体力上限并获得"荐言"`}}function dV(e,t){let n=e.ownerId;return N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0)return;let r=e.state.players[n];if(!r?.alive||r.vars[hV]||r.health>=r.maxHealth)return;e.state.players[n].vars[hV]=!0;let i=r.maxHealth-1;await B(e.state,{type:`设上限`,player:n,amount:i}),await B(e.state,{type:`添加技能`,player:n,skillId:gV})}),()=>{}}function fV(e,t){}var pV,mV,hV,gV,_V,Hde=t((()=>{V(),F(),pV=`界潜心`,mV=`潜心`,hV=`${pV}/awakened`,gV=`界荐言`,_V={createSkill:uV,onInit:dV,onMount:fV}})),Ude=r({createSkill:()=>vV,default:()=>PV,onInit:()=>bV,onMount:()=>xV});function vV(e,t){return{id:e,ownerId:t,name:CV,description:`准备阶段,你可以摸一张牌并展示一张牌;距离为1的其他角色本回合不能使用或打出与"潜袭"牌颜色相同的手牌,你本回合使用"潜袭"牌造成的伤害+1`}}function yV(e){return e.includes(AV)?`红`:e.includes(jV)?`黑`:null}function Wde(e,t,n,r){let i=e.players[t]?.hand??[];for(let t of i){let i=e.cardMap[t];if(i&&i.name===n&&i.color!==r&&i.color!==`无色`)return!0}return!1}function bV(e,t){let n=e.ownerId;j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===EV)return typeof t.choice==`boolean`?null:`需要选择一项`;if(a===DV){let r=t.cardId;return typeof r==`string`?e.players[n]?.hand.includes(r)?null:`牌不在手牌中`:`请选择一张手牌展示`}return`当前不是界潜袭回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===EV?e.localVars[wV]=t.choice===!0:r===DV&&(e.localVars[TV]=t.cardId)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||!e.state.players[n]?.alive)return;if(delete e.state.localVars[wV],await B(e.state,{type:`请求回应`,requestType:EV,target:n,prompt:{type:`confirm`,title:`是否发动潜袭?(摸一张并展示一张牌;距离1的其他角色本回合不能使用/打出同色手牌,你用此牌造伤+1)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[wV]!==!0){delete e.state.localVars[wV];return}delete e.state.localVars[wV],await I(e.state,SV,n,{}),await B(e.state,{type:`摸牌`,player:n,count:1});let r=e.state.players[n];if(!r?.alive||r.hand.length===0){await L(e.state);return}let i=r.hand.map(t=>{let n=e.state.cardMap[t];return n?{cardId:t,cardName:n.name,suit:n.suit,rank:n.rank}:null}).filter(e=>e!==null);delete e.state.localVars[TV],await B(e.state,{type:`请求回应`,requestType:DV,target:n,prompt:{type:`pickProcessingCard`,title:`潜袭:选择一张手牌展示(距离1的其他角色本回合不能使用/打出同色手牌,你用此牌造伤+1)`,cards:i},timeout:30});let a=e.state.localVars[TV],o=e.state.players[n]?.hand??[];(!a||!o.includes(a))&&(a=o[0]),delete e.state.localVars[TV];let s=a?e.state.cardMap[a]:void 0;if(!s){await L(e.state);return}await B(e.state,{type:`展示`,player:n,cardId:a});let c=s.color;if(c!==`红`&&c!==`黑`){await L(e.state);return}e.state.turn.vars[OV]=a,e.state.turn.vars[kV]=c;let l=c===`红`?AV:jV;for(let t of e.state.players)t.index!==n&&t.alive&&Wm(e.state,n,t.index)===1&&(t.tags.includes(l)||await B(e.state,{type:`加标签`,player:t.index,tag:l}));await L(e.state)}),M(t,e.id,n,`请求回应`,async e=>{let t=e.atom,r=t.target;if(typeof r!=`number`||r<0||r===n)return;let i=e.state.players[r];if(!i?.alive)return;let a=yV(i.tags);if(!a)return;let o=t.prompt?.type;if(!o||!NV.has(o))return;let s=t.prompt,c=s?.cardFilter;if(!c)return;let l=c.filter;if(!i.hand.some(t=>{let n=e.state.cardMap[t];return!n||n.color===a?!1:l?l(n):!0}))return{kind:`cancel`};let u=e=>e.color===a?!1:l?l(e):!0;return{kind:`modify`,atom:{...e.atom,prompt:{...s,cardFilter:{...c,filter:u}}}}});let r=e=>async t=>{let r=t.atom.target;if(typeof r!=`number`||r===n)return;let i=t.state.players[r];if(!i?.alive)return;let a=yV(i.tags);if(a&&!Wde(t.state,r,e,a))return{kind:`cancel`}};return M(t,e.id,n,`询问闪`,r(`闪`)),M(t,e.id,n,`询问杀`,r(`杀`)),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0)return;let r=t.cardId;if(typeof r==`string`&&e.state.turn.vars[OV]===r)return{kind:`modify`,atom:{...e.atom,amount:(t.amount??0)+1}}}),N(t,e.id,n,`回合结束`,async e=>{if(e.atom.player===n)for(let t of e.state.players)for(let n of MV)t.tags.includes(n)&&await B(e.state,{type:`去标签`,player:t.index,tag:n})}),()=>{}}function xV(e,t){t.defineAction(`respond`,{label:CV,style:`danger`,prompt:{type:`confirm`,title:`是否发动潜袭?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var SV,CV,wV,TV,EV,DV,OV,kV,AV,jV,MV,NV,PV,Gde=t((()=>{V(),z(),Xm(),F(),SV=`界潜袭`,CV=`潜袭`,wV=`${SV}/confirmed`,TV=`${SV}/pickedCard`,EV=`${SV}/confirm`,DV=`${SV}/pick`,OV=`${SV}/cardId`,kV=`${SV}/color`,AV=`${SV}/禁红`,jV=`${SV}/禁黑`,MV=[AV,jV],NV=new Set([`useCard`,`useCardAndTarget`,`pickProcessingCard`,`pickTargetCard`,`distribute`]),PV={createSkill:vV,onInit:bV,onMount:xV}})),Kde=r({createSkill:()=>FV,default:()=>GV,onInit:()=>IV,onMount:()=>LV});function FV(e,t){return{id:e,ownerId:t,name:`界激将`,description:`主公技:蜀势力角色可代你使用或打出杀;每回合限一次,蜀角色回合外用杀时可令你摸1张`}}function IV(e,t){let n=e.ownerId,r=[];r.push(de(t,n,`询问杀`)),r.push(j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n].alive===!0,s=n===0,c=t.target,l=typeof c==`number`&&!!e.players[c],u=l?e.players[c]:null,d=c!==n,f=u?.alive===!0,p=u?.faction===`蜀`,m=t.killTarget,h=m===void 0||e.players[m]?.alive===!0&&m!==c;return r&&i&&a&&o&&s&&l&&d&&f&&p&&h?null:`现在不能使用界激将`},async(e,t)=>{let r=n,i=t.target,a=t.killTarget;await I(e,`界激将`,r,{...t}),typeof a==`number`&&(e.localVars[UV]=a),await B(e,{type:`请求回应`,requestType:VV,target:i,prompt:{type:`useCardAndTarget`,title:`界激将:对 ${typeof a==`number`?e.players[a]?.name??`?`:`?`} 使用一张杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>typeof a==`number`?t===a:t!==i}},timeout:15});let o=e.localVars[HV];delete e.localVars[HV],delete e.localVars[UV],o?.cardId&&Array.isArray(o.targets)&&o.targets.length>0&&await Lh(e,i,o.cardId,o.targets,`杀`),await L(e)})),r.push(N(t,e.id,n,`指定目标`,async e=>{if(n!==0)return;let t=e.atom,r=t.source;if(typeof r!=`number`||r===n)return;let i=e.state.players[r];if(!i?.alive||i.faction!==`蜀`)return;let a=t.cardId;if(!a||e.state.cardMap[a]?.name!==`杀`||e.state.currentPlayerIndex===r)return;let o=e.state.players[n];o?.alive&&e.state.turn.vars[BV]!==!0&&(e.state.turn.vars[BV]=!0,await B(e.state,{type:`回合用量`,player:n,key:BV,value:!0}),delete e.state.localVars[zV],await B(e.state,{type:`请求回应`,requestType:RV,target:r,prompt:{type:`confirm`,title:`界激将:是否令${o.name}摸一张牌?`,confirmLabel:`令主公摸牌`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),e.state.localVars[zV]===!0&&await B(e.state,{type:`摸牌`,player:n,count:1}))})),r.push(N(t,e.id,n,`询问杀`,async e=>{if(n!==0)return;let t=e.atom.target;if(typeof t!=`number`)return;let r;if(t===n){let t=e.state.localVars[WV];if(delete e.state.localVars[WV],typeof t!=`number`)return;r=t}else r=t;let i=e.state.players[r];if(!i?.alive||i.faction!==`蜀`||e.state.currentPlayerIndex===r||!R(e.state).some(t=>e.state.cardMap[t]?.name===`杀`))return;let a=e.state.players[n];a?.alive&&e.state.turn.vars[BV]!==!0&&(e.state.turn.vars[BV]=!0,await B(e.state,{type:`回合用量`,player:n,key:BV,value:!0}),delete e.state.localVars[zV],await B(e.state,{type:`请求回应`,requestType:RV,target:r,prompt:{type:`confirm`,title:`界激将:是否令${a.name}摸一张牌?`,confirmLabel:`令主公摸牌`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),e.state.localVars[zV]===!0&&await B(e.state,{type:`摸牌`,player:n,count:1}))}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type===`询问杀`)return e.players[i]?.alive?i===0?e.players.some(e=>e.alive&&e.index!==i&&e.faction===`蜀`&&e.hand.length>0)?null:`没有可出杀的蜀势力角色`:`仅主公可用`:`玩家不存在或已死亡`;if(r.requestType===VV){let n=t.cardId,r=t.targets;if(typeof n!=`string`)return`请选择一张杀`;if(!Array.isArray(r)||r.length===0)return`请选择目标`;if(!e.players[i]?.hand.includes(n))return`牌不在手牌中`;if(e.cardMap[n]?.name!==`杀`)return`只能使用杀`;let a=e.localVars[UV];if(typeof a==`number`&&!r.includes(a))return`必须包含激将指定的目标`;for(let t of r)if(!Gm(e,i,t,n))return`目标不在攻击范围内`;return null}return r.requestType===RV?null:`当前不是界激将询问`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom;if(n?.type===`询问杀`){let t=e.players.length;for(let n=1;n<t;n++){let r=(i+n)%t,a=e.players[r];if(a?.alive&&a.faction===`蜀`&&a.hand.length!==0&&(await B(e,{type:`请求回应`,requestType:`杀/respondKill`,target:r,prompt:{type:`useCard`,title:`界激将:主公(${e.players[i]?.name??`P${i}`})需要杀,是否打出一张杀?`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},timeout:15}),R(e).find(t=>e.cardMap[t]?.name===`杀`))){e.localVars[WV]=r;return}}return}if(n?.requestType===VV){e.localVars[HV]={cardId:t.cardId,targets:t.targets};return}n?.requestType===RV&&(e.localVars[zV]=t.choice===!0||t.confirmed===!0)}))}return()=>{for(let e of r)e()}}function LV(e,t){return t.defineAction(`use`,{label:`界激将`,style:`primary`,prompt:{type:`choosePlayer`,title:`界激将:选择一名蜀势力角色出杀`,min:1,max:1,filter:(t,n)=>n!==e.ownerId&&t.players[n]?.alive===!0&&t.players[n]?.faction===`蜀`},activeWhen:t=>q(t)&&im(e.ownerId)}),t.defineAction(`respond`,{label:`界激将`,style:`primary`,prompt:{type:`confirm`,title:`界激将:令蜀势力角色替你打出杀?`,confirmLabel:`激将`,cancelLabel:`不发动`},activeWhen:e=>{let t=e.view.pending;if(!t||t.target!==e.perspectiveIdx)return!1;let n=t.atom;return n.type===`询问杀`||n.requestType===VV||n.requestType===RV}}),()=>{}}var RV,zV,BV,VV,HV,UV,WV,GV,qde=t((()=>{V(),z(),Gh(),F(),Xm(),J(),RV=`界激将/drawChoice`,zV=`界激将/confirmed`,BV=`界激将/triggered`,VV=`界激将/出杀`,HV=`界激将/出杀选择`,UV=`界激将/killTarget`,WV=`界激将/代打出者`,GV={createSkill:FV,onInit:IV,onMount:LV}})),Jde=r({createSkill:()=>qV,default:()=>rH,onInit:()=>JV,onMount:()=>YV});function Yde(e){return`${XV}/src/${e}`}function KV(e,t,n=!0){let r=t?e.cardMap[t]:void 0;if(r?.name===`决斗`||r?.name===`杀`&&r.color===`红`)return!0;if(!n)return!1;let i=Ke(e)?.skillId;return i===`决斗`||i===`离间`}function qV(e,t){return{id:e,ownerId:t,name:ZV,description:`使用/被使用【决斗】或红色【杀】时可摸一张牌;每回合首次此类牌因弃置入弃牌堆时可失去1体力获得之`}}function JV(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==QV&&a!==eH?`当前不是界激昂确认`:null},async(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return;let i=r.atom.requestType,a=t.choice===!0||t.confirmed===!0;i===QV?e.localVars[$V]=a:e.localVars[tH]=a}),N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if((t.source===n||t.target===n)&&e.state.players[n]?.alive&&KV(e.state,t.cardId)){if(t.source===n){let n=Yde(t.cardId??`__virtual__`);if(e.state.localVars[n])return;e.state.localVars[n]=!0}delete e.state.localVars[$V],await B(e.state,{type:`请求回应`,requestType:QV,target:n,prompt:{type:`confirm`,title:`是否发动激昂?(摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[$V]&&await B(e.state,{type:`摸牌`,player:n,count:1})}}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(!e.state.players[n]?.alive||e.state.players[n].vars[nH])return;let r=(t.cardIds??[]).filter(t=>KV(e.state,t,!1));if(r.length!==0&&(e.state.players[n].vars[nH]=!0,delete e.state.localVars[tH],await B(e.state,{type:`请求回应`,requestType:eH,target:n,prompt:{type:`confirm`,title:`是否发动激昂?(失去1点体力获得此牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[tH]&&(await B(e.state,{type:`失去体力`,target:n,amount:1}),e.state.players[n]?.alive)))for(let t of r)e.state.zones.discardPile.includes(t)&&await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}})}),()=>{}}function YV(e,t){t.defineAction(`respond`,{label:ZV,style:`primary`,prompt:{type:`confirm`,title:`是否发动激昂?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var XV,ZV,QV,$V,eH,tH,nH,rH,Xde=t((()=>{V(),z(),F(),XV=`界激昂`,ZV=`激昂`,QV=`${XV}/confirm`,$V=`${XV}/confirmed`,eH=`${XV}/recycle`,tH=`${XV}/recycleConfirm`,nH=`${XV}/recycle/usedThisTurn`,rH={createSkill:qV,onInit:JV,onMount:YV}})),Zde=r({createSkill:()=>iH,default:()=>cH,onInit:()=>oH,onMount:()=>sH});function iH(e,t){return{id:e,ownerId:t,name:`界火计`,description:`你可以将一张红色牌当【火攻】使用;你的【火攻】改为目标展示随机手牌,你弃同颜色牌造伤`}}function aH(e){return`${e}#界火计`}function oH(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=l&&Object.values(o.equipment).some(e=>e===c),p=!!u&&u.color===`红`;return r&&i&&a&&s&&(d||f)&&p?null:`现在不能使用界火计`},async(e,t)=>{let r=t.cardId,i=aH(r),a=e.players[n],o=Object.entries(a.equipment).find(([,e])=>e===r);if(o){let r=o[0];t._origSlot=r,await B(e,{type:`卸下`,player:n,slot:r})}await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`火攻`})},(e,t)=>{let r=t.cardId,i=aH(r),a=e.players[n],o=t._origSlot;delete e.cardMap[i];let s=a.hand.indexOf(i);s>=0&&(o?(a.hand.splice(s,1),a.equipment[o]=r):a.hand[s]=r)}),j(t,`火攻`,n,`use`,(e,t)=>{let r=oe(e,n,t,{cardName:`火攻`});if(r)return r;let i=t.targets;if(!Array.isArray(i)||i.length!==1)return`火攻只能指定一名目标`;let a=i[0],o=e.players[a];return o?.alive?o.hand.length===0?`目标必须有手牌`:null:`目标不合法`},async(e,t)=>{let r=n,i=t.cardId,a=t.targets[0];await I(e,`界火计`,r,{...t}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`处理区`}});try{if(!await Bm(e,{cardName:`无懈可击`,broadcast:!0},r,a)){let t=e.players[a];if(t&&t.hand.length>0){delete e.localVars[`界火计/展示`],delete e.localVars[`界火计/展示颜色`],delete e.localVars[`界火计/弃牌`];let n=t.hand.length,o=Ud(e.rngSeed),s=o.nextInt(n);e.rngSeed=o.getState();let c=t.hand[s],l=e.cardMap[c]?.color??`无色`;e.localVars[`界火计/展示`]={cardId:c,color:l},e.localVars[`界火计/展示颜色`]=l,await B(e,{type:`展示`,player:a,cardId:c});let u=e.players[r];if(u?.alive&&u.hand.some(t=>e.cardMap[t]?.color===l)){delete e.localVars[`界火计/弃牌`],await B(e,{type:`请求回应`,requestType:`界火计/弃牌`,target:r,prompt:{type:`useCard`,title:`界火计:弃置一张 ${l} 手牌对其造成1点火焰伤害(不弃则无效)`,cardFilter:{filter:e=>e.color===l,min:1,max:1}},timeout:15});let t=e.localVars[`界火计/弃牌`];t&&e.players[a]?.alive&&(await B(e,{type:`弃置`,player:r,cardIds:[t],voluntary:!0}),await Dm(e,r,a,1,i,`火焰`))}}}await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}finally{R(e).includes(i)&&await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await L(e)}}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`||r.atom.requestType!==`界火计/弃牌`)return`当前不是界火计窗口`;let i=t.cardId;if(typeof i!=`string`)return`cardId required`;let a=e.players[n];if(!a?.alive)return`你已死亡`;if(!a.hand.includes(i))return`牌不在手牌中`;let o=e.localVars[`界火计/展示颜色`],s=e.cardMap[i];return!o||s?.color!==o?`必须弃置与展示牌相同颜色的手牌`:null},async(e,t)=>{let n=t.cardId;e.localVars[`界火计/弃牌`]=n}),()=>{}}function sH(e,t){t.defineAction(`transform`,{label:`界火计`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张红色牌(手牌或装备)当火攻使用`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>(e.players[t]?.handCount??0)>0}},transform:t=>({name:`火攻`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];if(!t)return!1;let n=t.hand?.some(e=>e.color===`红`)??!1,r=Object.values(t.equipment??{}).some(t=>(t?e.view.cardMap[t]:void 0)?.color===`红`);return n||r}}),t.defineAction(`respond`,{label:`界火计`,style:`primary`,prompt:{type:`useCard`,title:`界火计:弃置一张与展示牌同颜色的手牌`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var cH,Qde=t((()=>{F(),V(),z(),Om(),Um(),J(),Wd(),cH={createSkill:iH,onInit:oH,onMount:sH}})),$de=r({createSkill:()=>uH,default:()=>bH,onInit:()=>dH,onMount:()=>fH});function lH(e){return!!e&&e.type===`锦囊牌`&&e.trickSubtype!==`响应锦囊`}function uH(e,t){return{id:e,ownerId:t,name:mH,description:`出牌阶段限一次:将一张锦囊牌置于牌堆顶,令一名有手牌的其他角色选择弃一张锦囊或依次弃两张牌`}}function dH(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,pH))return`本回合已使用过灭计`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;if(typeof i!=`string`)return`请选择一张锦囊牌`;if(!r.hand.includes(i))return`牌不在手牌中`;if(!lH(e.cardMap[i]))return`只能选择锦囊牌`;let a=t.target??t.targets?.[0];if(typeof a!=`number`)return`请指定一名目标`;if(a===n)return`不能以自己为目标`;let o=e.players[a];return o?.alive?o.hand.length===0?`目标没有手牌`:null:`目标不合法`},async(e,t)=>{let r=n,i=t.target??t.targets?.[0],a=t.cardId;await Z(e,r,pH),await I(e,pH,r,{target:i,cardId:a}),e.players[r]?.hand.includes(a)&&await B(e,{type:`移动牌`,cardId:a,from:{zone:`手牌`,player:r},to:{zone:`牌堆`}});let o=e.players[i],s=o?.hand.some(t=>lH(e.cardMap[t]))??!1,c=(o?.hand.length??0)>=2,l;if(s&&c)delete e.localVars[gH],await B(e,{type:`请求回应`,requestType:hH,target:i,prompt:{type:`confirm`,title:`灭计:选择一项`,description:`1.弃置一张锦囊牌;2.依次弃置两张牌`,confirmLabel:`弃一张锦囊`,cancelLabel:`依次弃两张`},defaultChoice:!1,timeout:30}),l=e.localVars[gH]===`trick`?`trick`:`twoCards`,delete e.localVars[gH];else if(s)l=`trick`;else if(c)l=`twoCards`;else{await L(e);return}if(l===`trick`){delete e.localVars[yH],await B(e,{type:`请求回应`,requestType:_H,target:i,prompt:{type:`useCard`,title:`灭计:弃置一张锦囊牌`,cardFilter:{filter:e=>lH(e),min:1,max:1}},mandatory:!0,timeout:30});let t=e.localVars[yH];delete e.localVars[yH];let n=t,r=e.players[i];(!n||!r?.hand.includes(n)||!lH(e.cardMap[n]))&&r?.alive&&(n=r.hand.find(t=>lH(e.cardMap[t]))),n&&r?.hand.includes(n)&&await B(e,{type:`弃置`,player:i,cardIds:[n]})}else for(let t=0;t<2;t++){let n=e.players[i];if(!n?.alive||n.hand.length===0)break;delete e.localVars[yH],await B(e,{type:`请求回应`,requestType:vH,target:i,prompt:{type:`useCard`,title:`灭计:依次弃置两张牌(第 ${t+1}/2 张)`,cardFilter:{filter:()=>!0,min:1,max:1}},mandatory:!0,timeout:30});let r=e.localVars[yH];delete e.localVars[yH];let a=r;if((!a||!n.hand.includes(a))&&n.alive&&(a=n.hand[0]),a&&e.players[i]?.hand.includes(a))await B(e,{type:`弃置`,player:i,cardIds:[a]});else break}await L(e)}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;if(a===hH)return null;if(a===_H||a===vH){let n=t.cardIds,r=Array.isArray(n)?n[0]:t.cardId;return typeof r==`string`?e.players[i]?.hand.includes(r)?a===_H&&!lH(e.cardMap[r])?`只能选择锦囊牌`:null:`牌不在手牌中`:`请选择一张牌`}return`当前不是灭计询问`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;if(n===hH)e.localVars[gH]=t.choice===!0||t.confirmed===!0?`trick`:`twoCards`;else if(n===_H||n===vH){let n=t.cardIds,r=Array.isArray(n)?n[0]:t.cardId;typeof r==`string`&&(e.localVars[yH]=r)}}))}return()=>{for(let e of r)e()}}function fH(e,t){t.defineAction(`use`,{label:mH,style:`primary`,prompt:{type:`useCardAndTarget`,title:`灭计:将一张锦囊牌置于牌堆顶,令一名有手牌的其他角色弃锦囊或弃两张牌`,cardFilter:{filter:e=>lH(e),min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players.find(e=>e.index===t);return!n||n.alive===!1?!1:n.handCount>0}}},activeWhen:e=>yh(pH)(e)}),t.defineAction(`respond`,{label:mH,style:`primary`,prompt:{type:`confirm`,title:`灭计:选择一项`,confirmLabel:`弃一张锦囊`,cancelLabel:`依次弃两张`}})}var pH,mH,hH,gH,_H,vH,yH,bH,efe=t((()=>{V(),z(),Q(),F(),pH=`界灭计`,mH=`灭计`,hH=`界灭计/选效果`,gH=`界灭计/effect`,_H=`界灭计/弃锦囊`,vH=`界灭计/弃一张`,yH=`界灭计/cardId`,bH={createSkill:uH,onInit:dH,onMount:fH}})),tfe=r({createSkill:()=>xH,default:()=>DH,onInit:()=>SH,onMount:()=>CH});function nfe(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function xH(e,t){return{id:e,ownerId:t,name:`界烈弓`,description:`你的杀攻击范围为此杀点数;指定目标后,若其手牌数不大于你,其不能抵消;若其体力值不小于你,伤害+1`}}function SH(e,t){let n=e.ownerId,r=qm(t,n,(e,t,n,r)=>{if(!r)return!1;let i=e.cardMap[r];if(!i)return!1;let a=nfe(i.rank);return a<=0?!1:Wm(e,t,n)<=a});return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===`界烈弓/confirm`?null:`当前不是界烈弓确认`:`当前不是请求回应`},async(e,t)=>{e.localVars[EH]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0)return;let r=t.target;if(t.cardId!==void 0&&e.state.cardMap[t.cardId]?.name!==`杀`)return;let i=e.state.players[n],a=e.state.players[r];if(!i?.alive||!a?.alive)return;a.tags.includes(wH)&&await B(e.state,{type:`去标签`,player:r,tag:wH}),a.tags.includes(TH)&&await B(e.state,{type:`去标签`,player:r,tag:TH});let o=a.hand.length<=i.hand.length,s=p(a)>=p(i);!o&&!s||(delete e.state.localVars[EH],await B(e.state,{type:`请求回应`,requestType:`界烈弓/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动烈弓?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[EH]&&(o&&await B(e.state,{type:`加标签`,player:r,tag:wH}),s&&await B(e.state,{type:`加标签`,player:r,tag:TH})))}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r!==void 0&&e.state.players[r]?.tags.includes(wH))return await B(e.state,{type:`去标签`,player:r,tag:wH}),{kind:`cancel`}}),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0)return;let r=t.target;if(r===void 0)return;let i=t.cardId;if(typeof i==`string`&&e.state.cardMap[i]?.name===`杀`&&e.state.players[r]?.tags.includes(TH))return await B(e.state,{type:`去标签`,player:r,tag:TH}),{kind:`modify`,atom:{...e.atom,amount:(t.amount??0)+1}}}),()=>{r()}}function CH(e,t){t.defineAction(`respond`,{label:`界烈弓`,style:`default`,prompt:{type:`confirm`,title:`是否发动烈弓?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var wH,TH,EH,DH,rfe=t((()=>{b(),V(),F(),Xm(),wH=`界烈弓/禁闪`,TH=`界烈弓/加伤`,EH=`界烈弓/confirmed`,DH={createSkill:xH,onInit:SH,onMount:CH}})),ife=r({createSkill:()=>OH,default:()=>HH,onInit:()=>AH,onMount:()=>jH});function OH(e,t){return{id:e,ownerId:t,name:NH,description:`限定技:选一名其他角色开始,所有其他角色依次弃比上家多的牌或受你造成的2点火焰伤害`}}function kH(e){let t=e.turn.vars[VH];return typeof t==`number`?t:0}function AH(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`use`,(e,t)=>e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:e.players[n]?.vars[PH]?`焚城已使用过(限定技)`:e.players[n]?.alive?e.players.filter(e=>e.alive&&e.index!==n).length===0?`场上没有其他存活角色`:null:`玩家不存在或已死亡`:`只能在出牌阶段发动`:`不是你的回合`,async(e,t)=>{let r=n;e.players[r].vars[PH]=!0,await I(e,MH,r,{});try{delete e.localVars[IH],await B(e,{type:`请求回应`,requestType:FH,target:r,prompt:{type:`choosePlayer`,title:`焚城:选择一名其他角色作为起点`,description:`所有其他角色从该角色开始依次选择弃牌或受2点火焰伤害`,min:1,max:1,filter:(t,n)=>n!==r&&e.players[n]?.alive===!0},timeout:30});let t=e.localVars[IH];if(delete e.localVars[IH],!Array.isArray(t)||t.length!==1)return;let n=t[0];if(!e.players[n]?.alive)return;e.turn.vars[VH]=0;let i=e.players.length;for(let t=0;t<i;t++){let a=(n+t)%i;if(a===r||!e.players[a]?.alive)continue;let o=kH(e),s=e.players[a].hand.length,c=s>o,l;if(c?(delete e.localVars[RH],await B(e,{type:`请求回应`,requestType:LH,target:a,prompt:{type:`confirm`,title:`焚城:选一项(上家弃 ${o} 张)`,description:`1.弃置 ${o+1} 张或更多牌;2.受到李儒造成的 2 点火焰伤害`,confirmLabel:`弃 ≥ ${o+1} 张`,cancelLabel:`受 2 点火伤`},defaultChoice:!1,timeout:30}),l=e.localVars[RH]===`discard`?`discard`:`damage`,delete e.localVars[RH]):l=`damage`,l===`discard`){delete e.localVars[BH],await B(e,{type:`请求回应`,requestType:zH,target:a,prompt:{type:`distribute`,mode:`select`,title:`焚城:弃置至少 ${o+1} 张牌(上家弃 ${o} 张)`,source:`hand`,minTotal:o+1,maxTotal:s},timeout:30});let t=e.localVars[BH];delete e.localVars[BH],Array.isArray(t)&&t.length>=o+1&&t.every(t=>e.players[a]?.hand.includes(t))?(await B(e,{type:`弃置`,player:a,cardIds:t}),e.turn.vars[VH]=t.length):e.players[a]?.alive&&await Dm(e,r,a,2,void 0,`火焰`)}else e.players[a]?.alive&&await Dm(e,r,a,2,void 0,`火焰`)}delete e.turn.vars[VH]}finally{await L(e)}}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;if(a===FH){let n=t.targets;if(!Array.isArray(n)||n.length!==1)return`请选择一名起点`;let r=n[0];return r===i?`不能选自己为起点`:e.players[r]?.alive?null:`起点不合法`}if(a===LH)return null;if(a===zH){let n=t.cardIds;if(!Array.isArray(n)||n.length===0)return`请选择要弃置的牌`;let r=e.players[i];if(!r)return`玩家不存在`;let a=kH(e);if(n.length<=a)return`须弃置至少 ${a+1} 张`;if(new Set(n).size!==n.length)return`不能重复选牌`;for(let e of n)if(!r.hand.includes(e))return`牌不在手牌中`;return null}return`当前不是焚城询问`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;if(n===FH){let n=t.targets;Array.isArray(n)&&(e.localVars[IH]=n)}else if(n===LH)e.localVars[RH]=t.choice===!0||t.confirmed===!0?`discard`:`damage`;else if(n===zH){let n=t.cardIds;Array.isArray(n)&&(e.localVars[BH]=n)}}))}return()=>{for(let e of r)e()}}function jH(e,t){t.defineAction(`use`,{label:NH,style:`danger`,prompt:{type:`confirm`,title:`焚城(限定技):选一名其他角色开始,所有其他角色依次弃比上家多的牌或受2点火焰伤害`},activeWhen:e=>q(e)}),t.defineAction(`respond`,{label:NH,style:`danger`,prompt:{type:`confirm`,title:`焚城:选择一项`}})}var MH,NH,PH,FH,IH,LH,RH,zH,BH,VH,HH,afe=t((()=>{V(),z(),Om(),J(),F(),MH=`界焚城`,NH=`焚城`,PH=`界焚城/used`,FH=`界焚城/选起点`,IH=`界焚城/start`,LH=`界焚城/选效果`,RH=`界焚城/effect`,zH=`界焚城/弃牌`,BH=`界焚城/discarded`,VH=`界焚城/lastCount`,HH={createSkill:OH,onInit:AH,onMount:jH}})),ofe=r({createSkill:()=>UH,default:()=>rU,onInit:()=>JH,onMount:()=>YH});function UH(e,t){return{id:e,ownerId:t,name:ZH,description:`出牌阶段,你可以重铸【杀】;出牌阶段结束时,若你本阶段失去过至少两张【杀】,可令一名男性角色摸两张牌`}}function WH(e,t){return e.players[t]?.vars[QH]??0}function GH(e,t,n){let r=e.players[t];if(!r)return;let i=WH(e,t);r.vars[QH]=i+n}function KH(e,t){return e.currentPlayerIndex===t&&e.phase===`出牌`}function sfe(e,t){let n=e.players[t];return n?.alive?kc(n.character)===`男`:!1}function cfe(e){return e.players.some(e=>e.alive&&kc(e.character)===`男`)}function qH(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function JH(e,t){let n=e.ownerId;return j(t,e.id,n,`recycle`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o?.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=!!u&&u.name===`杀`;return r&&i&&a&&s&&d&&f?null:`现在不能重铸(需出牌阶段、手中【杀】)`},async(e,t)=>{let r=n,i=t.cardId;await I(e,XH,r,{...t,recycle:!0}),await rP(e,r,i),await L(e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=qH(e,n);if(r!==$H&&r!==eU)return`当前不是燕语询问`;if(r===eU){let n=t.target;if(typeof n!=`number`)return`请选择一名男性角色`;if(!sfe(e,n))return`目标必须是存活的男性角色`}return null},async(e,t)=>{let r=qH(e,n);r===$H?e.localVars[tU]=t.choice===!0||t.confirmed===!0:r===eU&&(e.localVars[nU]=t.target)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`出牌`||t.player!==n)return;let r=e.state.players[n];r&&(r.vars[QH]=0)}),N(t,e.id,n,`移动牌`,async e=>{if(!KH(e.state,n))return;let t=e.atom;if(t.from?.zone!==`手牌`||t.from.player!==n)return;let r=t.cardId;typeof r==`string`&&e.state.cardMap[r]?.name===`杀`&&GH(e.state,n,1)}),N(t,e.id,n,`弃置`,async e=>{if(!KH(e.state,n))return;let t=e.atom;if(t.player!==n)return;let r=(Array.isArray(t.cardIds)?t.cardIds:[]).filter(t=>e.state.cardMap[t]?.name===`杀`).length;r>0&&GH(e.state,n,r)}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`出牌`||t.player!==n)return;let r=e.state;if(!r.players[n]?.alive||WH(r,n)<2||!cfe(r)||(delete r.localVars[tU],await B(r,{type:`请求回应`,requestType:$H,target:n,prompt:{type:`confirm`,title:`是否发动燕语?(令一名男性角色摸两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!r.localVars[tU]))return;delete r.localVars[tU],delete r.localVars[nU],await B(r,{type:`请求回应`,requestType:eU,target:n,prompt:{type:`choosePlayer`,title:`燕语:选择一名男性角色(其摸两张牌)`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0&&kc(e.players[t].character)===`男`},timeout:15});let i=r.localVars[nU];delete r.localVars[nU],typeof i==`number`&&r.players[i]?.alive&&await B(r,{type:`摸牌`,player:i,count:2})}),()=>{}}function YH(e,t){return t.defineAction(`recycle`,{label:`${ZH}·重铸`,style:`primary`,prompt:{type:`useCard`,title:`燕语:重铸一张【杀】(弃此牌,摸一张)`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}}}),t.defineAction(`respond`,{label:ZH,style:`primary`,prompt:{type:`confirm`,title:`是否发动燕语?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var XH,ZH,QH,$H,eU,tU,nU,rU,lfe=t((()=>{V(),z(),iP(),F(),Fc(),XH=`界燕语`,ZH=`燕语`,QH=`${XH}/lostShaThisPhase`,$H=`${XH}/confirm`,eU=`${XH}/target`,tU=`${XH}/confirmed`,nU=`${XH}/targetChoice`,rU={createSkill:UH,onInit:JH,onMount:YH}})),ufe=r({createSkill:()=>iU,default:()=>pU,onInit:()=>lU,onMount:()=>uU});function iU(e,t){return{id:e,ownerId:t,name:`父魂`,description:`转化技:两张牌当杀;转化杀目标只能用同色手牌响应;出牌阶段杀造成伤害后本回合获得武圣咆哮`}}function aU(e,t){return`${e}#${t}#界父魂`}function oU(e,t){return e.hand.includes(t)?!0:Object.values(e.equipment).some(e=>e===t)}function sU(e){return`${e}#界父魂`}function cU(e,t){return e.turn.vars[dU]===t}function lU(e,t){let n=e.ownerId,r=j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardIds;if(!Array.isArray(c)||c.length!==2)return`需要选择 2 张牌`;let[l,u]=c;if(typeof l!=`string`||typeof u!=`string`)return`cardIds 必须为字符串`;if(l===u)return`不能选择同一张牌`;let d=!!o&&oU(o,l)&&oU(o,u),f=e.cardMap[l],p=e.cardMap[u],m=!!f&&!!p,h=e.pendingSlots.get(n),g=h?.atom?.type,_=h?.atom?.requestType,v=h?.atom?.target;return(r&&i&&a||h&&v===n&&(g===`询问杀`||g===`请求回应`&&_===`杀/respondKill`))&&s&&d&&m?null:`父魂转化条件不满足`},async(e,t)=>{let r=t.cardIds,[i,a]=r,o=e.players[n],s=[];for(let e of r){let t=Object.entries(o.equipment).find(([,t])=>t===e);t&&s.push({slot:t[0],cardId:e})}if(s.length>0){t._unequipped=s;for(let{slot:t}of s)await B(e,{type:`卸下`,player:n,slot:t})}await B(e,{type:`当作`,player:n,cardIds:r,shadowId:aU(i,a),outputName:`杀`})},(e,t)=>{let r=t.cardIds,[i,a]=Array.isArray(r)?r:[],o=i&&a?aU(i,a):void 0;if(!o)return;delete e.cardMap[o];let s=e.players[n],c=s.hand.indexOf(o);c>=0&&s.hand.splice(c,1);let l=t._unequipped;if(l)for(let{slot:t,cardId:n}of l)if(s.equipment[t]===void 0){if(s.equipment[t]=n,t===`武器`){let t=e.cardMap[n];s.vars[wl]=t?.range??1}}else s.hand.push(n);for(let e of r)!s.hand.includes(e)&&!l?.some(t=>t.cardId===e)&&s.hand.push(e)}),i=j(t,e.id,n,`武圣transform`,(e,t)=>{if(!cU(e,n))return`本回合未获得武圣`;let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=!!u&&u.color===`红`,p=e.pendingSlots.get(n),m=p?.atom?.type,h=p?.atom?.requestType,g=p?.atom?.target;return(r&&i&&a||p&&g===n&&(m===`询问杀`||m===`请求回应`&&h===`杀/respondKill`))&&s&&d&&f?null:`现在不能使用武圣`},async(e,t)=>{let r=t.cardId,i=sU(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`杀`})},(e,t)=>{let r=t.cardId,i=sU(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),a=eh(t,n,(e,t)=>cU(e,t)),o=N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0||e.state.phase!==`出牌`||e.state.currentPlayerIndex!==n)return;let r=t.cardId;((r?e.state.cardMap[r]:void 0)?.name===`杀`||Ke(e.state)?.skillId===`杀`)&&(cU(e.state,n)||(e.state.turn.vars[dU]=n,await B(e.state,{type:`回合用量`,player:n,key:qc(`父魂`),value:!0})))}),s=M(t,e.id,n,`询问闪`,async e=>{if(e.atom.source!==n)return;let t=Ke(e.state);if(t?.skillId!==`杀`)return;let r=t.params.cardId;if(typeof r!=`string`||!r.includes(`#`))return;let i=e.state.cardMap[r];if(!i)return;let a=i.color;a!==`红`&&a!==`黑`||(e.state.localVars[fU]=a)}),c=N(t,e.id,n,`询问闪`,async e=>{delete e.state.localVars[fU]}),l=de(t,n,`询问杀`);return()=>{r(),i(),a(),o(),s(),c(),l()}}function uU(e,t){t.defineAction(`transform`,{label:`父魂`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择 2 张牌当杀使用`,cardFilter:{filter:()=>!0,min:2,max:2},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t?.alive)return!1;let n=Object.values(t.equipment??{}).filter(Boolean).length;if((t.handCount??0)+n<2)return!1;let r=q(e)&&sm(e.view,e.perspectiveIdx),i=e.view.pending,a=i?.atom?.type,o=i?.atom?.requestType,s=!!i&&i.target===e.perspectiveIdx&&(a===`询问杀`||a===`请求回应`&&o===`杀/respondKill`);return r||s}}),t.defineAction(`武圣transform`,{label:`武圣`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张红色手牌当杀使用`,cardFilter:{filter:e=>e.color===`红`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t?.alive||!t.turnUsage?.[qc(`父魂`)]||!(t.hand?.some(e=>e.color===`红`)??!1))return!1;let n=q(e)&&sm(e.view,e.perspectiveIdx),r=e.view.pending,i=r?.atom?.type,a=r?.atom?.requestType,o=!!r&&r.target===e.perspectiveIdx&&(i===`询问杀`||i===`请求回应`&&a===`杀/respondKill`);return n||o}})}var dU,fU,pU,dfe=t((()=>{F(),V(),z(),fh(),um(),J(),W(),dU=`父魂/granted`,fU=`闪/色限制`,pU={createSkill:iU,onInit:lU,onMount:uU}})),ffe=r({createSkill:()=>mU,default:()=>xU,onInit:()=>hU,onMount:()=>gU});function mU(e,t){return{id:e,ownerId:t,name:`界狂骨`,description:`对距离1以内的角色每造成1点伤害时,你可以回复1点体力或摸一张牌`}}function hU(e,t){let n=e.ownerId,r=j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==_U&&a!==vU?`当前不是狂骨询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===_U?e.localVars[yU]=t.choice===!0||t.confirmed===!0:r===vU&&(e.localVars[bU]=t.choice===!0?`heal`:`draw`)});return N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.amount??0;if(r<=0||t.target===void 0)return;let i=t.target;if(e.state.players[i]?.alive&&!(Wm(e.state,n,i)>1))for(let t=0;t<r;t++){let i=e.state.players[n];if(!i?.alive)return;let a=i.health>=i.maxHealth;delete e.state.localVars[yU],await B(e.state,{type:`请求回应`,requestType:_U,target:n,prompt:{type:`confirm`,title:`是否发动界狂骨?(第 ${t+1}/${r} 点伤害)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),e.state.localVars[yU]===!0&&(delete e.state.localVars[bU],await B(e.state,{type:`请求回应`,requestType:vU,target:n,prompt:{type:`confirm`,title:`界狂骨:回复1点体力,或摸一张牌?`,confirmLabel:`回复1点体力`,cancelLabel:`摸一张牌`,confirmDisabled:a?!0:void 0},defaultChoice:!1,timeout:30}),e.state.localVars[bU]===`heal`?await B(e.state,{type:`回复体力`,target:n,amount:1}):await B(e.state,{type:`摸牌`,player:n,count:1}))}}),()=>{r()}}function gU(e,t){}var _U,vU,yU,bU,xU,pfe=t((()=>{V(),F(),Xm(),_U=`界狂骨/confirm`,vU=`界狂骨/choose`,yU=`界狂骨/confirmed`,bU=`界狂骨/choice`,xU={createSkill:mU,onInit:hU,onMount:gU}})),mfe=r({createSkill:()=>SU,default:()=>LU,onInit:()=>wU,onMount:()=>TU});function SU(e,t){return{id:e,ownerId:t,name:DU,description:`其他角色出牌阶段开始时,你可以摸至多两张牌,然后交给其等量牌;此阶段结束时若其造成伤害小于你以此法交给其的牌数,你失去1点体力`}}function CU(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function wU(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=CU(e,n);if(!r)return`当前不需要回应`;if(r===NU||r===PU||r===FU)return null;if(r===IU){let r=t.cardIds,i=e.localVars[jU]??0;if(!Array.isArray(r))return`需要 cardIds 数组`;if(r.length!==i)return`需要给出 ${i} 张牌`;if(new Set(r).size!==r.length)return`不能重复`;let a=e.players[n];return a?r.every(e=>typeof e==`string`&&a.hand.includes(e))?null:`牌不在手牌中`:`玩家不存在`}return`当前不是献图询问`},async(e,t)=>{let r=CU(e,n);if(r){if(r===NU||r===PU||r===FU)e.localVars[MU]=t.choice===!0||t.confirmed===!0;else if(r===IU){let n=t.cardIds;e.localVars[AU]=Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`出牌`)return;let r=t.player;if(typeof r!=`number`||r===n)return;let i=e.state;if(!i.players[n]?.alive||!i.players[r]?.alive)return;if(delete i.turn.vars[OU(r)],delete i.turn.vars[kU(r)],delete i.localVars[MU],await B(i,{type:`请求回应`,requestType:NU,target:n,prompt:{type:`confirm`,title:`是否发动献图?(摸至多两张牌,然后交给 ${i.players[r]?.name} 等量牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!i.localVars[MU]){delete i.localVars[MU];return}delete i.localVars[MU],await I(i,EU,n,{target:r});let a;if(delete i.localVars[MU],await B(i,{type:`请求回应`,requestType:PU,target:n,prompt:{type:`confirm`,title:`献图:摸几张牌?(确认=2张,取消=少一些)`,confirmLabel:`摸 2 张`,cancelLabel:`少一些`},defaultChoice:!0,timeout:15}),i.localVars[MU]===!1?(delete i.localVars[MU],await B(i,{type:`请求回应`,requestType:FU,target:n,prompt:{type:`confirm`,title:`献图:摸 1 张牌?(确认=1张,取消=0张/不摸)`,confirmLabel:`摸 1 张`,cancelLabel:`不摸`},defaultChoice:!0,timeout:15}),a=i.localVars[MU]===!1?0:1):a=2,delete i.localVars[MU],a===0){i.turn.vars[OU(r)]=0,await L(i);return}if(await B(i,{type:`摸牌`,player:n,count:a}),!i.players[n]?.alive){i.turn.vars[OU(r)]=0,await L(i);return}let o=i.players[n].hand.length,s=Math.min(a,o);if(s===0){i.turn.vars[OU(r)]=0,await L(i);return}if(s===o){let e=[...i.players[n].hand],t=0;for(let a of e)i.players[n].hand.includes(a)&&(await B(i,{type:`给予`,cardId:a,from:n,to:r}),t++);i.turn.vars[OU(r)]=t,await L(i);return}i.localVars[jU]=s,delete i.localVars[AU],await B(i,{type:`请求回应`,requestType:IU,target:n,prompt:{type:`useCard`,title:`献图:选择 ${s} 张手牌给予 ${i.players[r]?.name}`,cardFilter:{filter:()=>!0,min:s,max:s}},mandatory:!0,timeout:30}),delete i.localVars[jU];let c=i.localVars[AU];delete i.localVars[AU];let l=Array.isArray(c)?c:[],u=0;for(let e of l)i.players[n].hand.includes(e)&&(await B(i,{type:`给予`,cardId:e,from:n,to:r}),u++);if(u<s)for(let e of[...i.players[n].hand]){if(u>=s)break;await B(i,{type:`给予`,cardId:e,from:n,to:r}),u++}i.turn.vars[OU(r)]=u,await L(i)}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.state;if(t.phase!==`出牌`)return;let n=e.atom;if(typeof n.source!=`number`||(n.amount??0)<=0||n.source!==t.currentPlayerIndex||typeof t.turn.vars[OU(t.currentPlayerIndex)]!=`number`)return;let r=t.turn.vars[kU(t.currentPlayerIndex)]??0;t.turn.vars[kU(t.currentPlayerIndex)]=r+(n.amount??0)}),N(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`出牌`)return;let r=t.player;if(typeof r!=`number`||r===n)return;let i=e.state;if(!i.players[n]?.alive)return;let a=i.turn.vars[OU(r)],o=i.turn.vars[kU(r)]??0;delete i.turn.vars[OU(r)],delete i.turn.vars[kU(r)],!(typeof a!=`number`||a<=0)&&(o>=a||await B(i,{type:`失去体力`,target:n,amount:1}))}),()=>{}}function TU(e,t){t.defineAction(`respond`,{label:DU,style:`primary`,prompt:{type:`confirm`,title:`是否发动献图?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var EU,DU,OU,kU,AU,jU,MU,NU,PU,FU,IU,LU,hfe=t((()=>{V(),z(),F(),EU=`界献图`,DU=`献图`,OU=e=>`${EU}/given/${e}`,kU=e=>`${EU}/damage/${e}`,AU=`${EU}/giveCards`,jU=`${EU}/giveN`,MU=`${EU}/confirmed`,NU=`${EU}/trigger`,PU=`${EU}/draw2`,FU=`${EU}/draw1`,IU=`${EU}/giveCards`,LU={createSkill:SU,onInit:wU,onMount:TU}})),gfe=r({createSkill:()=>RU,default:()=>QU,onInit:()=>BU,onMount:()=>VU});function RU(e,t){return{id:e,ownerId:t,name:UU,description:`限定技:出牌阶段将你装备区所有牌交给一名其他角色,其选择令你回复X点体力或对其攻击范围内至多X名角色各造成1点伤害(X为装备数)`}}function zU(e,t){let n=e.players[t]?.equipment??{},r=[];for(let e of ZU){let t=n[e];t&&r.push(t)}return r}function BU(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;if(r.vars[WU])return`献州已使用过(限定技)`;if(zU(e,n).length===0)return`装备区无牌,无法发动`;let i=t.target;return typeof i==`number`?i===n?`不能以自己为目标`:e.players[i]?.alive?null:`目标不合法`:`需要指定目标`},async(e,t)=>{let r=n,i=t.target;e.players[r].vars[WU]=!0,await I(e,HU,r,{...t});try{let t=zU(e,r),n=t.length;for(let n of t){let t=e.cardMap[n],i=ZU.find(t=>e.players[r].equipment[t]===n);i&&(t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:r,skillId:t.name}),await B(e,{type:`卸下`,player:r,slot:i}))}for(let n of t)await B(e,{type:`给予`,cardId:n,from:r,to:i});e.localVars[XU]=n,e.localVars[YU]=i,delete e.localVars[qU],await B(e,{type:`请求回应`,requestType:GU,target:i,prompt:{type:`confirm`,title:`献州:${e.players[r]?.name??`P${r}`} 将 ${n} 张装备交给你。选择一项`,description:`确认 = 令其回复 ${n} 点体力;取消 = 对你攻击范围内至多 ${n} 名角色各造成 1 点伤害`,confirmLabel:`令其回复 ${n} 点体力`,cancelLabel:`对至多 ${n} 名角色造伤`},defaultChoice:!1,timeout:20});let a=e.localVars[qU]===!0;if(delete e.localVars[qU],a)e.players[r]?.alive&&n>0&&await B(e,{type:`回复体力`,target:r,amount:n,source:i});else{delete e.localVars[JU],await B(e,{type:`请求回应`,requestType:KU,target:i,prompt:{type:`selectTarget`,title:`献州:选择至多 ${n} 名你攻击范围内的角色(对其各造成 1 点伤害)`,description:`可放弃(选 0 名);伤害来源为你`,targetFilter:{min:0,max:n,filter:(e,t)=>{if(t===i)return!1;let n=e.players.find(e=>e.index===t);return!n||n.alive===!1?!1:lm(e.players,e.cardMap,i,t)}}},defaultChoice:[],timeout:30});let t=e.localVars[JU];delete e.localVars[JU];let r=Array.isArray(t)?t:[];for(let t of r)e.players[t]?.alive&&Gm(e,i,t)&&await Dm(e,i,t,1)}delete e.localVars[XU],delete e.localVars[YU]}finally{await L(e)}});let r=[];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;if(a!==GU&&a!==KU)return`当前不是献州询问`;if(a===GU)return null;let o=t.targets;if(!Array.isArray(o))return`需要 targets 数组`;let s=o,c=e.localVars[XU];if(typeof c!=`number`)return`询问状态异常`;if(s.length>c)return`至多选 ${c} 名目标`;if(new Set(s).size!==s.length)return`不能选重复目标`;let l=i;for(let t of s){if(typeof t!=`number`)return`目标必须是数字`;if(t===l)return`不能选自己`;if(!e.players[t]?.alive)return`目标已死亡`;if(!Gm(e,l,t))return`目标不在你的攻击范围内`}return null},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;n===GU?e.localVars[qU]=t.choice===!0||t.confirmed===!0:n===KU&&(e.localVars[JU]=t.targets)});r.push(a)}return()=>{r.forEach(e=>e())}}function VU(e,t){return t.defineAction(`use`,{label:UU,style:`danger`,prompt:{type:`selectTarget`,title:`献州:将装备区所有牌交给一名其他角色,其选择回血或造伤`,description:`限定技(整局一次);X = 你交出的装备数`,targetFilter:{min:1,max:1,filter:(t,n)=>n!==e.ownerId}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?Object.values(t.equipment).some(e=>!!e):!1}}),t.defineAction(`respond`,{label:UU,style:`danger`,prompt:{type:`confirm`,title:`献州`,confirmLabel:`令其回血`,cancelLabel:`造伤`}}),()=>{}}var HU,UU,WU,GU,KU,qU,JU,YU,XU,ZU,QU,_fe=t((()=>{V(),z(),Om(),F(),Sm(),Xm(),um(),J(),HU=`界献州`,UU=`献州`,WU=`${HU}/used`,GU=`${HU}/option`,KU=`${HU}/targets`,qU=`${HU}/optionChoice`,JU=`${HU}/damageTargets`,YU=`${HU}/target`,XU=`${HU}/X`,ZU=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`],QU={createSkill:RU,onInit:BU,onMount:VU}})),vfe=r({createSkill:()=>iW,default:()=>mW,onInit:()=>aW,onMount:()=>oW});function $U(e,t){let n=e.players[t]?.equipment??{};return pW.filter(e=>typeof n[e]==`string`).length}function eW(e,t){let n=e.players[t];return n?Math.max(0,n.maxHealth-p(n)):0}function tW(e,t,n){return e.players[t]?.equipment[n]}async function nW(e,t,n){let r=tW(e,t,n);if(!r)return;let i=e.cardMap[r];i?.name&&ym(i.name)&&e.players[t].skills.includes(i.name)&&await B(e,{type:`移除技能`,player:t,skillId:i.name})}async function rW(e,t,n){await B(e,{type:`装备`,player:t,cardId:n});let r=e.cardMap[n];r?.name&&ym(r.name)&&await B(e,{type:`添加技能`,player:t,skillId:r.name})}async function yfe(e,t,n){for(let r of pW){let i=tW(e,t,r),a=tW(e,n,r);!i&&!a||(i&&await nW(e,t,r),a&&await nW(e,n,r),i&&await B(e,{type:`卸下`,player:t,slot:r}),a&&await B(e,{type:`卸下`,player:n,slot:r}),i&&(await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:t},to:{zone:`手牌`,player:n}}),await rW(e,n,i)),a&&(await B(e,{type:`移动牌`,cardId:a,from:{zone:`手牌`,player:n},to:{zone:`手牌`,player:t}}),await rW(e,t,a)))}}function iW(e,t){return{id:e,ownerId:t,name:cW,description:`出牌阶段限一次:令两名角色交换装备区里的牌;若两人装备数差 X 大于你已损失的体力值,你须弃 X 张牌`}}function aW(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,sW))return`本回合已使用过甘露`;if(!e.players[n]?.alive)return`角色不可用`;let r=e.players.filter(e=>e.alive);return r.length<2||r.filter(e=>e.index!==n).length===0?`需要至少两名存活角色`:null},async(e,t)=>{await Z(e,n,sW),await I(e,sW,n,{}),delete e.localVars[dW],await B(e,{type:`请求回应`,requestType:lW,target:n,prompt:{type:`choosePlayer`,title:`甘露:选择两名角色交换装备区里的牌`,min:2,max:2,filter:(t,n)=>e.players[n]?.alive===!0},timeout:30});let r=e.localVars[dW];if(delete e.localVars[dW],!Array.isArray(r)||r.length!==2){await L(e);return}let[i,a]=r;if(!e.players[i]?.alive||!e.players[a]?.alive||i===a){await L(e);return}let o=$U(e,i),s=$U(e,a),c=Math.abs(o-s),l=eW(e,n);if(c>l){if(e.players[n].hand.length<c){await L(e);return}delete e.localVars[fW],await B(e,{type:`请求回应`,requestType:uW,target:n,prompt:{type:`useCard`,title:`甘露:两人装备数差 ${c} 大于你已损失的体力值 ${l},须弃 ${c} 张手牌`,cardFilter:{filter:()=>!0,min:c,max:c}},mandatory:!0,timeout:30});let t=e.localVars[fW];delete e.localVars[fW],await B(e,{type:`弃置`,player:n,cardIds:Array.isArray(t)&&t.length===c?t:e.players[n]?.hand.slice(0,c)??[]})}await yfe(e,i,a),await L(e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==lW&&a!==uW)return`当前不是甘露询问`;if(a===lW){let r=t.targets;if(!Array.isArray(r))return`targets required`;if(r.length!==2)return`需要选择两名角色`;for(let t of r){if(typeof t!=`number`)return`目标必须是数字座次`;if(!e.players[t]?.alive)return`目标已死亡`}if(r[0]===r[1])return`不能选同一名角色`;let i=Math.abs($U(e,r[0])-$U(e,r[1]));if(i>eW(e,n)&&(e.players[n]?.hand.length??0)<i)return`手牌不足,无法支付弃牌代价`}else{let i=t.cardIds;if(!Array.isArray(i))return`cardIds required`;let a=e.players[n],o=r.atom.prompt?.cardFilter?.min??0;if(i.length!==o)return`需要弃 ${o} 张牌`;if(new Set(i).size!==i.length)return`不能选择重复的牌`;for(let e of i)if(typeof e!=`string`||!a.hand.includes(e))return`牌不在手牌中`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===lW?e.localVars[dW]=t.targets:r===uW&&(e.localVars[fW]=t.cardIds)}),()=>{}}function oW(e,t){return t.defineAction(`use`,{label:cW,style:`primary`,prompt:{type:`confirm`,title:`甘露`,description:`令两名角色交换装备区里的牌(若装备数差>已损失体力值,须弃等量牌)`,confirmLabel:`发动`},activeWhen:e=>yh(sW)(e)}),()=>{}}var sW,cW,lW,uW,dW,fW,pW,mW,bfe=t((()=>{b(),V(),z(),Q(),F(),Sm(),sW=`界甘露`,cW=`甘露`,lW=`界甘露/target`,uW=`界甘露/discard`,dW=`界甘露/targets`,fW=`界甘露/discardCards`,pW=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`],mW={createSkill:iW,onInit:aW,onMount:oW}})),xfe=r({createSkill:()=>hW,default:()=>wW,onInit:()=>yW,onMount:()=>bW});function hW(e,t){return{id:e,ownerId:t,name:xW,description:`你使用的非火【杀】可以改为火【杀】;此牌造成伤害后,你弃1牌或失去1体力;你使用的火【杀】可多指定一个目标`}}function gW(e){return`${e}#界疠火`}function _W(e){return`疠火/converted:${e}`}function vW(e){return`疠火/damaged:${e}`}function yW(e,t){let n=e.ownerId,r=t.players[n],i=`杀/火杀多目标`;r.tags.includes(i)||r.tags.push(i);let a=qh(t,n,(e,t,n)=>{if(!n)return 0;let r=e.cardMap[n];return r?.name===`杀`&&r.damageType===`火焰`?2:0});return j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=!!u&&u.name===`杀`&&u.damageType!==`火焰`;return r&&i&&a&&s&&d&&f?null:`现在不能使用疠火`},async(e,t)=>{let r=t.cardId,i=gW(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`杀`,outputDamageType:`火焰`}),e.localVars[_W(i)]=!0},(e,t)=>{let r=t.cardId,i=gW(r);delete e.cardMap[i],delete e.localVars[_W(i)],delete e.localVars[vW(i)],e.players[n].hand=e.players[n].hand.map(e=>e===i?r:e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;if(r.atom.requestType!==SW)return`当前不是疠火代价选择`;let i=t.cardId;return typeof i==`string`?e.players[n].hand.includes(i)?null:`牌不在手牌中`:`cardId required`},async(e,t)=>{e.localVars[CW]=t.cardId}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0)return;let r=t.cardId;typeof r==`string`&&e.state.localVars[_W(r)]&&(e.state.localVars[vW(r)]=!0)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.from?.zone!==`处理区`||t.to?.zone!==`弃牌堆`)return;let r=t.cardId;if(typeof r!=`string`||!e.state.localVars[_W(r)])return;let i=e.state.localVars[vW(r)]===!0;if(delete e.state.localVars[_W(r)],delete e.state.localVars[vW(r)],!i)return;let a=e.state.players[n];if(a?.alive)if(a.hand.length>0){delete e.state.localVars[CW],await B(e.state,{type:`请求回应`,requestType:SW,target:n,prompt:{type:`useCard`,title:`疠火:此杀造成伤害。弃置 1 张牌,或放弃(失去 1 体力)`,cardFilter:{filter:()=>!0,min:1,max:1}},defaultChoice:!1,timeout:10});let t=e.state.localVars[CW];delete e.state.localVars[CW],typeof t==`string`&&a.hand.includes(t)?await B(e.state,{type:`弃置`,player:n,cardIds:[t],voluntary:!0}):await B(e.state,{type:`失去体力`,target:n,amount:1})}else await B(e.state,{type:`失去体力`,target:n,amount:1})}),()=>{a(),r.tags=r.tags.filter(e=>e!==`杀/火杀多目标`)}}function bW(e,t){t.defineAction(`transform`,{label:xW,style:`danger`,prompt:{type:`useCardAndTarget`,title:`疠火:将非火【杀】当火【杀】使用`,cardFilter:{filter:e=>e.name===`杀`&&e.damageType!==`火焰`,min:1,max:1},targetFilter:{min:1,max:2,filter:(e,t)=>t!==e.currentPlayerIndex}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>q(e)&&sm(e.view,e.perspectiveIdx)}),t.defineAction(`respond`,{label:`弃1张牌`,style:`default`,prompt:{type:`useCard`,title:`疠火:请弃置 1 张牌(或放弃失去 1 体力)`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var xW,SW,CW,wW,Sfe=t((()=>{V(),F(),J(),Xh(),xW=`疠火`,SW=`界疠火/cost`,CW=`疠火/costCard`,wW={createSkill:hW,onInit:yW,onMount:bW}})),Cfe=r({createSkill:()=>TW,default:()=>NW,onInit:()=>EW,onMount:()=>DW});function wfe(e,t){let n=e.players.length;for(let r=1;r<=n;r++){let i=(t+r)%n;if(e.players[i]?.alive)return i}return t}function Tfe(e,t,n){return t===n?!1:wfe(e,t)===n}function Efe(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function TW(e,t){return{id:e,ownerId:t,name:OW,description:`你上家或你的结束阶段,你可令一名角色摸一张牌并展示之;装备牌:其使用之并回复1点体力;非装备且其体力不等于你:其失去1点体力`}}function EW(e,t){let n=e.ownerId;return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`)return;let r=e.state,i=t.player??-1;if(i<0)return;let a=i===n,o=Tfe(r,i,n);if(!a&&!o||!r.players[n]?.alive)return;if(delete r.localVars[jW],await B(r,{type:`请求回应`,requestType:kW,target:n,prompt:{type:`confirm`,title:`是否发动直言?(${a?`你的`:`上家的`}结束阶段)`,description:`令一名角色摸一张牌并展示之:装备牌→其使用之并回复1点体力;非装备牌且其体力不等于你→其失去1点体力`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),r.localVars[jW]!==!0){delete r.localVars[jW];return}delete r.localVars[jW],delete r.localVars[MW],await B(r,{type:`请求回应`,requestType:AW,target:n,prompt:{type:`choosePlayer`,title:`直言:选择一名角色摸一张牌并展示之`,min:1,max:1,filter:(e,t)=>r.players[t]?.alive===!0},timeout:30});let s=r.localVars[MW];if(delete r.localVars[MW],typeof s!=`number`||!r.players[s]?.alive)return;let c=r.players[s].hand.length;if(await B(r,{type:`摸牌`,player:s,count:1}),r.players[s].hand.length<=c)return;let l=r.players[s].hand[r.players[s].hand.length-1];await B(r,{type:`展示`,player:s,cardId:l});let u=r.cardMap[l];if(u?.type===`装备牌`){let e=Efe(u);if(e){let t=r.players[s].equipment[e];if(t){let n=r.cardMap[t];n?.name&&ym(n.name)&&await B(r,{type:`移除技能`,player:s,skillId:n.name}),await B(r,{type:`卸下`,player:s,slot:e}),await B(r,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:s},to:{zone:`弃牌堆`}})}await B(r,{type:`装备`,player:s,cardId:l}),u?.name&&ym(u.name)&&await B(r,{type:`添加技能`,player:s,skillId:u.name})}r.players[s].health<r.players[s].maxHealth&&await B(r,{type:`回复体力`,target:s,amount:1})}else p(r.players[s])!==p(r.players[n])&&r.players[s]?.alive&&await B(r,{type:`失去体力`,target:s,amount:1})}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是直言窗口`;let i=r.atom;if(i.requestType===kW)return null;if(i.requestType===AW){let n=t.target;return typeof n==`number`?e.players[n]?.alive?null:`目标不合法`:`需要选择一名角色`}return`当前不是直言窗口`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===kW)e.localVars[jW]=t.choice===!0||t.confirmed===!0;else if(r===AW){let n=t.target;typeof n==`number`&&(e.localVars[MW]=n)}}),()=>{}}function DW(e,t){return()=>{}}var OW,kW,AW,jW,MW,NW,Dfe=t((()=>{b(),V(),F(),Sm(),OW=`直言`,kW=`界直言/confirm`,AW=`界直言/target`,jW=`界直言/confirmed`,MW=`界直言/target`,NW={createSkill:TW,onInit:EW,onMount:DW}})),Ofe=r({createSkill:()=>FW,default:()=>zW,onInit:()=>IW,onMount:()=>LW});function PW(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function FW(e,t){return{id:e,ownerId:t,name:RW,description:`出牌阶段:将一张装备牌置入一名其他角色的装备区(可替换原装备),然后摸一张牌`}}function IW(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;let r=e.players[n];if(!r?.alive)return`你已死亡`;if(typeof t.cardId!=`string`)return`需要选择一张装备牌`;if(!r.hand.includes(t.cardId))return`牌不在手牌中`;let i=e.cardMap[t.cardId];if(i?.type!==`装备牌`)return`只能使用装备牌`;if(!PW(i))return`无效的装备牌`;let a=Array.isArray(t.targets)&&typeof t.targets[0]==`number`?t.targets[0]:typeof t.target==`number`?t.target:void 0;return a===void 0?`需要指定一名目标`:a===n?`不能对自己使用界直谏`:e.players[a]?.alive?null:`目标不合法`},async(e,t)=>{let r=t.cardId,i=Array.isArray(t.targets)&&typeof t.targets[0]==`number`?t.targets[0]:t.target,a=e.cardMap[r],o=PW(a);await I(e,RW,n,{...t}),await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:n},to:{zone:`手牌`,player:i}});let s=e.players[i].equipment[o];if(s){let t=e.cardMap[s];t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:i,skillId:t.name}),await B(e,{type:`卸下`,player:i,slot:o}),await B(e,{type:`移动牌`,cardId:s,from:{zone:`手牌`,player:i},to:{zone:`弃牌堆`}})}await B(e,{type:`装备`,player:i,cardId:r}),a?.name&&ym(a.name)&&await B(e,{type:`添加技能`,player:i,skillId:a.name}),await B(e,{type:`摸牌`,player:n,count:1}),await L(e)}),()=>{}}function LW(e,t){return t.defineAction(`use`,{label:RW,style:`primary`,prompt:{type:`useCardAndTarget`,title:`界直谏:将一张装备牌置入一名其他角色的装备区(可替换原装备)`,cardFilter:{filter:e=>e.type===`装备牌`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>t===e.viewer?!1:e.players[t]?.alive===!0}}}),()=>{}}var RW,zW,kfe=t((()=>{V(),z(),F(),Sm(),RW=`界直谏`,zW={createSkill:FW,onInit:IW,onMount:LW}})),Afe=r({createSkill:()=>BW,default:()=>WW,onInit:()=>HW,onMount:()=>UW});function BW(e,t){return{id:e,ownerId:t,name:`界看破`,description:`你可以将一张黑色牌当【无懈可击】使用;你的【无懈可击】不能被响应`}}function VW(e){return`${e}#界看破`}function jfe(e,t){for(let n of e.pendingSlots.values()){let e=n.atom;if(e.type===`请求回应`&&e.requestType===`无懈可击`&&typeof e.target==`number`&&(e.target<0||e.target===t))return!0}return!1}function HW(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId,a=typeof i==`string`,o=a?e.cardMap[i]:void 0,s=a&&r.hand.includes(i),c=a&&Object.values(r.equipment).some(e=>e===i),l=!!o&&o.color===`黑`,u=jfe(e,n),d=(()=>{for(let t of e.pendingSlots.values()){let e=t.atom;if(t.isBlocking&&!(e.type===`请求回应`&&e.requestType===`无懈可击`))return!0}return!1})();return(s||c)&&l&&u&&!d?null:`现在不能使用界看破`},async(e,t)=>{let r=t.cardId,i=VW(r),a=e.players[n],o=Object.entries(a.equipment).find(([,e])=>e===r);if(o){let r=o[0];t._origSlot=r,await B(e,{type:`卸下`,player:n,slot:r})}await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`无懈可击`})},(e,t)=>{let r=t.cardId,i=VW(r),a=e.players[n],o=t._origSlot;delete e.cardMap[i];let s=a.hand.indexOf(i);s>=0&&(o?(a.hand.splice(s,1),a.equipment[o]=r):a.hand[s]=r)}),j(t,`无懈可击`,n,`respond`,(e,t)=>{let r=ae(e,n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`||r.atom.requestType!==`无懈可击`)return`当前不是无懈可击窗口`;let i=t.cardId;if(!i)return`cardId required`;let a=e.players[n];return a.alive?a.hand.includes(i)?e.cardMap[i].name===`无懈可击`?null:`只能打出无懈可击`:`牌不在手牌中`:`你已死亡`},async(e,t)=>{let r=t.cardId;e.localVars[`抵消/已回应`]=!0,await Lh(e,n,r,[n],`无懈可击`,{skipCancelQuery:!0})}),()=>{}}function UW(e,t){t.defineAction(`transform`,{label:`界看破`,style:`passive`,prompt:{type:`useCard`,title:`选择一张黑色牌(手牌或装备)当无懈可击使用`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}},transform:t=>({name:`无懈可击`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view,n=t.pending;if(!n)return!1;let r=n.atom;if(r.type!==`请求回应`||r.requestType!==`无懈可击`)return!1;let i=t.players[e.perspectiveIdx];if(!i)return!1;let a=i.hand?.some(e=>e.color===`黑`)??!1,o=Object.values(i.equipment??{}).some(t=>(t?e.view.cardMap[t]:void 0)?.color===`黑`);return a||o}})}var WW,Mfe=t((()=>{F(),V(),Gh(),WW={createSkill:BW,onInit:HW,onMount:UW}})),Nfe=r({createSkill:()=>GW,default:()=>dG,onInit:()=>KW,onMount:()=>qW});function GW(e,t){return{id:e,ownerId:t,name:YW,description:`摸牌阶段结束时,交给一名其他角色两张牌,令其选:①对你指定的另一名角色出杀;②你观看其手牌并获得两张`}}function Pfe(e,t){return(e.players[t]?.hand??[]).some(t=>e.cardMap[t]?.name===`杀`)}function Ffe(e,t){return Pfe(e,t)?e.players.some(e=>e.alive&&e.index!==t):!1}function Ife(e,t){return(e.players[t]?.hand.length??0)>=2}async function Lfe(e,t,n,r){e.players[n]?.alive&&await Lh(e,t,r,[n],`杀`)}async function Rfe(e,t,n){delete e.localVars[$W],await B(e,{type:`请求回应`,requestType:oG,target:t,prompt:{type:`choosePlayer`,title:`眩惑:指定 X 出杀的目标 Y(可为法正自己)`,min:1,max:1,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:15});let r=e.localVars[$W];if(typeof r!=`number`||r<0||!e.players[r]?.alive)return;delete e.localVars[nG],await B(e,{type:`请求回应`,requestType:uG,target:n,prompt:{type:`useCard`,title:`眩惑:选择一张【杀】使用`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},timeout:15});let i=e.localVars[nG];typeof i!=`string`||!e.players[n]?.hand.includes(i)||await Lfe(e,n,r,i)}async function zfe(e,t,n){let r=e.players[n];if(!(!r||r.hand.length<2))for(let i=0;i<2&&r.hand.length!==0;i++){let a=`${eG}${i}`;delete e.localVars[a],await B(e,{type:`请求回应`,requestType:i===0?sG:cG,target:t,prompt:{type:`pickTargetCard`,title:`眩惑:观看 X 手牌,选第 ${i+1} 张获得`,target:n,equipment:r.hand.map((t,n)=>({slot:`hand-${n}`,cardId:t,cardName:e.cardMap[t]?.name??`?`})),judge:[],handCount:0},timeout:20});let o=e.localVars[a];typeof o==`string`&&r.hand.includes(o)&&await B(e,{type:`获得`,player:t,cardId:o,from:n})}}function KW(e,t){let n=e.ownerId;for(let r of t.players){let i=r.index,a=i===n;j(t,e.id,i,`respond`,e=>{let t=e.pendingSlots.get(i);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let n=t.atom.requestType??``,r=[rG,iG,aG,oG,sG,cG],o=[lG,uG];return a&&r.includes(n)||o.includes(n)?null:`当前不是眩惑询问`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;if(n===rG)e.localVars[XW]=t.choice===!0;else if(n===iG){let n=typeof t.target==`number`?t.target:void 0,r=Array.isArray(t.targets)?t.targets:void 0;e.localVars[ZW]=n??r?.[0]??-1}else if(n===aG){let n=t.cardIds;e.localVars[QW]=Array.isArray(n)?n:[]}else if(n===oG){let n=typeof t.target==`number`?t.target:void 0,r=Array.isArray(t.targets)?t.targets:void 0;e.localVars[$W]=n??r?.[0]??-1}else if(n===sG||n===cG){let r=typeof t.cardId==`string`?t.cardId:``;e.localVars[`${eG}${n===sG?0:1}`]=r}else if(n===lG)e.localVars[tG]=t.choice===!0?`kill`:`gain`;else if(n===uG){let n=typeof t.cardId==`string`?t.cardId:``;e.localVars[nG]=n}})}return M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.phase!==`摸牌`||t.player!==n||e.state.currentPlayerIndex!==n)return;let r=e.state.players[n];if(!r?.alive||r.hand.length<2||!e.state.players.some(e=>e.alive&&e.index!==n)||(delete e.state.localVars[XW],await B(e.state,{type:`请求回应`,requestType:rG,target:n,prompt:{type:`confirm`,title:`是否发动眩惑?(交给一名其他角色两张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[XW]!==!0))return;delete e.state.localVars[ZW],await B(e.state,{type:`请求回应`,requestType:iG,target:n,prompt:{type:`choosePlayer`,title:`眩惑:选择接收两张牌的角色`,min:1,max:1,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:15});let i=e.state.localVars[ZW];if(typeof i!=`number`||i<0||!e.state.players[i]?.alive)return;delete e.state.localVars[QW],await B(e.state,{type:`请求回应`,requestType:aG,target:n,prompt:{type:`distribute`,mode:`select`,title:`眩惑:选择交给对方的 2 张手牌`,source:`hand`,minTotal:2,maxTotal:2},timeout:20});let a=e.state.localVars[QW];if(!Array.isArray(a)||a.length!==2)return;let o=a.filter(e=>r.hand.includes(e));if(o.length===2&&new Set(o).size===2){await I(e.state,JW,n,{target:i,cards:o});try{for(let t of o)await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:n},to:{zone:`手牌`,player:i}});let t=Ffe(e.state,i),r=Ife(e.state,i);if(!t&&!r)return;let a;t&&r?(delete e.state.localVars[tG],await B(e.state,{type:`请求回应`,requestType:lG,target:i,prompt:{type:`confirm`,title:`眩惑:选择一项(确认=对法正指定角色出杀,取消=法正观看并取得你两张手牌)`,confirmLabel:`对法正指定角色出杀`,cancelLabel:`法正取得两张手牌`},defaultChoice:!1,timeout:15}),a=e.state.localVars[tG]===`kill`?`kill`:`gain`):a=t?`kill`:`gain`,a===`kill`?await Rfe(e.state,n,i):await zfe(e.state,n,i)}finally{await L(e.state)}}}),()=>{}}function qW(e,t){t.defineAction(`respond`,{label:YW,style:`default`,prompt:{type:`confirm`,title:`是否发动眩惑?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var JW,YW,XW,ZW,QW,$W,eG,tG,nG,rG,iG,aG,oG,sG,cG,lG,uG,dG,Bfe=t((()=>{V(),z(),Gh(),F(),JW=`界眩惑`,YW=`眩惑`,XW=`${JW}/triggered`,ZW=`${JW}/target`,QW=`${JW}/cards`,$W=`${JW}/victim`,eG=`${JW}/pickHand`,tG=`${JW}/xchoice`,nG=`${JW}/slashCardId`,rG=`${JW}/trigger`,iG=`${JW}/pickTarget`,aG=`${JW}/pickCards`,oG=`${JW}/pickVictim`,sG=`${JW}/pickHand0`,cG=`${JW}/pickHand1`,lG=`${JW}/xchoice`,uG=`${JW}/pickSlash`,dG={createSkill:GW,onInit:KW,onMount:qW}})),Vfe=r({createSkill:()=>fG,default:()=>xG,onInit:()=>mG,onMount:()=>hG});function fG(e,t){return{id:e,ownerId:t,name:_G,description:`锁定技:游戏开始时获得3点护甲;每回合首次受到伤害后回1血,本回合再受到伤害后失1血`,isLocked:!0}}function Hfe(e,t){return e.players[t].marks.filter(e=>e.id.startsWith(vG)).length}async function pG(e,t){await B(e,{type:`加标记`,player:t,mark:{id:`${vG}${e.seq}`,scope:t}})}async function Ufe(e,t,n){let r=e.players[t].marks,i=[];for(let e of r){if(i.length>=n)break;e.id.startsWith(vG)&&i.push(e.id)}for(let n of i)await B(e,{type:`去标记`,player:t,markId:n})}function mG(e,t){let n=e.ownerId;return N(t,e.id,n,`回合开始`,async e=>{let t=e.state;t.players[n]?.alive&&(t.localVars[yG(n)]||(t.localVars[yG(n)]=!0,await pG(t,n),await pG(t,n),await pG(t,n)))}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.amount??0;if(r<=0)return;let i=Hfe(e.state,n);if(i<=0)return;let a=Math.min(i,r),o=r-a;return await Ufe(e.state,n,a),{kind:`modify`,atom:{...e.atom,amount:o}}}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=e.state.players[n];if(!r?.alive)return;let i=r.vars[bG]??0;i===0?await B(e.state,{type:`回复体力`,target:n,amount:1}):await B(e.state,{type:`失去体力`,target:n,amount:1}),r.vars[bG]=i+1}),()=>{}}function hG(e,t){}var gG,_G,vG,yG,bG,xG,Wfe=t((()=>{V(),F(),gG=`界矢北`,_G=`矢北`,vG=`${gG}/护甲:`,yG=e=>`${gG}/init/${e}`,bG=`${gG}/damageCount/usedThisTurn`,xG={createSkill:fG,onInit:mG,onMount:hG}})),Gfe=r({createSkill:()=>SG,default:()=>PG,onInit:()=>TG,onMount:()=>EG});function SG(e,t){return{id:e,ownerId:t,name:OG,description:`出牌阶段限一次,你可将一张牌当本轮未有角色使用过的基本或普通锦囊牌使用`}}function CG(e){return`${e}#${DG}`}function wG(e){let t=e.turn.round;if(e.localVars[jG]!==t)return e.localVars[jG]=t,e.localVars[AG]=[],[];let n=e.localVars[AG];return Array.isArray(n)?n:[]}function Kfe(e,t){if(!MG.has(t))return;let n=wG(e);n.includes(t)||(e.localVars[AG]=[...n,t])}function qfe(e,t){return!!e.players[t]?.vars[kG]}function TG(e,t){let n=e.ownerId,r=r=>j(t,e.id,n,`${NG}${r}`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(qfe(e,n))return`本回合已使用过矫诏`;let i=e.players[n];if(!i?.alive)return`玩家不存在或已死亡`;let a=t.cardId;return typeof a==`string`?i.hand.includes(a)?wG(e).includes(r)?`本轮已有角色使用过【${r}】`:null:`牌不在手牌中`:`需要选择一张牌`},async(e,t)=>{let i=t.cardId,a=CG(i);e.players[n].vars[kG]=!0,await B(e,{type:`回合用量`,player:n,key:kG,value:!0}),await B(e,{type:`当作`,player:n,cardIds:[i],shadowId:a,outputName:r})},(e,t)=>{let r=t.cardId,i=CG(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r),delete a.vars[kG]}),i=[...MG].map(r);return N(t,e.id,n,`结算帧入栈`,async e=>{let t=e.atom.skillId;typeof t==`string`&&MG.has(t)&&Kfe(e.state,t)}),()=>{for(let e of i)e()}}function Jfe(e,t){let n=Wg(t);return n?n.timing===`生效前`?!1:!n.activeWhen||n.activeWhen(e):!0}function EG(e,t){let n=e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return!t||t.turnUsage?.[kG]?!1:(t.handCount??0)>0},r=e=>t=>n(t)&&Jfe(t,e);for(let e of MG)t.defineAction(`${NG}${e}`,{label:`${OG}·${e}`,style:`primary`,prompt:{type:`useCard`,title:`矫诏:将一张牌当【${e}】使用`,description:`出牌阶段限一次;转化后按声明的牌正常结算`,cardFilter:{filter:()=>!0,min:1,max:1}},transform:t=>({name:e,sourceCardId:t.id,fromSkill:DG}),activeWhen:r(e)})}var DG,OG,kG,AG,jG,MG,NG,PG,Yfe=t((()=>{V(),F(),J(),Yg(),DG=`界矫诏`,OG=`矫诏`,kG=`${DG}/usedThisTurn`,AG=`${DG}/已用牌名`,jG=`${DG}/lastRound`,MG=new Set([`杀`,`桃`,`酒`,`决斗`,`过河拆桥`,`顺手牵羊`,`无中生有`,`借刀杀人`,`桃园结义`,`五谷丰登`,`南蛮入侵`,`万箭齐发`,`火攻`,`铁索连环`]),NG=`transform:`,PG={createSkill:SG,onInit:TG,onMount:EG}})),Xfe=r({createSkill:()=>FG,default:()=>XG,onInit:()=>RG,onMount:()=>zG});function FG(e,t){return{id:e,ownerId:t,name:VG,description:`当你使用【杀】指定目标后,你可以将其至多X张牌移出游戏直到回合结束(X为其体力值)。你使用的【杀】对手牌区与装备区内牌数皆不大于你的角色造成的伤害+1`}}function IG(e){return Object.values(e.equipment).filter(e=>!!e).length}function Zfe(e){return e.hand.length+IG(e)}function Qfe(e){return[...e.hand,...Object.values(e.equipment).filter(e=>!!e)]}function LG(e,t){if(!t)return!1;let n=e.cardMap[t];return!!n&&n.name===`杀`}function RG(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==WG&&a!==GG)return`当前不是界破军回应`;if(a===WG)return null;let o=t.cardIds;if(!Array.isArray(o))return`需要选择牌`;let s=e.localVars[JG],c=e.localVars[YG];if(typeof s!=`number`)return`询问上下文异常`;let l=e.players[s];if(!l)return`目标不存在`;let u=new Set(Object.values(l.equipment).filter(e=>!!e));for(let e of o){if(typeof e!=`string`)return`cardIds 必须为字符串数组`;if(!l.hand.includes(e)&&!u.has(e))return`牌不在目标区域`}return o.length<1?`至少选择 1 张牌`:typeof c==`number`&&o.length>c?`至多选择 ${c} 张牌`:new Set(o).size===o.length?null:`不能重复选牌`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===WG?e.localVars[KG]=t.choice===!0:r===GG&&(e.localVars[qG]=t.cardIds)}),N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.type!==`指定目标`||t.source!==n||!LG(e.state,t.cardId))return;let r=t.target;if(typeof r!=`number`)return;let i=e.state.players[r];if(!i?.alive||r===n)return;let a=p(i);if(!(a<=0)&&Zfe(i)!==0){await I(e.state,BG,n,{});try{if(delete e.state.localVars[KG],await B(e.state,{type:`请求回应`,requestType:WG,target:n,prompt:{type:`confirm`,title:`是否发动破军?(将 ${i.name} 至多 ${a} 张牌移出游戏直到回合结束)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[KG]!==!0)return;let t=e.state.players[r];if(!t?.alive)return;let o=Math.min(a,p(t));if(o<=0)return;let s=Qfe(t);if(s.length===0)return;delete e.state.localVars[qG],e.state.localVars[JG]=r,e.state.localVars[YG]=o,await B(e.state,{type:`请求回应`,requestType:GG,target:n,prompt:{type:`distribute`,mode:`select`,title:`破军:选择 ${t.name} 的 1~${o} 张牌移出游戏(可从手牌或装备区)`,cardIds:s,minTotal:1,maxTotal:o},timeout:30});let c=e.state.localVars[qG],l=Array.isArray(c)?c:[];if(l.length===0)return;await B(e.state,{type:`移出至暂存区`,source:n,target:r,cardIds:l,varsKey:HG}),e.state.players[r].vars[UG]=e.state.currentPlayerIndex}finally{await L(e.state)}}}),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n||!LG(e.state,t.cardId))return;let r=t.target;if(typeof r!=`number`||r===n)return;let i=e.state.players[r],a=e.state.players[n];if(!i||!a||i.hand.length>a.hand.length||IG(i)>IG(a))return;let o=typeof t.amount==`number`?t.amount:0;return{kind:`modify`,atom:{...e.atom,amount:o+1}}}),N(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`)return;let n=t.player;for(let t=0;t<e.state.players.length;t++){let r=e.state.players[t];if(!r)continue;let i=r.vars[UG];if(typeof i!=`number`||i!==n)continue;let a=r.vars[HG];Array.isArray(a)&&a.length>0&&await B(e.state,{type:`归还暂存牌`,player:t,varsKey:HG}),delete r.vars[UG]}}),()=>{}}function zG(e,t){t.defineAction(`respond`,{label:VG,style:`primary`,prompt:{type:`confirm`,title:`破军`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var BG,VG,HG,UG,WG,GG,KG,qG,JG,YG,XG,$fe=t((()=>{b(),V(),z(),F(),BG=`界破军`,VG=`破军`,HG=`界破军/移出`,UG=`界破军/移出回合`,WG=`${BG}/askUse`,GG=`${BG}/askCards`,KG=`${BG}/use`,qG=`${BG}/cards`,JG=`${BG}/ctx/target`,YG=`${BG}/ctx/x`,XG={createSkill:FG,onInit:RG,onMount:zG}})),epe=r({createSkill:()=>ZG,default:()=>vK,onInit:()=>tK,onMount:()=>nK});function ZG(e,t){return{id:e,ownerId:t,name:`界神速`,description:`选择至多三项:①跳过判定+摸牌;②弃装备+跳过出牌;③翻面+跳过弃牌。每项视为出杀`}}function tpe(e,t,n){return`界神速:杀:${e}:${t}:${n}`}async function QG(e,t,n){if(!e.players[n]?.alive)return;let r=tpe(t,n,e.seq);e.cardMap[r]={id:r,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,r,[n],`杀`,{virtual:!0,onSettle:Hh(e,t,r)}),delete e.cardMap[r]}function $G(e,t){let n=e.players[t];return n?Object.values(n.equipment).filter(e=>!!e):[]}async function eK(e,t,n){if(!e.players.some((e,n)=>n!==t&&e.alive))return;delete e.localVars[mK],await B(e,{type:`请求回应`,requestType:oK,target:t,prompt:{type:`choosePlayer`,title:`${n}:选择一名其他角色(视为出杀,无距离限制)`,min:1,max:1,filter:(n,r)=>r!==t&&e.players[r]?.alive===!0},timeout:15});let r=e.localVars[mK];return delete e.localVars[mK],r}function tK(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let r=t.atom.requestType??``;return _K.includes(r)?null:`当前不是界神速询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType??``;if(r===rK||r===iK||r===aK)e.localVars[pK]=t.choice===!0;else if(r===oK){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[mK]=n)}else if(r===sK){let n=t.cardIds,r=t.cardId,i=(Array.isArray(n)&&n.length>0?n[0]:void 0)??(typeof r==`string`?r:void 0);i&&(e.localVars[hK]=i)}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`判定`||e.state.currentPlayerIndex!==n)return;let r=e.state.players[n];if(!r?.alive||r.vars[gK]||!e.state.players.some((e,t)=>t!==n&&e.alive))return;delete e.state.localVars[pK],await B(e.state,{type:`请求回应`,requestType:rK,target:n,prompt:{type:`confirm`,title:`是否发动界神速①?(跳过判定+摸牌,视为出杀)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10});let i=e.state.localVars[pK]===!0,a=!1;$G(e.state,n).length>0&&(delete e.state.localVars[pK],await B(e.state,{type:`请求回应`,requestType:iK,target:n,prompt:{type:`confirm`,title:`是否发动界神速②?(弃置一张装备牌,跳过出牌,视为出杀)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),a=e.state.localVars[pK]===!0),delete e.state.localVars[pK],await B(e.state,{type:`请求回应`,requestType:aK,target:n,prompt:{type:`confirm`,title:`是否发动界神速③?(翻面,跳过弃牌,视为出杀)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10});let o=e.state.localVars[pK]===!0;if(!i&&!a&&!o)return;r.vars[gK]=!0;let s=!1;await I(e.state,`界神速`,n,{opt1:i,opt2:a,opt3:o});try{if(i&&r.alive){let t=await eK(e.state,n,`界神速①`);typeof t==`number`&&e.state.players[t]?.alive&&(await B(e.state,{type:`加标签`,player:n,tag:cK}),await QG(e.state,n,t),s=!0)}if(a&&r.alive){delete e.state.localVars[hK],await B(e.state,{type:`请求回应`,requestType:sK,target:n,prompt:{type:`distribute`,mode:`select`,title:`界神速②:选择一张装备牌弃置`,source:`handAndEquip`,minTotal:1,maxTotal:1},timeout:15});let t=e.state.localVars[hK];if(delete e.state.localVars[hK],t&&$G(e.state,n).includes(t)){let r=await eK(e.state,n,`界神速②`);typeof r==`number`&&e.state.players[r]?.alive&&(await B(e.state,{type:`加标签`,player:n,tag:lK}),await B(e.state,{type:`弃置`,player:n,cardIds:[t],voluntary:!0}),await QG(e.state,n,r))}}if(o&&r.alive){let t=await eK(e.state,n,`界神速③`);typeof t==`number`&&e.state.players[t]?.alive&&(await B(e.state,{type:`加标签`,player:n,tag:uK}),await B(e.state,{type:`加标签`,player:n,tag:dK}),await QG(e.state,n,t))}}finally{await L(e.state)}if(s)return Nh(e.state,t)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`摸牌`&&e.state.players[n]?.tags.includes(cK))return Nh(e.state,t,cK)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`出牌`&&e.state.players[n]?.tags.includes(lK))return Nh(e.state,t,lK)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`弃牌`&&e.state.players[n]?.tags.includes(uK))return Nh(e.state,t,uK)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n)return;let r=e.state.players[n];if(t.phase===`准备`&&r?.tags.includes(dK))return await B(e.state,{type:`去标签`,player:n,tag:dK}),e.state.localVars[fK]=n,{kind:`cancel`};if(e.state.localVars[fK]===n)return{kind:`cancel`}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type===`阶段结束`&&t.player===n&&e.state.localVars[fK]===n)return delete e.state.localVars[fK],await B(e.state,{type:`清过期标记`,player:n}),await B(e.state,{type:`下一玩家`}),await B(e.state,{type:`回合结束`,player:n})&&await B(e.state,{type:`回合结束后`,player:n}),{kind:`cancel`}}),()=>{}}function nK(e,t){t.defineAction(`respond`,{label:`界神速`,style:`default`,prompt:{type:`confirm`,title:`是否发动界神速?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var rK,iK,aK,oK,sK,cK,lK,uK,dK,fK,pK,mK,hK,gK,_K,vK,npe=t((()=>{V(),z(),F(),Ph(),Gh(),rK=`界神速/opt1`,iK=`界神速/opt2`,aK=`界神速/opt3`,oK=`界神速/target`,sK=`界神速/equip`,cK=`神速/跳过摸牌`,lK=`神速/跳过出牌`,uK=`神速/跳过弃牌`,dK=`神速/翻面`,fK=`神速/skipAll`,pK=`神速/confirmed`,mK=`神速/target`,hK=`神速/equipCardId`,gK=`神速/usedThisTurn`,_K=[rK,iK,aK,oK,sK],vK={createSkill:ZG,onInit:tK,onMount:nK}})),rpe=r({createSkill:()=>yK,default:()=>DK,onInit:()=>SK,onMount:()=>CK});function yK(e,t){return{id:e,ownerId:t,name:wK,description:`锁定技:你的【酒】视为点数K的【杀】;其他角色不能于你的回合使用【酒】`,isLocked:!0}}function bK(e){return`${e}#界禁酒`}function xK(e){let t=EK.get(e);return t||(t=new Map,EK.set(e,t)),t}function SK(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=!E(e),a=e.players[n],o=a.alive===!0,s=t.cardId,c=typeof s==`string`,l=c?e.cardMap[s]:void 0,u=c&&a.hand.includes(s),d=!!l&&l.name===`酒`;return r&&i&&o&&u&&d?null:`现在不能使用禁酒`},async(e,t)=>{let r=t.cardId,i=bK(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`杀`});let a=e.cardMap[i];a&&(a.rank=TK)},(e,t)=>{let r=t.cardId,i=bK(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)});let r=N(t,e.id,n,`回合开始`,async()=>{ipe(t,n)});return()=>{r();let e=xK(t);for(let[,n]of e)se(t,n);e.clear()}}function ipe(e,t){for(let n of e.players){if(n.index===t)continue;let r=n.index;if(xK(e).has(r))continue;let i=ce(e,`酒`,r,`respond`);if(!i)continue;xK(e).set(r,{...i});let a=i.validate;j(e,`酒`,r,`respond`,(e,n)=>e.currentPlayerIndex===t?`禁酒:界高顺的回合内,其他角色不能使用【酒】`:a(e,n),i.execute,i.rollback)}}function CK(e,t){t.defineAction(`transform`,{label:wK,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张【酒】当点数K的【杀】使用`,cardFilter:{filter:e=>e.name===`酒`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},transform:t=>({name:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];return!t?.alive||!(t.hand?.some(e=>e.name===`酒`)??!1)?!1:q(e)&&sm(e.view,e.perspectiveIdx)}})}var wK,TK,EK,DK,ape=t((()=>{F(),V(),J(),um(),wK=`禁酒`,TK=`K`,EK=new WeakMap,DK={createSkill:yK,onInit:SK,onMount:CK}})),ope=r({createSkill:()=>OK,default:()=>HK,onInit:()=>kK,onMount:()=>jK});function spe(e,t){let n=e.players[t];return n?Math.max(0,n.maxHealth-p(n)):0}function OK(e,t){return{id:e,ownerId:t,name:MK,description:`结束阶段,你可以摸X张牌(X为你已损失的体力值),然后你可以交给其他角色至多X张牌`}}function kK(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===PK||i===FK)return null;if(i===IK){let r=t.target;return typeof r==`number`?r===n?`不能给自己`:e.players[r]?.alive?null:`目标不合法`:`需要指定目标`}if(i===LK){let r=t.cardIds??t.cardId,i=Array.isArray(r)?r:typeof r==`string`?[r]:[],a=e.localVars[NK]??0;if(i.length>a)return`至多 ${a} 张`;if(new Set(i).size!==i.length)return`不能重复`;let o=e.players[n];return o?i.every(e=>typeof e==`string`&&o.hand.includes(e))?null:`牌不在手牌中`:`玩家不存在`}return`当前不是秘计询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===PK)e.localVars[RK]=t.choice===!0||t.confirmed===!0;else if(r===FK)e.localVars[zK]=t.choice===!0||t.confirmed===!0;else if(r===IK)e.localVars[BK]=t.target;else if(r===LK){let n=t.cardIds??t.cardId,r=Array.isArray(n)?n:typeof n==`string`?[n]:[];e.localVars[VK]=r.filter(e=>typeof e==`string`)}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`)return;let r=e.state;if(!r.players[n]?.alive)return;let i=Qc(n);dl(r.players[n].vars,n)&&(delete r.players[n].vars[i],await AK(r,n,!1)),await AK(r,n,!0)}),()=>{}}async function AK(e,t,n){let r=spe(e,t);if(r<=0||!e.players[t]?.alive)return;if(n){if(delete e.localVars[RK],await B(e,{type:`请求回应`,requestType:PK,target:t,prompt:{type:`confirm`,title:`秘计:是否摸 ${r} 张牌(X=已损失体力)?然后可交给其他角色至多 ${r} 张牌`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.localVars[RK]!==!0){delete e.localVars[RK];return}delete e.localVars[RK]}if(await B(e,{type:`摸牌`,player:t,count:r}),!e.players[t]?.alive)return;if(delete e.localVars[zK],await B(e,{type:`请求回应`,requestType:FK,target:t,prompt:{type:`confirm`,title:`秘计:是否交给其他角色至多 ${r} 张牌?`,confirmLabel:`分发`,cancelLabel:`不分发`},defaultChoice:!1,timeout:15}),e.localVars[zK]!==!0){delete e.localVars[zK];return}if(delete e.localVars[zK],e.players.filter(e=>e.alive&&e.index!==t).length===0)return;delete e.localVars[BK],await B(e,{type:`请求回应`,requestType:IK,target:t,prompt:{type:`choosePlayer`,title:`秘计:选择分发目标(其他角色)`,min:1,max:1,filter:(n,r)=>r!==t&&e.players[r]?.alive===!0},timeout:20});let i=e.localVars[BK];if(delete e.localVars[BK],typeof i!=`number`||i===t||!e.players[i]?.alive)return;e.localVars[NK]=r,delete e.localVars[VK],await B(e,{type:`请求回应`,requestType:LK,target:t,prompt:{type:`useCard`,title:`秘计:选择至多 ${r} 张手牌给予 P${i}(可不选)`,cardFilter:{filter:()=>!0,min:0,max:r}},defaultChoice:{cardIds:[]},timeout:30}),delete e.localVars[NK];let a=e.localVars[VK];delete e.localVars[VK];let o=Array.isArray(a)?a.slice(0,r):[];for(let n of o)e.players[t].hand.includes(n)&&await B(e,{type:`给予`,cardId:n,from:t,to:i})}function jK(e,t){}var MK,NK,PK,FK,IK,LK,RK,zK,BK,VK,HK,cpe=t((()=>{b(),V(),F(),W(),MK=`秘计`,NK=`界秘计/giveMax`,PK=`界秘计/confirm`,FK=`界秘计/giveConfirm`,IK=`界秘计/giveTarget`,LK=`界秘计/giveCards`,RK=`界秘计/confirmed`,zK=`界秘计/giveConfirmed`,BK=`界秘计/giveTarget`,VK=`界秘计/giveCards`,HK={createSkill:OK,onInit:kK,onMount:jK}})),lpe=r({createSkill:()=>WK,default:()=>$K,onInit:()=>GK,onMount:()=>KK});function UK(e){if(!e)return 0;if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function upe(e,t){let n=e.players[t]?.vars[XK];return typeof n==`number`?n:0}function WK(e,t){return{id:e,ownerId:t,name:qK,description:`受到1点伤害后,亮出牌堆顶4张牌,获得其中点数和≤13的若干张;若点数和恰好为13,下次发动多亮出1张`}}function GK(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==`界称象/confirm`&&a!==`界称象/select`)return`当前不是称象询问`;if(a===`界称象/select`){let n=i.prompt?.cardIds??[],r=new Set(n),a=t.cardIds??[],o=new Set,s=0;for(let t of a){if(!r.has(t))return`牌不在亮出范围内`;if(o.has(t))return`存在重复的牌`;o.add(t),s+=UK(e.cardMap[t]?.rank)}if(s>QK)return`获得牌点数和(${s})超过13`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===`界称象/confirm`)e.localVars[YK]=t.choice===!0||t.confirmed===!0;else if(r===`界称象/select`){let n=t.cardIds??[];e.localVars[JK]=n}}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.amount??0;if(!(r<=0))for(let t=0;t<r&&e.state.players[n]?.alive;t++){let t=ZK+upe(e.state,n),r=e.state.zones.deck;if(r.length===0)break;let i=Math.min(t,r.length),a=[];for(let e=0;e<i;e++)a.push(r[r.length-1-e]);if(delete e.state.localVars[YK],await B(e.state,{type:`请求回应`,requestType:`界称象/confirm`,target:n,prompt:{type:`confirm`,title:`称象:是否亮出牌堆顶 ${i} 张牌并获取点数和≤13的若干张?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:20}),!e.state.localVars[YK]){delete e.state.localVars[YK];continue}delete e.state.players[n].vars[XK],delete e.state.localVars[JK],await B(e.state,{type:`请求回应`,requestType:`界称象/select`,target:n,prompt:{type:`distribute`,mode:`select`,title:`称象:选择点数和≤13的若干张(可不选)`,cardIds:a,minTotal:0,maxTotal:i},defaultChoice:!1,timeout:30});let o=e.state.localVars[JK]??[];if(delete e.state.localVars[YK],delete e.state.localVars[JK],o.length===0)continue;let s=0;for(let t of o)s+=UK(e.state.cardMap[t]?.rank);let c=e.state.zones.deck,l=c.slice(0,c.length-i),u=new Set(a),d=new Set(o),f=[];for(let e=0;e<i;e++){let t=c[c.length-1-e];u.has(t)&&!d.has(t)&&f.push(t)}let p=[...f].reverse(),m=[...l,...p,...[...o].reverse()];await B(e.state,{type:`整理牌堆`,cards:m,topCount:o.length,bottomCount:p.length}),await B(e.state,{type:`摸牌`,player:n,count:o.length}),s===QK&&(e.state.players[n].vars[XK]=1)}}),()=>{}}function KK(e,t){t.defineAction(`respond`,{label:qK,style:`primary`,prompt:{type:`confirm`,title:`是否发动称象?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var qK,JK,YK,XK,ZK,QK,$K,dpe=t((()=>{V(),F(),qK=`称象`,JK=`称象/selection`,YK=`称象/confirmed`,XK=`称象/bonus`,ZK=4,QK=13,$K={createSkill:WK,onInit:GK,onMount:KK}})),fpe=r({createSkill:()=>eq,default:()=>nq,onInit:()=>tq});function eq(e,t){return{id:e,ownerId:t,name:`界空城`,description:`锁定技:若你没有手牌,你不是杀和决斗的合法目标;你使用的杀被闪抵消后摸一张牌`,isLocked:!0}}function tq(e,t){let n=e.ownerId,r=M(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n||e.state.players[n]?.hand.length!==0)return;let r;if(t.cardId&&(r=e.state.cardMap[t.cardId]?.name),r||=Ke(e.state)?.skillId,!(r!==`杀`&&r!==`决斗`))return{kind:`cancel`}}),i=N(t,e.id,n,`被抵消`,async e=>{e.frame.skillId===`杀`&&e.atom.source===n&&await B(e.state,{type:`摸牌`,player:n,count:1})});return()=>{r(),i()}}var nq,ppe=t((()=>{V(),z(),F(),nq={createSkill:eq,onInit:tq}})),mpe=r({createSkill:()=>rq,default:()=>uq,onInit:()=>iq,onMount:()=>aq});function rq(e,t){return{id:e,ownerId:t,name:`界突袭`,description:`摸牌阶段,你可以少摸任意张牌并获得等量其他角色的各一张手牌`}}function iq(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let r=t.atom.requestType;return r!==oq&&r!==sq?`当前不是突袭回应`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===oq)e.localVars[cq]=t.choice===!0;else if(r===sq){let n=t.targets??(typeof t.target==`number`?[t.target]:void 0);e.localVars[lq]=n??[]}}),M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive)return;let r=t.count??2;if(r<=0)return;let i=e.state.players.filter((e,t)=>t!==n&&e.alive&&e.hand.length>0);if(i.length===0||(delete e.state.localVars[cq],await B(e.state,{type:`请求回应`,requestType:oq,target:n,prompt:{type:`confirm`,title:`是否发动界突袭?(少摸任意张牌并获得等量其他角色的各一张手牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[cq]!==!0))return;let a=Math.min(r,i.length);delete e.state.localVars[lq],await B(e.state,{type:`请求回应`,requestType:sq,target:n,prompt:{type:`choosePlayer`,title:`界突袭:选择 1~${a} 名角色(各获得一张手牌;少摸等量张)`,min:1,max:a,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0&&(e.players[t]?.handCount??0)>0},timeout:15});let o=e.state.localVars[lq],s=Array.isArray(o)?o.filter(t=>t!==n&&e.state.players[t]?.alive===!0&&e.state.players[t].hand.length>0):[];if(s.length===0)return;for(let t of s){let r=e.state.players[t];if(!r||!r.alive||r.hand.length===0)continue;let i=Ud(e.state.rngSeed),a=i.nextInt(r.hand.length);e.state.rngSeed=i.getState();let o=r.hand[a];await B(e.state,{type:`获得`,player:n,cardId:o,from:t})}let c=r-s.length;return c<=0?{kind:`cancel`}:{kind:`modify`,atom:{...e.atom,count:c}}}),()=>{}}function aq(e,t){t.defineAction(`respond`,{label:`界突袭`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界突袭?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var oq,sq,cq,lq,uq,hpe=t((()=>{V(),F(),Wd(),oq=`界突袭/trigger`,sq=`界突袭/select`,cq=`界突袭/triggered`,lq=`界突袭/targets`,uq={createSkill:rq,onInit:iq,onMount:aq}})),gpe=r({createSkill:()=>dq,default:()=>Dq,onInit:()=>pq,onMount:()=>mq});function dq(e,t){return{id:e,ownerId:t,name:gq,description:`其他角色的回合结束后,若其本回合未对其他角色造成伤害可选一项;若未使用过牌可选两项:1.夺其一张装备;2.摸一张牌`}}function _pe(e){return e.turn.vars[_q]===!0}function vpe(e){return e.turn.vars[vq]===!0}async function fq(e,t,n){let r=e.players[n];if(!r?.alive)return;let i=Object.entries(r.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`}));if(i.length===0)return;delete e.localVars[wq],await B(e,{type:`请求回应`,requestType:xq,target:t,prompt:{type:`pickTargetCard`,title:`窃听:选择 ${r.name??`P${n}`} 装备区一张牌置入你的装备区`,target:n,equipment:i,judge:[],handCount:0},defaultChoice:{zone:`equipment`,cardId:i[0].cardId},timeout:20});let a=e.localVars[wq];delete e.localVars[wq];let o=a?.zone===`equipment`&&typeof a.cardId==`string`?a.cardId:i[0].cardId,s=i.find(e=>e.cardId===o);if(!s)return;let c=s.slot,l=e.cardMap[o];if(!l)return;l.name&&ym(l.name)&&await B(e,{type:`移除技能`,player:n,skillId:l.name}),await B(e,{type:`获得`,player:t,cardId:o,from:n});let u=e.players[t].equipment[c];if(u){let n=e.cardMap[u];n?.name&&ym(n.name)&&await B(e,{type:`移除技能`,player:t,skillId:n.name}),await B(e,{type:`卸下`,player:t,slot:c}),await B(e,{type:`移动牌`,cardId:u,from:{zone:`手牌`,player:t},to:{zone:`弃牌堆`}})}await B(e,{type:`装备`,player:t,cardId:o}),l.name&&ym(l.name)&&await B(e,{type:`添加技能`,player:t,skillId:l.name})}function pq(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i!==yq&&i!==bq&&i!==xq)return`当前不是窃听询问`;if(i===xq){if(t.zone!==`equipment`)return`需要选装备`;if(typeof t.cardId!=`string`)return`需要 cardId`;let n=e.localVars[Tq];if(typeof n!=`number`)return`询问状态异常`;let r=e.players[n];if(!r)return`目标不存在`;if(!Object.values(r.equipment).includes(t.cardId))return`该牌不在目标装备区`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===yq?e.localVars[Sq]=t.choice===!0||t.confirmed===!0:r===bq?e.localVars[Cq]=t.choice===!0||t.confirmed===!0:r===xq&&(e.localVars[wq]={zone:t.zone,cardId:t.cardId??null})}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom,n=e.state.currentPlayerIndex;t.source===n&&t.target!==n&&((t.amount??0)<=0||(e.state.turn.vars[_q]=!0))}),N(t,e.id,n,`指定目标`,async e=>{let t=e.atom,n=e.state.currentPlayerIndex;t.source===n&&t.target!==n&&(e.state.turn.vars[vq]=!0)}),N(t,e.id,n,`询问闪`,async e=>{let t=e.atom,n=e.state.currentPlayerIndex;t.source===n&&t.target!==n&&(e.state.turn.vars[vq]=!0)}),N(t,e.id,n,`询问杀`,async e=>{let t=e.atom,n=e.state.currentPlayerIndex;t.source===n&&t.target!==n&&(e.state.turn.vars[vq]=!0)}),M(t,e.id,n,`回合结束`,async e=>{let t=e.atom.player;if(typeof t!=`number`||t===n||!e.state.players[n]?.alive)return{kind:`pass`};let r=!_pe(e.state),i=!vpe(e.state),a=r?i?2:1:0;if(a===0)return{kind:`pass`};if(e.state.localVars[Tq]=t,e.state.localVars[Eq]=a,delete e.state.localVars[Sq],await B(e.state,{type:`请求回应`,requestType:yq,target:n,prompt:{type:`confirm`,title:`窃听:${e.state.players[t]?.name??`P${t}`} 本回合${r?`未`:`已`}对其他角色造成伤害,${i?`未`:`已`}使用过牌。是否发动?`,description:a===2?`可选两项(夺装备+摸牌)`:`可选一项(夺装备或摸牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[Sq]!==!0)return delete e.state.localVars[Sq],delete e.state.localVars[Tq],delete e.state.localVars[Eq],{kind:`pass`};if(delete e.state.localVars[Sq],!e.state.players[t]?.alive||!e.state.players[n]?.alive)return delete e.state.localVars[Tq],delete e.state.localVars[Eq],{kind:`pass`};let o=Object.values(e.state.players[t].equipment).some(e=>typeof e==`string`);if(a===1)if(o){delete e.state.localVars[Cq],await B(e.state,{type:`请求回应`,requestType:bq,target:n,prompt:{type:`confirm`,title:`窃听:夺一张装备?(确认=夺装备,取消=摸一张牌)`,confirmLabel:`夺装备`,cancelLabel:`摸一张牌`},defaultChoice:!1,timeout:15});let r=e.state.localVars[Cq]===!0;delete e.state.localVars[Cq],r?await fq(e.state,n,t):await B(e.state,{type:`摸牌`,player:n,count:1})}else await B(e.state,{type:`摸牌`,player:n,count:1});else o&&await fq(e.state,n,t),await B(e.state,{type:`摸牌`,player:n,count:1});return delete e.state.localVars[Tq],delete e.state.localVars[Eq],{kind:`pass`}}),()=>{}}function mq(e,t){return t.defineAction(`respond`,{label:gq,style:`default`,prompt:{type:`confirm`,title:`是否发动窃听?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var hq,gq,_q,vq,yq,bq,xq,Sq,Cq,wq,Tq,Eq,Dq,ype=t((()=>{V(),F(),Sm(),hq=`界窃听`,gq=`窃听`,_q=`${hq}/damagedOther`,vq=`${hq}/usedCardOnOther`,yq=`${hq}/trigger`,bq=`${hq}/stealOrDraw`,xq=`${hq}/pickEquip`,Sq=`${hq}/confirmed`,Cq=`${hq}/stealChoice`,wq=`${hq}/pickResult`,Tq=`${hq}/turnPlayer`,Eq=`${hq}/choices`,Dq={createSkill:dq,onInit:pq,onMount:mq}})),bpe=r({createSkill:()=>Oq,default:()=>Vq,onInit:()=>Nq,onMount:()=>Pq});function Oq(e,t){return{id:e,ownerId:t,name:Iq,description:`本回合每使用一种新花色手牌,手牌上限+1;出牌阶段结束时,可以摸X张牌(X为本回合使用过牌的类型数)`}}function kq(e,t){let n=e.turn.vars[Lq+t];return Array.isArray(n)?n:[]}function Aq(e,t){let n=e.turn.vars[Rq+t];return Array.isArray(n)?n:[]}function jq(e,t,n){if(!n?.suit||!n?.type)return!1;let r=!1,i=kq(e,t);i.includes(n.suit)||(i.push(n.suit),e.turn.vars[Lq+t]=i,r=!0);let a=Aq(e,t);return a.includes(n.type)||(a.push(n.type),e.turn.vars[Rq+t]=a,r=!0),r}function Mq(e,t){let n=kq(e,t).length;n>0?e.turn.vars[$c(t)]=n:delete e.turn.vars[$c(t)]}function Nq(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?.atom.type===`请求回应`?r.atom.requestType===Bq?null:`当前不是精策确认`:`当前不需要回应`},async(e,t)=>{e.localVars[zq]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.from.zone!==`手牌`||t.from.player!==n||t.to.zone!==`处理区`||e.state.currentPlayerIndex!==n)return;let r=e.state.cardMap[t.cardId];jq(e.state,n,r)&&Mq(e.state,n)}),N(t,e.id,n,`装备`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n)return;let r=e.state.cardMap[t.cardId];jq(e.state,n,r)&&Mq(e.state,n)}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type!==`阶段结束`||t.phase!==`出牌`||t.player!==n||!e.state.players[n]?.alive)return;let r=Aq(e.state,n).length;r!==0&&(delete e.state.localVars[zq],await B(e.state,{type:`请求回应`,requestType:Bq,target:n,prompt:{type:`confirm`,title:`精策:是否摸 ${r} 张牌?(本回合已使用 ${r} 种类型的牌)`,confirmLabel:`摸牌`,cancelLabel:`不摸`},defaultChoice:!1,timeout:15}),e.state.localVars[zq]&&await B(e.state,{type:`摸牌`,player:n,count:r}))}),()=>{}}function Pq(e,t){return()=>{}}var Fq,Iq,Lq,Rq,zq,Bq,Vq,xpe=t((()=>{V(),F(),W(),Fq=`界精策`,Iq=`精策`,Lq=`${Fq}/usedSuits:`,Rq=`${Fq}/usedTypes:`,zq=`${Fq}/confirmed`,Bq=`${Fq}/confirm`,Vq={createSkill:Oq,onInit:Nq,onMount:Pq}})),Spe=r({createSkill:()=>Hq,default:()=>Gq,onInit:()=>Uq,onMount:()=>Wq});function Hq(e,t){return{id:e,ownerId:t,name:`界红颜`,description:`锁定技:你的黑桃牌和黑桃判定牌视为红桃牌;装备区有红桃牌时手牌上限等于体力上限`,isLocked:!0}}function Cpe(e,t){let n=e.players[t]?.equipment??{};for(let t of Object.values(n)){if(!t)continue;let n=e.cardMap[t];if(n?.suit===`♥`||n?.suit===`♠`)return!0}return!1}function Uq(e,t){let n=e.ownerId,r=M(t,e.id,n,`判定`,async e=>{if(e.atom.player!==n)return;let t=e.state.zones.deck[e.state.zones.deck.length-1];if(!t)return;let r=e.state.cardMap[t];r&&r.suit===`♠`&&(r.suit=`♥`,r.color=`红`)}),i=rp(t,n,(e,t)=>{if(Cpe(e,t))return e.players[t]?.maxHealth});return()=>{r(),i()}}function Wq(e,t){return()=>{}}var Gq,wpe=t((()=>{F(),op(),Gq={createSkill:Hq,onInit:Uq,onMount:Wq}})),Tpe=r({createSkill:()=>Kq,default:()=>iJ,onInit:()=>qq,onMount:()=>Jq});function Epe(e,t){let n=e.players.length;for(let r=1;r<=n;r++){let i=(t+r)%n;if(e.players[i]?.alive)return i}return t}function Dpe(e,t,n){return t===n?!1:Epe(e,t)===n}function Kq(e,t){return{id:e,ownerId:t,name:Xq,description:`当你的牌因弃置置入弃牌堆后,或你上家每回合首次因弃置置入弃牌堆后,你可以将其中任意张牌置于牌堆顶`}}function qq(e,t){let n=e.ownerId,r=`${rJ}:${n}`;return N(t,e.id,n,`弃置`,async e=>{let t=e.atom,i=e.state,a=t.player;if(!i.players[n]?.alive)return;let o=!1;if(a!==n)if(Dpe(i,a,n)){if(i.turn.vars[r])return;o=!0}else return;let s=t.cardIds.filter(e=>i.zones.discardPile.includes(e));if(s.length!==0){o&&(i.turn.vars[r]=!0),await I(i,Yq,n,{cardIds:[...s]});try{if(delete i.localVars[eJ],await B(i,{type:`请求回应`,requestType:Zq,target:n,prompt:{type:`confirm`,title:`是否发动纵玄?(${o?`上家`:`你`}弃置了 ${s.length} 张牌,可选若干置于牌堆顶)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30}),i.localVars[eJ]!==!0){delete i.localVars[eJ];return}delete i.localVars[eJ];let e=[...s];for(;;){let t=e.filter(e=>i.zones.discardPile.includes(e));if(t.length===0)break;delete i.localVars[tJ],await B(i,{type:`请求回应`,requestType:Qq,target:n,prompt:{type:`pickProcessingCard`,title:`纵玄:选择一张牌置于牌堆顶`,cards:t.map(e=>{let t=i.cardMap[e];return{cardId:e,cardName:t?.name??`?`,suit:t?.suit??``,rank:t?.rank??``}})},defaultChoice:t[0],timeout:30});let r=i.localVars[tJ];if(delete i.localVars[tJ],!r||!t.includes(r))break;await B(i,{type:`移动牌`,cardId:r,from:{zone:`弃牌堆`},to:{zone:`牌堆`}});let a=e.indexOf(r);a>=0&&e.splice(a,1);let o=e.filter(e=>i.zones.discardPile.includes(e));if(o.length===0)break;if(delete i.localVars[nJ],await B(i,{type:`请求回应`,requestType:$q,target:n,prompt:{type:`confirm`,title:`纵玄:是否继续选牌?(剩余 ${o.length} 张可选)`,confirmLabel:`继续`,cancelLabel:`完成`},defaultChoice:!1,timeout:30}),i.localVars[nJ]!==!0){delete i.localVars[nJ];break}delete i.localVars[nJ]}}finally{await L(i)}}}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`请求回应`)return`当前不是纵玄窗口`;let i=r.atom;return i.requestType===Zq||i.requestType===$q?null:i.requestType===Qq?typeof t.cardId==`string`?null:`需要选择一张牌`:`当前不是纵玄窗口`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===Zq?e.localVars[eJ]=t.choice===!0||t.confirmed===!0:r===$q?e.localVars[nJ]=t.choice===!0||t.confirmed===!0:r===Qq&&typeof t.cardId==`string`&&(e.localVars[tJ]=t.cardId)}),()=>{}}function Jq(e,t){return()=>{}}var Yq,Xq,Zq,Qq,$q,eJ,tJ,nJ,rJ,iJ,Ope=t((()=>{V(),z(),F(),Yq=`界纵玄`,Xq=`纵玄`,Zq=`界纵玄/confirm`,Qq=`界纵玄/pick`,$q=`界纵玄/again`,eJ=`界纵玄/confirmed`,tJ=`界纵玄/cardId`,nJ=`界纵玄/again`,rJ=`界纵玄/upstreamTriggeredThisTurn`,iJ={createSkill:Kq,onInit:qq,onMount:Jq}})),kpe=r({createSkill:()=>oJ,default:()=>pJ,onInit:()=>sJ,onMount:()=>cJ});function aJ(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function oJ(e,t){return{id:e,ownerId:t,name:uJ,description:`当你拼点赢时,你可以获得点数较小的拼点牌;当你没赢时,你可以获得你的拼点牌`}}function sJ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===dJ?null:`当前不是纵适回应`:`当前不需要回应`},async(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return;let i=r.atom;i.type!==`请求回应`||i.requestType!==dJ||(e.localVars[fJ]=t.choice===!0)}),N(t,e.id,n,`拼点后`,async e=>{let t=e.atom;if(t.type!==`拼点后`)return;let r=t.initiator===n,i=t.target===n;if(!r&&!i||!t.initiatorCard||!t.targetCard)return;let a=e.state.cardMap[t.initiatorCard],o=e.state.cardMap[t.targetCard];if(!a||!o)return;let s=aJ(a.rank),c=aJ(o.rank),l=r?s:c,u=r?c:s,d=r?t.initiatorCard:t.targetCard,f=r?t.targetCard:t.initiatorCard,p=l>u,m=p?f:d;if(!e.state.zones.discardPile.includes(m))return;delete e.state.localVars[fJ],await B(e.state,{type:`请求回应`,requestType:dJ,target:n,prompt:{type:`confirm`,title:p?`纵适:是否获得点数较小的拼点牌?`:`纵适:是否获得你的拼点牌?`},timeout:30});let h=e.state.localVars[fJ]===!0;delete e.state.localVars[fJ],h&&e.state.zones.discardPile.includes(m)&&await B(e.state,{type:`移动牌`,cardId:m,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}})}),()=>{}}function cJ(e,t){t.defineAction(`respond`,{label:uJ,style:`primary`,prompt:{type:`confirm`,title:`纵适:是否获得拼点牌?`}})}var lJ,uJ,dJ,fJ,pJ,Ape=t((()=>{V(),F(),lJ=`界纵适`,uJ=`纵适`,dJ=`${lJ}/confirm`,fJ=`${lJ}/confirmed`,pJ={createSkill:oJ,onInit:sJ,onMount:cJ}})),jpe=r({createSkill:()=>hJ,default:()=>CJ,onInit:()=>vJ,onMount:()=>yJ});function mJ(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function hJ(e,t){return{id:e,ownerId:t,name:bJ,description:`出牌阶段限一次:选一名男性角色,弃一张手牌或置一张装备牌入其装备区,体力大者摸1张,小者回1点`}}function Mpe(e,t){let n=e.players[t];return n?.alive?kc(n.character)===`男`:!1}function gJ(e,t,n){let r=e.players[t]?.equipment??{};for(let e of SJ)if(r[e]===n)return e;return null}function _J(e){let t=e.allocation;if(Array.isArray(t)&&t.length>0){let e=t[0],n=e.cardIds,r=e.target;if(Array.isArray(n)&&n.length>=1&&typeof r==`number`)return{cardId:String(n[0]),target:r}}let n=e.target;if(typeof n!=`number`)return null;let r=typeof e.cardId==`string`?e.cardId:Array.isArray(e.cardIds)&&typeof e.cardIds[0]==`string`?e.cardIds[0]:void 0;return r?{cardId:r,target:n}:null}function vJ(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r?.alive)return`角色不可用`;if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`不是出牌阶段`;if(E(e))return`当前有未回应的询问`;if(e.players[n]?.vars[xJ])return`本回合已使用过界结姻`;let i=_J(t);if(!i)return`需要选择一张牌和一名男性目标`;let{cardId:a,target:o}=i;if(!Mpe(e,o))return`目标必须是男性角色`;let s=r.hand.includes(a),c=gJ(e,n,a);if(!s&&c===null)return`牌不在手牌或装备区`;let l=e.cardMap[a];return l?.type===`装备牌`&&mJ(l)===null?`装备牌栏位不合法`:null},async(e,t)=>{let r=_J(t);if(!r)return;let{cardId:i,target:a}=r,o=n;await Z(e,o,bJ),await I(e,bJ,o,{});try{let t=e.cardMap[i];if(t?.type===`装备牌`){let n=mJ(t),r=gJ(e,o,i);r!==null&&(t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:o,skillId:t.name}),await B(e,{type:`卸下`,player:o,slot:r})),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:o},to:{zone:`手牌`,player:a}});let s=e.players[a].equipment[n];if(s){let t=e.cardMap[s];t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:a,skillId:t.name}),await B(e,{type:`卸下`,player:a,slot:n}),await B(e,{type:`移动牌`,cardId:s,from:{zone:`手牌`,player:a},to:{zone:`弃牌堆`}})}await B(e,{type:`装备`,player:a,cardId:i}),t?.name&&ym(t.name)&&await B(e,{type:`添加技能`,player:a,skillId:t.name})}else await B(e,{type:`弃置`,player:o,cardIds:[i],voluntary:!0});let n=p(e.players[o]),r=p(e.players[a]);n>r?(await B(e,{type:`摸牌`,player:o,count:1}),await B(e,{type:`回复体力`,target:a,amount:1,source:o})):n<r&&(await B(e,{type:`摸牌`,player:a,count:1}),await B(e,{type:`回复体力`,target:o,amount:1,source:o}))}finally{await L(e)}}),()=>{}}function yJ(e,t){return t.defineAction(`use`,{label:bJ,style:`primary`,prompt:{type:`distribute`,mode:`allocate`,title:`界结姻:选一张手牌弃置,或选一张装备牌置入一名男性角色的装备区`,source:`handAndEquip`,minTotal:1,maxTotal:1,minPerTarget:1,maxPerTarget:1,allowSelf:!1,targetFilter:(e,t)=>{let n=e.players[t];return!n||n.alive===!1?!1:kc(n.character)===`男`}},activeWhen:e=>yh(bJ)(e)}),()=>{}}var bJ,xJ,SJ,CJ,Npe=t((()=>{b(),V(),z(),Q(),F(),Fc(),Sm(),bJ=`界结姻`,xJ=`${bJ}/usedThisTurn`,SJ=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`],CJ={createSkill:hJ,onInit:vJ,onMount:yJ}})),Ppe=r({createSkill:()=>wJ,default:()=>DJ,onInit:()=>TJ,onMount:()=>EJ});function wJ(e,t){return{id:e,ownerId:t,name:`绝情`,description:`锁定技:你即将造成的伤害视为失去体力`,isLocked:!0}}function TJ(e,t){let n=e.ownerId;return M(t,e.id,n,`伤害结算开始时`,async e=>{let t=e.atom;if(t.source!==n||typeof t.target!=`number`)return;let r=t.amount??0;if(!(r<=0))return await B(e.state,{type:`失去体力`,target:t.target,amount:r}),{kind:`cancel`}}),()=>{}}function EJ(e,t){}var DJ,Fpe=t((()=>{V(),F(),DJ={createSkill:wJ,onInit:TJ,onMount:EJ}})),Ipe=r({createSkill:()=>OJ,default:()=>IJ,onInit:()=>kJ,onMount:()=>AJ});function OJ(e,t){return{id:e,ownerId:t,name:jJ,description:`结束阶段:对一名手牌数小于等于你的其他角色造成1点伤害`}}function kJ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===MJ)return null;if(a===PJ){let r=t.targets;if(!Array.isArray(r)||r.length!==1)return`请选择一名目标`;let i=r[0];if(i===n)return`不能以自己为目标`;if(!e.players[i]?.alive)return`目标不合法`;let a=e.players[n],o=e.players[i];return!a||!o?`目标不合法`:o.hand.length>a.hand.length?`目标手牌数须小于等于你`:null}return`当前不是绝策询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===MJ)e.localVars[NJ]=t.choice===!0||t.confirmed===!0;else if(r===PJ){let n=t.targets;Array.isArray(n)&&n.length===1&&(e.localVars[FJ]=n[0])}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n)return;let r=e.state,i=r.players[n];if(!i?.alive)return;let a=i.hand.length;if(!r.players.some(e=>e.alive&&e.index!==n&&e.hand.length<=a))return;if(delete r.localVars[NJ],await B(r,{type:`请求回应`,requestType:MJ,target:n,prompt:{type:`confirm`,title:`是否发动绝策?(对一名手牌数≤你的其他角色造成1点伤害)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!r.localVars[NJ]){delete r.localVars[NJ];return}delete r.localVars[NJ],delete r.localVars[FJ],await B(r,{type:`请求回应`,requestType:PJ,target:n,prompt:{type:`choosePlayer`,title:`绝策:选择一名手牌数≤你的其他角色`,min:1,max:1,filter:(e,t)=>t!==n&&r.players[t]?.alive===!0&&(r.players[t]?.hand.length??0)<=a},timeout:20});let o=r.localVars[FJ];delete r.localVars[FJ],typeof o==`number`&&r.players[o]?.alive&&await Dm(r,n,o,1)}),()=>{}}function AJ(e,t){}var jJ,MJ,NJ,PJ,FJ,IJ,Lpe=t((()=>{V(),Om(),F(),jJ=`绝策`,MJ=`界绝策/confirm`,NJ=`界绝策/confirmed`,PJ=`界绝策/choose`,FJ=`界绝策/target`,IJ={createSkill:OJ,onInit:kJ,onMount:AJ}})),Rpe=r({createSkill:()=>LJ,default:()=>JJ,onInit:()=>RJ,onMount:()=>zJ});function zpe(e,t){let n=e.players[t];return n?n.hand.length+Object.values(n.equipment).filter(e=>typeof e==`string`).length:0}function LJ(e,t){return{id:e,ownerId:t,name:KJ,description:`出牌阶段限一次,令两名角色交换手牌(差不大于你的牌数),出牌阶段结束时弃X张牌(X为手牌数差)`}}function RJ(e,t){let n=e.ownerId,r=[];return r.push(j(t,e.id,n,`use`,(e,t)=>e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:X(e,n,`界缔盟`)?`本回合已使用过缔盟`:e.players[n]?.alive?e.players.filter(e=>e.alive&&e.index!==n).length<2?`需要至少两名其他角色`:null:`角色不可用`:`只能在出牌阶段发动`:`不是你的回合`,async(e,t)=>{await Z(e,n,`界缔盟`),await I(e,`界缔盟`,n,{}),delete e.localVars[HJ],await B(e,{type:`请求回应`,requestType:BJ,target:n,prompt:{type:`choosePlayer`,title:`缔盟:选择两名其他角色交换手牌(差不大于你的牌数)`,min:2,max:2,filter:(t,r)=>r!==n&&e.players[r]?.alive===!0},timeout:30});let r=e.localVars[HJ];if(delete e.localVars[HJ],!Array.isArray(r)||r.length!==2){await L(e);return}let[i,a]=r;if(!e.players[i]?.alive||!e.players[a]?.alive){await L(e);return}let o=Math.abs(e.players[i].hand.length-e.players[a].hand.length);if(o>zpe(e,n)){await L(e);return}let s=[...e.players[i].hand],c=[...e.players[a].hand];for(let t of s)await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:i},to:{zone:`手牌`,player:a}});for(let t of c)await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:a},to:{zone:`手牌`,player:i}});o>0&&(e.localVars[WJ]=o,e.localVars[GJ]=n),await L(e)})),r.push(j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==BJ&&a!==VJ?`当前不是界缔盟询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===BJ){let n=t.targets;Array.isArray(n)&&n.length===2&&(e.localVars[HJ]=n)}else if(r===VJ){let n=t.cardIds;Array.isArray(n)&&(e.localVars[UJ]=n)}})),r.push(M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.phase!==`出牌`||t.player!==n)return;let r=e.state,i=r.localVars[WJ],a=r.localVars[GJ];if(typeof i!=`number`||a!==n||(delete r.localVars[WJ],delete r.localVars[GJ],!r.players[n]?.alive))return;let o=Math.min(i,r.players[n].hand.length);if(o<=0)return;delete r.localVars[UJ],await B(r,{type:`请求回应`,requestType:VJ,target:n,prompt:{type:`useCard`,title:`缔盟:出牌阶段结束,弃置 ${o} 张牌`,cardFilter:{filter:()=>!0,min:o,max:o}},mandatory:!0,timeout:30});let s=r.localVars[UJ];delete r.localVars[UJ],(!s||s.length===0)&&o>0&&(s=r.players[n]?.hand.slice(0,o)??[]),s&&s.length>0&&await B(r,{type:`弃置`,player:n,cardIds:s,voluntary:!0})})),()=>r.forEach(e=>e())}function zJ(e,t){return t.defineAction(`use`,{label:KJ,style:`primary`,prompt:{type:`confirm`,title:`缔盟:选择两名其他角色交换手牌`,confirmLabel:`发动`,cancelLabel:`取消`},activeWhen:e=>qJ(e)}),t.defineAction(`respond`,{label:KJ,style:`primary`,prompt:{type:`confirm`,title:KJ,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var BJ,VJ,HJ,UJ,WJ,GJ,KJ,qJ,JJ,Bpe=t((()=>{V(),z(),Q(),F(),BJ=`界缔盟/target`,VJ=`界缔盟/discard`,HJ=`界缔盟/targets`,UJ=`界缔盟/discardCards`,WJ=`界缔盟/待弃数`,GJ=`界缔盟/待弃归属`,KJ=`缔盟`,qJ=yh(`界缔盟`),JJ={createSkill:LJ,onInit:RJ,onMount:zJ}})),Vpe=r({createSkill:()=>XJ,default:()=>oY,onInit:()=>ZJ,onMount:()=>$J});function YJ(e){return e===!0?`红`:`黑`}function XJ(e,t){return{id:e,ownerId:t,name:tY,description:`出牌阶段限一次:与一名其他角色各选一种颜色,各自弃置所选颜色的手牌,弃牌较多者视为对另一方使用决斗`}}function ZJ(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,eY))return`本回合已使用过翦灭`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;if(r.hand.length===0)return`你需要有手牌才能发动翦灭`;let i=t.target;if(typeof i!=`number`)return`需要指定一名目标`;if(i===n)return`不能以自己为目标`;let a=e.players[i];return a?.alive?a.hand.length===0?`目标没有手牌`:null:`目标不存在或已死亡`},async(e,t)=>{let r=n,i=t.target;await Z(e,r,eY),await I(e,eY,r,{...t});try{delete e.localVars[iY],await B(e,{type:`请求回应`,requestType:nY,target:r,prompt:{type:`confirm`,title:`翦灭:选择你的颜色(确认=红色,取消=黑色)`,confirmLabel:`红色`,cancelLabel:`黑色`},defaultChoice:!1,timeout:15});let t=YJ(e.localVars[iY]);delete e.localVars[aY],await B(e,{type:`请求回应`,requestType:rY,target:i,prompt:{type:`confirm`,title:`翦灭:${e.players[r].name} 与你各选一色,各自弃该色手牌,多者对少者决斗。选择你的颜色(确认=红色,取消=黑色)`,confirmLabel:`红色`,cancelLabel:`黑色`},defaultChoice:!1,timeout:15});let n=YJ(e.localVars[aY]),a=QJ(e,r,t),o=QJ(e,i,n);a.length>0&&await B(e,{type:`弃置`,player:r,cardIds:a}),o.length>0&&await B(e,{type:`弃置`,player:i,cardIds:o});let s=eY;if(a.length>o.length){if(e.players[r]?.alive&&e.players[i]?.alive){let t=`${s}:决斗:${r}:${i}:${e.seq}`;e.cardMap[t]={id:t,name:`决斗`,suit:``,color:`无色`,rank:`A`,type:`锦囊牌`},await Lh(e,r,t,[i],`决斗`,{virtual:!0}),delete e.cardMap[t]}}else if(o.length>a.length&&e.players[r]?.alive&&e.players[i]?.alive){let t=`${s}:决斗:${i}:${r}:${e.seq}`;e.cardMap[t]={id:t,name:`决斗`,suit:``,color:`无色`,rank:`A`,type:`锦囊牌`},await Lh(e,i,t,[r],`决斗`,{virtual:!0}),delete e.cardMap[t]}}finally{await L(e)}});let r=[];for(let i of t.players){let a=i.index,o=j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return`当前不需要回应`;let r=n.atom;return r.type===`请求回应`?r.requestType!==nY&&r.requestType!==rY?`当前不是翦灭选色`:null:`当前不需要回应`},async(e,t)=>{let r=e.pendingSlots.get(a);if(!r)return;let i=r.atom,o=t.choice===!0||t.confirmed===!0;if(i.requestType===nY){if(a!==n)return;e.localVars[iY]=o}else i.requestType===rY&&(e.localVars[aY]=o)});r.push(o)}return()=>{r.forEach(e=>e())}}function QJ(e,t,n){let r=e.players[t];if(!r)return[];let i=[];for(let t of r.hand)e.cardMap[t]?.color===n&&i.push(t);return i}function $J(e,t){t.defineAction(`use`,{label:tY,style:`danger`,prompt:{type:`selectTarget`,title:`翦灭:选择一名其他角色,各选一色弃牌,多者对少者决斗`,description:`出牌阶段限一次;你和目标都需要有手牌`,targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return!n||n.alive===!1?!1:(n.handCount??0)>0}}},activeWhen:e=>yh(eY)(e)&&(e.view.players[e.perspectiveIdx]?.hand?.length??0)>0}),t.defineAction(`respond`,{label:tY,style:`primary`,prompt:{type:`confirm`,title:`翦灭:选择你的颜色(确认=红色,取消=黑色)`,confirmLabel:`红色`,cancelLabel:`黑色`}})}var eY,tY,nY,rY,iY,aY,oY,Hpe=t((()=>{V(),z(),Q(),F(),Gh(),eY=`界翦灭`,tY=`翦灭`,nY=`${eY}/我选色`,rY=`${eY}/敌选色`,iY=`${eY}/ownerColor`,aY=`${eY}/targetColor`,oY={createSkill:XJ,onInit:ZJ,onMount:$J}})),Upe=r({createSkill:()=>sY,default:()=>dY,onInit:()=>cY,onMount:()=>lY});function sY(e,t){return{id:e,ownerId:t,name:uY,description:`锁定技,当你受到伤害时,若造成伤害的牌为红色,来源摸一张牌;否则你摸一张牌`,isLocked:!0}}function cY(e,t){let n=e.ownerId,r=[];return r.push(N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=t.cardId,i=r?e.state.cardMap[r]:void 0;if(i&&i.color===`红`){let r=t.source,i=typeof r==`number`&&e.state.players[r]?.alive;await B(e.state,{type:`摸牌`,player:i?r:n,count:1})}else await B(e.state,{type:`摸牌`,player:n,count:1})})),()=>{for(let e of r)e()}}function lY(e,t){}var uY,dY,Wpe=t((()=>{V(),F(),uY=`耀武`,dY={createSkill:sY,onInit:cY,onMount:lY}})),Gpe=r({createSkill:()=>fY,default:()=>wY,onInit:()=>hY,onMount:()=>gY});function fY(e,t){return{id:e,ownerId:t,name:_Y,description:`摸牌阶段可多摸X张(X为全场势力数);若本回合对其他角色造成过伤害,结束阶段弃X张`}}function pY(e){let t=new Set;for(let n of e.players)n.alive&&n.faction&&t.add(n.faction);return t.size}function mY(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function hY(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=mY(e,n);if(r!==yY&&r!==bY)return`当前不是自守询问`;if(r===yY)return null;let i=t.cardIds;if(!Array.isArray(i)||i.length===0)return`请选择要弃置的牌`;let a=e.players[n];if(!a)return`玩家不存在`;let o=new Set;for(let e of i){if(typeof e!=`string`||!a.hand.includes(e))return`牌 ${e} 不在手牌中`;if(o.has(e))return`不能选择重复的牌`;o.add(e)}return null},async(e,t)=>{let r=mY(e,n);if(r===yY)e.localVars[vY]=t.choice===!0||t.confirmed===!0;else if(r===bY){let n=t.cardIds;Array.isArray(n)&&(e.localVars[CY]=n)}}),M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive)return;let r=pY(e.state);if(r<=0||(delete e.state.localVars[vY],await B(e.state,{type:`请求回应`,requestType:yY,target:n,prompt:{type:`confirm`,title:`是否发动自守?(多摸 ${r} 张牌;若本回合对其他角色造成过伤害,结束阶段弃 ${r} 张)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[vY]))return;e.state.turn.vars[xY]=!0;let i=t.count??2;return{kind:`modify`,atom:{...e.atom,count:i+r}}}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;t.source===n&&(t.target===void 0||t.target===n||(t.amount??0)<=0||(e.state.turn.vars[SY]=!0))}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n||!e.state.turn.vars[xY]||!e.state.turn.vars[SY])return;let r=e.state.players[n];if(!r?.alive)return;let i=pY(e.state);if(i<=0)return;let a=r.hand.length;if(a===0)return;let o=Math.min(i,a);delete e.state.localVars[CY],await B(e.state,{type:`请求回应`,requestType:bY,target:n,prompt:{type:`useCard`,title:`自守:本回合对其他角色造成过伤害,弃 ${o} 张牌`,cardFilter:{filter:()=>!0,min:o,max:o}},mandatory:!0,timeout:30});let s=e.state.localVars[CY];delete e.state.localVars[CY],(!s||s.length===0)&&o>0&&(s=e.state.players[n]?.hand.slice(0,o)??[]),s&&s.length>0&&await B(e.state,{type:`弃置`,player:n,cardIds:s})}),()=>{}}function gY(e,t){return t.defineAction(`respond`,{label:`自守`,style:`primary`,prompt:{type:`confirm`,title:`是否发动自守?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var _Y,vY,yY,bY,xY,SY,CY,wY,Kpe=t((()=>{V(),F(),_Y=`自守`,vY=`自守/confirmed`,yY=`界自守/confirm`,bY=`界自守/弃牌`,xY=`自守/active`,SY=`自守/damageDealt`,CY=`自守/discardCards`,wY={createSkill:fY,onInit:hY,onMount:gY}})),qpe=r({createSkill:()=>TY,default:()=>IY,onInit:()=>DY,onMount:()=>OY});function TY(e,t){return{id:e,ownerId:t,name:`界节命`,description:`受到1点伤害后或死亡时,令一名角色摸X张牌,然后将手牌弃至X张(X为其体力上限且至多为5)`}}async function EY(e,t){if(delete e.localVars[MY],await B(e,{type:`请求回应`,requestType:kY,target:t,prompt:{type:`confirm`,title:`是否发动节命?(令一名角色摸X张牌,然后将手牌弃至X张)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.localVars[MY])return;delete e.localVars[NY],await B(e,{type:`请求回应`,requestType:AY,target:t,prompt:{type:`choosePlayer`,title:`节命:选择一名角色(摸X张牌,然后将手牌弃至X张)`,min:1,max:1,filter:(t,n)=>e.players[n]?.alive===!0},timeout:15});let n=e.localVars[NY];if(delete e.localVars[NY],typeof n!=`number`)return;let r=e.players[n];if(!r?.alive)return;let i=Math.min(r.maxHealth,5);i>0&&await B(e,{type:`摸牌`,player:n,count:i});let a=(e.players[n]?.hand??[]).length-i;if(a>0){delete e.localVars[PY],await B(e,{type:`请求回应`,requestType:jY,target:n,prompt:{type:`useCard`,title:`节命:需弃置 ${a} 张手牌(将手牌弃至 ${i} 张)`,cardFilter:{filter:()=>!0,min:a,max:a}},mandatory:!0,timeout:15});let t=e.localVars[PY];delete e.localVars[PY],(!t||t.length===0)&&a>0&&(t=e.players[n]?.hand.slice(0,a)??[]),t&&t.length>0&&await B(e,{type:`弃置`,player:n,cardIds:t})}}function DY(e,t){let n=e.ownerId,r=[];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;if(a!==kY&&a!==AY&&a!==jY)return`当前不是节命询问`;if(a===jY){let n=Array.isArray(t.cardIds)?t.cardIds:typeof t.cardId==`string`?[t.cardId]:[];if(n.length===0)return`请选择要弃置的牌`;let r=e.players[i];if(!r?.alive)return`你已死亡`;for(let e of n)if(!r.hand.includes(e))return`弃置的牌必须在手牌中`;let a=Math.min(r.maxHealth,5),o=r.hand.length-a;if(o<=0)return`当前不需要弃牌`;if(n.length!==o)return`必须弃置 ${o} 张牌`}return null},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;if(n===kY)e.localVars[MY]=t.choice===!0;else if(n===AY){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[NY]=n)}else if(n===jY){let n=Array.isArray(t.cardIds)?t.cardIds:typeof t.cardId==`string`?[t.cardId]:[];n.length>0&&(e.localVars[PY]=n)}});r.push(a)}return r.push(N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;t.target===n&&((t.amount??0)<=0||e.state.players[n]?.alive&&(e.state.localVars[FY]=!0,await EY(e.state,n)))})),r.push(N(t,e.id,n,`死亡时`,async e=>{let t=e.atom;if(t.type===`死亡时`&&t.player===n){if(e.state.localVars[FY]){delete e.state.localVars[FY];return}await EY(e.state,n)}})),r.push(N(t,e.id,n,`伤害结算结束后`,async e=>{e.atom.target===n&&delete e.state.localVars[FY]})),()=>{for(let e of r)e()}}function OY(e,t){t.defineAction(`respond`,{label:`界节命`,style:`primary`,prompt:{type:`confirm`,title:`是否发动节命?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var kY,AY,jY,MY,NY,PY,FY,IY,Jpe=t((()=>{V(),F(),kY=`界节命/confirm`,AY=`界节命/target`,jY=`界节命/discard`,MY=`节命/confirmed`,NY=`节命/target`,PY=`节命/discardCards`,FY=`节命/伤害已触发`,IY={createSkill:TY,onInit:DY,onMount:OY}})),Ype=r({createSkill:()=>LY,default:()=>HY,onInit:()=>RY,onMount:()=>zY});function LY(e,t){return{id:e,ownerId:t,name:`界若愚`,description:`主公技/觉醒技:回合开始且体力全场最少时,增加1体力上限、回复至3点体力并永久获得"激将"`}}function RY(e,t){let n=e.ownerId;return N(t,e.id,n,`回合开始`,async e=>{if(e.atom.player!==n||e.state.players[n]?.vars[BY])return;let t=e.state.players[n];if(!t?.alive||n!==0)return;let r=e.state.players.filter(e=>e.alive);if(r.length===0)return;let i=Math.min(...r.map(e=>p(e)));if(p(t)>i)return;e.state.players[n].vars[BY]=!0,await B(e.state,{type:`设上限`,player:n,amount:t.maxHealth+1});let a=Math.max(0,VY-t.health);a>0&&await B(e.state,{type:`回复体力`,target:n,amount:a}),await B(e.state,{type:`添加技能`,player:n,skillId:`激将`})}),()=>{}}function zY(e,t){}var BY,VY,HY,Xpe=t((()=>{b(),V(),F(),BY=`界若愚/awakened`,VY=3,HY={createSkill:LY,onInit:RY,onMount:zY}})),Zpe=r({createSkill:()=>UY,default:()=>YY,onInit:()=>WY,onMount:()=>GY});function UY(e,t){return{id:e,ownerId:t,name:qY,description:`出牌阶段限一次,你可以弃置一张牌,然后失去1点体力。`}}function WY(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(X(e,n,KY))return`本回合已使用过苦肉`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;if(r.health<=0)return`体力不足,无法发动苦肉`;let i=t.cardIds??(typeof t.cardId==`string`?[t.cardId]:void 0);if(!Array.isArray(i)||i.length===0)return`需选择一张牌弃置`;if(i.length>1)return`苦肉只能弃置一张牌`;let a=i[0],o=r.hand.includes(a),s=Object.values(r.equipment).includes(a);return!o&&!s?`牌不在手牌或装备区中`:null},async(e,t)=>{let r=n;await Z(e,r,KY);let i=t.cardIds??(typeof t.cardId==`string`?[t.cardId]:[]);await I(e,qY,r,{}),await B(e,{type:`弃置`,player:r,cardIds:i,voluntary:!0}),await B(e,{type:`失去体力`,target:r,amount:1}),await L(e)}),()=>{}}function GY(e,t){return t.defineAction(`use`,{label:qY,style:`primary`,prompt:{type:`distribute`,mode:`select`,title:`苦肉:弃置一张牌,然后失去1点体力(出牌阶段限一次)`,source:`handAndEquip`,minTotal:1,maxTotal:1},activeWhen:e=>{let t=e.view.players[e.perspectiveIdx],n=(t?.handCount??0)+Object.values(t?.equipment??{}).length>0;return JY(e)&&n&&(t?.health??0)>0}}),()=>{}}var KY,qY,JY,YY,Qpe=t((()=>{V(),z(),Q(),F(),KY=`界苦肉`,qY=`苦肉`,JY=yh(KY),YY={createSkill:UY,onInit:WY,onMount:GY}})),$pe=r({createSkill:()=>XY,default:()=>$Y,onInit:()=>ZY,onMount:()=>QY});function XY(e,t){return{id:e,ownerId:t,name:`界英姿`,description:`锁定技:摸牌阶段你多摸一张牌;你的手牌上限为你的体力上限`,isLocked:!0}}function ZY(e,t){let n=e.ownerId,r=M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive)return;let r=t.count??2;return{kind:`modify`,atom:{...e.atom,count:r+1}}}),i=rp(t,n,(e,t)=>e.players[t]?.maxHealth);return()=>{r(),i()}}function QY(e,t){return()=>{}}var $Y,eme=t((()=>{F(),op(),$Y={createSkill:XY,onInit:ZY,onMount:QY}})),tme=r({createSkill:()=>eX,default:()=>pX,onInit:()=>rX,onMount:()=>iX});function eX(e,t){return{id:e,ownerId:t,name:oX,description:`出牌阶段限一次:声明一种牌的类别或颜色,连续亮出牌堆顶的牌直到亮出符合声明的牌,选择一名男性角色获得此牌,其余置入弃牌堆`}}function tX(e){return typeof e==`string`&&fX.includes(e)}function nme(e,t){return t===`基本牌`||t===`锦囊牌`||t===`装备牌`?e.type===t:e.color===t}function nX(e,t){let n=e.players[t];return n?.alive?kc(n.character)===`男`:!1}function rme(e,t){return!!e.players[t]?.vars[sX]}function rX(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i!==cX&&i!==lX)return`当前不是荐言询问`;if(i===cX){if(!tX(t.option??t.declaration))return`声明不合法(基本牌/锦囊牌/装备牌/红/黑)`}else if(i===lX){let n=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);if(typeof n!=`number`)return`需要选择目标`;if(!nX(e,n))return`目标必须是男性角色`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===cX){let n=t.option??t.declaration;tX(n)&&(e.localVars[uX]=n)}else if(r===lX){let n=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);typeof n==`number`&&(e.localVars[dX]=n)}}),j(t,e.id,n,`use`,(e,t)=>e.players[n]?.alive?e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:rme(e,n)?`本回合已使用过荐言`:e.players.some((t,n)=>nX(e,n))?e.zones.deck.length===0&&e.zones.discardPile.length===0?`牌堆已空`:null:`无男性角色可选`:`只能在出牌阶段使用`:`只能在你的回合使用`:`角色不可用`,async(e,t)=>{let r=n;e.players[r].vars[sX]=!0,await B(e,{type:`回合用量`,player:r,key:sX,value:!0}),await I(e,aX,r,{});try{delete e.localVars[uX],await B(e,{type:`请求回应`,requestType:cX,target:n,prompt:{type:`chooseOption`,title:`荐言:声明一种牌的类别(基本牌/锦囊牌/装备牌)或颜色(红/黑)`,description:`选择类别:基本牌、锦囊牌、装备牌;或颜色:红、黑。连续亮出牌堆顶直到出现符合声明的牌。`,options:fX.map(e=>({value:e,label:e}))},defaultChoice:`基本牌`,timeout:30});let t=e.localVars[uX],r=tX(t)?t:`基本牌`;delete e.localVars[uX],delete e.localVars[dX],await B(e,{type:`请求回应`,requestType:lX,target:n,prompt:{type:`choosePlayer`,title:`荐言:选择一名男性角色获得匹配的牌`,min:1,max:1,filter:(t,n)=>nX(e,n)},timeout:20});let i=e.localVars[dX];if(delete e.localVars[dX],typeof i!=`number`||!nX(e,i))return;let a=[],o;for(;e.zones.deck.length>0;){let t=e.zones.deck[e.zones.deck.length-1];await B(e,{type:`移动牌`,cardId:t,from:{zone:`牌堆`},to:{zone:`处理区`}}),a.push(t);let n=e.cardMap[t];if(n&&nme(n,r)){o=t;break}}o&&await B(e,{type:`移动牌`,cardId:o,from:{zone:`处理区`},to:{zone:`手牌`,player:i}});let s=R(e).filter(e=>a.includes(e));for(let t of s)await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}finally{await L(e)}}),()=>{}}function iX(e,t){t.defineAction(`use`,{label:oX,style:`primary`,activeWhen:e=>q(e)?!e.view.players[e.perspectiveIdx]?.turnUsage?.[sX]:!1,prompt:{type:`confirm`,title:`是否发动荐言?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var aX,oX,sX,cX,lX,uX,dX,fX,pX,ime=t((()=>{V(),z(),F(),Fc(),J(),aX=`界荐言`,oX=`荐言`,sX=`${aX}/usedThisTurn`,cX=`${aX}/declare`,lX=`${aX}/target`,uX=`${aX}/declaration`,dX=`${aX}/target`,fX=[`基本牌`,`锦囊牌`,`装备牌`,`红`,`黑`],pX={createSkill:eX,onInit:rX,onMount:iX}})),ame=r({createSkill:()=>mX,default:()=>wX,onInit:()=>vX,onMount:()=>yX});function mX(e,t){return{id:e,ownerId:t,name:bX,description:`其他角色的梅花牌因弃置或判定而置入弃牌堆后,你可以获得其中任意张牌`}}function ome(e,t){let n=e.players[t]?.vars[CX];return typeof n==`number`?n:0}function hX(e,t){let n=e.cardMap[t];return!!n&&n.suit===`♣`}async function gX(e,t,n,r){if(n.length===0||!e.players[t]?.alive)return 0;delete e.localVars[SX],await B(e,{type:`请求回应`,requestType:xX,target:t,prompt:{type:`confirm`,title:`落英:是否获得 ${n.length} 张梅花牌?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!1,timeout:10});let i=e.localVars[SX]===!0;if(delete e.localVars[SX],!i)return 0;let a=0;for(let i of n){if(r===`弃牌堆`){if(!e.zones.discardPile.includes(i))continue;await B(e,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:t}})}else{if(!R(e).includes(i))continue;await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`手牌`,player:t}})}a+=1}return a}async function _X(e,t,n){if(n<=0||e.currentPlayerIndex===t)return;let r=e.players[t];if(!r?.alive)return;let i=ome(e,t)+n;if(r.vars[CX]=i,!r.tags.some(e=>e.endsWith(`/翻面`))||i<r.maxHealth)return;delete e.localVars[`酒诗/flipChoice`],await B(e,{type:`请求回应`,requestType:`界酒诗/flipBack`,target:t,prompt:{type:`confirm`,title:`酒诗:回合外累计获得 ${i} 张"落英"牌(≥体力上限 ${r.maxHealth}),是否翻至正面?`,confirmLabel:`翻至正面`,cancelLabel:`保持背面`},defaultChoice:!1,timeout:10});let a=e.localVars[`酒诗/flipChoice`]===!0;delete e.localVars[`酒诗/flipChoice`],a&&await Oh(e,t)}function vX(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);return t?.atom.type===`请求回应`?t.atom.requestType===xX?null:`当前不是落英选择`:`当前不需要回应`},async(e,t)=>{e.localVars[SX]=t.choice===!0}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||t.player===n||!t.cardIds||t.cardIds.length===0)return;let r=t.cardIds.filter(t=>hX(e.state,t));if(r.length===0)return;let i=await gX(e.state,n,r,`弃牌堆`);await _X(e.state,n,i)}),N(t,e.id,n,`判定牌生效后`,async e=>{if(e.atom.player===n)return;let t=R(e.state);if(t.length===0||t.length>1)return;let r=t[t.length-1];if(!hX(e.state,r))return;let i=await gX(e.state,n,[r],`处理区`);await _X(e.state,n,i)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`)return;let r=e.state.players[n];r&&delete r.vars[CX]}),()=>{}}function yX(e,t){t.defineAction(`respond`,{label:bX,style:`default`,prompt:{type:`confirm`,title:`是否发动落英?`,confirmLabel:`获得`,cancelLabel:`不获得`}})}var bX,xX,SX,CX,wX,sme=t((()=>{V(),z(),Mh(),F(),bX=`落英`,xX=`界落英/choose`,SX=`落英/choice`,CX=`落英/外得计数`,wX={createSkill:mX,onInit:vX,onMount:yX}})),cme=r({createSkill:()=>TX,default:()=>BX,onInit:()=>OX,onMount:()=>kX});function TX(e,t){return{id:e,ownerId:t,name:MX,description:`每回合限一次,扣置一张手牌声明为基本牌使用/打出;其他角色可同时质疑:真→缠怨+弃牌或失1体力,假→作废+质疑者摸1牌`}}async function lme(e,t,n,r){let i=e.cardMap[r],a=i?.damageType;await I(e,`杀`,t,{cardId:r,declaredName:`杀`,target:n});let o=i?.name;i&&o!==`杀`&&(i.name=`杀`);try{if(!await B(e,{type:`成为目标`,source:t,target:n,cardId:r})||!await B(e,{type:`检测有效性`,source:t,target:n,cardId:r}))return;await B(e,{type:`询问闪`,target:n,source:t});let i=e.settlementStack[e.settlementStack.length-1],o=R(e).filter(t=>e.cardMap[t]?.name===`闪`);if(i?.cancelled||o.length>0){await B(e,{type:`被抵消`,source:t,target:n,cardId:r});let i=R(e).filter(t=>e.cardMap[t]?.name===`闪`);for(let t of i)await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}else e.players[n]?.alive&&await Dm(e,t,n,1,r,a)}finally{for(let t of R(e))e.cardMap[t]?.name===`闪`&&await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}});await L(e),i&&o!==void 0&&o!==`杀`&&(i.name=o)}uh(e),await B(e,{type:`回合用量`,player:t,key:El,value:ah(e)})}async function ume(e,t,n,r){await B(e,{type:`移动牌`,cardId:n,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:t}});let i=`${n}#界蛊惑${r}`;await B(e,{type:`当作`,player:t,cardIds:[n],shadowId:i,outputName:r}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:t},to:{zone:`处理区`}})}async function dme(e,t,n,r,i){if(n===`杀`){if(typeof r!=`number`||!e.players[r]?.alive)return;await lme(e,t,r,i)}else if(n===`桃`){let n=typeof r==`number`?r:t;if(!e.players[n]?.alive)return;await B(e,{type:`回复体力`,target:n,amount:1,source:t})}else n===`酒`&&await B(e,{type:`加标记`,player:t,mark:{id:`酒/nextKillDamageBonus`,scope:-1,payload:1,duration:`turn`}})}async function fme(e,t,n){if(await B(e,{type:`加标记`,player:t,mark:{id:`缠怨`,scope:t}}),e.players[t].hand.length>=1&&(delete e.localVars[IX+t],await B(e,{type:`请求回应`,requestType:PX,target:t,prompt:{type:`confirm`,title:`界蛊惑:弃置一张手牌,或失去1点体力?`,confirmLabel:`弃置一张手牌`,cancelLabel:`失去1点体力`},defaultChoice:!1,timeout:30}),e.localVars[IX+t]===`discard`)){await B(e,{type:`弃置`,player:t,cardIds:[...e.players[t].hand].slice(0,1)});return}await B(e,{type:`失去体力`,target:t,amount:1})}async function EX(e,t,n,r){await B(e,{type:`扣牌`,player:t,cardId:n,declaredName:r});let i=e.players.length,a=[];for(let n=1;n<i;n++){let o=(t+n)%i;if(o===t||!e.players[o]?.alive)continue;delete e.localVars[FX],await B(e,{type:`请求回应`,requestType:NX,target:o,prompt:{type:`confirm`,title:`是否质疑于吉声明为【${r}】的蛊惑?`},timeout:20});let s=e.localVars[FX];s!==void 0&&!a.includes(s)&&a.push(s)}let o=e.localVars[LX];if(a.length===0)return{voided:!1,downCard:o,questioners:[]};if(await B(e,{type:`展示`,player:t,cardId:o}),e.cardMap[o]?.name===r){for(let n of[...a].sort((e,t)=>e-t))e.players[n]?.alive&&await fme(e,n,t);return{voided:!1,downCard:o,questioners:a}}for(let t of[...a].sort((e,t)=>e-t))e.players[t]?.alive&&await B(e,{type:`摸牌`,player:t,count:1});return{voided:!0,downCard:o,questioners:a}}function DX(e){delete e.localVars[LX],delete e.localVars[FX];for(let t of Object.keys(e.localVars))t.startsWith(IX)&&delete e.localVars[t]}function OX(e,t){let n=e.ownerId,r=[];r.push(de(t,n,`询问闪`)),r.push(de(t,n,`请求回应`,`桃/求桃`));let i=r=>j(t,e.id,n,`${zX}${r}`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,jX))return`本回合已使用过蛊惑`;let i=e.players[n];if(!i?.alive)return`玩家不存在或已死亡`;let a=t.cardId;if(typeof a!=`string`||!i.hand.includes(a))return`请选择一张手牌`;if(r===`杀`){let r=t.target;if(typeof r!=`number`||!e.players[r]?.alive)return`请选择合法目标`;if(!Gm(e,n,r))return`目标不在攻击范围内`;if(!lh(e,n,a))return`出杀次数已达上限`}else if(r===`桃`){let r=t.target??n,i=e.players[r];if(!i?.alive)return`目标不存在`;if(i.health>=i.maxHealth)return`桃只能对受伤角色使用`}return null},async(e,t)=>{let i=n,a=t.cardId,o=t.target;await Z(e,i,jX),await I(e,`蛊惑`,i,{cardId:a,declaredName:r});try{let t=await EX(e,i,a,r);t.voided||await dme(e,i,r,o,t.downCard)}finally{DX(e),await L(e)}});for(let e of hme)r.push(i(e));r.push(j(t,e.id,n,`dodge`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`询问闪`)return`当前不是出闪的窗口`;if(r.atom.target!==n)return`不是问你的`;if(!e.players[n]?.alive)return`你已死亡`;if(X(e,n,jX))return`本回合已使用过蛊惑`;let i=t.cardId;return typeof i!=`string`||!e.players[n].hand.includes(i)?`请选择一张手牌`:null},async(e,t)=>{let r=n,i=t.cardId;await Z(e,r,jX),await I(e,`蛊惑`,r,{cardId:i,declaredName:`闪`});let a,o;try{let t=await EX(e,r,i,`闪`);a=!t.voided,o=t.downCard}finally{DX(e),await L(e)}a&&await ume(e,r,o,`闪`)})),r.push(j(t,e.id,n,`rescue`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`||i.requestType!==`桃/求桃`)return`当前不是求桃窗口`;if(i.target!==n)return`不是问你的`;if(!e.players[n]?.alive)return`你已死亡`;if(X(e,n,jX))return`本回合已使用过蛊惑`;let a=t.cardId;return typeof a!=`string`||!e.players[n].hand.includes(a)?`请选择一张手牌`:null},async(e,t)=>{let r=n,i=t.cardId;await Z(e,r,jX),await I(e,`蛊惑`,r,{cardId:i,declaredName:`桃`});let a;try{a=!(await EX(e,r,i,`桃`)).voided}finally{DX(e),await L(e)}a&&(e.localVars[RX]=!0)}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;return a!==NX&&a!==PX?`当前不是界蛊惑问询窗口`:e.players[i]?.alive?null:`你已死亡`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;if(n===NX){if(!(t.choice===!0||t.confirmed===!0))return;e.localVars[FX]=i}else n===PX&&(e.localVars[IX+i]=t.choice===!0?`discard`:`damage`)}))}return()=>{for(let e of r)e()}}function kX(e,t){return t.defineAction(`${zX}杀`,{label:`蛊惑·杀`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`蛊惑:扣置一张手牌,声明为【杀】使用`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,n)=>lm(e.players,e.cardMap,t.viewer,n)}},activeWhen:e=>AX(e)&&sm(e.view,e.perspectiveIdx)}),t.defineAction(`${zX}桃`,{label:`蛊惑·桃`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`蛊惑:扣置一张手牌,声明为【桃】使用`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:0,max:1,filter:(e,t)=>{let n=e.players[t];return n?.alive===!0&&n.health<n.maxHealth}},selfTarget:!0},activeWhen:e=>{if(!AX(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?.alive===!0&&t.health<t.maxHealth}}),t.defineAction(`${zX}酒`,{label:`蛊惑·酒`,style:`primary`,prompt:{type:`useCard`,title:`蛊惑:扣置一张手牌,声明为【酒】使用`,cardFilter:{filter:()=>!0,min:1,max:1}},activeWhen:e=>AX(e)}),t.defineAction(`dodge`,{label:`蛊惑·闪`,style:`primary`,prompt:{type:`useCard`,title:`蛊惑:扣置一张手牌,声明为闪打出`,cardFilter:{min:1,max:1}},activeWhen:e=>pme(e)}),t.defineAction(`rescue`,{label:`蛊惑·桃`,style:`primary`,prompt:{type:`useCard`,title:`蛊惑:扣置一张手牌,声明为桃救援`,cardFilter:{min:1,max:1}},activeWhen:e=>mme(e)}),t.defineAction(`respond`,{label:`质疑`,style:`danger`,prompt:{type:`confirm`,title:`是否质疑于吉的蛊惑?`}}),()=>{}}function AX(e){let{view:t,perspectiveIdx:n}=e,r=t.players[n];if(!r||t.currentPlayerIndex!==n||t.phase!==`出牌`)return!1;let i=t.pending;return i!=null&&i.isBlocking!==!1||r.turnUsage?.[Zc(jX)]?!1:(r.hand?.length??0)>0}function pme(e){let{view:t,perspectiveIdx:n}=e,r=t.players[n];if(!r||r.turnUsage?.[Zc(jX)]||(r.hand?.length??0)===0)return!1;let i=t.pending;return i?.target===n&&i.atom?.type===`询问闪`}function mme(e){let{view:t,perspectiveIdx:n}=e,r=t.players[n];if(!r||r.turnUsage?.[Zc(jX)]||(r.hand?.length??0)===0)return!1;let i=t.pending,a=i?.atom;return i?.target===n&&a?.type===`请求回应`&&a?.requestType===`桃/求桃`}var jX,MX,NX,PX,FX,IX,LX,RX,hme,zX,BX,gme=t((()=>{V(),z(),Om(),F(),Xm(),fh(),Q(),W(),um(),J(),jX=`界蛊惑`,MX=`蛊惑`,NX=`界蛊惑/质疑`,PX=`界蛊惑/choose`,FX=`界蛊惑/质疑者列表`,IX=`界蛊惑/choice/`,LX=`蛊惑/扣牌`,RX=`求桃/已救`,hme=[`杀`,`桃`,`酒`],zX=`use:`,BX={createSkill:TX,onInit:OX,onMount:kX}})),_me=r({createSkill:()=>VX,default:()=>ZX,onInit:()=>UX,onMount:()=>WX});function VX(e,t){return{id:e,ownerId:t,name:KX,description:`主公技:游戏开始时获得X枚裔标记(X为群势力角色数的两倍);出牌阶段开始时可移除1枚裔并摸一张牌;每枚裔手牌上限+1`}}function HX(e,t){return e.players[t]?.marks.filter(e=>e.id.startsWith(qX)).length??0}async function vme(e,t){await B(e,{type:`加标记`,player:t,mark:{id:`${qX}${e.seq}`,scope:t}})}async function yme(e,t){let n=(e.players[t]?.marks??[]).find(e=>e.id.startsWith(qX));n&&await B(e,{type:`去标记`,player:t,markId:n.id})}function bme(e){let t=0;for(let n of e.players)n.alive&&n.faction===`群`&&(t+=1);return t}function UX(e,t){let n=e.ownerId,r=rp(t,n,(e,t)=>{if(t!==n||n!==0)return;let r=e.players[t];if(!r)return;let i=sl(e.turn.vars,t)??0;return p(r)+i+HX(e,t)}),i=N(t,e.id,n,`回合开始`,async e=>{if(n!==0)return;let t=e.state;if(!t.players[n]?.alive||t.localVars[JX(n)])return;t.localVars[JX(n)]=!0;let r=bme(t)*2;for(let e=0;e<r;e++)await vme(t,n)}),a=N(t,e.id,n,`阶段开始`,async e=>{if(n!==0)return;let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`出牌`)return;let r=e.state;if(!r.players[n]?.alive||HX(r,n)<=0)return;delete r.localVars[XX],await B(r,{type:`请求回应`,requestType:YX,target:n,prompt:{type:`confirm`,title:`血裔:是否移除 1 枚裔标记并摸一张牌?`,confirmLabel:`移除裔并摸牌`,cancelLabel:`不发动`},defaultChoice:!1,timeout:20});let i=r.localVars[XX];delete r.localVars[XX],i===!0&&(await yme(r,n),r.players[n]?.alive&&await B(r,{type:`摸牌`,player:n,count:1}))});return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type!==`请求回应`||i.requestType!==YX?`当前不是血裔询问`:null},async(e,t)=>{e.localVars[XX]=t.choice===!0||t.confirmed===!0}),()=>{r(),i(),a()}}function WX(e,t){return()=>{}}var GX,KX,qX,JX,YX,XX,ZX,xme=t((()=>{b(),V(),F(),op(),W(),GX=`界血裔`,KX=`血裔`,qX=`${GX}/裔:`,JX=e=>`${GX}/init/${e}`,YX=`${GX}/use`,XX=`${GX}/useChoice`,ZX={createSkill:VX,onInit:UX,onMount:WX}})),Sme=r({createSkill:()=>$X,default:()=>sZ,onInit:()=>eZ,onMount:()=>tZ});function QX(e,t){let n=e.players[t];return n?{equipment:oZ.filter(e=>typeof n.equipment[e]==`string`).map(t=>{let r=n.equipment[t];return{slot:t,cardId:r,cardName:e.cardMap[r]?.name??`?`}}),handCount:n.hand.length}:{equipment:[],handCount:0}}function $X(e,t){return{id:e,ownerId:t,name:nZ,description:`当一名角色进入濒死状态时,可选其一张牌;若非基本牌,弃置之并回复1点体力`}}function eZ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==rZ&&a!==iZ)return`当前不是补益询问`;if(a===iZ){let n=i.prompt?.target;if(typeof n!=`number`)return`目标缺失`;let r=e.players[n];if(!r)return`目标不存在`;let a=t.zone;if(a===`equipment`){let e=t.cardId;if(typeof e!=`string`)return`cardId required`;if(!oZ.some(t=>r.equipment[t]===e))return`该牌不在目标装备区`}else if(a===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`;if(t.handIndex<0||t.handIndex>=r.hand.length)return`handIndex 越界`}else return`zone required (equipment|hand)`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===rZ?e.localVars[aZ]=t.choice===!0||t.confirmed===!0:r===iZ&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),N(t,e.id,n,`进入濒死状态时`,async e=>{let t=e.atom;if(typeof t.target!=`number`)return;let r=t.target,i=e.state.players[r];if(!i?.alive||i.health>0||!e.state.players[n]?.alive)return;let{equipment:a,handCount:o}=QX(e.state,r);if(a.length===0&&o===0)return;delete e.state.localVars[aZ],await B(e.state,{type:`请求回应`,requestType:rZ,target:n,prompt:{type:`confirm`,title:`补益:是否选择 ${i.name} 的一张牌?若非基本牌,弃置之并回复1点体力`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15});let s=e.state.localVars[aZ]===!0;if(delete e.state.localVars[aZ],!s||e.state.players[r]?.health>0)return;let{equipment:c,handCount:l}=QX(e.state,r);if(c.length===0&&l===0)return;delete e.state.localVars[Tl],l>0&&Og(e.state,r),await B(e.state,{type:`请求回应`,requestType:iZ,target:n,prompt:{type:`pickTargetCard`,title:`补益:选择目标一张牌(装备区明选,手牌盲选)`,target:r,equipment:c,judge:[],handCount:l},defaultChoice:c.length>0?{zone:`equipment`,cardId:c[0].cardId}:{zone:`hand`,handIndex:0},timeout:20});let u=e.state.localVars[Tl];delete e.state.localVars[Tl],u??=c.length>0?{zone:`equipment`,cardId:c[0].cardId,handIndex:null}:{zone:`hand`,cardId:null,handIndex:0};let d;if(u.zone===`equipment`)d=u.cardId??void 0;else if(u.zone===`hand`){let t=u.handIndex??0;d=e.state.players[r]?.hand[t]}if(!d)return;let f=e.state.players[r],p=oZ.some(e=>f?.equipment[e]===d),m=f?.hand.includes(d)??!1;!p&&!m||e.state.cardMap[d]?.type!==`基本牌`&&(await B(e.state,{type:`弃置`,player:r,cardIds:[d]}),await B(e.state,{type:`回复体力`,target:r,amount:1}))}),()=>{}}function tZ(e,t){return t.defineAction(`respond`,{label:nZ,style:`default`,prompt:{type:`confirm`,title:`补益`}}),()=>{}}var nZ,rZ,iZ,aZ,oZ,sZ,Cme=t((()=>{V(),F(),Ag(),W(),nZ=`补益`,rZ=`界补益/confirm`,iZ=`界补益/pick`,aZ=`界补益/confirmed`,oZ=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`],sZ={createSkill:$X,onInit:eZ,onMount:tZ}})),wme=r({createSkill:()=>cZ,default:()=>gZ,onInit:()=>lZ,onMount:()=>uZ});function cZ(e,t){return{id:e,ownerId:t,name:`界裸衣`,description:`摸牌阶段开始前,可亮出牌堆顶3张;可跳过摸牌阶段并获得其中的基本牌/武器牌/决斗,且直到你的下回合开始,杀/决斗伤害+1`}}function Tme(e){return e?e.name===`决斗`||e.type===`基本牌`||e.type===`装备牌`&&e.subtype===`武器`:!1}function lZ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==fZ&&a!==pZ?`当前不是界裸衣询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType,i=t.choice===!0||t.confirmed===!0;r===fZ?e.localVars[mZ]=i:r===pZ&&(e.localVars[hZ]=i)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`摸牌`||e.state.currentPlayerIndex!==n||!e.state.players[n]?.alive||X(e.state,n,`界裸衣`)||e.state.zones.deck.length<3||(delete e.state.localVars[mZ],await B(e.state,{type:`请求回应`,requestType:fZ,target:n,prompt:{type:`confirm`,title:`是否发动界裸衣?(亮出牌堆顶3张;直到你的下回合开始,你的杀/决斗伤害+1)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[mZ]!==!0))return;await Z(e.state,n,`界裸衣`);let r=e.state.zones.deck.slice(-3),i;await I(e.state,`界裸衣`,n,{});try{for(let t=r.length-1;t>=0;t--)await B(e.state,{type:`移动牌`,cardId:r[t],from:{zone:`牌堆`},to:{zone:`处理区`}});if(await B(e.state,{type:`加标签`,player:n,tag:dZ}),delete e.state.localVars[hZ],await B(e.state,{type:`请求回应`,requestType:pZ,target:n,prompt:{type:`confirm`,title:`界裸衣:是否跳过摸牌阶段并获得亮出牌中的基本牌、武器牌和【决斗】?(其余亮出牌置入弃牌堆)`,confirmLabel:`跳过并获得`,cancelLabel:`不跳过`},defaultChoice:!1,timeout:15}),i=e.state.localVars[hZ]===!0,i)for(let t of r){let r=e.state.zones.processing.includes(t),i=e.state.settlementStack[e.state.settlementStack.length-1]?.cards.includes(t)??!1;if(!r&&!i)continue;let a=e.state.cardMap[t],o=Tme(a);await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:o?{zone:`手牌`,player:n}:{zone:`弃牌堆`}})}else for(let t of r){let n=e.state.zones.processing.includes(t),r=e.state.settlementStack[e.state.settlementStack.length-1]?.cards.includes(t)??!1;!n&&!r||await B(e.state,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`牌堆`}})}}finally{await L(e.state)}if(delete e.state.localVars[mZ],delete e.state.localVars[hZ],i)return Nh(e.state,{player:n,phase:`摸牌`})}),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0||!e.state.players[n]?.tags.includes(dZ))return;let r=t.cardId;if(typeof r!=`string`)return;let i=e.state.cardMap[r];if(i&&!(i.name!==`杀`&&i.name!==`决斗`))return{kind:`modify`,atom:{...e.atom,amount:(t.amount??0)+1}}}),N(t,e.id,n,`回合开始`,async e=>{e.atom.player===n&&e.state.players[n]?.tags.includes(dZ)&&await B(e.state,{type:`去标签`,player:n,tag:dZ})}),()=>{}}function uZ(e,t){return t.defineAction(`respond`,{label:`界裸衣`,style:`primary`,prompt:{type:`confirm`,title:`是否发动界裸衣?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var dZ,fZ,pZ,mZ,hZ,gZ,Eme=t((()=>{V(),z(),Q(),F(),Ph(),dZ=`界裸衣/bonus`,fZ=`界裸衣/activate`,pZ=`界裸衣/skip`,mZ=`界裸衣/activated`,hZ=`界裸衣/skipChoice`,gZ={createSkill:cZ,onInit:lZ,onMount:uZ}})),Dme=r({createSkill:()=>_Z,default:()=>wZ,onInit:()=>yZ,onMount:()=>bZ});function _Z(e,t){return{id:e,ownerId:t,name:`界观星`,description:`准备阶段,观看牌堆顶 5 张(存活角色数<4 时为 3 张),任意排序置顶/置底;若皆置底,结束阶段可再次发动`}}function Ome(e){return e.players.filter(e=>e.alive).length<4?3:5}async function vZ(e,t){let n=e.zones.deck;if(n.length===0)return!1;let r=Ome(e),i=Math.min(r,n.length);if(i===0||(delete e.localVars[SZ],await B(e,{type:`请求回应`,requestType:`界观星/confirm`,target:t,prompt:{type:`confirm`,title:`是否发动界观星?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.localVars[SZ]))return!1;let a=n.slice(-i);delete e.localVars[CZ],await B(e,{type:`请求回应`,requestType:`界观星/arrange`,target:t,prompt:{type:`distribute`,title:`界观星:排列牌堆顶牌`,description:`选择留在牌堆顶的牌(顺序即摸牌顺序)与置于牌堆底的牌`,mode:`select`,cardIds:a,minTotal:0,maxTotal:i},defaultChoice:!1,timeout:30});let o=e.localVars[CZ];delete e.localVars[CZ],delete e.localVars[SZ];let s=o?.top??[],c=o?.bottom??[],l=new Set(a),u=[...s,...c];if(!(u.length===a.length&&new Set(u).size===u.length&&u.every(e=>l.has(e))))return!1;let d=n.slice(0,n.length-i);return await B(e,{type:`整理牌堆`,cards:[...c,...d,...[...s].reverse()],topCount:s.length,bottomCount:c.length}),s.length===0}function yZ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;return i!==`界观星/confirm`&&i!==`界观星/arrange`?`当前不是界观星询问`:i===`界观星/arrange`&&(!Array.isArray(t.top)||!Array.isArray(t.bottom))?`界观星:需要 top/bottom 划分`:null},async(e,t)=>{let r=(e.pendingSlots.get(n)?.atom).requestType;r===`界观星/confirm`?e.localVars[SZ]=t.choice===!0||t.confirmed===!0:r===`界观星/arrange`&&(e.localVars[CZ]={top:t.top??[],bottom:t.bottom??[]})}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&e.state.players[n]?.alive){if(t.phase===`准备`)delete e.state.localVars[xZ],await vZ(e.state,n)&&(e.state.localVars[xZ]=!0);else if(t.phase===`回合结束`){if(!e.state.localVars[xZ])return;delete e.state.localVars[xZ],await vZ(e.state,n)}}}),()=>{}}function bZ(e,t){t.defineAction(`respond`,{label:`界观星`,style:`default`,prompt:{type:`confirm`,title:`是否发动界观星?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var xZ,SZ,CZ,wZ,kme=t((()=>{V(),F(),xZ=`界观星/全置底`,SZ=`界观星/confirmed`,CZ=`界观星/arrangement`,wZ={createSkill:_Z,onInit:yZ,onMount:bZ}})),Ame=r({createSkill:()=>TZ,default:()=>FZ,onInit:()=>DZ,onMount:()=>OZ});function TZ(e,t){return{id:e,ownerId:t,name:AZ,description:`限定技,出牌阶段选择一名角色,令所有攻击范围内包含其的角色各选:弃一张武器牌 或 令该角色摸一张牌。第一轮发动后回合结束视为未发动`}}function jme(e){return!!e&&e.type===`装备牌`&&e.subtype===`武器`}function EZ(e,t){let n=e.players[t];if(!n)return[];let r=n.hand.filter(t=>jme(e.cardMap[t])),i=n.equipment?.武器;return i&&typeof i==`string`?[...r,i]:r}function Mme(e,t){let n=[];for(let r of e.players)r.alive&&r.index!==t&&Gm(e,r.index,t)&&n.push(r.index);return n}function DZ(e,t){let n=e.ownerId,r=[];r.push(j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(e.players[n]?.vars[jZ]===!0)return`解烦已发动过(限定技)`;if(!e.players[n]?.alive)return`玩家不存在或已死亡`;let r=t.target;return typeof r==`number`?e.players[r]?.alive?null:`目标不合法`:`需要指定目标`},async(e,t)=>{let r=n,i=t.target;e.players[r].vars[jZ]=!0,e.turn.round===1&&(e.turn.vars[MZ]=r,await B(e,{type:`回合用量`,player:r,key:MZ,value:!0})),await I(e,kZ,r,{...t,chosenTarget:i});try{let t=Mme(e,i);for(let n of t){if(!e.players[i]?.alive)break;if(!e.players[n]?.alive)continue;let t=EZ(e,n),r=`${NZ}${n}`;delete e.localVars[PZ(n)];let a=t.length>0;await B(e,{type:`请求回应`,requestType:r,target:n,prompt:{type:`confirm`,title:`解烦(目标 ${e.players[i].name}):弃一张武器牌 或 令 ${e.players[i].name} 摸一张牌?${t.length===0?`(你无武器牌,只能选令其摸牌)`:``}`,description:`confirm=true 弃一张武器牌;confirm=false(choice 取消 / 超时)令其摸一张牌`,confirmLabel:`弃武器牌`,cancelLabel:`令其摸牌`},defaultChoice:a,timeout:20});let o=e.localVars[PZ(n)];if(o===void 0?a:o===`discard`){let t=EZ(e,n);if(t.length>0){await B(e,{type:`弃置`,player:n,cardIds:[t[0]]});continue}}e.players[i]?.alive&&await B(e,{type:`摸牌`,player:i,count:1})}}finally{for(let t of Object.keys(e.localVars))t.startsWith(`${kZ}/choice/`)&&delete e.localVars[t];await L(e)}}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);return n?.atom.type===`请求回应`?(n.atom.requestType??``)===`${NZ}${i}`?null:`当前不是解烦询问`:`当前不需要回应`},async(e,t)=>{(e.pendingSlots.get(i)?.atom?.requestType??``)===`${NZ}${i}`&&(e.localVars[PZ(i)]=t.choice===!0||t.confirmed===!0?`discard`:`draw`)}))}return r.push(M(t,e.id,n,`回合结束`,async e=>{let t=e.atom;t.type===`回合结束`&&t.player===n&&e.state.turn.vars[MZ]===n&&delete e.state.players[n].vars[jZ]})),()=>{for(let e of r)e()}}function OZ(e,t){t.defineAction(`use`,{label:AZ,style:`danger`,prompt:{type:`selectTarget`,title:`解烦:选择一名角色(所有攻击范围内包含其的角色各选:弃武器 或 令其摸牌)`,targetFilter:{min:1,max:1,filter:(e,t)=>!0}},activeWhen:e=>q(e)}),t.defineAction(`respond`,{label:AZ,style:`default`,prompt:{type:`confirm`,title:`解烦`}})}var kZ,AZ,jZ,MZ,NZ,PZ,FZ,Nme=t((()=>{V(),z(),F(),Xm(),J(),kZ=`界解烦`,AZ=`解烦`,jZ=`${kZ}/used`,MZ=`${kZ}/resetOnEnd`,NZ=`${kZ}/choose/`,PZ=e=>`${kZ}/choice/${e}`,FZ={createSkill:TZ,onInit:DZ,onMount:OZ}})),Pme=r({createSkill:()=>LZ,default:()=>KZ,onInit:()=>RZ,onMount:()=>zZ});function IZ(e){return`${BZ}/source/${e}`}function LZ(e,t){return{id:e,ownerId:t,name:VZ,description:`其他角色的结束阶段,若其本回合造成过伤害,你可以对其使用一张【杀】`}}function Fme(e,t){return(e.players[t]?.hand??[]).some(t=>e.cardMap[t]?.name===`杀`)}async function Ime(e,t,n,r){e.players[n]?.alive&&await Lh(e,t,r,[n],`杀`)}function RZ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i!==HZ&&i!==UZ)return`当前不是诛害询问`;if(i===UZ){let r=t.cardId;if(typeof r!=`string`)return`需要选择一张杀`;if(e.cardMap[r]?.name!==`杀`)return`不是杀牌`;if(!e.players[n]?.hand.includes(r))return`杀不在你的手牌中`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===HZ)e.localVars[WZ]=t.choice===!0;else if(r===UZ){let n=t.cardId;e.localVars[GZ]=n}}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom,n=t.source;typeof n==`number`&&((t.amount??0)<=0||(e.state.turn.vars[IZ(n)]=!0))}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`)return;let r=t.player;if(typeof r!=`number`||r===n||!e.state.players[n]?.alive||e.state.turn.vars[IZ(r)]!==!0||!Fme(e.state,n))return;if(delete e.state.localVars[WZ],await B(e.state,{type:`请求回应`,requestType:HZ,target:n,prompt:{type:`confirm`,title:`诛害:是否对 ${e.state.players[r]?.name??`P${r}`} 使用一张杀?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[WZ]!==!0){delete e.state.localVars[WZ];return}if(delete e.state.localVars[WZ],!e.state.players[r]?.alive)return;delete e.state.localVars[GZ],await B(e.state,{type:`请求回应`,requestType:UZ,target:n,prompt:{type:`useCard`,title:`诛害:选择一张杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},timeout:15});let i=e.state.localVars[GZ];delete e.state.localVars[GZ],typeof i==`string`&&e.state.players[n]?.hand.includes(i)&&e.state.players[r]?.alive&&await Ime(e.state,n,r,i)}),()=>{}}function zZ(e,t){t.defineAction(`respond`,{label:VZ,style:`danger`,prompt:{type:`confirm`,title:`是否发动诛害?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var BZ,VZ,HZ,UZ,WZ,GZ,KZ,Lme=t((()=>{V(),Gh(),F(),BZ=`界诛害`,VZ=`诛害`,HZ=`界诛害/trigger`,UZ=`界诛害/pickKill`,WZ=`界诛害/confirmed`,GZ=`界诛害/killCardId`,KZ={createSkill:LZ,onInit:RZ,onMount:zZ}})),Rme=r({createSkill:()=>qZ,default:()=>$Z,onInit:()=>JZ,onMount:()=>YZ});function qZ(e,t){return{id:e,ownerId:t,name:`界谦逊`,description:`当延时锦囊或他人普通锦囊对你生效且你为唯一目标时,你可以将所有手牌移出游戏直到回合结束`}}function JZ(e,t){let n=e.ownerId;function r(e){return!e||e.type!==`锦囊牌`?!1:e.trickSubtype!==`延时锦囊`&&e.trickSubtype!==`响应锦囊`}function i(e){let t=e.params??{};if(e.skillId===`借刀杀人`){let e=typeof t.target==`number`?t.target:Array.isArray(t.targets)?t.targets[0]:void 0;return typeof e==`number`?[e]:[]}return Array.isArray(t.targets)?t.targets:typeof t.target==`number`?[t.target]:[]}async function a(e,t){let r=e.state.players[n];if(!r?.alive||r.hand.length===0||(delete e.state.localVars[ZZ],await B(e.state,{type:`请求回应`,requestType:XZ,target:n,prompt:{type:`confirm`,title:`是否发动谦逊?(${t};将所有手牌移出游戏直到回合结束)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[ZZ]!==!0))return;let i=e.state.players[n];if(!i||i.hand.length===0)return;let a=[...i.hand];await B(e.state,{type:`移出至暂存区`,source:n,target:n,cardIds:a,varsKey:QZ})}return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===XZ?null:`当前不是谦逊确认`:`当前不是请求回应`},async(e,t)=>{e.localVars[ZZ]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`添加延时锦囊`,async e=>{let t=e.atom;t.type===`添加延时锦囊`&&t.player===n&&await a(e,`延时锦囊${t.trick?.name?`「${t.trick.name}」`:``}对你生效`)}),N(t,e.id,n,`生效时`,async e=>{let t=e.atom;if(t.type!==`生效时`||t.target!==n)return;let o=Ke(e.state);if(!o||o.from===n)return;let s=o.cards.find(t=>r(e.state.cardMap[t]));if(!s)return;let c=i(o);c.length!==1||c[0]!==n||await a(e,`「${e.state.cardMap[s]?.name??`普通锦囊`}」对你生效`)}),N(t,e.id,n,`回合结束`,async e=>{if(e.atom.type!==`回合结束`)return;let t=e.state.players[n];if(!t)return;let r=t.vars[QZ];!Array.isArray(r)||r.length===0||await B(e.state,{type:`归还暂存牌`,player:n,varsKey:QZ})}),()=>{}}function YZ(e,t){t.defineAction(`respond`,{label:`谦逊`,style:`default`,prompt:{type:`confirm`,title:`是否发动谦逊?`,confirmLabel:`发动(将所有手牌移出游戏)`,cancelLabel:`不发动`}})}var XZ,ZZ,QZ,$Z,zme=t((()=>{V(),z(),F(),XZ=`界谦逊/trigger`,ZZ=`界谦逊/confirmed`,QZ=`界谦逊/移出`,$Z={createSkill:qZ,onInit:JZ,onMount:YZ}})),Bme=r({createSkill:()=>oQ,default:()=>_Q,onInit:()=>sQ,onMount:()=>cQ});function eQ(e,t){return`${hQ}${e}/${t}`}function tQ(e,t){return`${gQ}${e}/${t}`}function nQ(e){return e?e.name===`杀`?!0:e.type===`锦囊牌`?!wN(e)&&e.trickSubtype!==`响应锦囊`:!1:!1}function rQ(e,t,n){return t?e.localVars[eQ(t,n)]===!0:!1}function iQ(e,t,n){return t?e.localVars[tQ(t,n)]===!0:!1}async function aQ(e,t,n,r){if(delete e.localVars[pQ],await B(e,{type:`请求回应`,requestType:uQ,target:t,prompt:{type:`confirm`,title:`是否发动贞烈?(失去1点体力令此牌对你无效,然后二选一)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.localVars[pQ]!==!0||(await B(e,{type:`失去体力`,target:t,amount:1}),e.localVars[eQ(n,t)]=!0,!e.players[t]?.alive))return;delete e.localVars[mQ],await B(e,{type:`请求回应`,requestType:dQ,target:t,prompt:{type:`confirm`,title:`贞烈:选择一项(确认=获得使用者一张牌;取消=本回合结束阶段发动一次秘计)`,confirmLabel:`获得一张牌`,cancelLabel:`发动秘计`},defaultChoice:!1,timeout:15});let i=e.localVars[mQ];if(delete e.localVars[mQ],i===`gain`){let n=e.players[r];if(!n?.alive||!(n.hand.length>0||Object.keys(n.equipment).length>0))return;await kg(e,t,r,n,{mode:`obtain`,requestType:fQ,title:`贞烈:选择获得使用者的一张牌`,includeJudge:!1})}else e.players[t].vars[Qc(t)]=!0}function oQ(e,t){return{id:e,ownerId:t,name:lQ,description:`成为其他角色杀或普通锦囊的目标后,可失1体力令此牌对你无效,然后二选一:获得使用者一张牌或本回合结束阶段发动一次秘计`}}function sQ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===uQ||i===dQ)return null;if(i===fQ){let e=t.zone;if(e===`equipment`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|hand)`;return null}return`当前不是贞烈回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===uQ?e.localVars[pQ]=t.choice===!0||t.confirmed===!0:r===dQ?e.localVars[mQ]=t.choice===!0||t.confirmed===!0?`gain`:`miji`:r===fQ&&(e.localVars[Tl]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),N(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.source;if(r===void 0||r===n)return;let i=t.cardId;if(!i)return;let a=e.state.cardMap[i];nQ(a)&&(a.name!==`杀`&&a.name!==`决斗`||e.state.players[n]?.alive&&(iQ(e.state,i,n)||(e.state.localVars[tQ(i,n)]=!0,await aQ(e.state,n,i,r))))}),M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.requestType!==`无懈可击`||t.cancelTarget!==n)return;let r=Ke(e.state);if(!r||r.from===n)return;let i=r.params?.cardId;if(!i)return;let a=e.state.cardMap[i];nQ(a)&&a.name!==`杀`&&e.state.players[n]?.alive&&(iQ(e.state,i,n)||(e.state.localVars[tQ(i,n)]=!0,await aQ(e.state,n,i,r.from)))}),dC(t,e.id,n,(e,t)=>rQ(e,t?.id,n)),M(t,e.id,n,`设横置`,async e=>{if(e.atom.player!==n)return;let t=Ke(e.state);if(t?.skillId!==`铁索连环`||t.from===n)return;let r=t.params?.cardId;if(r&&!rQ(e.state,r,n)&&e.state.players[n]?.alive&&!iQ(e.state,r,n)&&(e.state.localVars[tQ(r,n)]=!0,await aQ(e.state,n,r,t.from),rQ(e.state,r,n)))return{kind:`cancel`}}),()=>{}}function cQ(e,t){t.defineAction(`respond`,{label:lQ,style:`danger`,prompt:{type:`confirm`,title:`是否发动贞烈?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var lQ,uQ,dQ,fQ,pQ,mQ,hQ,gQ,_Q,Vme=t((()=>{V(),z(),fC(),F(),EN(),Ag(),W(),lQ=`贞烈`,uQ=`界贞烈/confirm`,dQ=`界贞烈/choose`,fQ=`界贞烈/选牌`,pQ=`贞烈/confirmed`,mQ=`贞烈/choice`,hQ=`贞烈/无效/`,gQ=`贞烈/已处理/`,_Q={createSkill:oQ,onInit:sQ,onMount:cQ}})),Hme=r({createSkill:()=>vQ,default:()=>TQ,onInit:()=>yQ,onMount:()=>bQ});function vQ(e,t){return{id:e,ownerId:t,name:`趫猛`,description:`当你使用【杀】对一名角色造成伤害后,你可以弃置其区域里的一张牌。若此牌为坐骑牌,你获得之`}}function Ume(e){return!!e&&e.type===`装备牌`&&(e.subtype===`进攻马`||e.subtype===`防御马`)}function Wme(e,t){let n=e.players[t];if(!n)return{equipment:[],judge:[],handCount:0,hasCards:!1};let r=Object.entries(n.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`})),i=n.pendingTricks.map(e=>({cardId:e.card.id,cardName:e.card.name})),a=n.hand.length;return{equipment:r,judge:i,handCount:a,hasCards:r.length>0||i.length>0||a>0}}function Gme(e){return e.equipment.length>0?{zone:`equipment`,cardId:e.equipment[0].cardId}:e.judge.length>0?{zone:`judge`,cardId:e.judge[0].cardId}:{zone:`hand`,handIndex:0}}function yQ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==xQ&&a!==SQ)return`当前不是趫猛询问`;if(a===SQ){let e=t.zone;if(e===`equipment`||e===`judge`){if(typeof t.cardId!=`string`)return`cardId required`}else if(e===`hand`){if(typeof t.handIndex!=`number`)return`handIndex required`}else return`zone required (equipment|judge|hand)`}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===xQ?e.localVars[CQ]=t.choice===!0||t.confirmed===!0:r===SQ&&(e.localVars[wQ]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})}),N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0||t.target===void 0)return;let r=t.target;if(r===n||!e.state.players[r]?.alive)return;let i=t.cardId;if(typeof i!=`string`||e.state.cardMap[i]?.name!==`杀`||!e.state.players[n]?.alive)return;let a=Wme(e.state,r);if(!a.hasCards||(delete e.state.localVars[CQ],await B(e.state,{type:`请求回应`,requestType:xQ,target:n,prompt:{type:`confirm`,title:`趫猛:是否弃置目标一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[CQ]!==!0))return;let o=Gme(a);delete e.state.localVars[wQ],a.handCount>0&&Og(e.state,r);let s={type:`请求回应`,requestType:SQ,target:n,prompt:{type:`pickTargetCard`,mode:`discard`,title:`趫猛:选择目标一张牌(若是坐骑,获得之)`,target:r,equipment:a.equipment,judge:a.judge,handCount:a.handCount},defaultChoice:o,timeout:20};await B(e.state,s);let c=e.state.localVars[wQ];delete e.state.localVars[wQ];let l=s.prompt.equipment,u=o;u.zone===`equipment`&&(l.some(e=>e.cardId===u.cardId)||(u=l.length>0?{zone:`equipment`,cardId:l[0].cardId}:a.judge.length>0?{zone:`judge`,cardId:a.judge[0].cardId}:{zone:`hand`,handIndex:0}));let d=c?.zone??u.zone,f;if(d===`equipment`||d===`judge`)f=c?.cardId??u.cardId??void 0;else{let t=c?.handIndex??u.handIndex??0,n=e.state.players[r];f=n?.hand[t]??n?.hand[0]}if(!f)return;let p=e.state.cardMap[f],m=Ume(p);if(d===`judge`){let t=e.state.players[r]?.pendingTricks.find(e=>e.card.id===f);t&&(await B(e.state,{type:`移除延时锦囊`,player:r,trickName:t.name}),await B(e.state,{type:`弃置`,player:r,cardIds:[f]}))}else m?await B(e.state,{type:`获得`,player:n,cardId:f,from:r}):await B(e.state,{type:`弃置`,player:r,cardIds:[f]})}),()=>{}}function bQ(e,t){}var xQ,SQ,CQ,wQ,TQ,Kme=t((()=>{V(),F(),Ag(),xQ=`界趫猛/confirm`,SQ=`界趫猛/pick`,CQ=`趫猛/confirmed`,wQ=`趫猛/pickResult`,TQ={createSkill:vQ,onInit:yQ,onMount:bQ}})),qme=r({createSkill:()=>DQ,default:()=>MQ,onInit:()=>OQ,onMount:()=>kQ});function EQ(e){return`${e}#界连环`}function Jme(e,t){return e.players[t]?.marks.some(e=>e.id===AQ)??!1}function DQ(e,t){return{id:e,ownerId:t,name:`界连环`,description:`你可以将一张梅花牌当【铁索连环】使用或重铸;你使用【铁索连环】可以多指定一个目标(至多3名)`}}function OQ(e,t){let n=e.ownerId;return j(t,e.id,n,`recycle`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o?.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=!!u&&u.suit===`♣`;return r&&i&&a&&s&&d&&f?null:`现在不能重铸(需出牌阶段、手中梅花牌)`},async(e,t)=>{let r=n,i=t.cardId;await I(e,`界连环`,r,{...t}),await rP(e,r,i),await L(e)}),j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r?.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a),l=!!s&&s.suit===`♣`;return i?!o||!c?`牌不在手牌中`:l?null:`只能将梅花牌当铁索连环`:`你已死亡`},async(e,t)=>{let r=t.cardId,i=EQ(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`铁索连环`})},(e,t)=>{let r=t.cardId,i=EQ(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),j(t,`铁索连环`,n,`use`,(e,t)=>{let r=oe(e,n,t,{cardName:`铁索连环`});if(r)return r;let i=t.targets;if(!Array.isArray(i)||i.length<1||i.length>jQ)return`需选择一至${jQ}名角色`;for(let t of i)if(!e.players[t]?.alive)return`目标不合法`;return null},async(e,t)=>{let r=n,i=t.cardId,a=t.targets;await I(e,`铁索连环`,r,{...t}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`处理区`}});try{if(!await Bm(e,{cardName:`无懈可击`,broadcast:!0},r,r))for(let t of a)await Th(e,t,!Jme(e,t));await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}finally{R(e).includes(i)&&await B(e,{type:`移动牌`,cardId:i,from:{zone:`处理区`},to:{zone:`弃牌堆`}}),await L(e)}}),()=>{}}function kQ(e,t){t.defineAction(`recycle`,{label:`界连环·重铸`,style:`primary`,prompt:{type:`useCard`,title:`界连环:弃一张梅花手牌,摸一张牌`,cardFilter:{filter:e=>e.suit===`♣`,min:1,max:1}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.suit===`♣`)??!1:!1}}),t.defineAction(`transform`,{label:`界连环`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`界连环:将一张梅花手牌当铁索连环使用(至多3名目标)`,cardFilter:{filter:e=>e.suit===`♣`,min:1,max:1},targetFilter:{min:1,max:jQ,allowSelf:!0}},transform:t=>({name:`铁索连环`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.suit===`♣`)??!1:!1}})}var AQ,jQ,MQ,Yme=t((()=>{V(),z(),iP(),Mh(),F(),Um(),J(),AQ=`chained`,jQ=3,MQ={createSkill:DQ,onInit:OQ,onMount:kQ}})),Xme=r({createSkill:()=>NQ,default:()=>VQ,onInit:()=>PQ,onMount:()=>FQ});function NQ(e,t){return{id:e,ownerId:t,name:`界连营`,description:`被动技:当你失去所有手牌后,你可以令至多X名角色各摸一张牌(X为你失去的手牌数)`}}function PQ(e,t){let n=e.ownerId;async function r(e,t){let r=e.state.players[n];if(!r?.alive||r.hand.length!==0)return;let i=t;if(i<1||e.state.zones.deck.length===0&&e.state.zones.discardPile.length===0)return;let a=e.state.players.filter(e=>e.alive).length,o=Math.min(i,a);if(o<1||(delete e.state.localVars[RQ],await B(e.state,{type:`请求回应`,requestType:IQ,target:n,prompt:{type:`confirm`,title:`是否发动界连营?(失去${i}张手牌,令至多${o}名角色各摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[RQ]!==!0))return;delete e.state.localVars[zQ],await B(e.state,{type:`请求回应`,requestType:LQ,target:n,prompt:{type:`choosePlayer`,title:`界连营:选择至多${o}名角色(各摸一张牌)`,min:1,max:o,filter:(e,t)=>e.players[t]?.alive===!0},timeout:20});let s=e.state.localVars[zQ],c=(Array.isArray(s)?s.filter((t,n,r)=>e.state.players[t]?.alive===!0&&r.indexOf(t)===n):[]).slice(0,o);for(let t of c)await B(e.state,{type:`摸牌`,player:t,count:1})}function i(e){let t=e.localVars[BQ];return delete e.localVars[BQ],typeof t==`number`?t:void 0}return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType!==IQ&&i.requestType!==LQ?`当前不是界连营回应`:null:`当前不是请求回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===IQ)e.localVars[RQ]=t.choice===!0||t.confirmed===!0;else if(r===LQ){let n=t.targets??(typeof t.target==`number`?[t.target]:void 0);e.localVars[zQ]=n??[]}}),M(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.type===`移动牌`&&t.from.zone===`手牌`&&t.from.player===n&&(t.to.zone===`手牌`&&t.to.player===n||(e.state.localVars[BQ]=e.state.players[n]?.hand.length??0))}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.type!==`移动牌`||t.from.zone!==`手牌`||t.from.player!==n||t.to.zone===`手牌`&&t.to.player===n)return;let a=i(e.state);a!==void 0&&await r(e,a)}),M(t,e.id,n,`给予`,async e=>{let t=e.atom;t.type===`给予`&&t.from===n&&t.to!==n&&(e.state.localVars[BQ]=e.state.players[n]?.hand.length??0)}),N(t,e.id,n,`给予`,async e=>{let t=e.atom;if(t.type!==`给予`||t.from!==n||t.to===n)return;let a=i(e.state);a!==void 0&&await r(e,a)}),M(t,e.id,n,`装备`,async e=>{let t=e.atom;t.type===`装备`&&t.player===n&&(e.state.localVars[BQ]=e.state.players[n]?.hand.length??0)}),N(t,e.id,n,`装备`,async e=>{let t=e.atom;if(t.type!==`装备`||t.player!==n)return;let a=i(e.state);a!==void 0&&await r(e,a)}),M(t,e.id,n,`移出至暂存区`,async e=>{let t=e.atom;t.type===`移出至暂存区`&&t.target===n&&(e.state.localVars[BQ]=e.state.players[n]?.hand.length??0)}),N(t,e.id,n,`移出至暂存区`,async e=>{let t=e.atom;if(t.type!==`移出至暂存区`||t.target!==n)return;let a=i(e.state);a!==void 0&&await r(e,a)}),M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.type!==`获得`||t.from!==n||t.player===n)return;let r=e.state.players[n]?.hand??[];t.cardId&&r.includes(t.cardId)&&(e.state.localVars[BQ]=r.length)}),N(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.type!==`获得`||t.from!==n||t.player===n)return;let a=i(e.state);a!==void 0&&await r(e,a)}),M(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||t.player!==n)return;let r=e.state.players[n]?.hand??[];t.cardIds?.some(e=>r.includes(e))&&(e.state.localVars[BQ]=r.length)}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||t.player!==n)return;let a=i(e.state);a!==void 0&&await r(e,a)}),()=>{}}function FQ(e,t){t.defineAction(`respond`,{label:`界连营`,style:`default`,prompt:{type:`confirm`,title:`是否发动界连营?`,confirmLabel:`发动(令角色摸牌)`,cancelLabel:`不发动`}})}var IQ,LQ,RQ,zQ,BQ,VQ,Zme=t((()=>{V(),F(),IQ=`界连营/trigger`,LQ=`界连营/select`,RQ=`界连营/confirmed`,zQ=`界连营/targets`,BQ=`界连营/handBefore`,VQ={createSkill:NQ,onInit:PQ,onMount:FQ}})),Qme=r({createSkill:()=>HQ,default:()=>YQ,onInit:()=>UQ,onMount:()=>WQ});function HQ(e,t){return{id:e,ownerId:t,name:`界遗计`,description:`受到 1 点伤害后,摸两张牌,然后可以将至多两张手牌交给至多两名其他角色`}}function UQ(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==GQ&&a!==KQ)return`当前不是遗计询问`;if(a===GQ)return null;let o=t.allocation;if(!Array.isArray(o)||o.length===0)return`请选择分配方案`;if(o.length>2)return`至多交给两名其他角色`;if(o.reduce((e,t)=>e+t.cardIds.length,0)>2)return`至多交出两张手牌`;let s=new Set;for(let t of o){if(t.cardIds.length===0)return`分配数量不合法`;if(t.target===n)return`不能交给自己`;if(!e.players[t.target]?.alive)return`目标无效`;for(let r of t.cardIds){if(s.has(r))return`存在重复的牌`;if(s.add(r),!e.players[n]?.hand.includes(r))return`牌不在手牌中`}}return null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===GQ?e.localVars[qQ]=t.choice===!0||t.confirmed===!0:r===KQ&&(e.localVars[JQ]=t.allocation??null)}),N(t,e.id,n,`伤害结算结束后`,async e=>{let t=e.atom;if(t.target!==n||!e.state.players[n]?.alive)return;let r=t.amount??0;if(!(r<=0))for(let t=0;t<r&&e.state.players[n]?.alive;t++){await B(e.state,{type:`摸牌`,player:n,count:2});let t=e.state.players[n];if(!t?.alive||t.hand.length===0||!e.state.players.some((e,t)=>t!==n&&e.alive))continue;if(delete e.state.localVars[qQ],await B(e.state,{type:`请求回应`,requestType:GQ,target:n,prompt:{type:`confirm`,title:`遗计:是否将至多两张手牌交给至多两名其他角色?`,confirmLabel:`交牌`,cancelLabel:`不交`},defaultChoice:!1,timeout:15}),!e.state.localVars[qQ]){delete e.state.localVars[qQ];continue}delete e.state.localVars[JQ],await B(e.state,{type:`请求回应`,requestType:KQ,target:n,prompt:{type:`distribute`,mode:`allocate`,title:`遗计:将至多两张手牌交给至多两名其他角色`,source:`hand`,minPerTarget:1,maxPerTarget:2,minTotal:1,maxTotal:2,allowSelf:!1,targetFilter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0},timeout:30});let r=e.state.localVars[JQ];if(delete e.state.localVars[qQ],delete e.state.localVars[JQ],!(!Array.isArray(r)||r.length===0)&&!(r.length>2)&&!(r.reduce((e,t)=>e+t.cardIds.length,0)>2)){for(let t of r)if(t.target!==n&&e.state.players[t.target]?.alive)for(let r of t.cardIds)e.state.players[n]?.hand.includes(r)&&await B(e.state,{type:`给予`,cardId:r,from:n,to:t.target})}}}),()=>{}}function WQ(e,t){t.defineAction(`respond`,{label:`界遗计`,style:`primary`,prompt:{type:`confirm`,title:`是否发动遗计?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var GQ,KQ,qQ,JQ,YQ,$me=t((()=>{V(),F(),GQ=`界遗计/giveConfirm`,KQ=`界遗计/giveCard`,qQ=`遗计/confirmed`,JQ=`遗计/allocation`,YQ={createSkill:HQ,onInit:UQ,onMount:WQ}})),ehe=r({createSkill:()=>XQ,default:()=>n$,onInit:()=>QQ,onMount:()=>$Q});function XQ(e,t){return{id:e,ownerId:t,name:`界酒池`,description:`转化技:黑桃手牌当酒使用,无次数限制;使用酒杀造成伤害后本回合崩坏失效`}}function ZQ(e){return`${e}#界酒池`}function QQ(e,t){let n=e.ownerId,r=t.players[n];r&&!r.tags.includes(t$)&&r.tags.push(t$),j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=!E(e),a=e.players[n],o=a.alive===!0,s=t.cardId,c=typeof s==`string`,l=c?e.cardMap[s]:void 0,u=c&&a.hand.includes(s),d=!!l&&l.suit===`♠`;return r&&i&&o&&u&&d?null:`现在不能使用界酒池`},async(e,t)=>{let r=t.cardId,i=ZQ(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`酒`})},(e,t)=>{let r=t.cardId,i=ZQ(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),N(t,e.id,n,`去标记`,async e=>{let t=e.atom;t.type===`去标记`&&t.player===n&&t.markId===`酒/nextKillDamageBonus`&&(e.state.turn.vars[e$]=!0)});let i=de(t,n,`请求回应`,`桃/求桃`);return()=>{let e=t.players[n];e&&(e.tags=e.tags.filter(e=>e!==t$)),i()}}function $Q(e,t){t.defineAction(`transform`,{label:`界酒池`,style:`passive`,prompt:{type:`useCard`,title:`选择一张黑桃手牌当酒使用(无次数限制;酒杀造成伤害后本回合崩坏失效)`,cardFilter:{filter:e=>e.suit===`♠`,min:1,max:1}},transform:t=>({name:`酒`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.suit===`♠`)??!1:!1}})}var e$,t$,n$,the=t((()=>{F(),V(),J(),e$=`崩坏/disabled`,t$=`酒/无次数限制`,n$={createSkill:XQ,onInit:QQ,onMount:$Q}})),nhe=r({FLIP_BACK_KEY:()=>h$,FLIP_BACK_RT:()=>m$,createSkill:()=>r$,default:()=>g$,onInit:()=>a$,onMount:()=>o$});function r$(e,t){return{id:e,ownerId:t,name:c$,description:`翻面视为使用酒;背面朝上时落英牌增强;受伤后或回合外累计获X张落英牌后可翻回正面`}}function i$(e){return e.some(e=>e.endsWith(`/翻面`))}async function rhe(e,t){let n=(e.players[t]?.tags??[]).filter(e=>e.endsWith(`/翻面`));for(let r of n)await B(e,{type:`去标签`,player:t,tag:r});n.length>0&&await B(e,{type:`翻面后`,player:t,faceDown:!1})}async function ihe(e,t){let n=`${s$}:酒:${t}:${e.seq}`;e.cardMap[n]={id:n,name:`酒`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,n,[t],`酒`,{virtual:!0}),delete e.cardMap[n]}function a$(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o?.alive===!0,c=!i$(o?.tags??[]);return r&&i&&a&&s&&c?null:`现在不能发动酒诗`},async(e,t)=>{await I(e,s$,n,{});try{await B(e,{type:`加标签`,player:n,tag:l$}),await B(e,{type:`翻面后`,player:n,faceDown:!0}),await ihe(e,n)}finally{await L(e)}}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;return i!==u$&&i!==f$&&i!==`界酒诗/flipBack`?`当前不是酒诗询问`:null},async(e,t)=>{let r=(e.pendingSlots.get(n)?.atom).requestType,i=t.choice===!0;r===u$?e.localVars[d$]=i:r===f$?e.localVars[p$]=i:r===`界酒诗/flipBack`&&(e.localVars[h$]=i)}),N(t,e.id,n,`受到伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=e.state.players[n];if(!r?.alive||!i$(r.tags))return;delete e.state.localVars[p$],await B(e.state,{type:`请求回应`,requestType:f$,target:n,prompt:{type:`confirm`,title:`酒诗:受到伤害后,是否将武将牌翻至正面?`,confirmLabel:`翻至正面`,cancelLabel:`保持背面`},defaultChoice:!1,timeout:10});let i=e.state.localVars[p$]===!0;delete e.state.localVars[p$],i&&await rhe(e.state,n)}),()=>{}}function o$(e,t){t.defineAction(`use`,{label:c$,style:`primary`,prompt:{type:`confirm`,title:`是否发动酒诗?(翻至背面,视为使用一张酒)`,confirmLabel:`发动`,cancelLabel:`不发动`},activeWhen:e=>!(e.view.currentPlayerIndex!==e.perspectiveIdx||e.view.phase!==`出牌`||!e.view.players[e.perspectiveIdx])}),t.defineAction(`respond`,{label:c$,style:`default`,prompt:{type:`confirm`,title:`酒诗`,confirmLabel:`确认`,cancelLabel:`取消`}})}var s$,c$,l$,u$,d$,f$,p$,m$,h$,g$,ahe=t((()=>{V(),z(),F(),Gh(),s$=`界酒诗`,c$=`酒诗`,l$=`酒诗/翻面`,u$=`界酒诗/confirm`,d$=`酒诗/useConfirmed`,f$=`界酒诗/damageFlip`,p$=`酒诗/damageFlipChoice`,m$=`界酒诗/flipBack`,h$=`酒诗/flipChoice`,g$={createSkill:r$,onInit:a$,onMount:o$}})),ohe=r({createSkill:()=>_$,default:()=>E$,onInit:()=>b$,onMount:()=>x$});function _$(e,t){return{id:e,ownerId:t,name:S$,description:`你或相邻角色的【杀】因弃置置入弃牌堆后,将之置于你的武将牌上为"醇";濒死时你可移去X张"醇"视为一张【酒】(X为本轮以此法使用酒的次数)`}}function v$(e,t){let n=e.players[t].vars[C$];return Array.isArray(n)?n:[]}function she(e,t){let n=e.players.length;if(n<=1)return[];let r=(t-1+n)%n,i=(t+1)%n,a=[];return r!==t&&e.players[r]?.alive&&a.push(r),i!==t&&i!==r&&e.players[i]?.alive&&a.push(i),a}function y$(e,t){let n=e.players[t],r=n.vars[T$],i=e.turn.round;return r!==i&&(n.vars[w$]=0,n.vars[T$]=i),(n.vars[w$]??0)+1}function b$(e,t){let n=e.ownerId;N(t,e.id,n,`弃置`,async e=>{let t=e.atom,r=t.player;if(r!==n&&!she(e.state,n).includes(r))return;let i=t.cardIds.filter(t=>{let n=e.state.cardMap[t];return!!n&&n.name===`杀`});if(i.length===0)return;let a=v$(e.state,n),o=new Set(a);for(let e of i)o.has(e)||(a.push(e),o.add(e));e.state.players[n].vars[C$]=a}),j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(!t)return`当前不需要回应`;if(t.atom.target!==n)return`不是问你的`;if(t.atom.type!==`请求回应`||t.atom.requestType!==`桃/求桃`)return`当前不是求桃`;let r=y$(e,n);return v$(e,n).length<r?`醇数不足`:null},async e=>{let t=y$(e,n),r=v$(e,n),i=r.splice(0,t);e.players[n].vars[C$]=r;let a=e.players[n].vars[w$]??0;e.players[n].vars[w$]=a+1,e.localVars[`求桃/已救`]=!0,e.localVars[`醇醪/lastUsed`]=i});let r=de(t,n,`请求回应`,`桃/求桃`);return()=>{r()}}function x$(e,t){t.defineAction(`respond`,{label:`醇醪`,style:`primary`,respondFor:`桃/求桃`,prompt:{type:`confirm`,title:`醇醪:移去 X 张"醇"视为一张【酒】救援?`,confirmLabel:`移醇当酒`,cancelLabel:`不发动`}})}var S$,C$,w$,T$,E$,che=t((()=>{F(),S$=`醇醪`,C$=`醇醪/醇`,w$=`醇醪/usedThisRound`,T$=`醇醪/lastRound`,E$={createSkill:_$,onInit:b$,onMount:x$}})),lhe=r({SUPPRESSION_TAG:()=>A$,createSkill:()=>D$,default:()=>I$,onInit:()=>O$,onMount:()=>k$});function D$(e,t){return{id:e,ownerId:t,name:`界铁骑`,description:`使用杀指定目标后,可令其本回合非锁定技失效并判定;除非其弃一张与判定结果同花色的牌,否则不能抵消此杀`}}function O$(e,t){let n=e.ownerId,r=je(t,(e,t,n)=>e.players[t]?.tags.includes(A$)===!0);for(let n of t.players){let r=n.index;j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return`当前不需要回应`;let i=n.atom;if(i.type!==`请求回应`)return`当前不是请求回应`;if(i.requestType===`界铁骑/confirm`)return null;if(i.requestType===F$){let n=t.cardId;if(typeof n!=`string`)return`请选择一张手牌弃置`;if(!e.players[r].hand.includes(n))return`牌不在手牌中`;let i=e.localVars[N$(r)],a=e.cardMap[n];return!i||!a?`无法校验花色`:a.suit===i?null:`花色与判定结果不符`}return`当前不是铁骑回应`},async(e,t)=>{let n=e.pendingSlots.get(r)?.atom?.requestType;n===`界铁骑/confirm`?e.localVars[j$]=t.choice===!0||t.confirmed===!0:n===F$&&(e.localVars[P$]=t.cardId)})}return N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0)return;let r=t.target;if(t.cardId!==void 0&&e.state.cardMap[t.cardId]?.name!==`杀`)return;let i=e.state.players[r];i?.alive&&e.state.zones.deck.length!==0&&(delete e.state.localVars[j$],await B(e.state,{type:`请求回应`,requestType:`界铁骑/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动铁骑(令目标本回合非锁定技失效并判定)?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[j$]&&(i.tags.includes(`界铁骑/非锁定技失效`)||await B(e.state,{type:`加标签`,player:r,tag:A$}),e.state.localVars[M$]=r,await jm(e.state,n,`铁骑`)))}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.judgeType!==`铁骑`||t.player!==n)return;let r=e.state.localVars[M$];if(delete e.state.localVars[M$],r===void 0||!e.state.players[r]?.alive)return;let i=R(e.state);if(i.length===0)return;let a=i[i.length-1],o=e.state.cardMap[a];if(!o)return;let s=o.suit||``;e.state.localVars[N$(r)]=s}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r===void 0)return;let i=N$(r),a=e.state.localVars[i];if(a===void 0)return;let o=e.state.players[r];if(!o?.alive)return;if(!o.hand.some(t=>e.state.cardMap[t]?.suit===a))return delete e.state.localVars[i],{kind:`cancel`};delete e.state.localVars[P$],await B(e.state,{type:`请求回应`,requestType:F$,target:r,prompt:{type:`useCard`,title:`界铁骑:弃置一张${a}花色手牌,否则不能出闪抵消此杀`,cardFilter:{filter:e=>e.suit===a,min:1,max:1}},timeout:15}),delete e.state.localVars[i];let s=e.state.localVars[P$];if(delete e.state.localVars[P$],s&&o.hand.includes(s)){await B(e.state,{type:`弃置`,player:r,cardIds:[s]});return}return{kind:`cancel`}}),N(t,e.id,n,`回合结束`,async e=>{if(e.atom.player===n)for(let t of e.state.players)t.tags.includes(`界铁骑/非锁定技失效`)&&await B(e.state,{type:`去标签`,player:t.index,tag:A$})}),()=>{r()}}function k$(e,t){t.defineAction(`respond`,{label:`铁骑`,style:`default`,prompt:{type:`confirm`,title:`是否发动铁骑判定?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var A$,j$,M$,N$,P$,F$,I$,uhe=t((()=>{V(),z(),Fm(),F(),Pe(),A$=`界铁骑/非锁定技失效`,j$=`铁骑/confirmed`,M$=`铁骑/target`,N$=e=>`界铁骑/suit/${e}`,P$=`铁骑/discardCard`,F$=`界铁骑/discard`,I$={createSkill:D$,onInit:O$,onMount:k$}})),dhe=r({createSkill:()=>L$,default:()=>a1,onInit:()=>B$,onMount:()=>V$});function L$(e,t){return{id:e,ownerId:t,name:U$,description:`准备阶段,弃置一名角色X张牌(X为其手牌数减体力值且至少为1),然后选择:1.你弃置等量非装备牌数的牌;2.结束阶段其摸等量非装备牌数的牌`}}function R$(e){let t=Object.values(e.equipment).filter(e=>!!e).length;return e.hand.length+t}function z$(e){return Math.max(1,e.hand.length-p(e))}function fhe(e,t,n){let r=new Set(Object.values(e.players[t]?.equipment??{}).filter(e=>!!e));return n.filter(e=>!r.has(e)).length}function B$(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a!==K$&&a!==q$&&a!==J$&&a!==Y$&&a!==X$)return`当前不是界镇军回应`;if(a===K$)return null;if(a===q$)return((typeof t.target==`number`?t.target:void 0)??(Array.isArray(t.targets)&&typeof t.targets[0]==`number`?t.targets[0]:void 0))===void 0?`需要选择目标`:null;if(a===J$){let n=t.cardIds;if(!Array.isArray(n))return`需要选择牌`;let r=e.localVars[n1],i=e.localVars[r1];if(typeof r!=`number`)return`询问上下文异常`;let a=e.players[r];if(!a)return`目标不存在`;let o=new Set(Object.values(a.equipment).filter(e=>!!e));for(let e of n){if(typeof e!=`string`)return`cardIds 必须为字符串数组`;if(!a.hand.includes(e)&&!o.has(e))return`牌不在目标区域`}return typeof i==`number`&&n.length!==i?`需要选择 ${i} 张牌`:new Set(n).size===n.length?null:`不能重复选牌`}if(a===Y$){let r=t.option;if(r!==`self`&&r!==`defer`)return typeof t.choice==`boolean`?null:`option 必须为 'self' 或 'defer'`;if(r===`self`){let t=e.localVars[i1],r=e.players[n]?.hand.length??0;if(typeof t==`number`&&r<t)return`手牌不足,不能选选项1(需 ${t} 张)`}return null}let o=t.cardIds;if(!Array.isArray(o))return`需要选择牌`;let s=e.localVars[i1],c=e.players[n];if(!c)return`玩家不存在`;for(let e of o){if(typeof e!=`string`)return`cardIds 必须为字符串数组`;if(!c.hand.includes(e))return`牌不在自己手牌中`}return typeof s==`number`&&o.length!==s?`需要选择 ${s} 张牌`:new Set(o).size===o.length?null:`不能重复选牌`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===K$)e.localVars[Z$]=t.choice===!0;else if(r===q$){let n=(typeof t.target==`number`?t.target:void 0)??(Array.isArray(t.targets)&&typeof t.targets[0]==`number`?t.targets[0]:void 0);typeof n==`number`&&(e.localVars[Q$]=n)}else if(r===J$)e.localVars[$$]=t.cardIds;else if(r===Y$){let n=t.option;n===`self`||n===`defer`?e.localVars[e1]=n:e.localVars[e1]=t.choice===!0?`self`:`defer`}else r===X$&&(e.localVars[t1]=t.cardIds)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.phase===`准备`&&t.player===n&&e.state.currentPlayerIndex===n&&e.state.players[n]?.alive&&!e.state.turn.vars[W$]&&e.state.players.some((e,t)=>t!==n&&e.alive&&R$(e)>0)){await I(e.state,H$,n,{}),e.state.turn.vars[W$]=!0;try{if(delete e.state.localVars[Z$],await B(e.state,{type:`请求回应`,requestType:K$,target:n,prompt:{type:`confirm`,title:`是否发动镇军?(弃置一名角色X张牌,X为其手牌数减体力值且至少为1)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[Z$]!==!0){delete e.state.turn.vars[W$];return}delete e.state.localVars[Q$],await B(e.state,{type:`请求回应`,requestType:q$,target:n,prompt:{type:`choosePlayer`,title:`镇军:选择一名角色(弃置其X张牌,X为其手牌数减体力值且至少为1)`,min:1,max:1,filter:(t,r)=>{if(r===n)return!1;let i=e.state.players[r];if(!i?.alive)return!1;let a=z$(i);return R$(i)>=a}},timeout:20});let t=e.state.localVars[Q$];if(typeof t!=`number`||!e.state.players[t]?.alive){delete e.state.turn.vars[W$];return}let r=e.state.players[t],i=z$(r);if(R$(r)<i){delete e.state.turn.vars[W$];return}delete e.state.localVars[$$],e.state.localVars[n1]=t,e.state.localVars[r1]=i,await B(e.state,{type:`请求回应`,requestType:J$,target:n,prompt:{type:`distribute`,mode:`select`,title:`镇军:选择 ${r.name} 的 ${i} 张牌弃置(可从手牌或装备区)`,cardIds:[...r.hand,...Object.values(r.equipment).filter(e=>!!e)],minTotal:i,maxTotal:i},timeout:30});let a=e.state.localVars[$$],o=Array.isArray(a)?a:[];if(o.length!==i){delete e.state.turn.vars[W$];return}let s=fhe(e.state,t,o);await B(e.state,{type:`弃置`,player:t,cardIds:o});let c=e.state.players[n].hand.length>=s;if(delete e.state.localVars[e1],e.state.localVars[i1]=s,await B(e.state,{type:`请求回应`,requestType:Y$,target:n,prompt:{type:`confirm`,title:s===0?`镇军:其中无非装备牌,两选项均无额外效果`:c?`镇军:选项1(你弃置 ${s} 张手牌) 还是 选项2(结束阶段 ${r.name} 摸 ${s} 张)?`:`镇军:手牌不足 ${s} 张,只能选选项2(结束阶段 ${r.name} 摸 ${s} 张)`,confirmLabel:c?`选项1:弃置 ${s} 张`:`(手牌不足)`,cancelLabel:`选项2:${r.name} 摸 ${s} 张`},defaultChoice:!1,timeout:20}),(e.state.localVars[e1]===`self`&&c?`self`:`defer`)==`self`){if(s>0){delete e.state.localVars[t1],await B(e.state,{type:`请求回应`,requestType:X$,target:n,prompt:{type:`distribute`,mode:`select`,title:`镇军:选择你自己的 ${s} 张手牌弃置`,source:`hand`,minTotal:s,maxTotal:s},timeout:30});let t=e.state.localVars[t1],r=Array.isArray(t)?t:[];r.length>0&&await B(e.state,{type:`弃置`,player:n,cardIds:r})}}else s>0&&(e.state.turn.vars[G$]={target:t,count:s})}finally{await L(e.state)}}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n)return;let r=e.state.turn.vars[G$];r&&(delete e.state.turn.vars[G$],e.state.players[r.target]?.alive&&await B(e.state,{type:`摸牌`,player:r.target,count:r.count}))}),()=>{}}function V$(e,t){t.defineAction(`respond`,{label:U$,style:`primary`,prompt:{type:`confirm`,title:`镇军`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var H$,U$,W$,G$,K$,q$,J$,Y$,X$,Z$,Q$,$$,e1,t1,n1,r1,i1,a1,phe=t((()=>{b(),V(),z(),F(),H$=`界镇军`,U$=`镇军`,W$=`${H$}/usedThisTurn`,G$=`${H$}/deferDraw`,K$=`${H$}/askUse`,q$=`${H$}/askTarget`,J$=`${H$}/askCards`,Y$=`${H$}/askOption`,X$=`${H$}/askOwn`,Z$=`${H$}/use`,Q$=`${H$}/target`,$$=`${H$}/cards`,e1=`${H$}/option`,t1=`${H$}/ownCards`,n1=`${H$}/ctx/target`,r1=`${H$}/ctx/x`,i1=`${H$}/ctx/n`,a1={createSkill:L$,onInit:B$,onMount:V$}})),mhe=r({createSkill:()=>o1,default:()=>f1,onInit:()=>s1,onMount:()=>c1});function o1(e,t){return{id:e,ownerId:t,name:`闭月`,description:`结束阶段,若你没有手牌,你可以摸两张牌,否则你可以摸一张牌`}}function s1(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===u1?null:`当前不是闭月确认`:`当前不需要回应`},async(e,t)=>{e.localVars[d1]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n)return;let r=e.state.players[n];if(!r?.alive)return;let i=r.hand.length===0?2:1,a=i===2?`两张牌`:`一张牌`;delete e.state.localVars[d1],await B(e.state,{type:`请求回应`,requestType:u1,target:n,prompt:{type:`confirm`,title:`是否发动闭月?(摸${a})`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[d1]&&await B(e.state,{type:`摸牌`,player:n,count:i})}),()=>{}}function c1(e,t){return t.defineAction(`respond`,{label:`闭月`,style:`primary`,prompt:{type:`confirm`,title:`是否发动闭月?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var l1,u1,d1,f1,hhe=t((()=>{V(),F(),l1=`界闭月`,u1=`${l1}/confirm`,d1=`${l1}/confirmed`,f1={createSkill:o1,onInit:s1,onMount:c1}})),ghe=r({createSkill:()=>p1,default:()=>y1,onInit:()=>h1,onMount:()=>g1});function p1(e,t){return{id:e,ownerId:t,name:v1,description:`出牌阶段限一次,选择任意名势力各不相同的其他角色,弃置你和这些角色的各一张牌,被弃置黑桃牌的角色各摸一张牌`}}function m1(e,t){let n=e.players[t];if(!n)return[];let r=[...n.hand];for(let e of Object.values(n.equipment))e&&r.push(e);return r}function _he(e,t){let n=m1(e,t);if(n.length===0)return null;let r=Ud(e.rngSeed),i=r.nextInt(n.length);return e.rngSeed=r.getState(),n[i]}function h1(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,_1))return`本回合已使用过除疠`;let r=e.players[n];if(!r?.alive)return`角色不可用`;let i=t.cardId;if(typeof i!=`string`)return`cardId required`;let a=r.hand.includes(i),o=Object.values(r.equipment).includes(i);if(!a&&!o)return`牌不在手牌或装备区中`;let s=t.targets;if(!Array.isArray(s))return`targets required`;if(s.length===0)return`至少选择一名目标`;let c=new Set;for(let t of s){if(typeof t!=`number`)return`目标必须是数字`;if(t===n)return`不能以自己为目标`;let r=e.players[t];if(!r?.alive)return`目标已死亡`;if(m1(e,t).length===0)return`目标无可弃置的牌`;let i=r.faction??`群`;if(c.has(i))return`势力 ${i} 已有目标,势力必须各不相同`;c.add(i)}return null},async(e,t)=>{let r=n,i=t.cardId,a=t.targets??[];await Z(e,r,_1),await I(e,_1,r,{...t});let o=[];await B(e,{type:`弃置`,player:r,cardIds:[i],voluntary:!0}),o.push({cardId:i,owner:r});for(let t of a){let n=_he(e,t);n!==null&&(await B(e,{type:`弃置`,player:t,cardIds:[n]}),o.push({cardId:n,owner:t}))}for(let{cardId:t,owner:n}of o)e.cardMap[t]?.suit===`♠`&&await B(e,{type:`摸牌`,player:n,count:1});await L(e)}),()=>{}}function g1(e,t){t.defineAction(`use`,{label:v1,style:`primary`,prompt:{type:`useCardAndTarget`,title:`除疠:弃你和势力各不相同的其他角色各一张牌,被弃黑桃者各摸一张`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:99,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players.find(e=>e.index===t);return!(!n||n.alive===!1)}}},activeWhen:e=>yh(_1)(e)})}var _1,v1,y1,vhe=t((()=>{V(),z(),Wd(),Q(),F(),_1=`界除疠`,v1=`除疠`,y1={createSkill:p1,onInit:h1,onMount:g1}})),yhe=r({createSkill:()=>b1,default:()=>j1,onInit:()=>S1,onMount:()=>C1});function bhe(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function b1(e,t){return{id:e,ownerId:t,name:T1,description:`出牌阶段限一次,与一名角色拼点:赢则本回合对其使用牌无距离和次数限制且无视防具,可多指定其为目标;没赢则本回合不能对其使用杀,且你的杀不计入手牌上限`}}function x1(e){let t=A1.get(e);return t||(t=new Map,A1.set(e,t)),t}function S1(e,t){let n=e.ownerId,r=eh(t,n,(e,t)=>typeof e.turn.vars[O1]==`number`&&t===n),i=Jm(t,n,(e,t,r)=>e.turn.vars[O1]===r&&t===n),a=rp(t,n,(e,t)=>{if(t!==n||typeof e.turn.vars[k1]!=`number`)return;let r=e.players[t];if(!r)return;let i=r.hand.filter(t=>e.cardMap[t]?.name===`杀`).length;if(i===0)return;let a=sl(e.turn.vars,t)??0;return p(r)+a+i});j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(X(e,n,w1))return`本回合已使用过陷阵`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;if(typeof i!=`string`)return`需要选择一张拼点牌`;if(!r.hand.includes(i))return`拼点牌不在手牌中`;let a=t.target;if(typeof a!=`number`)return`需要选择拼点目标`;if(a===n)return`不能与自己拼点`;let o=e.players[a];return o?.alive?o.hand.length===0?`目标没有手牌,无法拼点`:null:`目标不存在或已死亡`},async(e,t)=>{let r=n,i=t.cardId,a=t.target;await Z(e,r,w1),await I(e,w1,r,{...t});let o=e.cardMap[i],s=o?bhe(o.rank):0;delete e.localVars[E1],await B(e,{type:`请求回应`,requestType:D1,target:a,prompt:{type:`useCard`,title:`陷阵:与 ${e.players[r].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let c=e.localVars[E1];delete e.localVars[E1];let l;c&&e.players[a].hand.includes(c)?l=await xb(e,r,a,i,c)===`赢`:(await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`弃牌堆`}}),l=s>0),l?(e.turn.vars[O1]=a,await B(e,{type:`回合用量`,player:r,key:O1,value:a}),await B(e,{type:`回合用量`,player:r,key:qc(`界陷阵`),value:!0})):(e.turn.vars[k1]=a,await B(e,{type:`回合用量`,player:r,key:k1,value:a})),await L(e)});for(let n of t.players){let r=n.index;j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return`当前不需要回应`;let i=n.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==D1)return`当前不是陷阵回应`;if(i.target!==r)return`不是问你的`;let a=t.cardId;return typeof a==`string`?e.players[r].hand.includes(a)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`},async(e,t)=>{let n=e.pendingSlots.get(r);if(!n)return;let i=n.atom;i.type!==`请求回应`||i.requestType!==D1||(e.localVars[E1]=t.cardId)})}N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n)return;let r=e.state.turn.vars[O1];if(typeof r!=`number`||t.target!==r)return;let i=t.cardId;if(typeof i!=`string`||e.state.cardMap[i]?.name!==`杀`)return;let a=e.state.players[r];if(!a)return;let o=a.equipment?.防具;if(!o)return;let s=e.state.cardMap[o];if(!s)return;let c=s.name;!c||!a.skills.includes(c)||x1(e.state).has(r)||(d9(e.state,c,r),x1(e.state).set(r,{target:r,skillId:c}))});for(let r of[`造成伤害后`,`被抵消`])N(t,e.id,n,r,async e=>{let t=e.atom;if(t.source!==n)return;let r=e.state.turn.vars[O1];if(typeof r!=`number`||t.target!==r)return;let i=x1(e.state).get(r);i&&(await f9(e.state,i.skillId,r),x1(e.state).delete(r))});return M(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.source!==n)return;let r=e.state.turn.vars[k1];if(typeof r!=`number`||t.target!==r)return;let i=t.cardId;if(typeof i==`string`&&e.state.cardMap[i]?.name===`杀`)return{kind:`cancel`}}),()=>{r(),a(),i()}}function C1(e,t){t.defineAction(`use`,{label:T1,style:`danger`,prompt:{type:`useCardAndTarget`,title:`选择一张手牌与一名其他角色拼点(陷阵)`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.players[t];return!n?.alive||n.index===e.currentPlayerIndex?!1:(n.handCount??0)>0}}},activeWhen:e=>{if(!q(e)||!yh(w1)(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?(t.handCount??0)>0:!1}})}var w1,T1,E1,D1,O1,k1,A1,j1,xhe=t((()=>{b(),V(),z(),Sb(),F(),v9(),Q(),fh(),W(),op(),Xm(),J(),w1=`界陷阵`,T1=`陷阵`,E1=`${w1}/targetCard`,D1=`${w1}/拼点`,O1=Nl,k1=`陷阵/lostTarget`,A1=new WeakMap,j1={createSkill:b1,onInit:S1,onMount:C1}})),She=r({createSkill:()=>N1,default:()=>z1,onInit:()=>P1,onMount:()=>F1});function M1(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function Che(e){return!!e.shadowOf||e.id.includes(`#`)}function N1(e,t){return{id:e,ownerId:t,name:`界集智`,description:`被动技:使用非转化锦囊牌时你可以摸一张牌;若此牌是基本牌,可弃之令本回合手牌上限+1`}}function P1(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=M1(e,n);return t!==L1&&t!==R1?`当前不是集智询问`:null},async(e,t)=>{let r=M1(e,n);r===L1?e.localVars[`界集智/confirmed`]=t.choice===!0||t.confirmed===!0:r===R1&&(e.localVars[`界集智/discard`]=t.choice===!0||t.confirmed===!0)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(!t.cardId)return;let r=t.from,i=t.to;if(r?.zone!==`手牌`||r.player!==n||!i||i.zone!==`处理区`&&i.zone!==`弃牌堆`)return;let a=e.state.cardMap[t.cardId];if(!a||a.type!==`锦囊牌`||!I1.has(a.name)||Che(a)||!e.state.players[n]?.alive||(delete e.state.localVars[`界集智/confirmed`],await B(e.state,{type:`请求回应`,requestType:L1,target:n,prompt:{type:`confirm`,title:`是否发动集智摸一张牌?`,confirmLabel:`摸牌`,cancelLabel:`不摸`},defaultChoice:!0,timeout:15}),!e.state.localVars[`界集智/confirmed`]))return;let o=e.state.players[n].hand.length;await B(e.state,{type:`摸牌`,player:n,count:1});let s=e.state.players[n].hand[o];if((s?e.state.cardMap[s]:void 0)?.type!==`基本牌`||(delete e.state.localVars[`界集智/discard`],await B(e.state,{type:`请求回应`,requestType:R1,target:n,prompt:{type:`confirm`,title:`集智:是否弃置此基本牌令本回合手牌上限+1?`,confirmLabel:`弃置`,cancelLabel:`保留`},defaultChoice:!1,timeout:15}),!e.state.localVars[`界集智/discard`]))return;let c=e.state.players[n];if(!c||c.hand.indexOf(s)<0)return;await B(e.state,{type:`弃置`,player:n,cardIds:[s]});let l=$c(n),u=sl(e.state.turn.vars,n)??0;e.state.turn.vars[l]=u+1}),()=>{}}function F1(e,t){t.defineAction(`respond`,{label:`集智`,style:`primary`,prompt:{type:`confirm`,title:`是否发动集智?`,confirmLabel:`摸牌`,cancelLabel:`不摸`}})}var I1,L1,R1,z1,whe=t((()=>{V(),F(),W(),I1=new Set([`过河拆桥`,`顺手牵羊`,`无中生有`,`无懈可击`,`借刀杀人`,`桃园结义`,`五谷丰登`,`南蛮入侵`,`万箭齐发`,`决斗`]),L1=`界集智/confirm`,R1=`界集智/discard`,z1={createSkill:N1,onInit:P1,onMount:F1}})),The=r({createSkill:()=>B1,default:()=>X1,onInit:()=>U1,onMount:()=>W1});function B1(e,t){return{id:e,ownerId:t,name:G1,description:`使用/打出【闪】或使用【闪电】时可判定;黑桃可对一名角色造成2点雷电伤害;梅花回复1点体力并可对一名角色造成1点雷电伤害`}}async function V1(e,t){delete e.localVars[Y1],await B(e,{type:`请求回应`,requestType:J1,target:t,prompt:{type:`choosePlayer`,title:`界雷击:选择雷电伤害目标(或放弃)`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0},timeout:20});let n=e.localVars[Y1];return delete e.localVars[Y1],typeof n==`number`?n:null}async function H1(e,t,n){if(!e.players[t]?.alive)return;delete e.localVars[q1],await B(e,{type:`请求回应`,requestType:K1,target:t,prompt:{type:`confirm`,title:`界雷击:是否判定?(${n})`,confirmLabel:`判定`,cancelLabel:`不判定`},defaultChoice:!1,timeout:20});let r=e.localVars[q1];if(delete e.localVars[q1],r!==!0)return;await jm(e,t,G1);let i=e.zones.discardPile;if(i.length===0)return;let a=i[i.length-1],o=e.cardMap[a];if(o){if(o.suit===`♠`){let n=await V1(e,t);if(n===null||!e.players[n]?.alive)return;await Dm(e,t,n,2,void 0,`雷电`)}else if(o.suit===`♣`){let n=e.players[t];n&&n.health<n.maxHealth&&await B(e,{type:`回复体力`,target:t,amount:1});let r=await V1(e,t);if(r===null||!e.players[r]?.alive)return;await Dm(e,t,r,1,void 0,`雷电`)}}}function U1(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===K1)return null;if(a===J1){let n=t.target;return typeof n==`number`&&!e.players[n]?.alive?`目标不存在或已死亡`:null}return`当前不是界雷击询问`},async(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return;let i=r.atom;if(i.requestType===K1)e.localVars[q1]=t.choice===!0||t.confirmed===!0;else if(i.requestType===J1){let n=t.target;e.localVars[Y1]=typeof n==`number`?n:null}}),N(t,e.id,n,`询问闪`,async e=>{let t=e.atom;t.type===`询问闪`&&t.target===n&&e.state.players[n]?.alive&&Je(e.state,e.frame.params.cardId??``,n)&&await H1(e.state,n,`已使用/打出闪`)}),N(t,e.id,n,`添加延时锦囊`,async e=>{let t=e.atom;t.type===`添加延时锦囊`&&t.player===n&&t.trick?.name===`闪电`&&t.trick?.source===n&&e.state.players[n]?.alive&&await H1(e.state,n,`已使用闪电`)}),()=>{}}function W1(e,t){t.defineAction(`respond`,{label:G1,style:`danger`,prompt:{type:`choosePlayer`,title:`界雷击:选择雷电伤害目标(或放弃)`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0}})}var G1,K1,q1,J1,Y1,X1,Ehe=t((()=>{V(),Fm(),Om(),F(),z(),G1=`雷击`,K1=`界雷击/judge`,q1=`界雷击/judgeChoice`,J1=`界雷击/target`,Y1=`界雷击/target`,X1={createSkill:B1,onInit:U1,onMount:W1}})),Dhe=r({createSkill:()=>Z1,default:()=>a0,onInit:()=>Q1,onMount:()=>$1});function Z1(e,t){return{id:e,ownerId:t,name:`鞬出`,description:`使用杀指定目标后,可弃其一张牌:基本牌则其获得此杀;非基本牌则其不能抵消此杀且本回合出杀次数+1`}}async function Ohe(e,t,n,r){let i=e.players[n];if(!i)return;let a=Object.entries(i.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`})),o=i.hand.length,s=a.length>0?{zone:`equipment`,cardId:a[0].cardId}:{zone:`hand`,handIndex:0};delete e.localVars[n0],await B(e,{type:`请求回应`,requestType:`界鞬出/选牌`,target:n,prompt:{type:`pickTargetCard`,title:`界鞬出:选择弃置的一张牌(基本牌→获得此杀;非基本牌→不能抵消且对方本回合出杀+1)`,target:n,equipment:a,judge:[],handCount:o},defaultChoice:s,timeout:20});let c=e.localVars[n0];delete e.localVars[n0];let l=c?.zone??s.zone,u;if(l===`equipment`)u=c?.cardId??s.cardId;else{let e=c?.handIndex??0;u=i.hand[e]??i.hand[0]}if(u)if(await B(e,{type:`弃置`,player:n,cardIds:[u]}),e.cardMap[u]?.type===`基本牌`){let t=e.localVars[r0]??{};t[n]=r,e.localVars[r0]=t}else{await B(e,{type:`加标签`,player:n,tag:e0});let r=e.turn.vars[i0]??0;e.turn.vars[i0]=r+1,await B(e,{type:`回合用量`,player:t,key:Jc(`界鞬出`),value:r+1})}}function Q1(e,t){let n=e.ownerId,r=[$m(t,n,(e,t)=>{if(t!==n)return 0;let r=e.turn.vars[i0];return typeof r==`number`?r:0})];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不是请求回应`;if(r.requestType===`界鞬出/confirm`)return null;if(r.requestType===`界鞬出/选牌`){let n=e.players[i];if(!n)return`玩家不存在`;let r=t.zone;return r===`equipment`?typeof t.cardId==`string`?Object.values(n.equipment).includes(t.cardId)?null:`该牌不在你的装备区`:`cardId required`:r===`hand`?typeof t.handIndex==`number`?t.handIndex<0||t.handIndex>=n.hand.length?`handIndex 越界`:null:`handIndex required`:`zone required (equipment|hand)`}return`当前不是界鞬出回应`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;n===`界鞬出/confirm`?e.localVars[t0]=t.choice===!0||t.confirmed===!0:n===`界鞬出/选牌`&&(e.localVars[n0]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})});r.push(a)}return N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0)return;let r=t.target;if(t.cardId===void 0||e.state.cardMap[t.cardId]?.name!==`杀`)return;let i=e.state.players[r];i?.alive&&(i.hand.length>0||Object.keys(i.equipment).length>0)&&(delete e.state.localVars[t0],await B(e.state,{type:`请求回应`,requestType:`界鞬出/confirm`,target:n,prompt:{type:`confirm`,title:`鞬出:是否弃置目标一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[t0]&&await Ohe(e.state,n,r,t.cardId))}),M(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r===void 0)return;let i=e.state.localVars[r0];if(!(!i||!(r in i)))return{kind:`cancel`}}),N(t,e.id,n,`移动牌`,async e=>{let t=e.state.localVars[r0];if(!t)return;let n=e.atom;if(n.to?.zone!==`弃牌堆`)return;let r=Object.entries(t).find(([,e])=>e===n.cardId);if(!r)return;let i=Number(r[0]);delete t[i],Object.keys(t).length===0&&delete e.state.localVars[r0],e.state.players[i]?.alive&&await B(e.state,{type:`移动牌`,cardId:n.cardId,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:i}})}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r!==void 0&&e.state.players[r]?.tags.includes(e0))return await B(e.state,{type:`去标签`,player:r,tag:e0}),{kind:`cancel`}}),()=>{r.forEach(e=>e())}}function $1(e,t){t.defineAction(`respond`,{label:`鞬出`,style:`default`,prompt:{type:`confirm`,title:`鞬出:是否弃置目标一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var e0,t0,n0,r0,i0,a0,khe=t((()=>{V(),F(),fh(),W(),e0=`界鞬出/禁闪`,t0=`界鞬出/confirmed`,n0=`界鞬出/选牌`,r0=`界鞬出/获得杀`,i0=`界鞬出/quotaBonus`,a0={createSkill:Z1,onInit:Q1,onMount:$1}})),Ahe=r({createSkill:()=>o0,default:()=>l0,onInit:()=>s0,onMount:()=>c0});function o0(e,t){return{id:e,ownerId:t,name:`界鬼才`,description:`判定牌生效前,你可以打出一张手牌或装备牌代替之`}}function s0(e,t){let n=e.ownerId;function r(e,t){let r=e.players[n];if(!r)return null;if(r.hand.includes(t))return`hand`;for(let e of Object.keys(r.equipment))if(r.equipment[e]===t)return e;return null}function i(e){let t=e.players[n];return t?t.hand.length>0?!0:Object.values(t.equipment).some(e=>e!==void 0):!1}return j(t,e.id,n,`respond`,(e,t)=>{let i=e.pendingSlots.get(n);if(!i)return`当前不需要回应`;let a=i.atom;if(a.type!==`请求回应`)return`当前不需要回应`;if(a.requestType!==`界鬼才/replace`)return`当前不是界鬼才询问`;if(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`){let n=t.cardId;if(typeof n!=`string`)return`请选择一张替换牌`;if(r(e,n)===null)return`替换牌不在手牌或装备区中`}return null},async(e,t)=>{if(!(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`)){e.localVars[`鬼才/replaceCard`]=null;return}e.localVars[`鬼才/replaceCard`]=t.cardId??null}),fe(t,e.id,n,async e=>{if(e.atom.type!==`判定牌生效前`)return;let t=e.state.players[n];if(!t?.alive||!i(e.state)||R(e.state).length===0)return;delete e.state.localVars[`鬼才/replaceCard`];let a=Object.values(t.equipment).filter(e=>typeof e==`string`);await B(e.state,{type:`请求回应`,requestType:`界鬼才/replace`,target:n,prompt:{type:`useCard`,title:`界鬼才:是否打出一张手牌或装备牌代替判定牌?`,cardFilter:{filter:()=>!0,candidates:[...t.hand,...a],min:1,max:1}},defaultChoice:!1,timeout:15});let o=e.state.localVars[`鬼才/replaceCard`];if(delete e.state.localVars[`鬼才/replaceCard`],!o)return;let s=r(e.state,o);if(s!==null){if(s!==`hand`){let r=s,i=e.state.cardMap[o];i?.name&&t.skills.includes(i.name)&&await B(e.state,{type:`移除技能`,player:n,skillId:i.name}),await B(e.state,{type:`卸下`,player:n,slot:r})}await Nm(e.state,n,o)}}),()=>{}}function c0(e,t){t.defineAction(`respond`,{label:`界鬼才`,style:`primary`,prompt:{type:`useCard`,title:`界鬼才:选择一张手牌或装备牌代替判定牌`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var l0,jhe=t((()=>{V(),z(),F(),Fm(),l0={createSkill:o0,onInit:s0,onMount:c0}})),Mhe=r({createSkill:()=>d0,default:()=>_0,onInit:()=>f0,onMount:()=>p0});function u0(e,t){let n=e.cardMap[t];return!!n&&n.color===`黑`}function Nhe(e){let t=e===`A`?1:e===`J`?11:e===`Q`?12:e===`K`?13:parseInt(e,10);return!Number.isNaN(t)&&t>=2&&t<=9}function Phe(e){return!!e&&e.suit===`♠`&&Nhe(e.rank)}function d0(e,t){return{id:e,ownerId:t,name:m0,description:`判定牌生效前,你可以用一张黑色牌替换之,若为黑桃2~9,你摸一张牌`}}function f0(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==h0)return`当前不是界鬼道询问`;if(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`){let r=t.cardId;if(typeof r!=`string`)return`请选择一张替换牌`;if(!e.players[n].hand.includes(r))return`替换牌不在手牌中`;if(!u0(e,r))return`界鬼道只能用黑色牌替换`}return null},async(e,t)=>{if(!(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`)){e.localVars[g0]=null;return}e.localVars[g0]=t.cardId??null}),fe(t,e.id,n,async e=>{if(e.atom.type!==`判定牌生效前`)return;let t=e.state.players[n];if(!t?.alive||!t.hand.some(t=>u0(e.state,t))||R(e.state).length===0)return;delete e.state.localVars[g0],await B(e.state,{type:`请求回应`,requestType:h0,target:n,prompt:{type:`useCard`,title:`界鬼道:是否打出一张黑色牌代替判定牌?(黑桃2~9摸一张)`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}},defaultChoice:!1,timeout:15});let r=e.state.localVars[g0];if(delete e.state.localVars[g0],!r||!t.hand.includes(r)||!u0(e.state,r))return;let i=e.state.cardMap[r];await Nm(e.state,n,r),Phe(i)&&await B(e.state,{type:`摸牌`,player:n,count:1})}),()=>{}}function p0(e,t){t.defineAction(`respond`,{label:m0,style:`primary`,prompt:{type:`useCard`,title:`界鬼道:选择一张黑色牌代替判定牌(黑桃2~9摸一张)`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}}})}var m0,h0,g0,_0,Fhe=t((()=>{V(),z(),F(),Fm(),m0=`鬼道`,h0=`界鬼道/replace`,g0=`界鬼道/replaceCard`,_0={createSkill:d0,onInit:f0,onMount:p0}})),Ihe=r({createSkill:()=>v0,default:()=>A0,onInit:()=>b0,onMount:()=>x0,performYinghunPrepare:()=>y0});function v0(e,t){return{id:e,ownerId:t,name:`英魂`,description:`回合开始阶段,若你已受伤,可令一名其他角色选择一项:摸X张牌再弃一张牌,或摸一张牌再弃X张牌(X为你已损失体力值)`}}async function y0(e,t){if(e.currentPlayerIndex!==t)return;let n=e.players[t];if(!n?.alive||n.health>=n.maxHealth)return;let r=n.maxHealth-p(n);if(delete e.localVars[E0],await B(e,{type:`请求回应`,requestType:S0,target:t,prompt:{type:`confirm`,title:`是否发动英魂?(令一名其他角色摸弃,X=${r})`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.localVars[E0])return;delete e.localVars[D0],await B(e,{type:`请求回应`,requestType:C0,target:t,prompt:{type:`choosePlayer`,title:`英魂:选择一名其他角色`,min:1,max:1,filter:(n,r)=>r!==t&&e.players[r]?.alive===!0},timeout:15});let i=e.localVars[D0];if(delete e.localVars[D0],typeof i!=`number`||!e.players[i]?.alive)return;delete e.localVars[O0],await B(e,{type:`请求回应`,requestType:w0,target:t,prompt:{type:`confirm`,title:`英魂:选择一项(你已损失 ${r} 体力)`,description:`选项1:令其摸${r}张牌再弃1张牌;选项2:令其摸1张牌再弃${r}张牌`,confirmLabel:`摸${r}弃1`,cancelLabel:`摸1弃${r}`},defaultChoice:!0,timeout:15});let a=e.localVars[O0]??`opt1`;delete e.localVars[O0];let o=a===`opt1`?r:1,s=a===`opt1`?1:r;if(o>0&&await B(e,{type:`摸牌`,player:i,count:o}),!e.players[i]?.alive)return;let c=e.players[i].hand,l=Math.min(s,c.length);if(l<=0)return;delete e.localVars[k0],await B(e,{type:`请求回应`,requestType:T0,target:i,prompt:{type:`useCard`,title:`英魂:弃 ${l} 张牌`,cardFilter:{filter:()=>!0,min:l,max:l}},mandatory:!0,timeout:20});let u=e.localVars[k0];delete e.localVars[k0],(!u||u.length===0)&&l>0&&(u=e.players[i]?.hand.slice(0,l)??[]),u&&u.length>0&&await B(e,{type:`弃置`,player:i,cardIds:u})}function b0(e,t){let n=e.ownerId,r=[];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;return a!==S0&&a!==C0&&a!==w0&&a!==T0?`当前不是英魂询问`:null},async(e,t)=>{let n=e.pendingSlots.get(i),r=n?.atom?.requestType;if(r===S0)e.localVars[E0]=t.choice===!0;else if(r===C0){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[D0]=n)}else if(r===w0)e.localVars[O0]=t.choice===!0?`opt1`:`opt2`;else if(r===T0){let r=t.cardIds,a=(n?.atom)?.prompt?.cardFilter?.min;Array.isArray(r)&&typeof a==`number`&&r.length===a&&new Set(r).size===r.length&&r.every(t=>e.players[i]?.hand.includes(t))&&(e.localVars[k0]=r)}});r.push(a)}return M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.player===n&&t.phase===`准备`&&await y0(e.state,n)}),()=>{r.forEach(e=>e())}}function x0(e,t){return t.defineAction(`respond`,{label:`英魂`,style:`primary`,prompt:{type:`confirm`,title:`英魂`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var S0,C0,w0,T0,E0,D0,O0,k0,A0,j0=t((()=>{b(),V(),F(),S0=`英魂/confirm`,C0=`英魂/target`,w0=`英魂/option`,T0=`英魂/discard`,E0=`英魂/confirmed`,D0=`英魂/target`,O0=`英魂/option`,k0=`英魂/discardCards`,A0={createSkill:v0,onInit:b0,onMount:x0}})),Lhe=r({createSkill:()=>M0,default:()=>R0,onInit:()=>N0,onMount:()=>P0});function M0(e,t){return{id:e,ownerId:t,name:`界魂姿`,description:`觉醒技:准备阶段且体力为1时,减1体力上限并永久获得"界英姿""英魂";本回合结束阶段摸2牌或回复1体力`}}async function Rhe(e,t){if(cl(e.players[t]?.vars))return;let n=e.players[t];n?.alive&&(n.health>1||(e.players[t].vars[yl]=!0,e.players[t].vars[F0]=!0,await B(e,{type:`设上限`,player:t,amount:n.maxHealth-1}),await B(e,{type:`添加技能`,player:t,skillId:`界英姿`}),await B(e,{type:`添加技能`,player:t,skillId:`英魂`}),await y0(e,t)))}async function zhe(e,t){let n=e.players[t];if(n?.alive&&n.vars[F0])if(delete e.players[t].vars[F0],delete e.localVars[L0],await B(e,{type:`请求回应`,requestType:I0,target:t,prompt:{type:`confirm`,title:`魂姿:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`},defaultChoice:!1,timeout:30}),e.localVars[L0]===`draw`)await B(e,{type:`摸牌`,player:t,count:2});else{let n=e.players[t].health,r=e.players[t].maxHealth,i=Math.min(1,Math.max(0,r-n));i>0&&await B(e,{type:`回复体力`,target:t,amount:i})}}function N0(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===I0?null:`当前不是魂姿选择`:`当前不需要回应`},async(e,t)=>{e.localVars[L0]=t.choice===!0?`draw`:`heal`}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n){if(t.phase===`准备`){await Rhe(e.state,n);return}t.phase===`回合结束`&&await zhe(e.state,n)}}),()=>{}}function P0(e,t){t.defineAction(`respond`,{label:`界魂姿`,style:`primary`,prompt:{type:`confirm`,title:`魂姿:摸两张牌,还是回复1点体力?`,confirmLabel:`摸两张牌`,cancelLabel:`回复1点体力`}})}var F0,I0,L0,R0,Bhe=t((()=>{V(),F(),j0(),W(),F0=`界魂姿/endBonus`,I0=`界魂姿/choose`,L0=`界魂姿/choice`,R0={createSkill:M0,onInit:N0,onMount:P0}})),Vhe=r({createSkill:()=>z0,default:()=>W0,onInit:()=>B0,onMount:()=>V0});function Hhe(e,t){let n=e.cardMap[t];return n?n.name===`闪`||n.suit===`♠`:!1}function z0(e,t){return{id:e,ownerId:t,name:U0,description:`主公技:其他群势力角色可在出牌阶段将一张【闪】或黑桃手牌交给你`}}function B0(e,t){let n=e.ownerId;for(let r of t.players){let i=r.index;i!==n&&r.faction===`群`&&j(t,e.id,i,`use`,(e,t)=>{if(n!==0)return`界黄天为主公技,界张角非主公`;if(!e.players[n]?.alive)return`主公不存在或已死亡`;let r=e.players[i];if(!r?.alive)return`已死亡`;let a=e.currentPlayerIndex===i,o=e.phase===`出牌`,s=!E(e);if(!a||!o||!s)return`现在不能使用界黄天`;if(X(e,i,H0))return`本回合已使用过界黄天`;let c=t.cardId;return typeof c==`string`?r.hand.includes(c)?Hhe(e,c)?null:`界黄天只能交出【闪】或黑桃手牌`:`牌不在手牌中`:`请选择一张牌`},async(e,t)=>{let r=t.cardId;await Z(e,i,H0),await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:i},to:{zone:`手牌`,player:n}})})}return()=>{}}function V0(e,t){let n=e.ownerId;t.defineAction(`use`,{label:U0,style:`primary`,prompt:{type:`useCard`,title:`界黄天:交出一张【闪】或黑桃手牌给主公`,cardFilter:{filter:e=>e.name===`闪`||e.suit===`♠`,min:1,max:1}},activeWhen:e=>e.perspectiveIdx!==n&&yh(H0)(e)&&e.view.players[e.perspectiveIdx]?.hand?.some(e=>e.name===`闪`||e.suit===`♠`)===!0})}var H0,U0,W0,Uhe=t((()=>{V(),Q(),F(),H0=`界黄天`,U0=`黄天`,W0={createSkill:z0,onInit:B0,onMount:V0}})),Whe=r({createSkill:()=>G0,default:()=>X0,onInit:()=>q0,onMount:()=>J0});function G0(e,t){return{id:e,ownerId:t,name:`界龙胆`,description:`你可以将一张【杀】当【闪】、【闪】当【杀】、【酒】当【桃】、【桃】当【酒】使用或打出`}}function K0(e){return`${e}#界龙胆`}function q0(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r?.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a);if(!i)return`你已死亡`;if(!o||!c)return`牌不在手牌中`;let l=s?Y0[s.name]:void 0,u=t.to??l;return l?u===l?null:`转化方向与原牌不符`:`该牌不能被界龙胆转化`},async(e,t)=>{let r=t.cardId,i=e.cardMap[r],a=t.to??(i?Y0[i.name]:void 0);if(!a)return;let o=K0(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:o,outputName:a})},(e,t)=>{let r=t.cardId,i=K0(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)});let r=de(t,n,`询问闪`),i=de(t,n,`询问杀`),a=de(t,n,`请求回应`,`桃/求桃`);return()=>{r(),i(),a()}}function J0(e,t){t.defineAction(`transform`,{label:`界龙胆`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张杀/闪/酒/桃转化`,cardFilter:{filter:e=>e.name===`杀`||e.name===`闪`||e.name===`酒`||e.name===`桃`,min:1,max:1},targetFilter:{min:1,max:3,filter:(e,t)=>t!==e.currentPlayerIndex&&e.players[t]?.alive}},transform:t=>({name:Y0[t.name]??t.name,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t?.alive)return!1;let n=t.hand??[],r=e=>n.some(t=>t.name===e);if(q(e)&&(r(`闪`)&&sm(e.view,e.perspectiveIdx)||r(`酒`)&&t.health<t.maxHealth||r(`桃`)))return!0;let i=e.view.pending;return!!(i&&i.atom.type===`询问闪`&&i.target===e.perspectiveIdx&&r(`杀`)||i&&i.atom.type===`询问杀`&&i.target===e.perspectiveIdx&&r(`闪`))}})}var Y0,X0,Ghe=t((()=>{F(),V(),J(),Y0={杀:`闪`,闪:`杀`,酒:`桃`,桃:`酒`},X0={createSkill:G0,onInit:q0,onMount:J0}})),Khe=r({createSkill:()=>qhe,onInit:()=>Jhe});function qhe(e,t){return{id:e,ownerId:t,name:`白银狮子`,description:`防具:每次受伤最多1点`,isLocked:!0}}function Z0(e,t){let n=e.players[t]?.equipment.防具;return n&&e.cardMap[n]?.name===`白银狮子`?n:null}function Jhe(e,t){let n=e.ownerId,r=`白银狮子/失去/${n}`;M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target===n&&!((t.amount??0)<=1)&&Z0(e.state,n))return{kind:`modify`,atom:{...e.atom,amount:1}}}),M(t,e.id,n,`卸下`,async e=>{let t=e.atom;t.player!==n||t.slot!==`防具`||Z0(e.state,n)&&(e.state.localVars[r]=!0)}),M(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.player!==n)return;let i=Z0(e.state,n);i&&(t.cardIds??[]).includes(i)&&(e.state.localVars[r]=!0)}),M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.from!==n)return;let i=Z0(e.state,n);i&&t.cardId===i&&(e.state.localVars[r]=!0)}),M(t,e.id,n,`移除技能`,async e=>{let t=e.atom;t.player!==n||t.skillId!==`白银狮子`||Z0(e.state,n)&&(e.state.localVars[r]=!0)});async function i(e){e.localVars[r]&&(delete e.localVars[r],e.players[n]?.alive&&await B(e,{type:`回复体力`,target:n,amount:1}))}return N(t,e.id,n,`卸下`,async e=>{let t=e.atom;t.player!==n||t.slot!==`防具`||await i(e.state)}),N(t,e.id,n,`弃置`,async e=>{e.atom.player===n&&await i(e.state)}),N(t,e.id,n,`获得`,async e=>{e.atom.from===n&&await i(e.state)}),N(t,e.id,n,`移除技能`,async e=>{let t=e.atom;t.player!==n||t.skillId!==`白银狮子`||await i(e.state)}),()=>{}}var Yhe=t((()=>{V(),F()})),Xhe=r({createSkill:()=>Q0,default:()=>t2,onInit:()=>$0,onMount:()=>e2});function Zhe(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function Q0(e,t){return{id:e,ownerId:t,name:`直谏`,description:`出牌阶段:将一张装备牌置于一名其他角色的空装备区,然后摸一张牌`}}function $0(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;let r=e.players[n];if(!r?.alive)return`你已死亡`;if(typeof t.cardId!=`string`)return`需要选择一张装备牌`;if(!r.hand.includes(t.cardId))return`牌不在手牌中`;let i=e.cardMap[t.cardId];if(i?.type!==`装备牌`)return`只能使用装备牌`;let a=Zhe(i);if(!a)return`无效的装备牌`;let o=Array.isArray(t.targets)&&typeof t.targets[0]==`number`?t.targets[0]:typeof t.target==`number`?t.target:void 0;if(o===void 0)return`需要指定一名目标`;if(o===n)return`不能对自己使用直谏`;let s=e.players[o];return s?.alive?s.equipment[a]?`目标该装备栏位已有装备,不得替换`:null:`目标不合法`},async(e,t)=>{let r=t.cardId,i=Array.isArray(t.targets)&&typeof t.targets[0]==`number`?t.targets[0]:t.target,a=e.cardMap[r];await I(e,`直谏`,n,{...t}),await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:n},to:{zone:`手牌`,player:i}}),await B(e,{type:`装备`,player:i,cardId:r}),a?.name&&ym(a.name)&&await B(e,{type:`添加技能`,player:i,skillId:a.name}),await B(e,{type:`摸牌`,player:n,count:1}),await L(e)}),()=>{}}function e2(e,t){return t.defineAction(`use`,{label:`直谏`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`直谏:将一张装备牌置于一名其他角色的空装备区`,cardFilter:{filter:e=>e.type===`装备牌`,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>t===e.viewer?!1:e.players[t]?.alive===!0}}}),()=>{}}var t2,Qhe=t((()=>{V(),z(),F(),Sm(),t2={createSkill:Q0,onInit:$0,onMount:e2}})),$he=r({createSkill:()=>n2,default:()=>o2,onInit:()=>i2,onMount:()=>a2});function n2(e,t){return{id:e,ownerId:t,name:`看破`,description:`你可以将一张黑色手牌当【无懈可击】使用`}}function r2(e){return`${e}#看破`}function ege(e,t){for(let n of e.pendingSlots.values()){let e=n.atom;if(e.type===`请求回应`&&e.requestType===`无懈可击`&&typeof e.target==`number`&&(e.target<0||e.target===t))return!0}return!1}function i2(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId,a=typeof i==`string`,o=a?e.cardMap[i]:void 0,s=a&&r.hand.includes(i),c=!!o&&o.color===`黑`,l=ege(e,n),u=(()=>{for(let t of e.pendingSlots.values()){let e=t.atom;if(t.isBlocking&&!(e.type===`请求回应`&&e.requestType===`无懈可击`))return!0}return!1})();return s&&c&&l&&!u?null:`现在不能使用看破`},async(e,t)=>{let r=t.cardId,i=r2(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`无懈可击`})},(e,t)=>{let r=t.cardId,i=r2(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),()=>{}}function a2(e,t){t.defineAction(`transform`,{label:`看破`,style:`passive`,prompt:{type:`useCard`,title:`选择一张黑色牌当无懈可击使用`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}},transform:t=>({name:`无懈可击`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view,n=t.pending;if(!n)return!1;let r=n.atom;if(r.type!==`请求回应`||r.requestType!==`无懈可击`)return!1;let i=t.players[e.perspectiveIdx];return i?i.hand?.some(e=>e.color===`黑`)??!1:!1}})}var o2,tge=t((()=>{F(),V(),o2={createSkill:n2,onInit:i2,onMount:a2}})),nge=r({allSlotsAbolished:()=>c2,createSkill:()=>s2,default:()=>p2,onInit:()=>l2,onMount:()=>u2});function s2(e,t){return{id:e,ownerId:t,name:`破势`,description:`觉醒技:准备阶段,若装备栏均被废除或体力值为1,减少1点体力上限,将手牌摸至体力上限,失去决堰并获得怀柔`}}function c2(e,t){let n=e.players[t]?.vars;return n?f2.every(e=>n[Cv+e]):!1}function l2(e,t){let n=e.ownerId;return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||e.state.players[n]?.vars[d2])return;let r=e.state.players[n];if(!r?.alive)return;let i=c2(e.state,n),a=p(r)===1;if(!i&&!a)return;e.state.players[n].vars[d2]=!0,await B(e.state,{type:`设上限`,player:n,amount:r.maxHealth-1});let o=e.state.players[n].maxHealth,s=e.state.players[n].hand.length,c=Math.max(0,o-s);c>0&&await B(e.state,{type:`摸牌`,player:n,count:c}),await B(e.state,{type:`移除技能`,player:n,skillId:`决堰`}),await B(e.state,{type:`添加技能`,player:n,skillId:`怀柔`})}),()=>{}}function u2(e,t){}var d2,f2,p2,rge=t((()=>{b(),V(),F(),Ov(),d2=`破势/awakened`,f2=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`],p2={createSkill:s2,onInit:l2,onMount:u2}})),ige=r({createSkill:()=>age,onInit:()=>sge,onMount:()=>cge});function age(e,t){return{id:e,ownerId:t,name:`神速`,description:`可选择至多三项:①跳过判定+摸牌;②弃装备+跳过出牌;③翻面+跳过弃牌。每项视为出杀`}}function oge(e,t,n){return`神速:杀:${e}:${t}:${n}`}async function m2(e,t,n){if(!e.players[n]?.alive)return;let r=oge(t,n,e.seq);e.cardMap[r]={id:r,name:`杀`,suit:``,color:`无色`,rank:`A`,type:`基本牌`},await Lh(e,t,r,[n],`杀`,{virtual:!0,onSettle:Hh(e,t,r)}),delete e.cardMap[r]}function sge(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let r=t.atom.requestType??``;return r!==h2&&r!==g2&&r!==_2&&r!==v2&&r!==y2&&r!==b2&&r!==x2?`当前不是神速询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType??``;if(r===h2||r===_2||r===b2)e.localVars[`神速/confirmed`]=t.choice===!0;else if(r===g2||r===v2||r===x2){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[`神速/target`]=n)}else if(r===y2){let n=t.cardIds,r=t.cardId;e.localVars[`神速/equipCardId`]=(Array.isArray(n)&&n.length>0?{cardIds:[n[0]]}:null)??(typeof r==`string`?r:null)}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`判定`||e.state.currentPlayerIndex!==n)return;let r=e.state.players[n];if(!r?.alive||r.vars[E2]||!e.state.players.some((e,t)=>t!==n&&e.alive)||(delete e.state.localVars[`神速/confirmed`],await B(e.state,{type:`请求回应`,requestType:h2,target:n,prompt:{type:`confirm`,title:`是否发动神速①?(跳过判定+摸牌,视为出杀)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[`神速/confirmed`]!==!0))return;delete e.state.localVars[`神速/target`],await B(e.state,{type:`请求回应`,requestType:g2,target:n,prompt:{type:`choosePlayer`,title:`神速①:选择一名其他角色(视为出杀,无距离限制)`,min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0},timeout:15});let i=e.state.localVars[`神速/target`];return delete e.state.localVars[`神速/target`],r.vars[E2]=!0,await B(e.state,{type:`加标签`,player:n,tag:S2}),typeof i==`number`&&e.state.players[i]?.alive&&await m2(e.state,n,i),Nh(e.state,t)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`出牌`||e.state.currentPlayerIndex!==n)return;let r=e.state.players[n];if(!r?.alive||r.vars[D2])return;let i=Object.values(r.equipment).filter(Boolean).length,a=e.state.players.some((e,t)=>t!==n&&e.alive);if(i===0||!a||(delete e.state.localVars[`神速/confirmed`],await B(e.state,{type:`请求回应`,requestType:_2,target:n,prompt:{type:`confirm`,title:`是否发动神速②?(弃置一张装备牌,跳过出牌,视为出杀)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[`神速/confirmed`]!==!0))return;delete e.state.localVars[`神速/equipCardId`],await B(e.state,{type:`请求回应`,requestType:y2,target:n,prompt:{type:`distribute`,mode:`select`,title:`神速②:选择一张装备牌弃置`,source:`handAndEquip`,minTotal:1,maxTotal:1},timeout:15});let o=e.state.localVars[`神速/equipCardId`],s=(o&&typeof o==`object`?o.cardIds?.[0]:o)??void 0;if(delete e.state.localVars[`神速/equipCardId`],!s||!Object.values(r.equipment).includes(s))return;delete e.state.localVars[`神速/target`],await B(e.state,{type:`请求回应`,requestType:v2,target:n,prompt:{type:`choosePlayer`,title:`神速②:选择一名其他角色(视为出杀,无距离限制)`,min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0},timeout:15});let c=e.state.localVars[`神速/target`];return delete e.state.localVars[`神速/target`],r.vars[D2]=!0,await B(e.state,{type:`弃置`,player:n,cardIds:[s],voluntary:!0}),typeof c==`number`&&e.state.players[c]?.alive&&await m2(e.state,n,c),Nh(e.state,t)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`摸牌`&&e.state.players[n]?.tags.includes(S2))return Nh(e.state,t,S2)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type===`阶段开始`&&t.player===n&&t.phase===`出牌`&&e.state.players[n]?.tags.includes(C2))return Nh(e.state,t,C2)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`弃牌`||e.state.currentPlayerIndex!==n)return;let r=e.state.players[n];if(!r?.alive||r.vars[O2]||!e.state.players.some((e,t)=>t!==n&&e.alive)||(delete e.state.localVars[`神速/confirmed`],await B(e.state,{type:`请求回应`,requestType:b2,target:n,prompt:{type:`confirm`,title:`是否发动神速③?(翻面,跳过弃牌,视为出杀)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[`神速/confirmed`]!==!0))return;delete e.state.localVars[`神速/target`],await B(e.state,{type:`请求回应`,requestType:x2,target:n,prompt:{type:`choosePlayer`,title:`神速③:选择一名其他角色(视为出杀,无距离限制)`,min:1,max:1,filter:(t,r)=>r!==n&&e.state.players[r]?.alive===!0},timeout:15});let i=e.state.localVars[`神速/target`];return delete e.state.localVars[`神速/target`],r.vars[O2]=!0,await B(e.state,{type:`加标签`,player:n,tag:w2}),typeof i==`number`&&e.state.players[i]?.alive&&await m2(e.state,n,i),Nh(e.state,t)}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n)return;let r=e.state.players[n];if(t.phase===`准备`&&r?.tags.includes(w2))return await B(e.state,{type:`去标签`,player:n,tag:w2}),e.state.localVars[T2]=n,{kind:`cancel`};if(e.state.localVars[T2]===n)return{kind:`cancel`}}),M(t,e.id,n,`阶段结束`,async e=>{let t=e.atom;if(t.type===`阶段结束`&&t.player===n&&e.state.localVars[T2]===n)return delete e.state.localVars[T2],await B(e.state,{type:`清过期标记`,player:n}),await B(e.state,{type:`下一玩家`}),await B(e.state,{type:`回合结束`,player:n})&&await B(e.state,{type:`回合结束后`,player:n}),{kind:`cancel`}}),()=>{}}function cge(e,t){t.defineAction(`respond`,{label:`神速`,style:`default`,prompt:{type:`confirm`,title:`是否发动神速?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var h2,g2,_2,v2,y2,b2,x2,S2,C2,w2,T2,E2,D2,O2,lge=t((()=>{V(),F(),Gh(),Ph(),h2=`神速/opt1-trigger`,g2=`神速/opt1-target`,_2=`神速/opt2-trigger`,v2=`神速/opt2-target`,y2=`神速/opt2-equip`,b2=`神速/opt3-trigger`,x2=`神速/opt3-target`,S2=`神速/跳过摸牌`,C2=`神速/跳过出牌`,w2=`神速/翻面`,T2=`神速/skipAll`,E2=`神速/opt1/usedThisTurn`,D2=`神速/opt2/usedThisTurn`,O2=`神速/opt3/usedThisTurn`})),uge=r({createSkill:()=>k2,default:()=>M2,onInit:()=>A2,onMount:()=>j2});function k2(e,t){return{id:e,ownerId:t,name:`祸首`,description:`锁定技:南蛮入侵对你无效;你是任何南蛮入侵造成伤害的来源`,isLocked:!0}}function A2(e,t){let n=e.ownerId;return M(t,e.id,n,`询问杀`,async e=>{if(e.atom.target===n&&Ke(e.state)?.skillId===`南蛮入侵`)return{kind:`cancel`}}),M(t,e.id,n,`伤害结算开始时`,async e=>{let t=e.atom;if(!t.cardId||e.state.cardMap[t.cardId]?.name!==`南蛮入侵`)return;let r=e.state.players[n]?.alive===!0;if(t.target===n)return{kind:`cancel`};if(r&&t.source!==void 0&&t.source!==n)return{kind:`modify`,atom:{...e.atom,source:n}}}),()=>{}}function j2(e,t){}var M2,dge=t((()=>{z(),F(),M2={createSkill:k2,onInit:A2,onMount:j2}})),fge=r({createSkill:()=>P2,default:()=>L2,onInit:()=>F2,onMount:()=>I2});function N2(e,t){let n=e.players[t];return n?.alive?kc(n.character)===`男`:!1}function P2(e,t){return{id:e,ownerId:t,name:`离间`,description:`出牌阶段限一次,弃一张牌,令一名男性角色视为对另一名男性角色使用决斗`}}function F2(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r?.alive)return`角色不可用`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`离间`))return`本回合已使用过离间`;let i=t.cardId;if(typeof i!=`string`)return`需要选择一张牌弃置`;let a=r.hand.includes(i),o=Object.values(r.equipment).includes(i);if(!a&&!o)return`牌不在你的手牌或装备区`;let s=t.targets;if(!Array.isArray(s)||s.length!==2)return`需要选择两名男性角色`;let[c,l]=s;return c===l?`必须选择两名不同的角色`:N2(e,c)?N2(e,l)?null:`决斗目标必须是男性角色`:`决斗发起者必须是男性角色`},async(e,t)=>{let r=t.cardId,[i,a]=t.targets;await Z(e,n,`离间`),await I(e,`离间`,n,{...t}),await B(e,{type:`弃置`,player:n,cardIds:[r],voluntary:!0});let o=`离间:决斗:${i}:${a}:${e.seq}`;e.cardMap[o]={id:o,name:`决斗`,suit:``,color:`无色`,rank:`A`,type:`锦囊牌`},await Lh(e,i,o,[a],`决斗`,{virtual:!0}),delete e.cardMap[o],await L(e)}),()=>{}}function I2(e,t){return t.defineAction(`use`,{label:`离间`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`离间:弃一张牌,令一名男性角色对另一名男性角色决斗`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:2,max:2,filter:(e,t)=>{let n=e.players[t];return!n||n.alive===!1?!1:kc(n.character)===`男`}}},activeWhen:e=>yh(`离间`)(e)}),()=>{}}var L2,pge=t((()=>{V(),z(),Q(),F(),Fc(),Gh(),L2={createSkill:P2,onInit:F2,onMount:I2}})),mge=r({createSkill:()=>R2,default:()=>B2,onInit:()=>z2});function R2(e,t){return{id:e,ownerId:t,name:`空城`,description:`锁定技:若你没有手牌,你不是杀和决斗的合法目标`,isLocked:!0}}function z2(e,t){let n=e.ownerId;return M(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.target!==n||e.state.players[n]?.hand.length!==0)return;let r;if(t.cardId&&(r=e.state.cardMap[t.cardId]?.name),r||=Ke(e.state)?.skillId,!(r!==`杀`&&r!==`决斗`))return{kind:`cancel`}}),()=>{}}var B2,hge=t((()=>{z(),F(),B2={createSkill:R2,onInit:z2}})),gge=r({createSkill:()=>_ge,onInit:()=>vge,onMount:()=>yge});function _ge(e,t){return{id:e,ownerId:t,name:`突袭`,description:`摸牌阶段,你可以改为获得至多两名角色的各一张手牌`}}function vge(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);if(t?.atom.type!==`请求回应`)return`当前不需要回应`;let r=t.atom.requestType;return r!==V2&&r!==H2?`当前不是突袭回应`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===V2)e.localVars[U2]=t.choice===!0;else if(r===H2){let n=t.targets??(typeof t.target==`number`?[t.target]:void 0);e.localVars[W2]=n??[]}}),M(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`摸牌`||e.state.currentPlayerIndex!==n||!e.state.players[n]?.alive||!e.state.players.some((e,t)=>t!==n&&e.alive&&e.hand.length>0)||(delete e.state.localVars[U2],await B(e.state,{type:`请求回应`,requestType:V2,target:n,prompt:{type:`confirm`,title:`是否发动突袭?(放弃摸牌,获得至多两名角色各一张手牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[U2]!==!0))return;delete e.state.localVars[W2],await B(e.state,{type:`请求回应`,requestType:H2,target:n,prompt:{type:`choosePlayer`,title:`突袭:选择至多两名角色(各获得一张手牌)`,min:1,max:2,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0&&(e.players[t]?.handCount??0)>0},timeout:15});let r=e.state.localVars[W2],i=Array.isArray(r)?r.filter(t=>t!==n&&e.state.players[t]?.alive===!0&&e.state.players[t].hand.length>0):[];if(i.length!==0){for(let t of i){let r=e.state.players[t];if(!r||!r.alive||r.hand.length===0)continue;let i=Ud(e.state.rngSeed),a=i.nextInt(r.hand.length);e.state.rngSeed=i.getState();let o=r.hand[a];await B(e.state,{type:`获得`,player:n,cardId:o,from:t})}return await B(e.state,{type:`阶段结束`,player:n,phase:`摸牌`}),{kind:`cancel`}}}),()=>{}}function yge(e,t){t.defineAction(`respond`,{label:`突袭`,style:`primary`,prompt:{type:`confirm`,title:`是否发动突袭?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var V2,H2,U2,W2,bge=t((()=>{V(),F(),Wd(),V2=`突袭/trigger`,H2=`突袭/select`,U2=`突袭/triggered`,W2=`突袭/targets`})),xge=r({createSkill:()=>q2,default:()=>t4,onInit:()=>J2,onMount:()=>Y2});function G2(e){return`立军/used/${e}`}function K2(e){return`立军/quota/${e}`}function q2(e,t){return{id:e,ownerId:t,name:`立军`,description:`主公技:其他吴势力角色用杀后可交给你获得,你可令其摸一张牌且本回合使用杀的限制次数+1`}}function J2(e,t){let n=e.ownerId,r=[];for(let e of t.players){if(e.index===n||e.faction!==`吴`)continue;let i=e.index,a=$m(t,i,e=>+(e.turn.vars[K2(i)]===!0));r.push(a)}r.push(N(t,e.id,n,`使用时`,async e=>{let t=e.atom;if(t.type!==`使用时`)return;let n=e.state.cardMap[t.cardId];n&&(e.frame.params[e4]=n.shadowOf??t.cardId)})),r.push(N(t,e.id,n,`使用结算结束后`,async e=>{let t=e.atom,r=e.state;if(n!==0||(r.cardMap[t.cardId]?.name??e.frame?.skillId)!==`杀`)return;let i=e.frame.params[e4]??t.cardId,a=t.source;if(a===n||r.currentPlayerIndex!==a)return;let o=r.players[a];if(!o?.alive||o.faction!==`吴`)return;let s=r.players[n];if(!s?.alive||r.turn.vars[G2(a)]===!0)return;r.turn.vars[G2(a)]=!0,await I(r,`立军`,n,{ally:a,cardId:i}),delete r.localVars[Q2],await B(r,{type:`请求回应`,requestType:X2,target:a,prompt:{type:`confirm`,title:`立军:是否将此【杀】交给 ${s.name??`主公`}?`,confirmLabel:`交给主公`,cancelLabel:`不交`},defaultChoice:!1,timeout:30});let c=r.localVars[Q2]===!0;if(delete r.localVars[Q2],!c){await L(r);return}r.zones.discardPile.includes(i)&&await B(r,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}}),delete r.localVars[$2],await B(r,{type:`请求回应`,requestType:Z2,target:n,prompt:{type:`confirm`,title:`立军:是否令 ${o.name??`该角色`} 摸一张牌且本回合使用杀的限制次数+1?`,confirmLabel:`令其摸牌+杀次+1`,cancelLabel:`不发动`},defaultChoice:!1,timeout:30});let l=r.localVars[$2]===!0;if(delete r.localVars[$2],!l){await L(r);return}r.players[a]?.alive&&await B(r,{type:`摸牌`,player:a,count:1}),r.turn.vars[K2(a)]=!0,await B(r,{type:`回合用量`,player:a,key:Jc(`立军`),value:1}),await L(r)}));for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;if(n.atom.type!==`请求回应`)return`当前不是立军窗口`;let r=n.atom.requestType;return r!==X2&&r!==Z2?`当前不是立军窗口`:null},async(e,t)=>{let n=e.pendingSlots.get(i).atom.requestType,r=t.choice===!0||t.confirmed===!0;n===X2?e.localVars[Q2]=r:n===Z2&&(e.localVars[$2]=r)});r.push(a)}return()=>{for(let e of r)e()}}function Y2(e,t){return()=>{}}var X2,Z2,Q2,$2,e4,t4,Sge=t((()=>{V(),z(),F(),fh(),W(),X2=`立军/盟友确认`,Z2=`立军/主公确认`,Q2=`立军/盟友确认结果`,$2=`立军/主公确认结果`,e4=`立军/effectiveCardId`,t4={createSkill:q2,onInit:J2,onMount:Y2}})),Cge=r({createSkill:()=>n4,default:()=>f4,onInit:()=>r4,onMount:()=>i4});function wge(e,t){return e.players[t].vars[a4]??[]}function Tge(e){switch(e?.subtype){case`武器`:return`武器`;case`防具`:return`防具`;case`进攻马`:return`进攻马`;case`防御马`:return`防御马`;case`宝物`:return`宝物`;default:return null}}function n4(e,t){return{id:e,ownerId:t,name:`箜声`,description:`准备阶段,你可以将任意张牌置于你的武将牌上;结束阶段,你获得其中的非装备牌,然后令一名角色使用剩余牌并失去1点体力`}}async function Ege(e,t){let n=e.players[t];if(!n?.alive||n.hand.length===0)return;if(delete e.localVars[l4],await B(e,{type:`请求回应`,requestType:o4,target:t,prompt:{type:`confirm`,title:`是否发动箜声?(将任意张牌置于武将牌上)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.localVars[l4]){delete e.localVars[l4];return}delete e.localVars[l4],delete e.localVars[u4],await B(e,{type:`请求回应`,requestType:s4,target:t,prompt:{type:`useCard`,title:`箜声:选择要置于武将牌上的牌`,cardFilter:{filter:()=>!0,min:1,max:n.hand.length}},timeout:30});let r=e.localVars[u4];delete e.localVars[u4];let i=Array.isArray(r)&&r.length>0&&r.every(e=>n.hand.includes(e))&&new Set(r).size===r.length?r:[];i.length!==0&&await B(e,{type:`移出至暂存区`,source:t,target:t,cardIds:i,varsKey:a4})}async function Dge(e,t){if(!e.players[t]?.alive)return;let n=wge(e,t);if(n.length===0)return;let r=n.filter(t=>e.cardMap[t]?.type===`装备牌`);if(await B(e,{type:`归还暂存牌`,player:t,varsKey:a4}),r.length===0||!e.players[t]?.alive)return;delete e.localVars[d4],await B(e,{type:`请求回应`,requestType:c4,target:t,prompt:{type:`choosePlayer`,title:`箜声:令一名角色使用剩余(装备)牌并失去1点体力`,min:1,max:1,filter:(t,n)=>e.players[n]?.alive===!0},timeout:30});let i=e.localVars[d4];if(delete e.localVars[d4],!(typeof i!=`number`||!e.players[i]?.alive)){for(let n of r){if(!e.players[t]?.alive)break;if(!e.players[t].hand.includes(n))continue;i!==t&&await B(e,{type:`给予`,cardId:n,from:t,to:i});let r=e.cardMap[n],a=Tge(r);if(!a)continue;let o=e.players[i].equipment[a];if(o){let t=e.cardMap[o];t?.name&&ym(t.name)&&await B(e,{type:`移除技能`,player:i,skillId:t.name}),await B(e,{type:`卸下`,player:i,slot:a}),await B(e,{type:`移动牌`,cardId:o,from:{zone:`手牌`,player:i},to:{zone:`弃牌堆`}})}await B(e,{type:`装备`,player:i,cardId:n}),r?.name&&ym(r.name)&&await B(e,{type:`添加技能`,player:i,skillId:r.name})}e.players[i]?.alive&&await B(e,{type:`失去体力`,target:i,amount:1})}}function r4(e,t){let n=e.ownerId;return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&e.state.currentPlayerIndex===n&&(t.phase===`准备`?await Ege(e.state,n):t.phase===`回合结束`&&await Dge(e.state,n))}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===o4)return null;if(i===s4){let e=t.cardIds??t.cardId,n=Array.isArray(e)?e:typeof e==`string`?[e]:void 0;return!n||n.length,null}return i===c4?typeof t.target==`number`?null:`需要选择一名角色`:`当前不是箜声询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===o4)e.localVars[l4]=t.choice===!0||t.confirmed===!0;else if(r===s4){let n=t.cardIds??t.cardId,r=Array.isArray(n)?n:typeof n==`string`?[n]:void 0;r&&r.length>0&&(e.localVars[u4]=r)}else if(r===c4){let n=t.target;typeof n==`number`&&(e.localVars[d4]=n)}}),()=>{}}function i4(e,t){return()=>{}}var a4,o4,s4,c4,l4,u4,d4,f4,Oge=t((()=>{V(),F(),Sm(),a4=`箜声/牌`,o4=`箜声/confirm`,s4=`箜声/select`,c4=`箜声/target`,l4=`箜声/confirmed`,u4=`箜声/selected`,d4=`箜声/target`,f4={createSkill:n4,onInit:r4,onMount:i4}})),kge=r({createSkill:()=>p4,default:()=>g4,onInit:()=>m4,onMount:()=>h4});function p4(e,t){return{id:e,ownerId:t,name:`红颜`,description:`锁定技:你的黑桃牌均视为红桃牌`,isLocked:!0}}function m4(e,t){let n=e.ownerId;return M(t,e.id,n,`判定`,async e=>{if(e.atom.player!==n)return;let t=e.state.zones.deck[e.state.zones.deck.length-1];if(!t)return;let r=e.state.cardMap[t];r&&r.suit===`♠`&&(r.suit=`♥`,r.color=`红`)}),()=>{}}function h4(e,t){}var g4,Age=t((()=>{F(),g4={createSkill:p4,onInit:m4,onMount:h4}})),jge=r({createSkill:()=>_4,default:()=>x4,onInit:()=>y4,onMount:()=>b4});function _4(e,t){return{id:e,ownerId:t,name:`结姻`,description:`出牌阶段限一次,弃两张手牌,令你与一名已受伤的男性角色各回复1点体力`}}function Mge(e,t){let n=e.players[t];return!n?.alive||n.health>=n.maxHealth?!1:kc(n.character)===`男`}function v4(e){let t=e.allocation;if(Array.isArray(t)&&t.length>0)return{cardIds:t.flatMap(e=>e.cardIds),target:t[0].target};let n=e.cardIds,r=e.target;return Array.isArray(n)&&typeof r==`number`?{cardIds:n,target:r}:null}function y4(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r?.alive)return`角色不可用`;if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`不是出牌阶段`;if(E(e))return`当前有未回应的询问`;if(X(e,n,`结姻`))return`本回合已使用过结姻`;if(r.hand.length<2)return`手牌不足两张`;let i=v4(t);if(!i)return`需要选择两张手牌和一名目标`;let{cardIds:a,target:o}=i;return a.length===2?new Set(a).size===2?a.every(e=>r.hand.includes(e))?Mge(e,o)?null:`目标必须是已受伤的男性角色`:`牌不在手牌中`:`不能弃置相同的牌`:`必须弃置两张手牌`},async(e,t)=>{let r=v4(t);if(!r)return;let{cardIds:i,target:a}=r;await Z(e,n,`结姻`),await I(e,`结姻`,n,{cardIds:i,target:a}),await B(e,{type:`弃置`,player:n,cardIds:i,voluntary:!0}),await B(e,{type:`回复体力`,target:n,amount:1,source:n}),await B(e,{type:`回复体力`,target:a,amount:1,source:n}),await L(e)}),()=>{}}function b4(e,t){return t.defineAction(`use`,{label:`结姻`,style:`primary`,prompt:{type:`distribute`,mode:`allocate`,title:`结姻:弃两张手牌,令你与一名已受伤的男性角色各回复1点体力`,source:`hand`,minTotal:2,maxTotal:2,minPerTarget:2,maxPerTarget:2,allowSelf:!1,targetFilter:(e,t)=>{let n=e.players[t];return!n||n.alive===!1||(n.health??0)>=(n.maxHealth??0)?!1:kc(n.character)===`男`}},activeWhen:e=>yh(`结姻`)(e)}),()=>{}}var x4,Nge=t((()=>{V(),z(),Q(),F(),Fc(),x4={createSkill:_4,onInit:y4,onMount:b4}})),Pge=r({createSkill:()=>S4,default:()=>k4,onInit:()=>C4,onMount:()=>w4});function S4(e,t){return{id:e,ownerId:t,name:`缔盟`,description:`出牌阶段限一次,选择两名其他角色,弃置等同于他们手牌数差的牌,然后交换他们的手牌`}}function C4(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>e.currentPlayerIndex===n?e.phase===`出牌`?E(e)?`当前有未完成的询问`:X(e,n,`缔盟`)?`本回合已使用过缔盟`:e.players[n]?.alive?e.players.filter(e=>e.alive&&e.index!==n).length<2?`需要至少两名其他角色`:null:`角色不可用`:`只能在出牌阶段发动`:`不是你的回合`,async(e,t)=>{await Z(e,n,`缔盟`),await I(e,`缔盟`,n,{}),delete e.localVars[D4],await B(e,{type:`请求回应`,requestType:T4,target:n,prompt:{type:`choosePlayer`,title:`缔盟:选择两名其他角色交换手牌`,min:2,max:2,filter:(t,r)=>r!==n&&e.players[r]?.alive===!0},timeout:30});let r=e.localVars[D4];if(delete e.localVars[D4],!Array.isArray(r)||r.length!==2){await L(e);return}let[i,a]=r;if(!e.players[i]?.alive||!e.players[a]?.alive){await L(e);return}let o=Math.abs(e.players[i].hand.length-e.players[a].hand.length),s=Math.min(o,e.players[n].hand.length);if(s>0){delete e.localVars[O4],await B(e,{type:`请求回应`,requestType:E4,target:n,prompt:{type:`useCard`,title:`缔盟:弃置 ${s} 张牌`,cardFilter:{filter:()=>!0,min:s,max:s}},mandatory:!0,timeout:30});let t=e.localVars[O4];delete e.localVars[O4],(!t||t.length===0)&&(t=e.players[n]?.hand.slice(0,s)??[]),t.length>0&&await B(e,{type:`弃置`,player:n,cardIds:t,voluntary:!0})}let c=[...e.players[i].hand],l=[...e.players[a].hand];for(let t of c)await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:i},to:{zone:`手牌`,player:a}});for(let t of l)await B(e,{type:`移动牌`,cardId:t,from:{zone:`手牌`,player:a},to:{zone:`手牌`,player:i}});await L(e)}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==T4&&a!==E4?`当前不是缔盟询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n),i=r?.atom?.requestType;if(i===T4){let n=t.targets;Array.isArray(n)&&n.length===2&&(e.localVars[D4]=n)}else if(i===E4){let i=t.cardIds,a=(r?.atom)?.prompt?.cardFilter?.min;Array.isArray(i)&&typeof a==`number`&&i.length===a&&i.every(t=>e.players[n]?.hand.includes(t))&&(e.localVars[O4]=i)}}),()=>{}}function w4(e,t){return t.defineAction(`use`,{label:`缔盟`,style:`primary`,prompt:{type:`confirm`,title:`缔盟:选择两名其他角色交换手牌`,confirmLabel:`发动`,cancelLabel:`取消`},activeWhen:e=>yh(`缔盟`)(e)}),t.defineAction(`respond`,{label:`缔盟`,style:`primary`,prompt:{type:`confirm`,title:`缔盟`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var T4,E4,D4,O4,k4,Fge=t((()=>{V(),z(),Q(),F(),T4=`缔盟/target`,E4=`缔盟/discard`,D4=`缔盟/targets`,O4=`缔盟/discardCards`,k4={createSkill:S4,onInit:C4,onMount:w4}})),Ige=r({createSkill:()=>A4,default:()=>G4,onInit:()=>M4,onMount:()=>N4});function A4(e,t){return{id:e,ownerId:t,name:P4,description:`结束阶段可观看牌堆顶三张牌,获得其中X张(X为满足项数:本回合造成过伤害/未弃置过牌/手牌数全场最少),余牌任意顺序置牌堆顶;均不满足则自己与一名其他角色各失去1点体力`}}function j4(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function M4(e,t){let n=e.ownerId;return N(t,e.id,n,`造成伤害后`,async e=>{e.atom.source===n&&(e.state.turn.vars[U4(n)]=!0)}),N(t,e.id,n,`弃置`,async e=>{e.atom.player===n&&(e.state.turn.vars[W4(n)]=!0)}),j(t,e.id,n,`respond`,(e,t)=>{let r=j4(e,n);if(r!==F4&&r!==I4&&r!==L4)return`当前不是罪论询问`;if(r===F4)return null;if(r===L4){let r=t.target??t.targets?.[0];return typeof r==`number`?r===n?`不能选择自己`:e.players[r]?.alive?null:`目标已死亡`:`请选择一名其他角色`}let i=e.localVars[H4]??[],a=e.localVars[V4]??0,o=t.gained,s=t.topOrder;if(!Array.isArray(o)||!Array.isArray(s))return`需要 gained/topOrder 划分`;if(o.length!==a)return`应获得 ${a} 张牌`;let c=new Set(i),l=[...o,...s];return l.length===i.length&&new Set(l).size===l.length&&l.every(e=>c.has(e))?null:`划分不合法(必须恰好覆盖观看的牌)`},async(e,t)=>{let r=j4(e,n);if(r===F4)e.localVars[R4]=t.choice===!0||t.confirmed===!0;else if(r===I4)e.localVars[z4]={gained:t.gained??[],topOrder:t.topOrder??[]};else if(r===L4){let n=t.target??t.targets?.[0];typeof n==`number`&&(e.localVars[B4]=n)}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n)return;let r=e.state,i=r.players[n];if(!i?.alive)return;let a=!!r.turn.vars[U4(n)],o=!r.turn.vars[W4(n)],s=r.players.filter(e=>e.alive),c=s.reduce((e,t)=>Math.min(e,t.hand.length),1/0),l=s.length>0&&i.hand.length===c,u=+!!a+ +!!o+ +!!l;if(u===0){let e=s.filter(e=>e.index!==n),t;e.length>0&&(delete r.localVars[B4],await B(r,{type:`请求回应`,requestType:L4,target:n,prompt:{type:`choosePlayer`,title:`罪论:选择一名其他角色与其各失去1点体力`,min:1,max:1,candidates:e.map(e=>e.index)},timeout:20}),t=r.localVars[B4],delete r.localVars[B4],(typeof t!=`number`||!r.players[t]?.alive||t===n)&&(t=e[0].index)),await B(r,{type:`失去体力`,target:n,amount:1}),typeof t==`number`&&r.players[t]?.alive&&await B(r,{type:`失去体力`,target:t,amount:1});return}let d=r.zones.deck;if(d.length===0)return;let f=Math.min(3,d.length),p=d.slice(-f),m=Math.min(u,f);if(delete r.localVars[R4],await B(r,{type:`请求回应`,requestType:F4,target:n,prompt:{type:`confirm`,title:`是否发动罪论?(满足 ${u} 项,获得 ${m} 张)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!r.localVars[R4]){delete r.localVars[R4];return}delete r.localVars[R4],r.localVars[H4]=p,r.localVars[V4]=m,delete r.localVars[z4],await B(r,{type:`请求回应`,requestType:I4,target:n,prompt:{type:`distribute`,title:`罪论:选择 ${m} 张获得,其余 ${f-m} 张按顺序置于牌堆顶`,description:`respond: { gained: 要获得的牌; topOrder: 留在牌堆顶的牌(顺序即摸牌顺序,首个最先摸到) }`,mode:`select`,cardIds:p,minTotal:f,maxTotal:f},timeout:30});let h=r.localVars[z4];delete r.localVars[z4],delete r.localVars[H4],delete r.localVars[V4],(!h||!Array.isArray(h.gained)||!Array.isArray(h.topOrder))&&(h={gained:p.slice(0,m),topOrder:p.slice(m)});let g=h.gained,_=h.topOrder;for(let e of g)r.zones.deck.includes(e)&&await B(r,{type:`移动牌`,cardId:e,from:{zone:`牌堆`},to:{zone:`手牌`,player:n}});if(_.length>0){let e=_.length,t=[...r.zones.deck.slice(0,r.zones.deck.length-e),...[..._].reverse()];t.length===r.zones.deck.length&&await B(r,{type:`整理牌堆`,cards:t,topCount:e})}}),()=>{}}function N4(e,t){return t.defineAction(`respond`,{label:P4,style:`primary`,prompt:{type:`confirm`,title:`是否发动罪论?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var P4,F4,I4,L4,R4,z4,B4,V4,H4,U4,W4,G4,Lge=t((()=>{V(),F(),P4=`罪论`,F4=`${P4}/confirm`,I4=`${P4}/pick`,L4=`${P4}/chooseTarget`,R4=`${P4}/confirmed`,z4=`${P4}/pick`,B4=`${P4}/target`,V4=`${P4}/expectedGain`,H4=`${P4}/observed`,U4=e=>`${P4}/伤害/${e}`,W4=e=>`${P4}/弃置/${e}`,G4={createSkill:A4,onInit:M4,onMount:N4}})),Rge=r({createSkill:()=>K4,default:()=>$4,onInit:()=>q4,onMount:()=>J4});function K4(e,t){return{id:e,ownerId:t,name:`耀武`,description:`锁定技,当一名角色使用红色杀对你造成伤害时,其选择回复1点体力或摸一张牌`,isLocked:!0}}function q4(e,t){let n=e.ownerId,r=[];for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n||n.atom.type!==`请求回应`)return`当前不需要回应`;if(n.atom.requestType!==Y4)return`当前不是耀武选择`;let r=t.option;return r!==Z4&&r!==Q4?`请选择回复体力或摸牌`:null},async(e,t)=>{e.localVars[X4]=t.option}))}return r.push(N(t,e.id,n,`造成伤害后`,async e=>{let t=e.atom;if(t.target!==n||(t.amount??0)<=0)return;let r=t.source;if(typeof r!=`number`||!e.state.players[r]?.alive)return;let i=t.cardId,a=i?e.state.cardMap[i]:void 0;if(!a||a.name!==`杀`||a.color!==`红`)return;delete e.state.localVars[X4],await B(e.state,{type:`请求回应`,requestType:Y4,target:r,prompt:{type:`chooseOption`,title:`耀武:你对 ${e.state.players[n].name} 造成红色杀伤害,选择一项`,options:[{value:Z4,label:`回复1点体力`},{value:Q4,label:`摸一张牌`}]},timeout:20});let o=e.state.localVars[X4];delete e.state.localVars[X4],o===Z4?await B(e.state,{type:`回复体力`,target:r,amount:1,source:n}):await B(e.state,{type:`摸牌`,player:r,count:1})})),()=>{for(let e of r)e()}}function J4(e,t){t.defineAction(`respond`,{label:`耀武`,style:`primary`,prompt:{type:`chooseOption`,title:`耀武:选择一项`,options:[{value:Z4,label:`回复1点体力`},{value:Q4,label:`摸一张牌`}]}})}var Y4,X4,Z4,Q4,$4,zge=t((()=>{V(),F(),Y4=`耀武/选择`,X4=`耀武/选择结果`,Z4=`recover`,Q4=`draw`,$4={createSkill:K4,onInit:q4,onMount:J4}})),Bge=r({createSkill:()=>e3,default:()=>n3,onInit:()=>t3});function e3(e,t){return{id:e,ownerId:t,name:`肉林`,description:`锁定技:你对女性角色/女性角色对你使用【杀】时,目标需连续出两张闪才能抵消`,isLocked:!0}}function Vge(e,t,n){let r=e.players[t],i=e.players[n];if(!r||!i)return!1;let a=r.skills.includes(`肉林`),o=i.skills.includes(`肉林`),s=kc(i.character)===`女`,c=kc(r.character)===`女`;return a&&s||o&&c}function Hge(e,t){return`肉林/dodgeCount/${e}/${t}`}function Uge(e){return e.settlementStack[e.settlementStack.length-1]?.params?.cardId??``}function t3(e,t){let n=e.ownerId;return N(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(!Vge(e.state,t.source,t.target))return;let n=t.target,r=Uge(e.state);if(e.state.cardMap[r]?.name!==`杀`||!Je(e.state,r,n))return;let i=Hge(r,n),a=e.state.localVars[i]??0;if(a>=1){delete e.state.localVars[i];return}Ye(e.state,r,n),e.state.localVars[i]=a+1,await B(e.state,{type:`询问闪`,target:n,source:t.source}),delete e.state.localVars[i]}),()=>{}}var n3,Wge=t((()=>{V(),F(),z(),Fc(),n3={createSkill:e3,onInit:t3}})),Gge=r({createSkill:()=>a3,default:()=>x3,onInit:()=>c3,onMount:()=>l3});function r3(e){return`良姻/已触发/${e}`}function Kge(e,t){return e.players[t].vars[u3]?.length??0}function i3(e){let t=e.targets;if(Array.isArray(t)&&t.length>0)return t[0];let n=e.target;return typeof n==`number`?n:void 0}function a3(e,t){return{id:e,ownerId:t,name:`良姻`,description:`每回合首次有牌移出/移入游戏后,你可以与一名其他角色各摸/弃置一张牌,然后可令其中一名手牌数为X的角色回复1点体力(X为箜声牌数)`}}async function o3(e,t){if(!e.players[t]?.alive)return;let n=Kge(e,t);if(delete e.localVars[g3],await B(e,{type:`请求回应`,requestType:d3,target:t,prompt:{type:`confirm`,title:`是否发动良姻?(与一名其他角色各摸/弃一张牌,X=${n})`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.localVars[g3]){delete e.localVars[g3];return}delete e.localVars[g3],delete e.localVars[_3],await B(e,{type:`请求回应`,requestType:f3,target:t,prompt:{type:`choosePlayer`,title:`良姻:选择一名其他角色`,min:1,max:1,filter:(n,r)=>r!==t&&e.players[r]?.alive===!0},timeout:15});let r=e.localVars[_3];if(delete e.localVars[_3],typeof r!=`number`||!e.players[r]?.alive)return;delete e.localVars[v3],await B(e,{type:`请求回应`,requestType:p3,target:t,prompt:{type:`confirm`,title:`良姻:各摸一张牌 还是 各弃一张牌?`,confirmLabel:`各摸一张`,cancelLabel:`各弃一张`},defaultChoice:!0,timeout:15});let i=e.localVars[v3]??`摸`;if(delete e.localVars[v3],i===`摸`?(await B(e,{type:`摸牌`,player:t,count:1}),e.players[r]?.alive&&await B(e,{type:`摸牌`,player:r,count:1})):(await s3(e,t),e.players[r]?.alive&&await s3(e,r)),!e.players[t]?.alive)return;let a=[t,r].filter(t=>{let r=e.players[t];return!r?.alive||r.hand.length!==n?!1:p(r)<r.maxHealth});if(a.length===0)return;delete e.localVars[b3],await B(e,{type:`请求回应`,requestType:h3,target:t,prompt:{type:`choosePlayer`,title:`良姻:令一名手牌数为${n}的角色回复1点体力(可不选)`,min:1,max:1,filter:(e,t)=>a.includes(t)},timeout:15});let o=e.localVars[b3];delete e.localVars[b3],typeof o==`number`&&e.players[o]?.alive&&await B(e,{type:`回复体力`,target:o,amount:1,source:t})}async function s3(e,t){let n=e.players[t];if(!n?.alive||n.hand.length===0)return;delete e.localVars[y3],await B(e,{type:`请求回应`,requestType:m3,target:t,prompt:{type:`useCard`,title:`良姻:弃置一张牌`,cardFilter:{filter:()=>!0,min:1,max:1}},mandatory:!0,timeout:20});let r=e.localVars[y3];delete e.localVars[y3],(!r||r.length===0)&&e.players[t]?.hand.length&&(r=e.players[t].hand.slice(0,1)),r&&r.length>0&&await B(e,{type:`弃置`,player:t,cardIds:r})}function c3(e,t){let n=e.ownerId;N(t,e.id,n,`移出至暂存区`,async e=>{e.state.players[n]?.alive&&(e.state.turn.vars[r3(n)]||(e.state.turn.vars[r3(n)]=!0,await o3(e.state,n)))}),N(t,e.id,n,`归还暂存牌`,async e=>{e.state.players[n]?.alive&&(e.state.turn.vars[r3(n)]||(e.state.turn.vars[r3(n)]=!0,await o3(e.state,n)))});for(let n of t.players){let r=n.index;j(t,e.id,r,`respond`,(e,t)=>{let n=e.pendingSlots.get(r);if(!n||n.atom.type!==`请求回应`)return`当前不需要回应`;let i=n.atom.requestType;if(i===d3||i===p3)return null;if(i===f3||i===h3)return typeof t.target!=`number`&&!t.targets?`需要选择一名角色`:null;if(i===m3){let n=t.cardIds;if(!Array.isArray(n)||n.length!==1)return`请选择一张要弃置的手牌`;let i=e.players[r];return i?n.every(e=>typeof e==`string`&&i.hand.includes(e))?new Set(n).size===n.length?null:`cardIds 含重复牌`:`牌不在手牌中`:`玩家不存在`}return`当前不是良姻询问`},async(e,t)=>{let n=e.pendingSlots.get(r)?.atom?.requestType;if(n===d3)e.localVars[g3]=t.choice===!0||t.confirmed===!0;else if(n===f3){let n=i3(t);typeof n==`number`&&(e.localVars[_3]=n)}else if(n===p3)e.localVars[v3]=t.choice===!0?`摸`:`弃`;else if(n===m3)e.localVars[y3]=t.cardIds;else if(n===h3){let n=i3(t);typeof n==`number`&&(e.localVars[b3]=n)}})}return()=>{}}function l3(e,t){return()=>{}}var u3,d3,f3,p3,m3,h3,g3,_3,v3,y3,b3,x3,qge=t((()=>{b(),V(),F(),u3=`箜声/牌`,d3=`良姻/confirm`,f3=`良姻/目标`,p3=`良姻/摸弃`,m3=`良姻/弃牌`,h3=`良姻/回血`,g3=`良姻/confirmed`,_3=`良姻/目标`,v3=`良姻/摸弃`,y3=`良姻/弃牌结果`,b3=`良姻/回血目标`,x3={createSkill:a3,onInit:c3,onMount:l3}})),Jge=r({createSkill:()=>S3,default:()=>k3,onInit:()=>C3,onMount:()=>w3});function S3(e,t){return{id:e,ownerId:t,name:`节命`,description:`受到伤害后,令一名角色将手牌摸至其体力上限(最多5张)`}}function C3(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==T3&&a!==E3?`当前不是节命询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===T3)e.localVars[D3]=t.choice===!0;else if(r===E3){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[O3]=n)}}),N(t,e.id,n,`伤害结算结束后`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.amount??0;if(!(r<=0)&&e.state.players[n]?.alive)for(let t=0;t<r&&e.state.players[n]?.alive;t++){if(delete e.state.localVars[D3],await B(e.state,{type:`请求回应`,requestType:T3,target:n,prompt:{type:`confirm`,title:`是否发动节命?(令一名角色将手牌摸至体力上限)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),!e.state.localVars[D3])continue;delete e.state.localVars[O3],await B(e.state,{type:`请求回应`,requestType:E3,target:n,prompt:{type:`choosePlayer`,title:`节命:选择一名角色(手牌摸至体力上限)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0},timeout:15});let t=e.state.localVars[O3];if(delete e.state.localVars[O3],typeof t!=`number`||!e.state.players[t]?.alive)continue;let r=e.state.players[t],i=Math.min(r.maxHealth,5)-r.hand.length;i>0&&await B(e.state,{type:`摸牌`,player:t,count:i})}}),()=>{}}function w3(e,t){t.defineAction(`respond`,{label:`节命`,style:`primary`,prompt:{type:`confirm`,title:`是否发动节命?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var T3,E3,D3,O3,k3,Yge=t((()=>{V(),F(),T3=`节命/confirm`,E3=`节命/target`,D3=`节命/confirmed`,O3=`节命/target`,k3={createSkill:S3,onInit:C3,onMount:w3}})),Xge=r({createSkill:()=>A3,default:()=>P3,onInit:()=>j3,onMount:()=>M3});function A3(e,t){return{id:e,ownerId:t,name:`若愚`,description:`主公技/觉醒技:回合开始且体力全场最少时,增加1体力上限、回复1体力并永久获得"激将"`}}function j3(e,t){let n=e.ownerId;return N(t,e.id,n,`回合开始`,async e=>{if(e.atom.player!==n||e.state.players[n]?.vars[N3])return;let t=e.state.players[n];if(!t?.alive||n!==0)return;let r=e.state.players.filter(e=>e.alive);if(r.length===0)return;let i=Math.min(...r.map(e=>p(e)));p(t)>i||(e.state.players[n].vars[N3]=!0,await B(e.state,{type:`设上限`,player:n,amount:t.maxHealth+1}),await B(e.state,{type:`回复体力`,target:n,amount:1}),await B(e.state,{type:`添加技能`,player:n,skillId:`激将`}))}),()=>{}}function M3(e,t){}var N3,P3,Zge=t((()=>{b(),V(),F(),N3=`若愚/awakened`,P3={createSkill:A3,onInit:j3,onMount:M3}})),Qge=r({createSkill:()=>F3,default:()=>R3,onInit:()=>I3,onMount:()=>L3});function F3(e,t){return{id:e,ownerId:t,name:`苦肉`,description:`出牌阶段,你可以失去1点体力,然后摸两张牌。`}}function I3(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];return r?r.alive?r.health<=0?`体力不足,无法发动苦肉`:null:`player is dead`:`player not found`},async(e,t)=>{let r=n;await I(e,`苦肉`,r,{}),await B(e,{type:`失去体力`,target:r,amount:1}),e.players[r].alive&&await B(e,{type:`摸牌`,player:r,count:2}),await L(e)}),()=>{}}function L3(e,t){return t.defineAction(`use`,{label:`苦肉`,style:`primary`,prompt:{type:`confirm`,title:`苦肉:失去1点体力,然后摸两张牌`},activeWhen:e=>q(e)&&(e.view.players[e.perspectiveIdx]?.health??0)>0}),()=>{}}var R3,$ge=t((()=>{V(),z(),J(),F(),R3={createSkill:F3,onInit:I3,onMount:L3}})),e_e=r({createSkill:()=>z3,default:()=>U3,onInit:()=>B3,onMount:()=>V3});function z3(e,t){return{id:e,ownerId:t,name:`英姿`,description:`摸牌阶段,你可以额外摸一张牌`}}function B3(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===H3?null:`当前不是英姿确认`:`当前不需要回应`},async(e,t)=>{e.localVars[`英姿/confirmed`]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive||X(e.state,n,`英姿`)||(delete e.state.localVars[`英姿/confirmed`],await B(e.state,{type:`请求回应`,requestType:H3,target:n,prompt:{type:`confirm`,title:`是否发动英姿?(额外摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[`英姿/confirmed`]))return;await Z(e.state,n,`英姿`);let r=t.count??2;return{kind:`modify`,atom:{...e.atom,count:r+1}}}),()=>{}}function V3(e,t){t.defineAction(`respond`,{label:`英姿`,style:`primary`,prompt:{type:`confirm`,title:`是否发动英姿?(额外摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var H3,U3,t_e=t((()=>{V(),Q(),F(),H3=`英姿/confirm`,U3={createSkill:z3,onInit:B3,onMount:V3}})),n_e=r({createSkill:()=>W3,default:()=>Z3,onInit:()=>G3,onMount:()=>K3});function W3(e,t){return{id:e,ownerId:t,name:`荐降`,description:`当你成为其他角色使用牌的目标后,你可以令手牌数最少的一名角色摸一张牌`}}function r_e(e){let t=1/0,n=[];for(let r of e.players)r.alive&&(r.hand.length<t?(t=r.hand.length,n.length=0,n.push(r.index)):r.hand.length===t&&n.push(r.index));return n}function G3(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==q3&&a!==J3?`当前不是荐降询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===q3)e.localVars[Y3]=t.choice===!0||t.confirmed===!0;else if(r===J3){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[X3]=n)}}),N(t,e.id,n,`成为目标后`,async e=>{let t=e.atom;if(t.target!==n||t.source===n||!e.state.players[n]?.alive||(delete e.state.localVars[Y3],await B(e.state,{type:`请求回应`,requestType:q3,target:n,prompt:{type:`confirm`,title:`荐降:是否令手牌数最少的一名角色摸一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[Y3]))return;delete e.state.localVars[Y3];let r=r_e(e.state);if(r.length===0)return;let i;if(r.length===1)i=r[0];else{delete e.state.localVars[X3],await B(e.state,{type:`请求回应`,requestType:J3,target:n,prompt:{type:`choosePlayer`,title:`荐降:选择手牌数最少的一名角色(摸一张牌)`,min:1,max:1,candidates:r,filter:(e,t)=>r.includes(t)},timeout:15});let t=e.state.localVars[X3];if(delete e.state.localVars[X3],typeof t!=`number`)return;i=t}e.state.players[i]?.alive&&await B(e.state,{type:`摸牌`,player:i,count:1})}),()=>{}}function K3(e,t){return t.defineAction(`respond`,{label:`荐降`,style:`primary`,prompt:{type:`confirm`,title:`荐降`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var q3,J3,Y3,X3,Z3,i_e=t((()=>{V(),F(),q3=`荐降/confirm`,J3=`荐降/choose`,Y3=`荐降/confirmed`,X3=`荐降/target`,Z3={createSkill:W3,onInit:G3,onMount:K3}})),a_e=r({createSkill:()=>o_e,onInit:()=>s_e});function o_e(e,t){return{id:e,ownerId:t,name:`藤甲`,description:`锁定技,南蛮入侵/万箭齐发/普通杀对你无效;火焰伤害+1`,isLocked:!0}}function s_e(e,t){let n=e.ownerId,r=e=>{let t=e.players[n]?.equipment?.防具;return!!t&&e.cardMap[t]?.name===`藤甲`};return M(t,e.id,n,`检测有效性`,async e=>{let t=e.atom;if(t.target!==n||!r(e.state))return;let i=t.cardId;if(!i)return;let a=e.state.cardMap[i];if(!a)return;let o=a.name===`杀`&&a.damageType!==`火焰`&&a.damageType!==`雷电`,s=a.name===`南蛮入侵`||a.name===`万箭齐发`;if(o||s)return{kind:`cancel`}}),M(t,e.id,n,`受到伤害时`,async e=>{let t=e.atom;if(t.target!==n||!r(e.state)||t.damageType!==`火焰`)return;let i=t.amount??1;return{kind:`modify`,atom:{...e.atom,amount:i+1}}}),()=>{}}var c_e=t((()=>{F()})),l_e=r({createSkill:()=>Q3,default:()=>d6,onInit:()=>t6,onMount:()=>n6});function Q3(e,t){return{id:e,ownerId:t,name:`蛊惑`,description:`每回合限一次,扣置一张手牌声明为基本牌(杀/闪/桃/酒)使用或打出;其他角色可质疑`}}async function u_e(e,t,n,r){let i=e.cardMap[r],a=i?.damageType;await I(e,`杀`,t,{cardId:r,declaredName:`杀`,target:n});let o=i?.name;i&&o!==`杀`&&(i.name=`杀`);try{if(!await B(e,{type:`成为目标`,source:t,target:n,cardId:r})||!await B(e,{type:`检测有效性`,source:t,target:n,cardId:r}))return;await B(e,{type:`询问闪`,target:n,source:t});let i=e.settlementStack[e.settlementStack.length-1],o=R(e).filter(t=>e.cardMap[t]?.name===`闪`);if(i?.cancelled||o.length>0){await B(e,{type:`被抵消`,source:t,target:n,cardId:r});let i=R(e).filter(t=>e.cardMap[t]?.name===`闪`);for(let t of i)await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}})}else e.players[n]?.alive&&await Dm(e,t,n,1,r,a)}finally{for(let t of R(e))e.cardMap[t]?.name===`闪`&&await B(e,{type:`移动牌`,cardId:t,from:{zone:`处理区`},to:{zone:`弃牌堆`}});await L(e),i&&o!==void 0&&o!==`杀`&&(i.name=o)}uh(e),await B(e,{type:`回合用量`,player:t,key:El,value:ah(e)})}async function d_e(e,t,n,r){await B(e,{type:`移动牌`,cardId:n,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:t}});let i=`${n}#蛊惑${r}`;await B(e,{type:`当作`,player:t,cardIds:[n],shadowId:i,outputName:r}),await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:t},to:{zone:`处理区`}})}async function f_e(e,t,n,r,i){if(n===`杀`){if(typeof r!=`number`||!e.players[r]?.alive)return;await u_e(e,t,r,i)}else if(n===`桃`){let n=typeof r==`number`?r:t;if(!e.players[n]?.alive)return;await B(e,{type:`回复体力`,target:n,amount:1,source:t})}else n===`酒`&&await B(e,{type:`加标记`,player:t,mark:{id:`酒/nextKillDamageBonus`,scope:-1,payload:1,duration:`turn`}})}async function $3(e,t,n,r){await B(e,{type:`扣牌`,player:t,cardId:n,declaredName:r});let i=e.players.length,a;for(let n=1;n<i;n++){let o=(t+n)%i;if(o===t||!e.players[o]?.alive)continue;delete e.localVars[a6],await B(e,{type:`请求回应`,requestType:i6,target:o,prompt:{type:`confirm`,title:`是否质疑于吉声明为【${r}】的蛊惑?`},timeout:20});let s=e.localVars[a6];if(s!==void 0){a=s;break}}let o=e.localVars[o6];return a===void 0?{voided:!1,downCard:o}:(await B(e,{type:`展示`,player:t,cardId:o}),e.cardMap[o]?.name===r?(await B(e,{type:`失去体力`,target:a,amount:1}),{voided:!1,downCard:o,questioner:a}):(await B(e,{type:`移动牌`,cardId:o,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:a}}),{voided:!0,downCard:o,questioner:a}))}function e6(e){delete e.localVars[o6],delete e.localVars[s6],delete e.localVars[a6]}function t6(e,t){let n=e.ownerId,r=[];r.push(de(t,n,`询问闪`)),r.push(de(t,n,`请求回应`,`桃/求桃`));let i=r=>j(t,e.id,n,`${u6}${r}`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`蛊惑`))return`本回合已使用过蛊惑`;let i=e.players[n];if(!i?.alive)return`玩家不存在或已死亡`;let a=t.cardId;if(typeof a!=`string`||!i.hand.includes(a))return`请选择一张手牌`;if(r===`杀`){let r=t.target;if(typeof r!=`number`||!e.players[r]?.alive)return`请选择合法目标`;if(!Gm(e,n,r))return`目标不在攻击范围内`;if(!lh(e,n,a))return`出杀次数已达上限`}else if(r===`桃`){let r=t.target??n,i=e.players[r];if(!i?.alive)return`目标不存在`;if(i.health>=i.maxHealth)return`桃只能对受伤角色使用`}return null},async(e,t)=>{let i=n,a=t.cardId,o=t.target;await Z(e,i,`蛊惑`),await I(e,`蛊惑`,i,{cardId:a,declaredName:r});try{let t=await $3(e,i,a,r);t.voided||await f_e(e,i,r,o,t.downCard)}finally{e6(e),await L(e)}});for(let e of l6)r.push(i(e));r.push(j(t,e.id,n,`dodge`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;if(r.atom.type!==`询问闪`)return`当前不是出闪的窗口`;if(r.atom.target!==n)return`不是问你的`;if(!e.players[n]?.alive)return`你已死亡`;if(X(e,n,`蛊惑`))return`本回合已使用过蛊惑`;let i=t.cardId;return typeof i!=`string`||!e.players[n].hand.includes(i)?`请选择一张手牌`:null},async(e,t)=>{let r=n,i=t.cardId;await Z(e,r,`蛊惑`),await I(e,`蛊惑`,r,{cardId:i,declaredName:`闪`});let a,o;try{let t=await $3(e,r,i,`闪`);a=!t.voided,o=t.downCard}finally{e6(e),await L(e)}a&&await d_e(e,r,o,`闪`)})),r.push(j(t,e.id,n,`rescue`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`||i.requestType!==`桃/求桃`)return`当前不是求桃窗口`;if(i.target!==n)return`不是问你的`;if(!e.players[n]?.alive)return`你已死亡`;if(X(e,n,`蛊惑`))return`本回合已使用过蛊惑`;let a=t.cardId;return typeof a!=`string`||!e.players[n].hand.includes(a)?`请选择一张手牌`:null},async(e,t)=>{let r=n,i=t.cardId;await Z(e,r,`蛊惑`),await I(e,`蛊惑`,r,{cardId:i,declaredName:`桃`});let a;try{a=!(await $3(e,r,i,`桃`)).voided}finally{e6(e),await L(e)}a&&(e.localVars[c6]=!0)}));for(let n of t.players){let i=n.index;r.push(j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);return n?n.atom.requestType===i6?e.players[i]?.alive?null:`你已死亡`:`当前不是蛊惑质疑窗口`:`当前不需要回应`},async(e,t)=>{e.localVars[a6]=i}))}return()=>{for(let e of r)e()}}function n6(e,t){return t.defineAction(`${u6}杀`,{label:`蛊惑·杀`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`蛊惑:扣置一张手牌,声明为【杀】使用`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,n)=>lm(e.players,e.cardMap,t.viewer,n)}},activeWhen:e=>r6(e)&&sm(e.view,e.perspectiveIdx)}),t.defineAction(`${u6}桃`,{label:`蛊惑·桃`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`蛊惑:扣置一张手牌,声明为【桃】使用`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:0,max:1,filter:(e,t)=>{let n=e.players[t];return n?.alive===!0&&n.health<n.maxHealth}},selfTarget:!0},activeWhen:e=>{if(!r6(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?.alive===!0&&t.health<t.maxHealth}}),t.defineAction(`${u6}酒`,{label:`蛊惑·酒`,style:`primary`,prompt:{type:`useCard`,title:`蛊惑:扣置一张手牌,声明为【酒】使用`,cardFilter:{filter:()=>!0,min:1,max:1}},activeWhen:e=>r6(e)}),t.defineAction(`dodge`,{label:`蛊惑·闪`,style:`primary`,prompt:{type:`useCard`,title:`蛊惑:扣置一张手牌,声明为闪打出`,cardFilter:{min:1,max:1}},activeWhen:e=>p_e(e)}),t.defineAction(`rescue`,{label:`蛊惑·桃`,style:`primary`,prompt:{type:`useCard`,title:`蛊惑:扣置一张手牌,声明为桃救援`,cardFilter:{min:1,max:1}},activeWhen:e=>m_e(e)}),t.defineAction(`respond`,{label:`质疑`,style:`danger`,prompt:{type:`confirm`,title:`是否质疑于吉的蛊惑?`}}),()=>{}}function r6(e){let{view:t,perspectiveIdx:n}=e,r=t.players[n];if(!r||t.currentPlayerIndex!==n||t.phase!==`出牌`)return!1;let i=t.pending;return i!=null&&i.isBlocking!==!1||r.turnUsage?.[Zc(`蛊惑`)]?!1:(r.hand?.length??0)>0}function p_e(e){let{view:t,perspectiveIdx:n}=e,r=t.players[n];if(!r||r.turnUsage?.[Zc(`蛊惑`)]||(r.hand?.length??0)===0)return!1;let i=t.pending;return i?.target===n&&i.atom?.type===`询问闪`}function m_e(e){let{view:t,perspectiveIdx:n}=e,r=t.players[n];if(!r||r.turnUsage?.[Zc(`蛊惑`)]||(r.hand?.length??0)===0)return!1;let i=t.pending,a=i?.atom;return i?.target===n&&a?.type===`请求回应`&&a?.requestType===`桃/求桃`}var i6,a6,o6,s6,c6,l6,u6,d6,h_e=t((()=>{V(),z(),Om(),F(),Xm(),fh(),Q(),W(),um(),J(),i6=`蛊惑/质疑`,a6=`蛊惑/质疑者`,o6=`蛊惑/扣牌`,s6=`蛊惑/声明`,c6=`求桃/已救`,l6=[`杀`,`桃`,`酒`],u6=`use:`,d6={createSkill:Q3,onInit:t6,onMount:n6}})),g_e=r({createSkill:()=>f6,default:()=>_6,onInit:()=>p6,onMount:()=>m6});function f6(e,t){return{id:e,ownerId:t,name:`行殇`,description:`当其他角色死亡时,你可以获得其所有牌(手牌/装备/判定区)`}}function p6(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===h6?null:`当前不是行殇确认`:`当前不需要回应`},async(e,t)=>{e.localVars[g6]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`死亡时`,async e=>{let t=e.atom;if(t.type!==`死亡时`)return;let r=t.player;if(r===void 0||r===n||!e.state.players[n]?.alive)return;let i=e.state.players[r];if(!i)return;let a=[...i.hand],o=Object.values(i.equipment).filter(e=>typeof e==`string`),s=i.pendingTricks.map(e=>({trickName:e.name,cardId:e.card.id})),c=a.length+o.length+s.length;if(c!==0&&(delete e.state.localVars[g6],await B(e.state,{type:`请求回应`,requestType:h6,target:n,prompt:{type:`confirm`,title:`是否发动行殇?(从 ${e.state.players[r]?.name??`P${r}`} 获得 ${c} 张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[g6])){for(let t of a)await B(e.state,{type:`获得`,player:n,cardId:t,from:r});for(let t of o)await B(e.state,{type:`获得`,player:n,cardId:t,from:r});for(let{trickName:t,cardId:i}of s)await B(e.state,{type:`移除延时锦囊`,player:r,trickName:t}),await nt(e.state,r,i,n)}}),()=>{}}function m6(e,t){t.defineAction(`respond`,{label:`行殇`,style:`primary`,prompt:{type:`confirm`,title:`是否发动行殇?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var h6,g6,_6,__e=t((()=>{V(),rt(),F(),h6=`行殇/confirm`,g6=`行殇/confirmed`,_6={createSkill:f6,onInit:p6,onMount:m6}})),v_e=r({createSkill:()=>y_e,onInit:()=>b_e,onMount:()=>x_e});function y_e(e,t){return{id:e,ownerId:t,name:`装备`,description:`装备到对应栏位`}}function b_e(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o.alive===!0;if(typeof t.cardId!=`string`)return`cardId required`;let c=!!o.hand.includes(t.cardId),l=!!e.cardMap[t.cardId]?.subtype;return r&&i&&a&&s&&c&&l?null:`装备使用条件不满足`},async(e,t)=>{let r=n;await I(e,`装备通用`,r,{...t});let i=t.cardId,a=e.cardMap[i];if(a.subtype){let t=a.subtype,n=e.players[r].equipment[t];if(n){let i=e.cardMap[n];i?.name&&ym(i.name)&&await B(e,{type:`移除技能`,player:r,skillId:i.name}),await B(e,{type:`卸下`,player:r,slot:t}),await B(e,{type:`移动牌`,cardId:n,from:{zone:`手牌`,player:r},to:{zone:`弃牌堆`}})}}await B(e,{type:`装备`,player:r,cardId:i}),a?.name&&ym(a.name)&&await B(e,{type:`添加技能`,player:r,skillId:a.name}),await L(e)}),()=>{}}function x_e(e,t){t.defineAction(`use`,{label:`装备`,style:`default`,prompt:{type:`useCard`,title:`装备`,cardFilter:{filter:e=>e.type===`装备牌`,min:1,max:1}}})}var S_e=t((()=>{V(),z(),F(),Sm()})),C_e=r({createSkill:()=>v6,default:()=>C6,onInit:()=>y6,onMount:()=>b6});function v6(e,t){return{id:e,ownerId:t,name:`裸衣`,description:`摸牌阶段少摸一张牌,本回合使用【杀】或【决斗】造成的伤害+1`}}function y6(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===S6?null:`当前不是裸衣确认`:`当前不需要回应`},async(e,t)=>{e.localVars[`裸衣/confirmed`]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`摸牌`,async e=>{let t=e.atom;if(t.player!==n||e.state.currentPlayerIndex!==n||e.state.phase!==`摸牌`||!e.state.players[n]?.alive||X(e.state,n,`裸衣`)||(delete e.state.localVars[`裸衣/confirmed`],await B(e.state,{type:`请求回应`,requestType:S6,target:n,prompt:{type:`confirm`,title:`是否发动裸衣?(少摸一张牌,杀/决斗伤害 +1)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[`裸衣/confirmed`]))return;await Z(e.state,n,`裸衣`),await B(e.state,{type:`加标签`,player:n,tag:x6});let r=t.count??2;return{kind:`modify`,atom:{...e.atom,count:Math.max(0,r-1)}}}),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n||(t.amount??0)<=0||!e.state.players[n]?.tags.includes(x6))return;let r=t.cardId;if(typeof r!=`string`)return;let i=e.state.cardMap[r];if(i&&!(i.name!==`杀`&&i.name!==`决斗`))return{kind:`modify`,atom:{...e.atom,amount:(t.amount??0)+1}}}),N(t,e.id,n,`回合结束`,async e=>{e.atom.player===n&&e.state.players[n]?.tags.includes(x6)&&await B(e.state,{type:`去标签`,player:n,tag:x6})}),()=>{}}function b6(e,t){t.defineAction(`respond`,{label:`裸衣`,style:`primary`,prompt:{type:`confirm`,title:`是否发动裸衣?(少摸一张牌,杀/决斗伤害 +1)`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var x6,S6,C6,w_e=t((()=>{V(),Q(),F(),x6=`裸衣/bonus`,S6=`裸衣/confirm`,C6={createSkill:v6,onInit:y6,onMount:b6}})),T_e=r({createSkill:()=>w6,default:()=>D6,onInit:()=>T6,onMount:()=>E6});function w6(e,t){return{id:e,ownerId:t,name:`观星`,description:`准备阶段开始时,观看牌堆顶X张牌(X为全场角色数至多5),调整顺序,余者置牌堆底`}}function T6(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;return i!==`观星/confirm`&&i!==`观星/arrange`?`当前不是观星询问`:i===`观星/arrange`&&(!Array.isArray(t.top)||!Array.isArray(t.bottom))?`观星:需要 top/bottom 划分`:null},async(e,t)=>{let r=(e.pendingSlots.get(n)?.atom).requestType;r===`观星/confirm`?e.localVars[`观星/confirmed`]=t.choice===!0||t.confirmed===!0:r===`观星/arrange`&&(e.localVars[`观星/arrangement`]={top:t.top??[],bottom:t.bottom??[]})}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||!e.state.players[n]?.alive)return;let r=e.state.zones.deck;if(r.length===0)return;let i=Math.min(e.state.players.length,5),a=Math.min(i,r.length);if(a===0||(delete e.state.localVars[`观星/confirmed`],await B(e.state,{type:`请求回应`,requestType:`观星/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动观星?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[`观星/confirmed`]))return;let o=r.slice(-a);delete e.state.localVars[`观星/arrangement`],await B(e.state,{type:`请求回应`,requestType:`观星/arrange`,target:n,prompt:{type:`distribute`,title:`观星:排列牌堆顶牌`,description:`选择留在牌堆顶的牌(顺序即摸牌顺序)与置于牌堆底的牌`,mode:`select`,cardIds:o,minTotal:0,maxTotal:a},defaultChoice:!1,timeout:30});let s=e.state.localVars[`观星/arrangement`];delete e.state.localVars[`观星/arrangement`],delete e.state.localVars[`观星/confirmed`];let c=s?.top??[],l=s?.bottom??[],u=new Set(o),d=[...c,...l];if(!(d.length===o.length&&new Set(d).size===d.length&&d.every(e=>u.has(e))))return;let f=r.slice(0,r.length-a),p=[...l,...f,...[...c].reverse()];await B(e.state,{type:`整理牌堆`,cards:p,topCount:c.length,bottomCount:l.length})}),()=>{}}function E6(e,t){t.defineAction(`respond`,{label:`观星`,style:`default`,prompt:{type:`confirm`,title:`是否发动观星?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var D6,E_e=t((()=>{V(),F(),D6={createSkill:w6,onInit:T6,onMount:E6}})),D_e=r({createSkill:()=>A6,default:()=>G6,onInit:()=>j6,onMount:()=>M6});function O6(e){return`${e}#${N6}`}function O_e(e,t){for(let n of e.pendingSlots.values()){let e=n.atom;if(e.type===`请求回应`&&e.requestType===`无懈可击`&&typeof e.target==`number`&&(e.target<0||e.target===t))return!0}return!1}function k6(e,t){let n=e.players[t];if(!n)return[];let r=[...n.hand],i=Object.values(n.equipment).filter(e=>!!e),a=n.pendingTricks.map(e=>e.card.id);return[...r,...i,...a]}async function k_e(e,t,n,r){if(t===r)return;let i=e.players[t];if(!i||!e.cardMap[n])return;let a=i.pendingTricks.find(e=>e.card.id===n);if(a){await B(e,{type:`移除延时锦囊`,player:t,trickName:a.name}),await B(e,{type:`获得`,player:r,cardId:n,from:t});return}await B(e,{type:`获得`,player:r,cardId:n,from:t})}function A6(e,t){return{id:e,ownerId:t,name:`解围`,description:`装备区的一张牌当无懈可击使用;武将牌从背面翻至正面时可弃置一张牌移动场上的一张牌`}}function j6(e,t){let n=e.ownerId;return j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId,a=typeof i==`string`,o=a?e.cardMap[i]:void 0,s=!!o&&o.type===`装备牌`,c=a&&Object.values(r.equipment).some(e=>e===i),l=O_e(e,n),u=(()=>{for(let t of e.pendingSlots.values()){let e=t.atom;if(t.isBlocking&&!(e.type===`请求回应`&&e.requestType===`无懈可击`))return!0}return!1})();return s&&c&&l&&!u?null:`现在不能使用解围`},async(e,t)=>{let r=t.cardId,i=O6(r),a=e.players[n],o=Object.entries(a.equipment).find(([,e])=>e===r);if(o){let i=o[0];t._origSlot=i;let a=e.cardMap[r];a?.name&&ym(a.name)&&await B(e,{type:`移除技能`,player:n,skillId:a.name}),await B(e,{type:`卸下`,player:n,slot:i})}await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`无懈可击`})},async(e,t)=>{let r=t.cardId,i=O6(r),a=e.players[n],o=t._origSlot;delete e.cardMap[i];let s=a.hand.indexOf(i);if(s>=0)if(o){if(a.hand.splice(s,1),a.equipment[o]=r,o===`武器`){let t=e.cardMap[r];a.vars[wl]=t?.range??1}let t=e.cardMap[r];t?.name&&ym(t.name)&&(a.skills.includes(t.name)||a.skills.push(t.name),await f9(e,t.name,n))}else a.hand[s]=r}),j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return[P6,F6,I6,L6,R6].includes(a)?null:`当前不是解围询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===P6){e.localVars[z6]=t.choice===!0;return}if(r===F6){let n=t.cardIds,r=t.cardId,i=(Array.isArray(n)&&n.length>0?n[0]:void 0)??(typeof r==`string`?r:void 0);i&&(e.localVars[B6]=i);return}if(r===I6){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[V6]=n);return}if(r===L6){let n=t.zone,r=t.cardId,i=t.handIndex;e.localVars[H6]=JSON.stringify({zone:n,cardId:r,handIndex:i});return}if(r===R6){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[U6]=n);return}}),N(t,e.id,n,`翻面后`,async e=>{let t=e.atom;if(t.type!==`翻面后`||t.player!==n||t.faceDown!==!1||e.state.localVars[W6])return;let r=e.state.players[n];if(r?.alive&&r.hand.length!==0&&e.state.players.some(t=>t.alive&&k6(e.state,t.index).length>0)){e.state.localVars[W6]=!0;try{if(delete e.state.localVars[z6],await B(e.state,{type:`请求回应`,requestType:P6,target:n,prompt:{type:`confirm`,title:`解围:是否弃置一张牌移动场上的一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[z6])return;delete e.state.localVars[B6],await B(e.state,{type:`请求回应`,requestType:F6,target:n,prompt:{type:`distribute`,mode:`select`,title:`解围:选择一张手牌弃置`,source:`hand`,minTotal:1,maxTotal:1},timeout:20});let t=e.state.localVars[B6];if(delete e.state.localVars[B6],!t||!r.hand.includes(t)||(await B(e.state,{type:`弃置`,player:n,cardIds:[t],voluntary:!0}),e.state.players.filter(t=>t.alive&&k6(e.state,t.index).length>0).length===0))return;delete e.state.localVars[V6],await B(e.state,{type:`请求回应`,requestType:I6,target:n,prompt:{type:`choosePlayer`,title:`解围:选择源玩家(从其场上选一张牌移动)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0&&k6(e.state,n).length>0},timeout:15});let i=e.state.localVars[V6];if(delete e.state.localVars[V6],typeof i!=`number`)return;let a=e.state.players[i];if(!a?.alive||k6(e.state,i).length===0)return;let o=Object.entries(a.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.state.cardMap[n]?.name??`?`})),s=a.pendingTricks.map(e=>({cardId:e.card.id,cardName:e.card.name})),c=a.hand.length;if(o.length===0&&s.length===0&&c===0)return;delete e.state.localVars[H6],await B(e.state,{type:`请求回应`,requestType:L6,target:n,prompt:{type:`pickTargetCard`,title:`解围:选择要移动的场上牌`,target:i,equipment:o,judge:s,handCount:c},timeout:20});let l=e.state.localVars[H6];delete e.state.localVars[H6];let u;if(l)try{let e=JSON.parse(l);if(e.zone===`equipment`||e.zone===`judge`)typeof e.cardId==`string`&&(u=e.cardId);else if(e.zone===`hand`){let t=typeof e.handIndex==`number`?e.handIndex:0;u=a.hand[t]??a.hand[0]}}catch{}if(!u||!k6(e.state,i).includes(u))return;delete e.state.localVars[U6],await B(e.state,{type:`请求回应`,requestType:R6,target:n,prompt:{type:`choosePlayer`,title:`解围:选择目标玩家(将牌移到其场上)`,min:1,max:1,filter:(t,n)=>e.state.players[n]?.alive===!0&&n!==i},timeout:15});let d=e.state.localVars[U6];if(delete e.state.localVars[U6],typeof d!=`number`)return;await k_e(e.state,i,u,d)}finally{delete e.state.localVars[W6]}}}),()=>{}}function M6(e,t){t.defineAction(`transform`,{label:`解围`,style:`passive`,prompt:{type:`useCard`,title:`选择一张装备牌当无懈可击使用`,cardFilter:{filter:e=>e.type===`装备牌`,min:1,max:1}},transform:t=>({name:`无懈可击`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view,n=t.pending;if(!n)return!1;let r=n.atom;if(r.type!==`请求回应`||r.requestType!==`无懈可击`)return!1;let i=t.players[e.perspectiveIdx];return i?Object.values(i.equipment??{}).some(e=>typeof e==`string`&&!!e):!1}}),t.defineAction(`respond`,{label:`解围`,style:`primary`,prompt:{type:`confirm`,title:`是否发动解围?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var N6,P6,F6,I6,L6,R6,z6,B6,V6,H6,U6,W6,G6,A_e=t((()=>{V(),F(),v9(),Sm(),W(),N6=`解围`,P6=`解围/confirm`,F6=`解围/discard`,I6=`解围/source-player`,L6=`解围/source-card`,R6=`解围/dest-player`,z6=`解围/confirmed`,B6=`解围/discardCardId`,V6=`解围/sourcePlayer`,H6=`解围/sourceCard`,U6=`解围/destPlayer`,W6=`解围/moving`,G6={createSkill:A6,onInit:j6,onMount:M6}})),j_e=r({createSkill:()=>K6,default:()=>X6,onInit:()=>q6,onMount:()=>J6});function M_e(e,t){return e.currentPlayerIndex===t&&e.phase===`出牌`}function K6(e,t){return{id:e,ownerId:t,name:`诈降`,description:`锁定技:当你失去1点体力后,你摸三张牌,若在你的出牌阶段,你本回合使用【杀】的限制次数+1、使用红色【杀】无距离限制且不能被抵消。`,isLocked:!0}}function q6(e,t){let n=e.ownerId,r=$m(t,n,(e,t)=>+(e.turn.vars[Y6]===t)),i=qm(t,n,(e,t,n,r)=>e.turn.vars[Y6]!==t||!r?!1:e.cardMap[r]?.color===`红`),a=M(t,e.id,n,`询问闪`,async e=>{if(e.atom.source!==n||e.state.turn.vars[Y6]!==n)return;let t=e.params?.cardId;if(!t)return;let r=e.state.cardMap[t];if(r?.name===`杀`&&r.color===`红`)return{kind:`cancel`}});return N(t,e.id,n,`失去体力`,async e=>{let t=e.atom;t.target===n&&((t.amount??0)<=0||(await B(e.state,{type:`摸牌`,player:n,count:3}),M_e(e.state,n)&&(e.state.turn.vars[Y6]=n,await B(e.state,{type:`回合用量`,player:n,key:Jc(`诈降`),value:1}))))}),()=>{r(),i(),a()}}function J6(e,t){return()=>{}}var Y6,X6,N_e=t((()=>{V(),F(),fh(),Xm(),W(),Y6=`诈降/active`,X6={createSkill:K6,onInit:q6,onMount:J6}})),P_e=r({createSkill:()=>F_e,onInit:()=>I_e});function F_e(e,t){return{id:e,ownerId:t,name:`诸葛连弩`,description:`武器:出牌阶段使用【杀】无次数限制`,isLocked:!0}}function I_e(e,t){let n=e.ownerId;return eh(t,n,()=>!0)}var L_e=t((()=>{fh()})),R_e=r({createSkill:()=>Z6,default:()=>$6,onInit:()=>Q6});function Z6(e,t){return{id:e,ownerId:t,name:`谦节`,description:`锁定技:当你进入连环状态时防止之;你不能成为延时锦囊牌和其他角色拼点的目标`,isLocked:!0}}function z_e(e){switch(e){case`武器`:case`防具`:case`进攻马`:case`防御马`:case`宝物`:return e;default:return null}}function Q6(e,t){let n=e.ownerId;return M(t,e.id,n,`设横置`,async e=>{let t=e.atom;if(t.player===n&&t.chained)return{kind:`cancel`}}),M(t,e.id,n,`添加延时锦囊`,async e=>{if(e.atom.player===n)return{kind:`cancel`}}),M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.target!==n)return;let r=t.requestType;if(!(typeof r!=`string`||!r.endsWith(`/拼点`)))return{kind:`cancel`}}),M(t,e.id,n,`装备`,async e=>{let t=e.atom;if(t.player!==n)return;let r=e.state.cardMap[t.cardId];if(!r)return;let i=z_e(r.subtype);if(i&&e.state.players[n]?.vars[`决堰/废除:`+i])return{kind:`cancel`}}),()=>{}}var $6,B_e=t((()=>{F(),Ov(),$6={createSkill:Z6,onInit:Q6}})),V_e=r({createSkill:()=>e8,default:()=>n8,onInit:()=>t8});function e8(e,t){return{id:e,ownerId:t,name:`谦逊`,description:`锁定技:你不能成为顺手牵羊和乐不思蜀的目标`,isLocked:!0}}function t8(e,t){let n=e.ownerId;return M(t,e.id,n,`添加延时锦囊`,async e=>{let t=e.atom;if(t.player===n&&t.trick?.name===`乐不思蜀`)return{kind:`cancel`}}),M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.from===n&&t.player!==n&&Ke(e.state)?.skillId===`顺手牵羊`)return{kind:`cancel`}}),()=>{}}var n8,H_e=t((()=>{z(),F(),n8={createSkill:e8,onInit:t8}})),U_e=r({createSkill:()=>o8,default:()=>_8,onInit:()=>s8,onMount:()=>c8});function r8(e,t){return e.players[t]?.vars[u8]===`阴`?`阴`:`阳`}async function i8(e,t){await B(e,{type:`回合用量`,player:t,key:d8,value:r8(e,t)})}function a8(e,t){let n=e.cardMap[t];if(!n)return;let r=n.color;if(r!==`红`&&r!==`黑`)return;let i=e.localVars[g8]??{};t in i||(i[t]=r),e.localVars[g8]=i}function o8(e,t){return{id:e,ownerId:t,name:l8,description:`转换技。阳:出牌阶段限一次,选攻击范围内一名其他角色,弃一张与"任"同色的牌对其造成1点伤害。阴:回合外使用或打出的牌置入弃牌堆时,若与"任"同色,可令一名角色摸一张牌`}}function s8(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;if(a===f8)return null;if(a===p8){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);return typeof n==`number`?e.players[n]?.alive?null:`目标不合法`:`需要指定一名角色`}return`当前不是贞良回应`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;if(r===f8)e.localVars[m8]=t.choice===!0||t.confirmed===!0;else if(r===p8){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[h8]=n)}}),j(t,e.id,n,`use`,(e,t)=>{let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,l8))return`本回合已使用过贞良`;if(r8(e,n)!==`阳`)return`当前为阴状态,无法发动阳`;let i=kD(e,n);if(!i)return`没有"任",无法发动贞良`;let a=t.target;if(typeof a!=`number`)return`需要指定目标`;if(a===n)return`不能对自己发动贞良`;if(!e.players[a]?.alive)return`目标不合法`;if(!Gm(e,n,a))return`目标不在攻击范围内`;let o=t.cardId;return typeof o==`string`?r.hand.includes(o)?e.cardMap[o]?.color===i?null:`必须弃置一张与"任"颜色相同的牌`:`牌不在手牌中`:`需要选择一张牌`},async(e,t)=>{let r=n,i=t.target,a=t.cardId;await Z(e,r,l8),e.players[r].vars[u8]=`阴`,await i8(e,r),await I(e,`${l8}(阳)`,r,{target:i,cardId:a}),e.players[r].hand.includes(a)&&await B(e,{type:`弃置`,player:r,cardIds:[a]}),e.players[i]?.alive&&await Dm(e,r,i,1),await L(e)}),N(t,e.id,n,`使用时`,async e=>{let t=e.atom;t.type===`使用时`&&t.source===n&&t.cardId&&a8(e.state,t.cardId)}),N(t,e.id,n,`打出牌时`,async e=>{let t=e.atom;t.type===`打出牌时`&&t.player===n&&t.cardId&&a8(e.state,t.cardId)}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(t.type!==`移动牌`||!t.cardId||t.from?.zone!==`处理区`||t.to?.zone!==`弃牌堆`)return;let r=e.state,i=r.localVars[g8];if(!i||!(t.cardId in i))return;let a=i[t.cardId];if(delete i[t.cardId],r8(r,n)!==`阴`||!r.players[n]?.alive||r.currentPlayerIndex===n)return;let o=kD(r,n);if(!o||a!==o||(delete r.localVars[m8],await B(r,{type:`请求回应`,requestType:f8,target:n,prompt:{type:`confirm`,title:`贞良(阴):是否令一名角色摸一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!r.localVars[m8]))return;delete r.localVars[m8],delete r.localVars[h8],await B(r,{type:`请求回应`,requestType:p8,target:n,prompt:{type:`choosePlayer`,title:`贞良(阴):选择一名角色摸一张牌`,min:1,max:1,candidates:r.players.filter(e=>e.alive).map(e=>e.index),filter:(e,t)=>!!r.players[t]?.alive},timeout:20});let s=r.localVars[h8];delete r.localVars[h8],!(typeof s!=`number`||!r.players[s]?.alive)&&(await B(r,{type:`摸牌`,player:s,count:1}),r.players[n].vars[u8]=`阳`,await i8(r,n))}),N(t,e.id,n,`回合开始`,async e=>{e.atom.type===`回合开始`&&e.atom.player===n&&await i8(e.state,n)}),()=>{}}function c8(e,t){return t.defineAction(`use`,{label:l8,style:`danger`,prompt:{type:`useCardAndTarget`,title:`贞良(阳):弃一张与"任"同色的牌,对攻击范围内一名角色造成1点伤害`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>lm(e.players,e.cardMap,e.currentPlayerIndex,t)}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];if(!t||t.turnUsage?.[d8]===`阴`||t.turnUsage?.[`贞良/usedThisTurn`])return!1;let n=t.marks.find(e=>e.id===PD)?.payload?.cardId;if(typeof n!=`string`)return!1;let r=e.view.cardMap[n]?.color;return r!==`红`&&r!==`黑`||!(t.hand??[]).some(e=>e.color===r)?!1:e.view.players.some(t=>t.index!==e.perspectiveIdx&&t.alive)}}),t.defineAction(`respond`,{label:l8,style:`primary`,prompt:{type:`confirm`,title:`贞良`,confirmLabel:`确认`,cancelLabel:`取消`}}),()=>{}}var l8,u8,d8,f8,p8,m8,h8,g8,_8,W_e=t((()=>{V(),z(),Om(),Xm(),Q(),J(),um(),F(),VD(),l8=`贞良`,u8=`贞良/态`,d8=`贞良/态`,f8=`贞良/阴/confirm`,p8=`贞良/阴/选目标`,m8=`贞良/阴/confirmed`,h8=`贞良/阴/目标`,g8=`贞良/阴/usedColors`,_8={createSkill:o8,onInit:s8,onMount:c8}})),G_e=r({createSkill:()=>K_e,onInit:()=>q_e,onMount:()=>J_e});function K_e(e,t){return{id:e,ownerId:t,name:`贯石斧`,description:`武器技:杀被闪抵消后,可弃两张牌令此杀依然造成伤害`}}function q_e(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;if(r.atom.requestType!==`贯石斧/select`)return`当前不是贯石斧询问`;let i=t.cardIds;if(!Array.isArray(i)||i.length!==2)return`需要选择 2 张牌`;let a=e.players[n];if(!a)return`player not found`;let[o,s]=i;if(o===s)return`不能选择同一张牌`;let c=Object.values(a.equipment).filter(e=>typeof e==`string`);return[o,s].every(e=>a.hand.includes(e)||c.includes(e))?null:`所选牌不在你的手牌或装备区`},async(e,t)=>{e.localVars[`贯石斧/selected`]=t.cardIds}),N(t,e.id,n,`被抵消`,async e=>{if(e.frame.skillId!==`杀`)return;let t=e.atom;if(t.source!==n)return;let r=e.state.players[n];if(!r)return;let i=r.equipment.武器;if(!i||e.state.cardMap[i]?.name!==`贯石斧`||!Je(e.state,t.cardId,t.target))return;let a=Object.values(r.equipment).filter(e=>typeof e==`string`);if(r.hand.length+a.length<2)return;delete e.state.localVars[`贯石斧/selected`],await B(e.state,{type:`请求回应`,requestType:`贯石斧/select`,target:n,prompt:{type:`distribute`,title:`贯石斧:选择 2 张牌弃置强命(不选则不发动)`,mode:`select`,source:`handAndEquip`,minTotal:2,maxTotal:2},defaultChoice:!1,timeout:30});let o=e.state.localVars[`贯石斧/selected`];delete e.state.localVars[`贯石斧/selected`],o?.length===2&&(await B(e.state,{type:`弃置`,player:n,cardIds:o,voluntary:!0}),Ye(e.state,t.cardId,t.target))}),()=>{}}function J_e(e,t){t.defineAction(`respond`,{label:`贯石斧`,style:`danger`,prompt:{type:`distribute`,title:`贯石斧:选择 2 张牌弃置强命(不选则不发动)`,mode:`select`,source:`handAndEquip`,minTotal:2,maxTotal:2}})}var Y_e=t((()=>{V(),F(),z()})),X_e=r({createSkill:()=>v8,default:()=>D8,onInit:()=>b8,onMount:()=>x8});function v8(e,t){return{id:e,ownerId:t,name:S8,description:`结束阶段可摸两张牌,然后将手牌弃至X张(X为本回合发动奇制的次数)`}}function y8(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function b8(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=y8(e,n);if(r!==C8&&r!==w8)return`当前不是进趋询问`;if(r===C8)return null;let i=t.cardIds;if(!Array.isArray(i)||i.length===0)return`请选择要弃置的牌`;let a=e.players[n];if(!a)return`玩家不存在`;let o=new Set;for(let e of i){if(typeof e!=`string`||!a.hand.includes(e))return`牌 ${e} 不在手牌中`;if(o.has(e))return`存在重复的牌`;o.add(e)}let s=fl(e.turn.vars)??0,c=a.hand.length-s;return c<=0?`当前无需弃置`:i.length===c?null:`需要恰好弃置 ${c} 张手牌`},async(e,t)=>{let r=y8(e,n);if(r===C8)e.localVars[T8]=t.choice===!0||t.confirmed===!0;else if(r===w8){let n=t.cardIds;Array.isArray(n)&&(e.localVars[E8]=n)}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n||!e.state.players[n]?.alive)return;let r=fl(e.state.turn.vars)??0;if(delete e.state.localVars[T8],await B(e.state,{type:`请求回应`,requestType:C8,target:n,prompt:{type:`confirm`,title:`是否发动进趋?(摸两张牌,然后将手牌弃至 ${r} 张)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),!e.state.localVars[T8]){delete e.state.localVars[T8];return}delete e.state.localVars[T8],await B(e.state,{type:`摸牌`,player:n,count:2});let i=e.state.players[n]?.hand.length??0;if(i>r){let t=i-r;delete e.state.localVars[E8],await B(e.state,{type:`请求回应`,requestType:w8,target:n,prompt:{type:`useCard`,title:`进趋:弃 ${t} 张手牌(弃至 ${r} 张)`,cardFilter:{filter:()=>!0,min:t,max:t}},mandatory:!0,timeout:30});let a=e.state.localVars[E8];delete e.state.localVars[E8],(!a||a.length===0)&&t>0&&(a=e.state.players[n]?.hand.slice(0,t)??[]),a&&a.length>0&&await B(e.state,{type:`弃置`,player:n,cardIds:a})}}),()=>{}}function x8(e,t){return t.defineAction(`respond`,{label:S8,style:`primary`,prompt:{type:`confirm`,title:`是否发动进趋?`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var S8,C8,w8,T8,E8,D8,Z_e=t((()=>{V(),F(),W(),S8=`进趋`,C8=`${S8}/confirm`,w8=`${S8}/弃牌`,T8=`${S8}/confirmed`,E8=`${S8}/discardCards`,D8={createSkill:v8,onInit:b8,onMount:x8}})),Q_e=r({createSkill:()=>k8,default:()=>M8,onInit:()=>A8,onMount:()=>j8});function O8(e){return`${e}#连环`}function k8(e,t){return{id:e,ownerId:t,name:`连环`,description:`你可以将一张梅花手牌当【铁索连环】使用或重铸`}}function A8(e,t){let n=e.ownerId;return j(t,e.id,n,`recycle`,(e,t)=>{let r=e.currentPlayerIndex===n,i=e.phase===`出牌`,a=!E(e),o=e.players[n],s=o?.alive===!0,c=t.cardId,l=typeof c==`string`,u=l?e.cardMap[c]:void 0,d=l&&o.hand.includes(c),f=!!u&&u.suit===`♣`;return r&&i&&a&&s&&d&&f?null:`现在不能重铸(需出牌阶段、手中梅花牌)`},async(e,t)=>{let r=n,i=t.cardId;await I(e,`连环`,r,{...t}),await rP(e,r,i),await L(e)}),j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r?.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a),l=!!s&&s.suit===`♣`;return i?!o||!c?`牌不在手牌中`:l?null:`只能将梅花牌当铁索连环`:`你已死亡`},async(e,t)=>{let r=t.cardId,i=O8(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`铁索连环`})},(e,t)=>{let r=t.cardId,i=O8(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)}),()=>{}}function j8(e,t){t.defineAction(`recycle`,{label:`连环·重铸`,style:`primary`,prompt:{type:`useCard`,title:`连环:弃一张梅花手牌,摸一张牌`,cardFilter:{filter:e=>e.suit===`♣`,min:1,max:1}},activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.suit===`♣`)??!1:!1}}),t.defineAction(`transform`,{label:`连环`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`连环:将一张梅花手牌当铁索连环使用`,cardFilter:{filter:e=>e.suit===`♣`,min:1,max:1},targetFilter:{min:1,max:2,allowSelf:!0}},transform:t=>({name:`铁索连环`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{if(!q(e))return!1;let t=e.view.players[e.perspectiveIdx];return t?t.hand?.some(e=>e.suit===`♣`)??!1:!1}})}var M8,$_e=t((()=>{V(),z(),iP(),F(),J(),M8={createSkill:k8,onInit:A8,onMount:j8}})),eve=r({createSkill:()=>N8,default:()=>z8,onInit:()=>P8,onMount:()=>F8});function N8(e,t){return{id:e,ownerId:t,name:`连营`,description:`被动技:当你失去最后的手牌时,你可以摸一张牌`}}function P8(e,t){let n=e.ownerId;async function r(e){let t=e.state.players[n];t?.alive&&t.hand.length===0&&(e.state.zones.deck.length===0&&e.state.zones.discardPile.length===0||(delete e.state.localVars[L8],await B(e.state,{type:`请求回应`,requestType:I8,target:n,prompt:{type:`confirm`,title:`是否发动连营?(失去最后的手牌,摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[L8]&&await B(e.state,{type:`摸牌`,player:n,count:1})))}return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===I8?null:`当前不是连营确认`:`当前不是请求回应`},async(e,t)=>{e.localVars[L8]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;t.type===`移动牌`&&t.from.zone===`手牌`&&t.from.player===n&&(t.to.zone===`手牌`&&t.to.player===n||await r(e))}),N(t,e.id,n,`给予`,async e=>{let t=e.atom;t.type===`给予`&&t.from===n&&t.to!==n&&await r(e)}),N(t,e.id,n,`装备`,async e=>{let t=e.atom;t.type===`装备`&&t.player===n&&await r(e)}),M(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.type!==`获得`||t.from!==n||t.player===n)return;let r=e.state.players[n]?.hand??[];t.cardId&&r.includes(t.cardId)&&(e.state.localVars[R8]=r.length)}),N(t,e.id,n,`获得`,async e=>{let t=e.atom;if(t.type!==`获得`||t.from!==n||t.player===n)return;let i=e.state.localVars[R8];delete e.state.localVars[R8],typeof i==`number`&&await r(e)}),M(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||t.player!==n)return;let r=e.state.players[n]?.hand??[];t.cardIds?.some(e=>r.includes(e))&&(e.state.localVars[R8]=r.length)}),N(t,e.id,n,`弃置`,async e=>{let t=e.atom;if(t.type!==`弃置`||t.player!==n)return;let i=e.state.localVars[R8];delete e.state.localVars[R8],typeof i==`number`&&await r(e)}),M(t,e.id,n,`移出至暂存区`,async e=>{let t=e.atom;if(t.type!==`移出至暂存区`||t.target!==n)return;let r=e.state.players[n]?.hand??[];t.cardIds?.some(e=>r.includes(e))&&(e.state.localVars[R8]=r.length)}),N(t,e.id,n,`移出至暂存区`,async e=>{let t=e.atom;if(t.type!==`移出至暂存区`||t.target!==n)return;let i=e.state.localVars[R8];delete e.state.localVars[R8],typeof i==`number`&&await r(e)}),()=>{}}function F8(e,t){t.defineAction(`respond`,{label:`连营`,style:`default`,prompt:{type:`confirm`,title:`是否发动连营?`,confirmLabel:`发动(摸一张牌)`,cancelLabel:`不发动`}})}var I8,L8,R8,z8,tve=t((()=>{V(),F(),I8=`连营/confirm`,L8=`连营/confirmed`,R8=`连营/handBefore`,z8={createSkill:N8,onInit:P8,onMount:F8}})),nve=r({createSkill:()=>B8,default:()=>Z8,onInit:()=>H8,onMount:()=>U8});function B8(e,t){return{id:e,ownerId:t,name:W8,description:`出牌阶段开始时,你可以失去1点体力或移除1枚橘,然后令一名其他角色获得1枚橘`}}function V8(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function H8(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=V8(e,n);if(r!==G8&&r!==K8&&r!==q8)return`当前不是遗礼询问`;if(r===G8)return null;if(r===K8){let r=t.option;return r!==`loseHp`&&r!==`removeJu`?`请选择代价(失去体力/移除橘)`:r===`removeJu`&&kw(e,n)<=0?`你没有橘标记可移除`:null}let i=t.target??t.targets?.[0];return typeof i==`number`?i===n?`不能选择自己`:e.players[i]?.alive?null:`目标已死亡`:`请选择一名其他角色`},async(e,t)=>{let r=V8(e,n);if(r===G8)e.localVars[J8]=t.choice===!0||t.confirmed===!0;else if(r===K8)e.localVars[Y8]=t.option;else if(r===q8){let n=t.target??t.targets?.[0];typeof n==`number`&&(e.localVars[X8]=n)}}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`出牌`||t.player!==n)return;let r=e.state;if(!r.players[n]?.alive||r.players.filter(e=>e.alive&&e.index!==n).length===0)return;if(delete r.localVars[J8],await B(r,{type:`请求回应`,requestType:G8,target:n,prompt:{type:`confirm`,title:`是否发动遗礼?(失去1点体力或移除1枚橘,令一名其他角色获得1枚橘)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:20}),!r.localVars[J8]){delete r.localVars[J8];return}delete r.localVars[J8];let i=kw(r,n)>0,a;if(i){delete r.localVars[Y8],await B(r,{type:`请求回应`,requestType:K8,target:n,prompt:{type:`chooseOption`,title:`遗礼:选择代价`,options:[{value:`loseHp`,label:`失去 1 点体力`},{value:`removeJu`,label:`移除 1 枚橘`}]},timeout:20});let e=r.localVars[Y8];delete r.localVars[Y8],a=e===`removeJu`?`removeJu`:`loseHp`}else a=`loseHp`;let o=r.players.filter(e=>e.alive&&e.index!==n);delete r.localVars[X8],await B(r,{type:`请求回应`,requestType:q8,target:n,prompt:{type:`choosePlayer`,title:`遗礼:选择一名其他角色获得 1 枚橘`,min:1,max:1,candidates:o.map(e=>e.index)},timeout:20});let s=r.localVars[X8];delete r.localVars[X8],(typeof s!=`number`||!r.players[s]?.alive||s===n)&&(s=o[0].index),a===`loseHp`?await B(r,{type:`失去体力`,target:n,amount:1}):await jw(r,n),r.players[s]?.alive&&await Aw(r,s)}),()=>{}}function U8(e,t){return()=>{}}var W8,G8,K8,q8,J8,Y8,X8,Z8,rve=t((()=>{V(),F(),zw(),W8=`遗礼`,G8=`${W8}/confirm`,K8=`${W8}/cost`,q8=`${W8}/target`,J8=`${W8}/confirmed`,Y8=`${W8}/costChoice`,X8=`${W8}/chosenTarget`,Z8={createSkill:B8,onInit:H8,onMount:U8}})),ive=r({createSkill:()=>Q8,default:()=>r5,onInit:()=>$8,onMount:()=>e5});function Q8(e,t){return{id:e,ownerId:t,name:`遗计`,description:`受到 1 点伤害后,观看牌堆顶的两张牌,然后将这些牌交给任意角色`}}function $8(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`||i.requestType!==t5)return`当前不是遗计分配`;let a=t.allocation;if(Array.isArray(a)&&a.length>0){let t=e.zones.deck,n=new Set([t[t.length-1],t[t.length-2]]),r=new Set;for(let t of a){if(!e.players[t.target]?.alive)return`目标无效`;for(let e of t.cardIds){if(!n.has(e))return`牌不在可分配范围`;if(r.has(e))return`存在重复的牌`;r.add(e)}}if(r.size!==n.size)return`必须分配全部两张牌`}return null},async(e,t)=>{e.localVars[n5]=t.allocation??null}),N(t,e.id,n,`伤害结算结束后`,async e=>{if(e.atom.target!==n||!e.state.players[n]?.alive)return;let t=e.atom.amount??0;if(!(t<=0))for(let r=0;r<t&&!(!e.state.players[n]?.alive||e.state.zones.deck.length<2);r++){let t=e.state.zones.deck,r=[t[t.length-1],t[t.length-2]];delete e.state.localVars[n5],await B(e.state,{type:`请求回应`,requestType:t5,target:n,prompt:{type:`distribute`,title:`遗计:观看牌堆顶两张牌并分配`,cardIds:r,minPerTarget:1,maxPerTarget:2},timeout:30});let i=e.state.localVars[n5];if(Array.isArray(i)){let t=new Map;for(let n of i)if(e.state.players[n.target]?.alive)for(let e of n.cardIds)t.set(e,n.target);for(let n of r){let r=t.get(n);typeof r==`number`&&await B(e.state,{type:`摸牌`,player:r,count:1})}}delete e.state.localVars[n5]}}),()=>{}}function e5(e,t){t.defineAction(`respond`,{label:`遗计`,style:`primary`,prompt:{type:`distribute`,title:`遗计:观看牌堆顶两张牌并分配`,minPerTarget:1,maxPerTarget:2}})}var t5,n5,r5,ave=t((()=>{V(),F(),t5=`遗计/distribute`,n5=`遗计/allocation`,r5={createSkill:Q8,onInit:$8,onMount:e5}})),ove=r({createSkill:()=>i5,default:()=>c5,onInit:()=>o5,onMount:()=>s5});function i5(e,t){return{id:e,ownerId:t,name:`酒池`,description:`你可以将一张黑桃手牌当【酒】使用`}}function a5(e){return`${e}#酒池`}function o5(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.currentPlayerIndex===n,i=!E(e),a=e.players[n],o=a.alive===!0,s=t.cardId,c=typeof s==`string`,l=c?e.cardMap[s]:void 0,u=c&&a.hand.includes(s),d=!!l&&l.suit===`♠`,f=e.pendingSlots.get(n),p=f?.atom?.type,m=f?.atom?.requestType,h=f?.atom?.target,g=!!f&&h===n&&p===`请求回应`&&m===`桃/求桃`&&a.health<=0;return u&&d&&(r&&i&&o||o&&g)?null:`现在不能使用酒池`},async(e,t)=>{let r=t.cardId,i=a5(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:i,outputName:`酒`})},(e,t)=>{let r=t.cardId,i=a5(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)});let r=de(t,n,`请求回应`,`桃/求桃`);return()=>{r()}}function s5(e,t){t.defineAction(`transform`,{label:`酒池`,style:`passive`,prompt:{type:`useCard`,title:`选择一张黑桃手牌当酒使用`,cardFilter:{filter:e=>e.suit===`♠`,min:1,max:1}},transform:t=>({name:`酒`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t||!(t.hand?.some(e=>e.suit===`♠`)??!1))return!1;if(q(e))return!0;let n=e.view.pending,r=n?.atom?.requestType;return!!n&&n.target===e.perspectiveIdx&&r===`桃/求桃`&&t.health<=0}})}var c5,sve=t((()=>{F(),V(),J(),c5={createSkill:i5,onInit:o5,onMount:s5}})),cve=r({createSkill:()=>l5,default:()=>v5,onInit:()=>u5,onMount:()=>d5});function lve(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function l5(e,t){return{id:e,ownerId:t,name:`酣战`,description:`拼点前可令对方用随机手牌拼点;拼点后可获得两张拼点牌中点数最大的杀`}}function u5(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;let a=i.requestType;return a!==m5&&a!==g5?`当前不是酣战询问`:null},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType,i=t.choice===!0||t.confirmed===!0;r===m5?e.localVars[h5]=i:r===g5&&(e.localVars[_5]=i)}),M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(t.type!==`请求回应`||t.requestType!==f5||e.state.currentPlayerIndex!==n)return;let r=t.target;if(typeof r!=`number`)return;let i=e.state.players[r];if(!i?.alive||i.hand.length===0||!e.state.players[n]?.alive)return;delete e.state.localVars[h5],await B(e.state,{type:`请求回应`,requestType:m5,target:n,prompt:{type:`confirm`,title:`酣战:是否令对方用一张随机手牌拼点?`,confirmLabel:`随机拼点`,cancelLabel:`正常拼点`},defaultChoice:!1,timeout:20});let a=e.state.localVars[h5];if(delete e.state.localVars[h5],!a)return;let o=Ud(e.state.rngSeed),s=e.state.players[r].hand,c=s[o.nextInt(s.length)];return e.state.rngSeed=o.getState(),e.state.localVars[p5]=c,{kind:`cancel`}}),N(t,e.id,n,`拼点后`,async e=>{let t=e.atom;if(t.type!==`拼点后`||t.initiator!==n)return;let r=e.state;if(!r.players[n]?.alive)return;let i=[];for(let e of[t.initiatorCard,t.targetCard]){if(!e)continue;let t=r.cardMap[e];t?.name===`杀`&&i.push({id:e,value:lve(t.rank)})}if(i.length===0)return;delete r.localVars[_5],await B(r,{type:`请求回应`,requestType:g5,target:n,prompt:{type:`confirm`,title:`酣战:是否获得两张拼点牌中点数最大的杀?`,confirmLabel:`获得`,cancelLabel:`不获得`},defaultChoice:!1,timeout:20});let a=r.localVars[_5];if(delete r.localVars[_5],!a)return;i.sort((e,t)=>t.value-e.value);let o=i[0].id;r.zones.discardPile.includes(o)&&await B(r,{type:`移动牌`,cardId:o,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:n}})}),()=>{}}function d5(e,t){}var f5,p5,m5,h5,g5,_5,v5,uve=t((()=>{V(),F(),Wd(),f5=`天义/拼点`,p5=`天义/targetCard`,m5=`酣战/随机拼点`,h5=`酣战/forceConfirmed`,g5=`酣战/获杀`,_5=`酣战/gainConfirmed`,v5={createSkill:l5,onInit:u5,onMount:d5}})),dve=r({createSkill:()=>y5,default:()=>S5,onInit:()=>b5,onMount:()=>x5});function y5(e,t){return{id:e,ownerId:t,name:`铁索连环`,description:`横置/重置一至两名角色;或重铸`}}function b5(e,t){let n=e.ownerId,r=j(t,e.id,n,`recast`,(e,t)=>oe(e,n,t,{cardName:`铁索连环`}),async(e,t)=>{let r=t.cardId;await rP(e,n,r)});return()=>{r()}}function x5(e,t){t.defineAction(`recast`,{label:`铁索连环·重铸`,style:`primary`,prompt:{type:`useCard`,title:`铁索连环:重铸(弃此牌,摸一张)`,cardFilter:{filter:e=>e.name===`铁索连环`,min:1,max:1}}})}var S5,fve=t((()=>{iP(),F(),S5={createSkill:y5,onInit:b5,onMount:x5}})),pve=r({createSkill:()=>mve,onInit:()=>hve,onMount:()=>gve});function mve(e,t){return{id:e,ownerId:t,name:`铁骑`,description:`使用杀指定目标后可判定,红色则目标不能出闪抵消`}}function hve(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===`铁骑/confirm`?null:`当前不是铁骑确认`:`当前不是请求回应`},async(e,t)=>{e.localVars[w5]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0)return;let r=t.target;t.cardId!==void 0&&e.state.cardMap[t.cardId]?.name!==`杀`||e.state.players[r]?.alive&&e.state.zones.deck.length!==0&&(delete e.state.localVars[w5],await B(e.state,{type:`请求回应`,requestType:`铁骑/confirm`,target:n,prompt:{type:`confirm`,title:`是否发动铁骑判定?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[w5]&&(e.state.localVars[T5]=r,await jm(e.state,n,`铁骑`)))}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.judgeType!==`铁骑`||t.player!==n)return;let r=e.state.localVars[T5];if(delete e.state.localVars[T5],r===void 0||!e.state.players[r]?.alive)return;let i=R(e.state);if(i.length===0)return;let a=i[i.length-1],o=e.state.cardMap[a];o&&o.color===`红`&&await B(e.state,{type:`加标签`,player:r,tag:C5})}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r!==void 0&&e.state.players[r]?.tags.includes(C5))return await B(e.state,{type:`去标签`,player:r,tag:C5}),{kind:`cancel`}}),()=>{}}function gve(e,t){t.defineAction(`respond`,{label:`铁骑`,style:`default`,prompt:{type:`confirm`,title:`是否发动铁骑判定?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var C5,w5,T5,_ve=t((()=>{V(),z(),Fm(),F(),C5=`铁骑/禁闪`,w5=`铁骑/confirmed`,T5=`铁骑/target`})),vve=r({createSkill:()=>E5,default:()=>R5,onInit:()=>O5,onMount:()=>k5});function E5(e,t){return{id:e,ownerId:t,name:A5,description:`结束阶段,你可以选择一名其他角色,本回合结束时和其下回合结束时,其将手牌调整至与你手牌数相同(至多摸至五张)`}}function yve(e,t){return e.pendingSlots.get(t)?.atom?.requestType}async function D5(e,t,n){let r=e.players[t],i=e.players[n];if(!r?.alive||!i?.alive)return;let a=r.hand.length,o=i.hand.length;if(o<a){let t=Math.min(a-o,L5);t>0&&await B(e,{type:`摸牌`,player:n,count:t});return}if(o>a){let t=o-a;delete e.localVars[P5],await B(e,{type:`请求回应`,requestType:I5,target:n,prompt:{type:`useCard`,title:`镇骨:手牌调整,弃 ${t} 张牌`,cardFilter:{filter:()=>!0,min:t,max:t}},mandatory:!0,timeout:30});let r=e.localVars[P5];delete e.localVars[P5],(!r||r.length===0)&&t>0&&(r=e.players[n]?.hand.slice(0,t)??[]),r&&r.length>0&&await B(e,{type:`弃置`,player:n,cardIds:r})}}function O5(e,t){let n=e.ownerId,r=[];for(let i of t.players){let a=i.index,o=a===n,s=j(t,e.id,a,`respond`,(e,t)=>{let n=e.pendingSlots.get(a);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let i=r.requestType;if(i===F5)return o?null:`当前不是你的询问`;if(i===I5){let r=t.cardIds;if(!Array.isArray(r)||r.length===0)return`请选择要弃置的牌`;let i=e.players[a];if(!i)return`玩家不存在`;for(let e of r)if(typeof e!=`string`||!i.hand.includes(e))return`牌 ${e} 不在手牌中`;if(new Set(r).size!==r.length)return`cardIds 含重复牌`;let o=n.atom.prompt?.cardFilter?.min;return typeof o==`number`&&r.length!==o?`需要恰好弃置 ${o} 张手牌`:null}return`当前不是镇骨询问`},async(e,t)=>{let n=yve(e,a);if(n===F5){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[N5]=n)}else if(n===I5){let n=t.cardIds;Array.isArray(n)&&(e.localVars[P5]=n)}});r.push(s)}return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.phase!==`回合结束`||t.player!==n)return;let r=e.state.players[n];if(!r?.alive)return;delete e.state.localVars[N5],await B(e.state,{type:`请求回应`,requestType:F5,target:n,prompt:{type:`choosePlayer`,title:`镇骨:选择一名其他角色(本回合结束及其下回合结束时,其手牌调整至与你相同)`,min:1,max:1,filter:(e,t)=>t!==n&&e.players[t]?.alive===!0},timeout:20});let i=e.state.localVars[N5];delete e.state.localVars[N5],typeof i==`number`&&e.state.players[i]?.alive&&(r.vars[j5]=i,r.vars[M5]=`本回合`)}),N(t,e.id,n,`回合结束`,async e=>{let t=e.atom;if(t.type!==`回合结束`)return;let r=e.state.players[n];if(!r)return;let i=r.vars[M5],a=r.vars[j5];if(i===`本回合`&&t.player===n){if(typeof a!=`number`)return;await D5(e.state,n,a),e.state.players[n]?.alive?r.vars[M5]=`目标下回合`:(delete r.vars[M5],delete r.vars[j5]);return}i===`目标下回合`&&typeof a==`number`&&t.player===a&&(await D5(e.state,n,a),delete r.vars[M5],delete r.vars[j5])}),()=>{r.forEach(e=>e())}}function k5(e,t){t.defineAction(`respond`,{label:`镇骨`,style:`primary`,prompt:{type:`choosePlayer`,title:`镇骨:选择一名其他角色`,min:1,max:1}})}var A5,j5,M5,N5,P5,F5,I5,L5,R5,bve=t((()=>{V(),F(),A5=`镇骨`,j5=`镇骨/目标`,M5=`镇骨/阶段`,N5=`镇骨/chooseTarget`,P5=`镇骨/discardCards`,F5=`镇骨/选目标`,I5=`镇骨/弃牌`,L5=5,R5={createSkill:E5,onInit:O5,onMount:k5}})),xve=r({createSkill:()=>z5,default:()=>W5,onInit:()=>B5,onMount:()=>V5});function z5(e,t){return{id:e,ownerId:t,name:`闭月`,description:`回合结束阶段,你可以摸一张牌`}}function B5(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===H5?null:`当前不是闭月确认`:`当前不需要回应`},async(e,t)=>{e.localVars[U5]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;t.type===`阶段开始`&&t.phase===`回合结束`&&t.player===n&&e.state.players[n]?.alive&&(delete e.state.localVars[U5],await B(e.state,{type:`请求回应`,requestType:H5,target:n,prompt:{type:`confirm`,title:`是否发动闭月?(摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[U5]&&await B(e.state,{type:`摸牌`,player:n,count:1}))}),()=>{}}function V5(e,t){return t.defineAction(`respond`,{label:`闭月`,style:`primary`,prompt:{type:`confirm`,title:`是否发动闭月?(摸一张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`}}),()=>{}}var H5,U5,W5,Sve=t((()=>{V(),F(),H5=`闭月/confirm`,U5=`闭月/confirmed`,W5={createSkill:z5,onInit:B5,onMount:V5}})),Cve=r({createSkill:()=>G5,default:()=>n7,onInit:()=>q5,onMount:()=>J5});function wve(e){switch(e){case`武器`:case`防具`:case`进攻马`:case`防御马`:case`宝物`:return e;default:return null}}function G5(e,t){return{id:e,ownerId:t,name:Y5,description:`限定技,出牌阶段,指定一名其他角色并废除你的判定区和装备区,本回合对其使用牌无距离和次数限制,其本回合不能使用和打出手牌`}}function K5(e,t){return e.turn.vars[Z5]===t}function q5(e,t){let n=e.ownerId,r=j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(E(e))return`当前有未完成的询问`;if(e.players[n]?.vars[X5])return`雄乱已使用过(限定技)`;if(!e.players[n]?.alive)return`玩家不存在或已死亡`;let r=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);return typeof r==`number`?r===n?`不能选择自己`:e.players[r]?.alive?null:`目标不存在或已死亡`:`请选择一名其他角色`},async(e,t)=>{let r=t.target??(Array.isArray(t.targets)?t.targets[0]:void 0);if(typeof r==`number`){e.players[n].vars[X5]=!0,await I(e,Y5,n,{target:r});try{let t=e.players[n],i=[...new Set(t.pendingTricks.map(e=>e.name))];for(let t of i)await B(e,{type:`移除延时锦囊`,player:n,trickName:t});e.players[n].vars[$5]=!0;for(let r of e7){let i=t.equipment[r];i&&(await B(e,{type:`卸下`,player:n,slot:r}),e.players[n].hand.includes(i)&&await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:n},to:{zone:`弃牌堆`}})),e.players[n].vars[Q5+r]=!0}e.turn.vars[Z5]=r,await B(e,{type:`回合用量`,player:n,key:qc(`雄乱`),value:!0}),await B(e,{type:`回合用量`,player:n,key:Z5,value:r})}finally{await L(e)}}}),i=Jm(t,n,(e,t,r)=>t===n?e.turn.vars[Z5]===r:!1),a=eh(t,n,(e,t)=>t===n?typeof e.turn.vars[Z5]==`number`:!1),o=M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(typeof t.target==`number`&&K5(e.state,t.target))return{kind:`cancel`}}),s=M(t,e.id,n,`询问杀`,async e=>{let t=e.atom;if(typeof t.target==`number`&&K5(e.state,t.target))return{kind:`cancel`}}),c=M(t,e.id,n,`请求回应`,async e=>{let t=e.atom;if(typeof t.target!=`number`)return;let n=t.prompt?.type;if(!(!n||!t7.has(n))&&K5(e.state,t.target))return{kind:`cancel`}}),l=M(t,e.id,n,`添加延时锦囊`,async e=>{let t=e.atom;if(typeof t.player==`number`&&t.player===n&&e.state.players[n]?.vars[$5])return{kind:`cancel`}}),u=M(t,e.id,n,`装备`,async e=>{let t=e.atom;if(typeof t.player!=`number`||t.player!==n)return;let r=e.state.cardMap[t.cardId??``];if(!r)return;let i=wve(r.subtype);if(i&&e.state.players[n]?.vars[Q5+i])return{kind:`cancel`}});return()=>{r(),i(),a(),o(),s(),c(),l(),u()}}function J5(e,t){t.defineAction(`use`,{label:`雄乱`,style:`danger`,activeWhen:e=>q(e),prompt:{type:`selectTarget`,title:`雄乱(限定技):指定一名其他角色,废除你的判定区和装备区,本回合对其使用牌无距离和次数限制,其本回合不能使用和打出手牌`,targetFilter:{min:1,max:1,filter:(e,t)=>t!==e.currentPlayerIndex&&!!e.players[t]?.alive}}})}var Y5,X5,Z5,Q5,$5,e7,t7,n7,Tve=t((()=>{V(),z(),F(),fh(),W(),Xm(),J(),Y5=`雄乱`,X5=`雄乱/used`,Z5=Vl,Q5=`雄乱/废除:`,$5=`${Q5}判定`,e7=[`武器`,`防具`,`进攻马`,`防御马`,`宝物`],t7=new Set([`useCard`,`useCardAndTarget`,`pickProcessingCard`,`pickTargetCard`,`distribute`]),n7={createSkill:G5,onInit:q5,onMount:J5}})),Eve=r({createSkill:()=>Dve,onInit:()=>Ove,onMount:()=>kve});function Dve(e,t){return{id:e,ownerId:t,name:`集智`,description:`被动技:使用非延时锦囊牌时,你可以摸一张牌`}}function Ove(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,e=>{let t=e.pendingSlots.get(n);return t?t.atom.type!==`请求回应`||t.atom.requestType!==i7?`当前不是集智确认窗口`:null:`当前不需要回应`},async(e,t)=>{e.localVars[`集智/confirmed`]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`移动牌`,async e=>{let t=e.atom;if(!t.cardId)return;let r=t.from,i=t.to;if(r?.zone!==`手牌`||r.player!==n||!i||i.zone!==`处理区`&&i.zone!==`弃牌堆`)return;let a=e.state.cardMap[t.cardId];a&&a.type===`锦囊牌`&&r7.has(a.name)&&e.state.players[n]?.alive&&(delete e.state.localVars[`集智/confirmed`],await B(e.state,{type:`请求回应`,requestType:i7,target:n,prompt:{type:`confirm`,title:`是否发动集智摸一张牌?`,confirmLabel:`摸牌`,cancelLabel:`不摸`},defaultChoice:!0,timeout:15}),e.state.localVars[`集智/confirmed`]!==!1&&await B(e.state,{type:`摸牌`,player:n,count:1}))}),()=>{}}function kve(e,t){t.defineAction(`respond`,{label:`集智`,style:`primary`,prompt:{type:`confirm`,title:`是否发动集智摸一张牌?`,confirmLabel:`摸牌`,cancelLabel:`不摸`}})}var r7,i7,Ave=t((()=>{V(),F(),r7=new Set([`过河拆桥`,`顺手牵羊`,`无中生有`,`无懈可击`,`借刀杀人`,`桃园结义`,`五谷丰登`,`南蛮入侵`,`万箭齐发`,`决斗`,`火攻`,`铁索连环`]),i7=`集智/confirm`})),jve=r({createSkill:()=>a7,default:()=>f7,onInit:()=>o7,onMount:()=>s7});function a7(e,t){return{id:e,ownerId:t,name:`雌雄双股剑`,description:`武器:你使用杀指定异性角色为目标后,可令其弃1手牌或令你摸1牌`,isLocked:!0}}function o7(e,t){let n=e.ownerId,r=e.id,i=[];for(let e of t.players){let n=e.index,a=j(t,r,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(r?.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i===c7)return null;if(i===l7){let r=t.cardId;return r!==void 0&&!e.players[n].hand.includes(r)?`牌不在手牌中`:null}return`当前不是雌雄双股剑询问`},async(e,t)=>{let r=e.pendingSlots.get(n)?.atom?.requestType;r===c7?e.localVars[u7]=t.choice===!0:r===l7&&(e.localVars[d7]=t.cardId??null)});i.push(a)}let a=N(t,r,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||typeof t.target!=`number`||!t.cardId||!e.state.cardMap[t.cardId]?.name.includes(`杀`))return;let r=e.state.players[n],i=e.state.players[t.target];if(!r||!i)return;let a=r.equipment.武器;if(!a||e.state.cardMap[a]?.name!==`雌雄双股剑`||kc(r.character)===kc(i.character))return;if(delete e.state.localVars[u7],await B(e.state,{type:`请求回应`,requestType:c7,target:n,prompt:{type:`confirm`,title:`雌雄双股剑:是否发动?(令目标弃1手牌,或你摸1张牌)`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:10}),e.state.localVars[u7]!==!0){delete e.state.localVars[u7];return}if(delete e.state.localVars[u7],i.hand.length===0){await B(e.state,{type:`摸牌`,player:n,count:1});return}delete e.state.localVars[d7],await B(e.state,{type:`请求回应`,requestType:l7,target:t.target,prompt:{type:`useCard`,title:`雌雄双股剑:弃置一张手牌,或放弃(令 ${r.name} 摸一张牌)`,cardFilter:{filter:()=>!0,candidates:i.hand.slice(),min:1,max:1}},timeout:15});let o=e.state.localVars[d7];delete e.state.localVars[d7],typeof o==`string`&&i.hand.includes(o)?await B(e.state,{type:`弃置`,player:t.target,cardIds:[o]}):await B(e.state,{type:`摸牌`,player:n,count:1})});return i.push(a),()=>{for(let e of i)e()}}function s7(e,t){t.defineAction(`respond`,{label:`雌雄双股剑`,style:`default`,prompt:{type:`confirm`,title:`雌雄双股剑:是否发动?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var c7,l7,u7,d7,f7,Mve=t((()=>{V(),F(),Fc(),c7=`雌雄双股剑/confirm`,l7=`雌雄双股剑/choice`,u7=`雌雄双股剑/confirmed`,d7=`雌雄双股剑/discardId`,f7={createSkill:a7,onInit:o7,onMount:s7}})),Nve=r({createSkill:()=>p7,default:()=>v7,onInit:()=>m7,onMount:()=>h7});function p7(e,t){return{id:e,ownerId:t,name:`雷击`,description:`当你使用或打出【闪】时,可令一名其他角色判定,黑桃则造成2点雷电伤害;梅花则你回复1点体力并对其造成1点雷电伤害`}}function m7(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==g7)return`当前不是雷击选择`;let a=t.target;if(typeof a==`number`){if(a===n)return`不能选择自己`;if(!e.players[a]?.alive)return`目标不存在或已死亡`}return null},async(e,t)=>{let n=t.target;e.localVars[_7]=typeof n==`number`?n:null}),N(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.type!==`询问闪`||t.target!==n)return;let r=e.state.players[n];if(!r?.alive||!Je(e.state,e.frame.params.cardId??``,n))return;delete e.state.localVars[_7],await B(e.state,{type:`请求回应`,requestType:g7,target:n,prompt:{type:`choosePlayer`,title:`雷击:选择一名角色进行判定(或放弃)`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0&&t!==n},timeout:20});let i=e.state.localVars[_7];if(delete e.state.localVars[_7],typeof i!=`number`||!e.state.players[i]?.alive)return;await jm(e.state,i,`雷击`);let a=e.state.zones.discardPile;if(a.length===0)return;let o=a[a.length-1],s=e.state.cardMap[o];s&&(s.suit===`♠`?await Dm(e.state,n,i,2,void 0,`雷电`):s.suit===`♣`&&(r.health<r.maxHealth&&await B(e.state,{type:`回复体力`,target:n,amount:1}),await Dm(e.state,n,i,1,void 0,`雷电`)))}),()=>{}}function h7(e,t){t.defineAction(`respond`,{label:`雷击`,style:`danger`,prompt:{type:`choosePlayer`,title:`雷击:选择判定目标(或放弃)`,min:1,max:1,filter:(t,n)=>t.players[n]?.alive===!0&&n!==e.ownerId}})}var g7,_7,v7,Pve=t((()=>{V(),Fm(),Om(),F(),z(),g7=`雷击/chooseTarget`,_7=`雷击/target`,v7={createSkill:p7,onInit:m7,onMount:h7}})),Fve=r({createSkill:()=>Ive,onInit:()=>Lve,onMount:()=>Rve});function Ive(e,t){return{id:e,ownerId:t,name:`青囊`,description:`出牌阶段限一次,弃一张手牌,令一名角色回复 1 点体力`}}function Lve(e,t){let n=e.ownerId;return j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`不是出牌阶段`;if(X(e,n,`青囊`))return`本回合已使用过青囊`;let r=e.players[n];if(!r)return`player not found`;if(!r.alive)return`你已死亡`;let i=t.cardId;if(!i)return`cardId required`;if(!r.hand.includes(i))return`牌不在手牌中`;let a=t.target??t.targets?.[0]??n,o=e.players[a];return o?o.alive?o.health>=o.maxHealth?`目标体力已满`:null:`目标已死亡`:`目标不存在`},async(e,t)=>{let r=n,i=t.cardId,a=t.target??t.targets?.[0]??n;await Z(e,r,`青囊`),await I(e,`青囊`,r,{...t}),await B(e,{type:`弃置`,player:r,cardIds:[i],voluntary:!0}),await B(e,{type:`回复体力`,target:a,amount:1,source:r}),await L(e)}),()=>{}}function Rve(e,t){t.defineAction(`use`,{label:`青囊`,style:`primary`,prompt:{type:`useCardAndTarget`,title:`青囊:弃一张手牌,令一名角色回复 1 点体力`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{let n=e.players[t];return!!n&&n.alive!==!1&&n.health<n.maxHealth}}},activeWhen:e=>yh(`青囊`)(e)})}var zve=t((()=>{V(),z(),Q(),F()})),Bve=r({createSkill:()=>Vve,onInit:()=>Hve});function y7(e){let t=b7.get(e);return t||(t=new Map,b7.set(e,t)),t}function Vve(e,t){return{id:e,ownerId:t,name:`青釭剑`,description:`武器:杀无视目标防具`,isLocked:!0}}function Hve(e,t){let n=e.ownerId;N(t,e.id,n,`指定目标`,async e=>{if(e.atom.source!==n)return;let t=e.atom.cardId;if(!t||e.state.cardMap[t]?.name!==`杀`)return;let r=e.state.players[n];if(!r)return;let i=r.equipment.武器;if(!i||e.state.cardMap[i]?.name!==`青釭剑`)return;let a=e.atom.target,o=e.state.players[a];if(!o)return;let s=o.equipment?.防具;if(!s)return;let c=e.state.cardMap[s];if(!c)return;let l=[],u=c.name;u&&o.skills.includes(u)&&(l.push({target:a,skillId:u}),d9(e.state,u,a)),l.length>0&&y7(e.state).set(n,l)});async function r(e,t){if(t!==n)return;let r=y7(e).get(n);if(!(!r||r.length===0)){for(let{target:t,skillId:n}of r)await f9(e,n,t);y7(e).delete(n)}}return N(t,e.id,n,`造成伤害后`,async e=>{await r(e.state,e.atom.source)}),N(t,e.id,n,`被抵消`,async e=>{await r(e.state,e.atom.source)}),()=>{}}var b7,Uve=t((()=>{F(),v9(),b7=new WeakMap})),Wve=r({createSkill:()=>Gve,onInit:()=>Kve,onMount:()=>qve});function Gve(e,t){return{id:e,ownerId:t,name:`青龙偃月刀`,description:`武器技:杀被闪抵消后,可对相同目标再使用一张杀`}}function Kve(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r||r.atom.type!==`请求回应`)return`当前不需要回应`;let i=r.atom.requestType;if(i!==`青龙偃月刀/confirm`&&i!==`青龙偃月刀/useKill`)return`当前不是青龙偃月刀询问`;if(i===`青龙偃月刀/useKill`){let r=t.cardId;if(!r)return`需要选择一张杀`;let i=e.players[n];if(!i)return`player not found`;if(!i.hand.includes(r))return`牌不在手牌中`;if(e.cardMap[r]?.name!==`杀`)return`只能使用杀`}return null},async(e,t)=>{let r=e.pendingSlots.get(n).atom.requestType;r===`青龙偃月刀/confirm`?e.localVars[`青龙偃月刀/confirmed`]=t.choice===!0||t.confirmed===!0:r===`青龙偃月刀/useKill`&&(e.localVars[`青龙偃月刀/killCardId`]=t.cardId)}),N(t,e.id,n,`被抵消`,async e=>{if(e.frame.skillId!==`杀`)return;let t=e.atom;if(t.source!==n)return;let r=e.state.players[n];if(!r)return;let i=r.equipment.武器;if(!i||e.state.cardMap[i]?.name!==`青龙偃月刀`||!Je(e.state,t.cardId,t.target)||!r.hand.some(t=>e.state.cardMap[t]?.name===`杀`)||(delete e.state.localVars[`青龙偃月刀/confirmed`],await B(e.state,{type:`请求回应`,requestType:`青龙偃月刀/confirm`,target:n,prompt:{type:`confirm`,title:`青龙偃月刀:是否追杀?`,confirmLabel:`追杀`,cancelLabel:`不追杀`},defaultChoice:!1,timeout:10}),!e.state.localVars[`青龙偃月刀/confirmed`]))return;delete e.state.localVars[`青龙偃月刀/confirmed`],delete e.state.localVars[`青龙偃月刀/killCardId`],await B(e.state,{type:`请求回应`,requestType:`青龙偃月刀/useKill`,target:n,prompt:{type:`useCard`,title:`青龙偃月刀:选择一张杀追杀`,cardFilter:{filter:e=>e.name===`杀`,min:1,max:1}},defaultChoice:!1,timeout:15});let a=e.state.localVars[`青龙偃月刀/killCardId`];delete e.state.localVars[`青龙偃月刀/killCardId`],a&&await Lh(e.state,n,a,[t.target],`杀`,{onSettle:Hh(e.state,n,a)})}),()=>{}}function qve(e,t){t.defineAction(`respond`,{label:`青龙偃月刀`,style:`danger`,prompt:{type:`confirm`,title:`青龙偃月刀:是否追杀?`,confirmLabel:`追杀`,cancelLabel:`不追杀`}})}var Jve=t((()=>{V(),F(),z(),Gh()})),Yve=r({createSkill:()=>x7,default:()=>O7,onInit:()=>S7,onMount:()=>C7});function x7(e,t){return{id:e,ownerId:t,name:`鞬出`,description:`使用杀指定目标后,可弃其一张牌:装备牌则其不能出闪,非装备牌则其获得此杀`}}async function Xve(e,t,n){let r=e.players[t];if(!r)return;let i=Object.entries(r.equipment).filter(([,e])=>typeof e==`string`).map(([t,n])=>({slot:t,cardId:n,cardName:e.cardMap[n]?.name??`?`})),a=r.hand.length,o=i.length>0?{zone:`equipment`,cardId:i[0].cardId}:{zone:`hand`,handIndex:0};delete e.localVars[E7],await B(e,{type:`请求回应`,requestType:`鞬出/选牌`,target:t,prompt:{type:`pickTargetCard`,title:`鞬出:选择弃置的一张牌(装备→不能出闪;非装备→获得此杀不命中)`,target:t,equipment:i,judge:[],handCount:a},defaultChoice:o,timeout:20});let s=e.localVars[E7];delete e.localVars[E7];let c=s?.zone??o.zone,l;if(c===`equipment`)l=s?.cardId??o.cardId;else{let e=s?.handIndex??0;l=r.hand[e]??r.hand[0]}if(l)if(await B(e,{type:`弃置`,player:t,cardIds:[l]}),e.cardMap[l]?.type===`装备牌`)await B(e,{type:`加标签`,player:t,tag:w7});else{let r=e.localVars[D7]??{};r[t]=n,e.localVars[D7]=r}}function S7(e,t){let n=e.ownerId,r=[];for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不是请求回应`;if(r.requestType===`鞬出/confirm`)return null;if(r.requestType===`鞬出/选牌`){let n=e.players[i];if(!n)return`玩家不存在`;let r=t.zone;return r===`equipment`?typeof t.cardId==`string`?Object.values(n.equipment).includes(t.cardId)?null:`该牌不在你的装备区`:`cardId required`:r===`hand`?typeof t.handIndex==`number`?t.handIndex<0||t.handIndex>=n.hand.length?`handIndex 越界`:null:`handIndex required`:`zone required (equipment|hand)`}return`当前不是鞬出回应`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;n===`鞬出/confirm`?e.localVars[T7]=t.choice===!0||t.confirmed===!0:n===`鞬出/选牌`&&(e.localVars[E7]={zone:t.zone,cardId:t.cardId??null,handIndex:t.handIndex??null})});r.push(a)}return N(t,e.id,n,`指定目标`,async e=>{let t=e.atom;if(t.source!==n||t.target===void 0)return;let r=t.target;if(t.cardId===void 0||e.state.cardMap[t.cardId]?.name!==`杀`)return;let i=e.state.players[r];i?.alive&&(i.hand.length>0||Object.keys(i.equipment).length>0)&&(i.tags.includes(w7)&&await B(e.state,{type:`去标签`,player:r,tag:w7}),delete e.state.localVars[T7],await B(e.state,{type:`请求回应`,requestType:`鞬出/confirm`,target:n,prompt:{type:`confirm`,title:`鞬出:是否弃置目标一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`},defaultChoice:!1,timeout:15}),e.state.localVars[T7]&&await Xve(e.state,r,t.cardId))}),M(t,e.id,n,`成为目标`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r===void 0)return;let i=e.state.localVars[D7];if(!(!i||!(r in i)))return{kind:`cancel`}}),N(t,e.id,n,`移动牌`,async e=>{let t=e.state.localVars[D7];if(!t)return;let n=e.atom;if(n.to?.zone!==`弃牌堆`)return;let r=Object.entries(t).find(([,e])=>e===n.cardId);if(!r)return;let i=Number(r[0]);delete t[i],Object.keys(t).length===0&&delete e.state.localVars[D7],e.state.players[i]?.alive&&await B(e.state,{type:`移动牌`,cardId:n.cardId,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:i}})}),M(t,e.id,n,`询问闪`,async e=>{let t=e.atom;if(t.source!==n)return;let r=t.target;if(r!==void 0&&e.state.players[r]?.tags.includes(w7))return await B(e.state,{type:`去标签`,player:r,tag:w7}),{kind:`cancel`}}),()=>{r.forEach(e=>e())}}function C7(e,t){t.defineAction(`respond`,{label:`鞬出`,style:`default`,prompt:{type:`confirm`,title:`鞬出:是否弃置目标一张牌?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var w7,T7,E7,D7,O7,Zve=t((()=>{V(),F(),w7=`鞬出/禁闪`,T7=`鞬出/confirmed`,E7=`鞬出/选牌`,D7=`鞬出/获得杀`,O7={createSkill:x7,onInit:S7,onMount:C7}})),Qve=r({createSkill:()=>k7,default:()=>P7,onInit:()=>A7,onMount:()=>j7});function k7(e,t){return{id:e,ownerId:t,name:`颂威`,description:`主公技:其他魏势力角色判定牌黑色且生效后,你可以摸一张牌`}}function A7(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;return i.type===`请求回应`?i.requestType===M7?null:`当前不是颂威确认`:`当前不需要回应`},async(e,t)=>{e.localVars[N7]=t.choice===!0||t.confirmed===!0}),N(t,e.id,n,`判定牌生效后`,async e=>{let t=e.atom;if(t.player===n)return;let r=e.state.players[t.player??-1];if(!r?.alive||r.faction!==`魏`)return;let i=R(e.state);if(i.length===0)return;let a=i[i.length-1],o=e.state.cardMap[a];o&&(o.suit!==`♠`&&o.suit!==`♣`||e.state.players[n]?.alive&&(delete e.state.localVars[N7],await B(e.state,{type:`请求回应`,requestType:M7,target:n,prompt:{type:`confirm`,title:`颂威:${r.name} 判定牌为${o.suit}${o.rank},是否摸一张牌?`,confirmLabel:`摸牌`,cancelLabel:`不摸`},defaultChoice:!1,timeout:10}),e.state.localVars[N7]&&await B(e.state,{type:`摸牌`,player:n,count:1})))}),()=>{}}function j7(e,t){t.defineAction(`respond`,{label:`颂威`,style:`primary`,prompt:{type:`confirm`,title:`颂威:是否摸一张牌?`,confirmLabel:`摸牌`,cancelLabel:`不摸`}})}var M7,N7,P7,$ve=t((()=>{V(),z(),F(),M7=`颂威/confirm`,N7=`颂威/confirmed`,P7={createSkill:k7,onInit:A7,onMount:j7}})),eye=r({createSkill:()=>I7,default:()=>tye,onInit:()=>L7,onMount:()=>R7});function F7(e,t){let n=e.pendingSlots.get(t);if(n)return n.atom.requestType}function I7(e,t){return{id:e,ownerId:t,name:`飘零`,description:`结束阶段可判定,红桃则将判定牌置牌堆顶或交给一名角色(给自己则弃一张牌)`}}function L7(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=F7(e,n);if(r!==z7&&r!==B7&&r!==V7&&r!==H7)return`当前不是飘零询问`;if(r===V7){let n=t.target;return typeof n==`number`?e.players[n]?.alive?null:`目标无效`:`请选择一名角色`}if(r===H7){let r=t.cardId;if(typeof r!=`string`)return`请选择一张手牌弃置`;if(!e.players[n]?.hand.includes(r))return`牌不在手牌中`}return null},async(e,t)=>{let r=F7(e,n),i=t.choice===!0||t.confirmed===!0;r===z7?e.localVars[U7]=i:r===B7?e.localVars[W7]=i:r===V7?e.localVars[G7]=t.target??null:r===H7&&(e.localVars[K7]=t.cardId??null)}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`回合结束`||!e.state.players[n]?.alive||e.state.zones.deck.length===0||(delete e.state.localVars[U7],await B(e.state,{type:`请求回应`,requestType:z7,target:n,prompt:{type:`confirm`,title:`是否发动飘零判定?`,confirmLabel:`判定`,cancelLabel:`不判定`},defaultChoice:!1,timeout:10}),!e.state.localVars[U7]))return;await jm(e.state,n,`飘零`);let r=e.state.zones.discardPile;if(r.length===0)return;let i=r[r.length-1];if(e.state.cardMap[i]?.suit!==`♥`)return;delete e.state.localVars[W7],await B(e.state,{type:`请求回应`,requestType:B7,target:n,prompt:{type:`confirm`,title:`飘零:将判定牌交给一名角色?(否则置于牌堆顶)`,confirmLabel:`交给角色`,cancelLabel:`置牌堆顶`},defaultChoice:!1,timeout:15});let a=e.state.localVars[W7]===!0;if(delete e.state.localVars[W7],!a){await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`牌堆`}});return}delete e.state.localVars[G7],await B(e.state,{type:`请求回应`,requestType:V7,target:n,prompt:{type:`choosePlayer`,title:`飘零:选择交给哪名角色`,min:1,max:1,filter:(e,t)=>e.players[t]?.alive===!0},timeout:15});let o=e.state.localVars[G7];if(delete e.state.localVars[G7],typeof o!=`number`){await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`牌堆`}});return}if(e.state.players[o]?.alive&&(await B(e.state,{type:`移动牌`,cardId:i,from:{zone:`弃牌堆`},to:{zone:`手牌`,player:o}}),o===n)){let t=e.state.players[n];if(!t?.alive||t.hand.length===0)return;delete e.state.localVars[K7],await B(e.state,{type:`请求回应`,requestType:H7,target:n,prompt:{type:`useCard`,title:`飘零:弃置一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:15});let r=e.state.localVars[K7];delete e.state.localVars[K7],typeof r==`string`&&t.hand.includes(r)&&await B(e.state,{type:`弃置`,player:n,cardIds:[r]})}}),()=>{}}function R7(e,t){t.defineAction(`respond`,{label:`飘零`,style:`primary`,prompt:{type:`confirm`,title:`是否发动飘零?`,confirmLabel:`发动`,cancelLabel:`不发动`}})}var z7,B7,V7,H7,U7,W7,G7,K7,tye,nye=t((()=>{V(),Fm(),F(),z7=`飘零/confirm`,B7=`飘零/give`,V7=`飘零/chooseTarget`,H7=`飘零/discard`,U7=`飘零/confirmed`,W7=`飘零/give`,G7=`飘零/target`,K7=`飘零/discardCardId`,tye={createSkill:I7,onInit:L7,onMount:R7}})),rye=r({createSkill:()=>aye,default:()=>cye,onInit:()=>oye,onMount:()=>sye});function q7(e){return Object.values(e).filter(e=>!!e).length}function iye(e,t){return t.map(t=>{let n=e.cardMap[t];return n?{cardId:t,cardName:n.name,suit:n.suit,rank:n.rank}:null}).filter(e=>e!==null)}function aye(e,t){return{id:e,ownerId:t,name:`飞军`,description:`出牌阶段限一次,弃置一张牌,令一名手牌数大于你的角色交给你一张牌,或令一名装备区里牌数大于你的角色弃置一张装备`}}function oye(e,t){let n=e.ownerId,r=[],i=j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`只能在你的回合使用`;if(e.phase!==`出牌`)return`只能在出牌阶段使用`;if(E(e))return`当前有未完成的询问`;if(X(e,n,`飞军`))return`本回合已使用过飞军`;let r=e.players[n];if(!r?.alive)return`你已死亡`;let i=t.cardId;return i?r.hand.includes(i)?null:`弃置的牌必须在手牌中`:`请选择要弃置的牌`},async(e,t)=>{let r=t.cardId;await Z(e,n,`飞军`),await I(e,`飞军`,n,{...t}),await B(e,{type:`弃置`,player:n,cardIds:[r],voluntary:!0});let i=e.players[n];if(!i?.alive){await L(e);return}let a=i.hand.length,o=q7(i.equipment),s=e.players.some(e=>e.index!==n&&e.alive&&e.hand.length>a),c=e.players.some(e=>e.index!==n&&e.alive&&q7(e.equipment)>o);if(!s&&!c){await L(e);return}let l;s&&c?(delete e.localVars[Q7],await B(e,{type:`请求回应`,requestType:J7,target:n,prompt:{type:`chooseOption`,title:`飞军:选择一项`,options:[{value:`hand`,label:`令一名手牌数大于你的角色交给你一张牌`},{value:`equip`,label:`令一名装备区里牌数大于你的角色弃置一张装备`}]},timeout:30}),l=e.localVars[Q7]??`hand`,delete e.localVars[Q7]):l=s?`hand`:`equip`;let u=[];for(let t of e.players)t.index===n||!t.alive||(l===`hand`?t.hand.length>a&&u.push(t.index):q7(t.equipment)>o&&u.push(t.index));if(u.length===0){await L(e);return}let d;if(u.length===1?d=u[0]:(delete e.localVars[$7],await B(e,{type:`请求回应`,requestType:Y7,target:n,prompt:{type:`choosePlayer`,title:l===`hand`?`飞军:选择一名手牌数大于你的角色(交给你一张牌)`:`飞军:选择一名装备数大于你的角色(弃置一张装备)`,min:1,max:1,candidates:u},timeout:30}),d=e.localVars[$7]??u[0],delete e.localVars[$7]),e.players[n]?.skills.includes(`兵略`)){let t=ul(e.players[n].vars)??[];t.includes(d)||(e.players[n].vars[xl]=[...t,d],await B(e,{type:`摸牌`,player:n,count:2}))}let f=e.players[d];if(!f?.alive){await L(e);return}if(l===`hand`){if(f.hand.length===0){await L(e);return}delete e.localVars[e9],await B(e,{type:`请求回应`,requestType:X7,target:d,prompt:{type:`pickProcessingCard`,title:`飞军:选择一张手牌交给 ${e.players[n]?.name??`对方`}`,cards:iye(e,f.hand)},timeout:30});let t=e.localVars[e9],r=e.players[d]?.hand??[];(!t||!r.includes(t))&&(t=r[0]),delete e.localVars[e9],t&&r.includes(t)&&await B(e,{type:`给予`,cardId:t,from:d,to:n})}else{let t=Object.values(f.equipment).filter(e=>!!e);if(t.length===0){await L(e);return}delete e.localVars[t9],await B(e,{type:`请求回应`,requestType:Z7,target:d,prompt:{type:`pickProcessingCard`,title:`飞军:选择一张装备牌弃置`,cards:iye(e,t)},timeout:30});let n=e.localVars[t9],r=Object.values(e.players[d]?.equipment??{}).filter(e=>!!e);(!n||!r.includes(n))&&(n=r[0]),delete e.localVars[t9],n&&r.includes(n)&&await B(e,{type:`弃置`,player:d,cardIds:[n],voluntary:!0})}await L(e)});r.push(i);for(let n of t.players){let i=n.index,a=j(t,e.id,i,`respond`,(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return`当前不需要回应`;let r=n.atom;if(r.type!==`请求回应`)return`当前不需要回应`;let a=r.requestType;if(a===J7)return t.option!==`hand`&&t.option!==`equip`?`请选择一项`:null;if(a===Y7)return typeof(t.targets?.[0]??(typeof t.target==`number`?t.target:void 0))==`number`?null:`请选择目标`;if(a===X7){let n=t.cardId;return n?e.players[i].hand.includes(n)?null:`牌不在手牌中`:`请选择一张手牌`}if(a===Z7){let n=t.cardId;return n?Object.values(e.players[i].equipment).includes(n)?null:`牌不在装备区`:`请选择一张装备`}return`当前不是飞军询问`},async(e,t)=>{let n=e.pendingSlots.get(i)?.atom?.requestType;if(n===J7)e.localVars[Q7]=t.option;else if(n===Y7){let n=t.targets?.[0]??(typeof t.target==`number`?t.target:void 0);typeof n==`number`&&(e.localVars[$7]=n)}else n===X7?e.localVars[e9]=t.cardId:n===Z7&&(e.localVars[t9]=t.cardId)});r.push(a)}return()=>{r.forEach(e=>e())}}function sye(e,t){return t.defineAction(`use`,{label:`飞军`,style:`primary`,prompt:{type:`useCard`,title:`飞军:弃置一张牌,令手牌数或装备数多于你的角色交牌或弃装备`,cardFilter:{filter:()=>!0,min:1,max:1}},activeWhen:t=>{if(!yh(`飞军`)(t))return!1;let n=t.view.players[t.perspectiveIdx];if(!n||(n.hand?.length??0)===0)return!1;let r=n.handCount,i=Object.values(n.equipment??{}).filter(e=>!!e).length,a=t.view.players.some(t=>t.index!==e.ownerId&&t.alive&&(t.handCount??0)>r),o=t.view.players.some(t=>t.index===e.ownerId||!t.alive?!1:Object.values(t.equipment??{}).filter(e=>!!e).length>i);return a||o}}),t.defineAction(`respond`,{label:`飞军`,style:`primary`,prompt:{type:`chooseOption`,title:`飞军`,options:[]}}),()=>{}}var J7,Y7,X7,Z7,Q7,$7,e9,t9,cye,lye=t((()=>{V(),z(),Q(),F(),W(),J7=`飞军/option`,Y7=`飞军/target`,X7=`飞军/giveCard`,Z7=`飞军/discardEquip`,Q7=`飞军/option`,$7=`飞军/target`,e9=`飞军/giveCardId`,t9=`飞军/discardEquipCardId`,cye={createSkill:aye,onInit:oye,onMount:sye}})),uye=r({createMountSkill:()=>n9,大宛:()=>mye,爪黄飞电:()=>_ye,的卢:()=>hye,紫骍:()=>pye,绝影:()=>gye,赤兔:()=>fye,骅骝:()=>vye});function n9(e,t,n){let r=dye[t];return{createSkill(t,r){return{id:t,ownerId:r,name:e,description:n}},onInit(e,t){let n=e.ownerId;return t.players[n].vars[r]=1,()=>{delete t.players[n]?.vars[r]}}}}var dye,fye,pye,mye,hye,gye,_ye,vye,yye=t((()=>{W(),dye={进攻:Sl,防御:Cl},fye=n9(`赤兔`,`进攻`,`进攻马:你与其他角色的距离-1`),pye=n9(`紫骍`,`进攻`,`进攻马:你与其他角色的距离-1`),mye=n9(`大宛`,`进攻`,`进攻马:你与其他角色的距离-1`),hye=n9(`的卢`,`防御`,`防御马:其他角色与你的距离+1`),gye=n9(`绝影`,`防御`,`防御马:其他角色与你的距离+1`),_ye=n9(`爪黄飞电`,`防御`,`防御马:其他角色与你的距离+1`),vye=n9(`骅骝`,`防御`,`防御马:其他角色与你的距离+1`)})),bye=r({createSkill:()=>xye,onInit:()=>Sye});function xye(e,t){return{id:e,ownerId:t,name:`马术`,description:`锁定技:你与其他角色的距离-1`,isLocked:!0}}function Sye(e,t){let n=e.ownerId;return t.players[n].vars[Sl]=1,()=>{delete t.players[n]?.vars[Sl]}}var Cye=t((()=>{W()})),wye=r({createSkill:()=>Eye,onInit:()=>Dye,onMount:()=>Oye});function Tye(e){if(e===`A`)return 1;if(e===`J`)return 11;if(e===`Q`)return 12;if(e===`K`)return 13;let t=parseInt(e,10);return Number.isFinite(t)?t:0}function Eye(e,t){return{id:e,ownerId:t,name:`驱虎`,description:`出牌阶段限一次,与一名角色拼点:赢则该角色对其攻击范围内另一角色造成1伤害,没赢则其对你造成1伤害`}}function Dye(e,t){let n=e.ownerId;j(t,e.id,n,`use`,(e,t)=>{if(e.currentPlayerIndex!==n)return`不是你的回合`;if(e.phase!==`出牌`)return`只能在出牌阶段发动`;if(X(e,n,`驱虎`))return`本回合已使用过驱虎`;let r=e.players[n];if(!r?.alive)return`玩家不存在或已死亡`;let i=t.cardId;if(typeof i!=`string`)return`需要选择拼点牌`;if(!r.hand.includes(i))return`拼点牌不在手牌中`;let a=t.target;if(typeof a!=`number`)return`需要选择拼点目标`;if(a===n)return`不能与自己拼点`;let o=e.players[a];return o?.alive?o.hand.length===0?`目标没有手牌,无法拼点`:null:`目标不存在或已死亡`},async(e,t)=>{let r=n,i=t.cardId,a=t.target;await Z(e,r,`驱虎`),await I(e,`驱虎`,r,{...t});let o=e.cardMap[i],s=o?Tye(o.rank):0;delete e.localVars[`驱虎/targetCard`],await B(e,{type:`请求回应`,requestType:`驱虎/拼点`,target:a,prompt:{type:`useCard`,title:`驱虎:与 ${e.players[r].name} 拼点,请出一张手牌`,cardFilter:{filter:()=>!0,min:1,max:1}},timeout:30});let c=e.localVars[`驱虎/targetCard`];delete e.localVars[`驱虎/targetCard`];let l;if(c&&e.players[a].hand.includes(c)?l=await xb(e,r,a,i,c)===`赢`:(await B(e,{type:`移动牌`,cardId:i,from:{zone:`手牌`,player:r},to:{zone:`弃牌堆`}}),l=s>0),l){if(e.players.filter(t=>t.alive&&t.index!==a&&Gm(e,a,t.index)).map(e=>e.index).length===0){await L(e);return}delete e.localVars[`驱虎/victim`],await B(e,{type:`请求回应`,requestType:`驱虎/选目标`,target:r,prompt:{type:`choosePlayer`,title:`驱虎:选择 ${e.players[a].name} 攻击范围内的一名角色,其将受到1点伤害`,min:1,max:1,filter:(e,t)=>t!==r&&e.players[t]?.alive===!0},timeout:30});let t=e.localVars[`驱虎/victim`];delete e.localVars[`驱虎/victim`],typeof t==`number`&&e.players[t]?.alive&&t!==a&&Gm(e,a,t)&&await Dm(e,a,t,1)}else await Dm(e,a,r,1);await L(e)});for(let r of t.players){let i=r.index;j(t,e.id,i,`respond`,(e,t)=>{let r=e.pendingSlots.get(i);if(!r)return`当前不需要回应`;let a=r.atom;if(a.type!==`请求回应`)return`当前不需要回应`;let o=a.requestType;if(o===`驱虎/拼点`){let n=t.cardId;return typeof n==`string`?e.players[i].hand.includes(n)?null:`拼点牌不在手牌中`:`请选择一张拼点牌`}return o===`驱虎/选目标`?i===n?typeof t.target==`number`?null:`请选择一名目标`:`只有驱虎发动者可以选择目标`:`当前不是驱虎回应`},async(e,t)=>{let n=e.pendingSlots.get(i);if(!n)return;let r=n.atom.requestType;r===`驱虎/拼点`?e.localVars[`驱虎/targetCard`]=t.cardId:r===`驱虎/选目标`&&(e.localVars[`驱虎/victim`]=t.target)})}return()=>{}}function Oye(e,t){t.defineAction(`use`,{label:`驱虎`,style:`danger`,prompt:{type:`useCardAndTarget`,title:`驱虎:选择一张拼点牌和一名目标`,cardFilter:{filter:()=>!0,min:1,max:1},targetFilter:{min:1,max:1,filter:(e,t)=>{if(t===e.currentPlayerIndex)return!1;let n=e.players[t];return n?n.alive!==!1&&(n.handCount??0)>0:!1}}},activeWhen:e=>yh(`驱虎`)(e)&&(e.view.players[e.perspectiveIdx]?.hand?.length??0)>0}),t.defineAction(`respond`,{label:`驱虎`,style:`primary`,prompt:{type:`useCard`,title:`驱虎:请出一张拼点牌`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var kye=t((()=>{V(),z(),Om(),Sb(),Q(),F(),Xm()})),Aye=r({createSkill:()=>jye,onInit:()=>Mye,onMount:()=>Nye});function jye(e,t){return{id:e,ownerId:t,name:`鬼才`,description:`判定牌生效前,你可以打出一张手牌代替之`}}function Mye(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==`鬼才/replace`)return`当前不是鬼才询问`;if(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`){let r=t.cardId;if(typeof r!=`string`)return`请选择一张替换牌`;if(!e.players[n].hand.includes(r))return`替换牌不在手牌中`}return null},async(e,t)=>{if(!(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`)){e.localVars[`鬼才/replaceCard`]=null;return}e.localVars[`鬼才/replaceCard`]=t.cardId??null}),fe(t,e.id,n,async e=>{if(e.atom.type!==`判定牌生效前`)return;let t=e.state.players[n];if(!t?.alive||t.hand.length===0||R(e.state).length===0)return;delete e.state.localVars[`鬼才/replaceCard`],await B(e.state,{type:`请求回应`,requestType:`鬼才/replace`,target:n,prompt:{type:`useCard`,title:`鬼才:是否打出一张手牌代替判定牌?`,cardFilter:{filter:()=>!0,min:1,max:1}},defaultChoice:!1,timeout:15});let r=e.state.localVars[`鬼才/replaceCard`];delete e.state.localVars[`鬼才/replaceCard`],r&&t.hand.includes(r)&&await Nm(e.state,n,r)}),()=>{}}function Nye(e,t){t.defineAction(`respond`,{label:`鬼才`,style:`primary`,prompt:{type:`useCard`,title:`鬼才:选择一张手牌代替判定牌`,cardFilter:{filter:()=>!0,min:1,max:1}}})}var Pye=t((()=>{V(),z(),F(),Fm()})),Fye=r({createSkill:()=>Iye,default:()=>zye,onInit:()=>Lye,onMount:()=>Rye});function r9(e,t){let n=e.cardMap[t];return!!n&&n.color===`黑`}function Iye(e,t){return{id:e,ownerId:t,name:`鬼道`,description:`判定牌生效前,你可以用一张黑色牌替换之`}}function Lye(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`)return`当前不需要回应`;if(i.requestType!==i9)return`当前不是鬼道询问`;if(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`){let r=t.cardId;if(typeof r!=`string`)return`请选择一张替换牌`;if(!e.players[n].hand.includes(r))return`替换牌不在手牌中`;if(!r9(e,r))return`鬼道只能用黑色牌替换`}return null},async(e,t)=>{if(!(t.choice===!0||t.confirmed===!0||typeof t.cardId==`string`)){e.localVars[a9]=null;return}e.localVars[a9]=t.cardId??null}),fe(t,e.id,n,async e=>{if(e.atom.type!==`判定牌生效前`)return;let t=e.state.players[n];if(!t?.alive||!t.hand.some(t=>r9(e.state,t))||R(e.state).length===0)return;delete e.state.localVars[a9],await B(e.state,{type:`请求回应`,requestType:i9,target:n,prompt:{type:`useCard`,title:`鬼道:是否打出一张黑色牌代替判定牌?`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}},defaultChoice:!1,timeout:15});let r=e.state.localVars[a9];delete e.state.localVars[a9],r&&t.hand.includes(r)&&r9(e.state,r)&&await Nm(e.state,n,r)}),()=>{}}function Rye(e,t){t.defineAction(`respond`,{label:`鬼道`,style:`primary`,prompt:{type:`useCard`,title:`鬼道:选择一张黑色牌代替判定牌`,cardFilter:{filter:e=>e.color===`黑`,min:1,max:1}}})}var i9,a9,zye,Bye=t((()=>{V(),z(),F(),Fm(),i9=`鬼道/replace`,a9=`鬼道/replaceCard`,zye={createSkill:Iye,onInit:Lye,onMount:Rye}})),Vye=r({createSkill:()=>Hye,default:()=>Gye,onInit:()=>Uye,onMount:()=>Wye});function Hye(e,t){return{id:e,ownerId:t,name:`魂姿`,description:`觉醒技:准备阶段且体力为1时,减1体力上限并永久获得"英姿"和"英魂"`}}function Uye(e,t){let n=e.ownerId;return N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||cl(e.state.players[n]?.vars))return;let r=e.state.players[n];r?.alive&&r.health===1&&(e.state.players[n].vars[yl]=!0,await B(e.state,{type:`设上限`,player:n,amount:r.maxHealth-1}),await B(e.state,{type:`添加技能`,player:n,skillId:`英姿`}),await B(e.state,{type:`添加技能`,player:n,skillId:`英魂`}),await y0(e.state,n))}),()=>{}}function Wye(e,t){}var Gye,Kye=t((()=>{V(),F(),j0(),W(),Gye={createSkill:Hye,onInit:Uye,onMount:Wye}})),qye=r({createSkill:()=>Jye,default:()=>Zye,onInit:()=>Yye,onMount:()=>Xye});function Jye(e,t){return{id:e,ownerId:t,name:`鸿举`,description:`觉醒技:准备阶段若荣≥3,用任意手牌替换等量的荣,减1体力上限并获得"清侧"`}}function Yye(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);if(!r)return`当前不需要回应`;let i=r.atom;if(i.type!==`请求回应`||i.requestType!==s9)return`当前不是鸿举换荣`;let a=t.cardIds;if(Array.isArray(a)){let t=new Set(e.players[n].hand),r=new Set;for(let e of a){if(typeof e!=`string`)return`cardId 必须为字符串`;if(!t.has(e))return`牌不在手牌中`;if(r.has(e))return`存在重复的牌`;r.add(e)}let i=e.players[n].marks.filter(e=>e.id.startsWith(vw)).length;if(a.length>i)return`替换数量超过荣数`}return null},async(e,t)=>{e.localVars[c9]=t.cardIds??[]}),N(t,e.id,n,`阶段开始`,async e=>{let t=e.atom;if(t.type!==`阶段开始`||t.player!==n||t.phase!==`准备`||e.state.players[n]?.vars[o9])return;let r=e.state.players[n];if(!r?.alive)return;let i=lw(e.state,n);if(i<3)return;e.state.players[n].vars[o9]=!0;let a=Math.min(r.hand.length,i);if(a>0){delete e.state.localVars[c9],await B(e.state,{type:`请求回应`,requestType:s9,target:n,prompt:{type:`distribute`,mode:`select`,title:`鸿举:选择任意手牌替换等量的荣(可不选)`,source:`hand`,minTotal:0,maxTotal:a},defaultChoice:[],timeout:20});let t=e.state.localVars[c9]??[],o=Math.min(t.length,i),s=r.marks.filter(e=>e.id.startsWith(vw));for(let t=0;t<o;t++)await B(e.state,{type:`去标记`,player:n,markId:s[t].id});for(let r of t.slice(0,o))await B(e.state,{type:`弃置`,player:n,cardIds:[r]}),await B(e.state,{type:`加标记`,player:n,mark:{id:`${vw}${e.state.seq}`,scope:n,payload:{cardId:r}}})}await B(e.state,{type:`设上限`,player:n,amount:r.maxHealth-1}),await B(e.state,{type:`添加技能`,player:n,skillId:`清侧`})}),()=>{}}function Xye(e,t){}var o9,s9,c9,Zye,Qye=t((()=>{V(),F(),xw(),o9=`鸿举/awakened`,s9=`鸿举/换荣`,c9=`鸿举/换荣结果`,Zye={createSkill:Jye,onInit:Yye,onMount:Xye}})),$ye=r({createSkill:()=>ebe,onInit:()=>tbe,onMount:()=>nbe});function ebe(e,t){return{id:e,ownerId:t,name:`麒麟弓`,description:`武器:杀造成伤害时可弃目标1匹马`,isLocked:!0}}function tbe(e,t){let n=e.ownerId;return j(t,e.id,n,`respond`,(e,t)=>{let r=e.pendingSlots.get(n);return r?r.atom.type!==`请求回应`||r.atom.requestType!==`麒麟弓/confirm`?`当前不是麒麟弓窗口`:null:`当前不需要回应`},async(e,t)=>{e.localVars[`麒麟弓/confirmed`]=t.choice===!0||t.confirmed===!0}),M(t,e.id,n,`造成伤害时`,async e=>{let t=e.atom;if(t.source!==n)return;let r=e.state.players[n];if(!r)return;let i=r.equipment.武器;if(!i||e.state.cardMap[i]?.name!==`麒麟弓`)return;let a=t.cardId;if(!a||e.state.cardMap[a]?.name!==`杀`)return;let o=t.target;if(typeof o!=`number`)return;let s=e.state.players[o];if(!s)return;let c=[`进攻马`,`防御马`].filter(e=>!!s.equipment?.[e]);if(c.length===0)return;if(delete e.state.localVars[`麒麟弓/confirmed`],await B(e.state,{type:`请求回应`,requestType:`麒麟弓/confirm`,target:n,prompt:{type:`confirm`,title:`麒麟弓:是否弃目标1匹马?`,confirmLabel:`弃马`,cancelLabel:`不发动`},timeout:10}),!e.state.localVars[`麒麟弓/confirmed`]){delete e.state.localVars[`麒麟弓/confirmed`];return}let l=s.equipment[c[0]];l&&await B(e.state,{type:`弃置`,player:o,cardIds:[l]}),delete e.state.localVars[`麒麟弓/confirmed`]}),()=>{}}function nbe(e,t){t.defineAction(`respond`,{label:`麒麟弓`,style:`default`,prompt:{type:`confirm`,title:`麒麟弓:是否弃目标1匹马?`,confirmLabel:`弃马`,cancelLabel:`不发动`}})}var rbe=t((()=>{V(),F()})),ibe=r({createSkill:()=>obe,default:()=>lbe,onInit:()=>sbe,onMount:()=>cbe});function abe(e,t){let n=e.cardMap[t]?.name;return n===`闪`||n===`闪电`}function obe(e,t){return{id:e,ownerId:t,name:`黄天`,description:`主公技:其他群势力角色可在出牌阶段将一张【闪】或【闪电】交给你`}}function sbe(e,t){let n=e.ownerId;for(let r of t.players){let i=r.index;i!==n&&r.faction===`群`&&j(t,e.id,i,`use`,(e,t)=>{if(n!==0)return`黄天为主公技,张角非主公`;if(!e.players[n]?.alive)return`主公不存在或已死亡`;let r=e.players[i];if(!r?.alive)return`已死亡`;let a=e.currentPlayerIndex===i,o=e.phase===`出牌`,s=!E(e);if(!a||!o||!s)return`现在不能使用黄天`;if(X(e,i,`黄天`))return`本回合已使用过黄天`;let c=t.cardId;return typeof c==`string`?r.hand.includes(c)?abe(e,c)?null:`黄天只能交出【闪】或【闪电】`:`牌不在手牌中`:`请选择一张牌`},async(e,t)=>{let r=t.cardId;await Z(e,i,`黄天`),await B(e,{type:`移动牌`,cardId:r,from:{zone:`手牌`,player:i},to:{zone:`手牌`,player:n}})})}return()=>{}}function cbe(e,t){let n=e.ownerId;t.defineAction(`use`,{label:`黄天`,style:`primary`,prompt:{type:`useCard`,title:`黄天:交出一张【闪】或【闪电】给主公`,cardFilter:{filter:e=>e.name===`闪`||e.name===`闪电`,min:1,max:1}},activeWhen:e=>e.perspectiveIdx!==n&&yh(`黄天`)(e)&&e.view.players[e.perspectiveIdx]?.hand?.some(e=>e.name===`闪`||e.name===`闪电`)===!0})}var lbe,ube=t((()=>{V(),Q(),F(),lbe={createSkill:obe,onInit:sbe,onMount:cbe}})),dbe=r({createSkill:()=>fbe,onInit:()=>mbe,onMount:()=>hbe});function fbe(e,t){return{id:e,ownerId:t,name:`龙胆`,description:`你可以将一张【杀】当【闪】使用或打出,或将一张【闪】当【杀】使用或打出`}}function pbe(e){return`${e}#龙胆`}function mbe(e,t){let n=e.ownerId;j(t,e.id,n,`transform`,(e,t)=>{let r=e.players[n],i=r?.alive===!0,a=t.cardId,o=typeof a==`string`,s=o?e.cardMap[a]:void 0,c=o&&r.hand.includes(a);if(!i)return`你已死亡`;if(!o||!c)return`牌不在手牌中`;let l=s?l9[s.name]:void 0,u=t.to??l;return l?u===l?null:u===`闪`?`只能将杀当闪`:u===`杀`?`只能将闪当杀`:`无效的转化方向`:`只能将杀当闪或将闪当杀`},async(e,t)=>{let r=t.cardId,i=e.cardMap[r],a=t.to??(i?l9[i.name]:void 0);if(!a)return;let o=pbe(r);await B(e,{type:`当作`,player:n,cardIds:[r],shadowId:o,outputName:a})},(e,t)=>{let r=t.cardId,i=pbe(r);delete e.cardMap[i];let a=e.players[n],o=a.hand.indexOf(i);o>=0&&(a.hand[o]=r)});let r=de(t,n,`询问闪`),i=de(t,n,`询问杀`);return()=>{r(),i()}}function hbe(e,t){t.defineAction(`transform`,{label:`龙胆`,style:`passive`,prompt:{type:`useCardAndTarget`,title:`选择一张杀或闪转化`,cardFilter:{filter:e=>e.name===`杀`||e.name===`闪`,min:1,max:1},targetFilter:{min:1,max:3,filter:(e,t)=>{let n=e.currentPlayerIndex;return e.players.some((e,t)=>t===n)&&t!==n&&e.players[t]?.alive}}},transform:t=>({name:t.name===`杀`?`闪`:`杀`,sourceCardId:t.id,fromSkill:e.id}),activeWhen:e=>{let t=e.view.players[e.perspectiveIdx];if(!t?.alive||!(t.hand?.some(e=>e.name===`杀`||e.name===`闪`)??!1))return!1;let n=q(e)&&sm(e.view,e.perspectiveIdx),r=e.view.pending,i=!!r&&r.atom.type===`询问闪`&&r.target===e.perspectiveIdx,a=!!r&&r.atom.type===`询问杀`&&r.target===e.perspectiveIdx;return n||i||a}})}var l9,gbe=t((()=>{F(),V(),J(),l9={杀:`闪`,闪:`杀`}})),_be=r({default:()=>vbe}),vbe,ybe=t((()=>{Em(),vbe=Object.assign({"./cards/index.ts":()=>Y(()=>Promise.resolve().then(()=>(Yg(),cne)),void 0,import.meta.url),"./cards/play-card.ts":()=>Y(()=>Promise.resolve().then(()=>(ug(),Cte)),void 0,import.meta.url),"./cards/use-card.ts":()=>Y(()=>Promise.resolve().then(()=>(Gh(),hte)),void 0,import.meta.url),"./cards/validate.ts":()=>Y(()=>Promise.resolve().then(()=>(vh(),cte)),void 0,import.meta.url),"./cards/万箭齐发.ts":()=>Y(()=>Promise.resolve().then(()=>(Am(),Wee)),void 0,import.meta.url),"./cards/乐不思蜀.ts":()=>Y(()=>Promise.resolve().then(()=>(Xee(),qee)),void 0,import.meta.url),"./cards/五谷丰登.ts":()=>Y(()=>Promise.resolve().then(()=>(zm(),Zee)),void 0,import.meta.url),"./cards/借刀杀人.ts":()=>Y(()=>Promise.resolve().then(()=>(tg(),gte)),void 0,import.meta.url),"./cards/兵粮寸断.ts":()=>Y(()=>Promise.resolve().then(()=>(ig(),bte)),void 0,import.meta.url),"./cards/决斗.ts":()=>Y(()=>Promise.resolve().then(()=>(fg(),Tte)),void 0,import.meta.url),"./cards/南蛮入侵.ts":()=>Y(()=>Promise.resolve().then(()=>(mg(),kte)),void 0,import.meta.url),"./cards/无中生有.ts":()=>Y(()=>Promise.resolve().then(()=>(gg(),jte)),void 0,import.meta.url),"./cards/无懈可击.ts":()=>Y(()=>Promise.resolve().then(()=>(yg(),Nte)),void 0,import.meta.url),"./cards/杀.ts":()=>Y(()=>Promise.resolve().then(()=>(xg(),Pte)),void 0,import.meta.url),"./cards/桃.ts":()=>Y(()=>Promise.resolve().then(()=>(Cg(),Rte)),void 0,import.meta.url),"./cards/桃园结义.ts":()=>Y(()=>Promise.resolve().then(()=>(Tg(),Hte)),void 0,import.meta.url),"./cards/火攻.ts":()=>Y(()=>Promise.resolve().then(()=>(Dg(),Wte)),void 0,import.meta.url),"./cards/过河拆桥.ts":()=>Y(()=>Promise.resolve().then(()=>(Mg(),qte)),void 0,import.meta.url),"./cards/酒.ts":()=>Y(()=>Promise.resolve().then(()=>(Sh(),ute)),void 0,import.meta.url),"./cards/铁索连环.ts":()=>Y(()=>Promise.resolve().then(()=>(Pg(),Xte)),void 0,import.meta.url),"./cards/闪.ts":()=>Y(()=>Promise.resolve().then(()=>(Lg(),$te)),void 0,import.meta.url),"./cards/闪电.ts":()=>Y(()=>Promise.resolve().then(()=>(Vg(),ene)),void 0,import.meta.url),"./cards/顺手牵羊.ts":()=>Y(()=>Promise.resolve().then(()=>(Ug(),ane)),void 0,import.meta.url),"./丈八蛇矛.ts":()=>Y(()=>Promise.resolve().then(()=>(pne(),lne)),void 0,import.meta.url),"./不屈.ts":()=>Y(()=>Promise.resolve().then(()=>(hne(),mne)),void 0,import.meta.url),"./义绝.ts":()=>Y(()=>Promise.resolve().then(()=>(_ne(),gne)),void 0,import.meta.url),"./乱击.ts":()=>Y(()=>Promise.resolve().then(()=>(yne(),vne)),void 0,import.meta.url),"./乱武.ts":()=>Y(()=>Promise.resolve().then(()=>(xne(),bne)),void 0,import.meta.url),"./享乐.ts":()=>Y(()=>Promise.resolve().then(()=>(Cne(),Sne)),void 0,import.meta.url),"./仁德.ts":()=>Y(()=>Promise.resolve().then(()=>(Tne(),wne)),void 0,import.meta.url),"./仁王盾.ts":()=>Y(()=>Promise.resolve().then(()=>(kne(),Ene)),void 0,import.meta.url),"./从谏.ts":()=>Y(()=>Promise.resolve().then(()=>(jne(),Ane)),void 0,import.meta.url),"./伪帝.ts":()=>Y(()=>Promise.resolve().then(()=>(Nne(),Mne)),void 0,import.meta.url),"./倾国.ts":()=>Y(()=>Promise.resolve().then(()=>(Fne(),Pne)),void 0,import.meta.url),"./克己.ts":()=>Y(()=>Promise.resolve().then(()=>(Lne(),Ine)),void 0,import.meta.url),"./八卦阵.ts":()=>Y(()=>Promise.resolve().then(()=>(Hne(),Rne)),void 0,import.meta.url),"./八阵.ts":()=>Y(()=>Promise.resolve().then(()=>(Gne(),Une)),void 0,import.meta.url),"./兵略.ts":()=>Y(()=>Promise.resolve().then(()=>(qne(),Kne)),void 0,import.meta.url),"./再起.ts":()=>Y(()=>Promise.resolve().then(()=>(Xne(),Jne)),void 0,import.meta.url),"./决堰.ts":()=>Y(()=>Promise.resolve().then(()=>(Ov(),Zne)),void 0,import.meta.url),"./凿险.ts":()=>Y(()=>Promise.resolve().then(()=>(dre(),are)),void 0,import.meta.url),"./刚烈.ts":()=>Y(()=>Promise.resolve().then(()=>(pre(),fre)),void 0,import.meta.url),"./制衡.ts":()=>Y(()=>Promise.resolve().then(()=>(vre(),mre)),void 0,import.meta.url),"./制霸.ts":()=>Y(()=>Promise.resolve().then(()=>(bre(),yre)),void 0,import.meta.url),"./勤学.ts":()=>Y(()=>Promise.resolve().then(()=>(Sre(),xre)),void 0,import.meta.url),"./化身.ts":()=>Y(()=>Promise.resolve().then(()=>(Mre(),Cre)),void 0,import.meta.url),"./博图.ts":()=>Y(()=>Promise.resolve().then(()=>(Ire(),Nre)),void 0,import.meta.url),"./双雄.ts":()=>Y(()=>Promise.resolve().then(()=>(Rre(),Lre)),void 0,import.meta.url),"./反间.ts":()=>Y(()=>Promise.resolve().then(()=>(Bre(),zre)),void 0,import.meta.url),"./反馈.ts":()=>Y(()=>Promise.resolve().then(()=>(Gre(),Vre)),void 0,import.meta.url),"./古锭刀.ts":()=>Y(()=>Promise.resolve().then(()=>(qre(),Kre)),void 0,import.meta.url),"./咆哮.ts":()=>Y(()=>Promise.resolve().then(()=>(Zre(),Jre)),void 0,import.meta.url),"./回合管理.ts":()=>Y(()=>Promise.resolve().then(()=>(iie(),Qre)),void 0,import.meta.url),"./固政.ts":()=>Y(()=>Promise.resolve().then(()=>(oie(),aie)),void 0,import.meta.url),"./国色.ts":()=>Y(()=>Promise.resolve().then(()=>(cie(),sie)),void 0,import.meta.url),"./天义.ts":()=>Y(()=>Promise.resolve().then(()=>(die(),lie)),void 0,import.meta.url),"./天妒.ts":()=>Y(()=>Promise.resolve().then(()=>(gie(),fie)),void 0,import.meta.url),"./天香.ts":()=>Y(()=>Promise.resolve().then(()=>(vie(),_ie)),void 0,import.meta.url),"./奇制.ts":()=>Y(()=>Promise.resolve().then(()=>(bie(),yie)),void 0,import.meta.url),"./奇才.ts":()=>Y(()=>Promise.resolve().then(()=>(wie(),xie)),void 0,import.meta.url),"./奇袭.ts":()=>Y(()=>Promise.resolve().then(()=>(Eie(),Tie)),void 0,import.meta.url),"./奇谋.ts":()=>Y(()=>Promise.resolve().then(()=>(Oie(),Die)),void 0,import.meta.url),"./奋威.ts":()=>Y(()=>Promise.resolve().then(()=>(jie(),kie)),void 0,import.meta.url),"./奋激.ts":()=>Y(()=>Promise.resolve().then(()=>(Nie(),Mie)),void 0,import.meta.url),"./奸雄.ts":()=>Y(()=>Promise.resolve().then(()=>(Rie(),Pie)),void 0,import.meta.url),"./好施.ts":()=>Y(()=>Promise.resolve().then(()=>(Bie(),zie)),void 0,import.meta.url),"./完杀.ts":()=>Y(()=>Promise.resolve().then(()=>(Hie(),Vie)),void 0,import.meta.url),"./审时.ts":()=>Y(()=>Promise.resolve().then(()=>(Gie(),Uie)),void 0,import.meta.url),"./寒冰剑.ts":()=>Y(()=>Promise.resolve().then(()=>(Xie(),Kie)),void 0,import.meta.url),"./寸目.ts":()=>Y(()=>Promise.resolve().then(()=>(Qie(),Zie)),void 0,import.meta.url),"./屯田.ts":()=>Y(()=>Promise.resolve().then(()=>(tae(),$ie)),void 0,import.meta.url),"./崩坏.ts":()=>Y(()=>Promise.resolve().then(()=>(rae(),nae)),void 0,import.meta.url),"./巧变.ts":()=>Y(()=>Promise.resolve().then(()=>(oae(),iae)),void 0,import.meta.url),"./巨象.ts":()=>Y(()=>Promise.resolve().then(()=>(cae(),sae)),void 0,import.meta.url),"./帷幕.ts":()=>Y(()=>Promise.resolve().then(()=>(dae(),lae)),void 0,import.meta.url),"./庸肆.ts":()=>Y(()=>Promise.resolve().then(()=>(pae(),fae)),void 0,import.meta.url),"./开局.ts":()=>Y(()=>Promise.resolve().then(()=>(kae(),wae)),void 0,import.meta.url),"./强袭.ts":()=>Y(()=>Promise.resolve().then(()=>(jae(),Aae)),void 0,import.meta.url),"./往烈.ts":()=>Y(()=>Promise.resolve().then(()=>(Pae(),Mae)),void 0,import.meta.url),"./征荣.ts":()=>Y(()=>Promise.resolve().then(()=>(xw(),Fae)),void 0,import.meta.url),"./志继.ts":()=>Y(()=>Promise.resolve().then(()=>(Lae(),Iae)),void 0,import.meta.url),"./怀橘.ts":()=>Y(()=>Promise.resolve().then(()=>(zw(),Rae)),void 0,import.meta.url),"./急救.ts":()=>Y(()=>Promise.resolve().then(()=>(Uae(),zae)),void 0,import.meta.url),"./急袭.ts":()=>Y(()=>Promise.resolve().then(()=>(Gae(),Wae)),void 0,import.meta.url),"./恃才.ts":()=>Y(()=>Promise.resolve().then(()=>(Jae(),Kae)),void 0,import.meta.url),"./悲歌.ts":()=>Y(()=>Promise.resolve().then(()=>(Xae(),Yae)),void 0,import.meta.url),"./成略.ts":()=>Y(()=>Promise.resolve().then(()=>(Qae(),Zae)),void 0,import.meta.url),"./截辎.ts":()=>Y(()=>Promise.resolve().then(()=>(ioe(),$ae)),void 0,import.meta.url),"./护甲.ts":()=>Y(()=>Promise.resolve().then(()=>(coe(),aoe)),void 0,import.meta.url),"./护驾.ts":()=>Y(()=>Promise.resolve().then(()=>(uoe(),loe)),void 0,import.meta.url),"./拒战.ts":()=>Y(()=>Promise.resolve().then(()=>(poe(),doe)),void 0,import.meta.url),"./挑衅.ts":()=>Y(()=>Promise.resolve().then(()=>(goe(),moe)),void 0,import.meta.url),"./据守.ts":()=>Y(()=>Promise.resolve().then(()=>(yoe(),_oe)),void 0,import.meta.url),"./掣政.ts":()=>Y(()=>Promise.resolve().then(()=>(Coe(),boe)),void 0,import.meta.url),"./攻心.ts":()=>Y(()=>Promise.resolve().then(()=>(Toe(),woe)),void 0,import.meta.url),"./放权.ts":()=>Y(()=>Promise.resolve().then(()=>(Doe(),Eoe)),void 0,import.meta.url),"./放逐.ts":()=>Y(()=>Promise.resolve().then(()=>(koe(),Ooe)),void 0,import.meta.url),"./救援.ts":()=>Y(()=>Promise.resolve().then(()=>(joe(),Aoe)),void 0,import.meta.url),"./整论.ts":()=>Y(()=>Promise.resolve().then(()=>(Poe(),Moe)),void 0,import.meta.url),"./断粮.ts":()=>Y(()=>Promise.resolve().then(()=>(zoe(),Foe)),void 0,import.meta.url),"./断肠.ts":()=>Y(()=>Promise.resolve().then(()=>(Voe(),Boe)),void 0,import.meta.url),"./新生.ts":()=>Y(()=>Promise.resolve().then(()=>(Goe(),Hoe)),void 0,import.meta.url),"./方天画戟.ts":()=>Y(()=>Promise.resolve().then(()=>(Yoe(),Koe)),void 0,import.meta.url),"./无双.ts":()=>Y(()=>Promise.resolve().then(()=>(ese(),Xoe)),void 0,import.meta.url),"./明任.ts":()=>Y(()=>Promise.resolve().then(()=>(VD(),tse)),void 0,import.meta.url),"./暴虐.ts":()=>Y(()=>Promise.resolve().then(()=>(ise(),rse)),void 0,import.meta.url),"./朱雀羽扇.ts":()=>Y(()=>Promise.resolve().then(()=>(ose(),ase)),void 0,import.meta.url),"./枭姬.ts":()=>Y(()=>Promise.resolve().then(()=>(cse(),sse)),void 0,import.meta.url),"./武圣.ts":()=>Y(()=>Promise.resolve().then(()=>(pse(),lse)),void 0,import.meta.url),"./武烈.ts":()=>Y(()=>Promise.resolve().then(()=>(hse(),mse)),void 0,import.meta.url),"./洛神.ts":()=>Y(()=>Promise.resolve().then(()=>(xse(),gse)),void 0,import.meta.url),"./流离.ts":()=>Y(()=>Promise.resolve().then(()=>(Ese(),Sse)),void 0,import.meta.url),"./涅槃.ts":()=>Y(()=>Promise.resolve().then(()=>(Ose(),Dse)),void 0,import.meta.url),"./涯角.ts":()=>Y(()=>Promise.resolve().then(()=>(Ase(),kse)),void 0,import.meta.url),"./溃诛.ts":()=>Y(()=>Promise.resolve().then(()=>(Mse(),jse)),void 0,import.meta.url),"./激将.ts":()=>Y(()=>Promise.resolve().then(()=>(Lse(),Nse)),void 0,import.meta.url),"./激昂.ts":()=>Y(()=>Promise.resolve().then(()=>(Vse(),Rse)),void 0,import.meta.url),"./火计.ts":()=>Y(()=>Promise.resolve().then(()=>(Use(),Hse)),void 0,import.meta.url),"./烈刃.ts":()=>Y(()=>Promise.resolve().then(()=>(Kse(),Wse)),void 0,import.meta.url),"./烈弓.ts":()=>Y(()=>Promise.resolve().then(()=>(Zse(),qse)),void 0,import.meta.url),"./父荫.ts":()=>Y(()=>Promise.resolve().then(()=>($se(),Qse)),void 0,import.meta.url),"./狂骨.ts":()=>Y(()=>Promise.resolve().then(()=>(tce(),ece)),void 0,import.meta.url),"./界不屈.ts":()=>Y(()=>Promise.resolve().then(()=>(rce(),nce)),void 0,import.meta.url),"./界义从.ts":()=>Y(()=>Promise.resolve().then(()=>(ace(),ice)),void 0,import.meta.url),"./界乱击.ts":()=>Y(()=>Promise.resolve().then(()=>(fce(),oce)),void 0,import.meta.url),"./界乱武.ts":()=>Y(()=>Promise.resolve().then(()=>(bce(),pce)),void 0,import.meta.url),"./界仁德.ts":()=>Y(()=>Promise.resolve().then(()=>(Ace(),xce)),void 0,import.meta.url),"./界仁心.ts":()=>Y(()=>Promise.resolve().then(()=>(Rce(),jce)),void 0,import.meta.url),"./界伏枥.ts":()=>Y(()=>Promise.resolve().then(()=>(Wce(),zce)),void 0,import.meta.url),"./界伤逝.ts":()=>Y(()=>Promise.resolve().then(()=>(qce(),Gce)),void 0,import.meta.url),"./界克己.ts":()=>Y(()=>Promise.resolve().then(()=>(Yce(),Jce)),void 0,import.meta.url),"./界再起.ts":()=>Y(()=>Promise.resolve().then(()=>(Zce(),Xce)),void 0,import.meta.url),"./界凿险.ts":()=>Y(()=>Promise.resolve().then(()=>(ele(),Qce)),void 0,import.meta.url),"./界刚烈.ts":()=>Y(()=>Promise.resolve().then(()=>(nle(),tle)),void 0,import.meta.url),"./界利驭.ts":()=>Y(()=>Promise.resolve().then(()=>(ile(),rle)),void 0,import.meta.url),"./界制衡.ts":()=>Y(()=>Promise.resolve().then(()=>(ole(),ale)),void 0,import.meta.url),"./界制霸.ts":()=>Y(()=>Promise.resolve().then(()=>(cle(),sle)),void 0,import.meta.url),"./界势斩.ts":()=>Y(()=>Promise.resolve().then(()=>(ule(),lle)),void 0,import.meta.url),"./界双雄.ts":()=>Y(()=>Promise.resolve().then(()=>(fle(),dle)),void 0,import.meta.url),"./界反间.ts":()=>Y(()=>Promise.resolve().then(()=>(mle(),ple)),void 0,import.meta.url),"./界咆哮.ts":()=>Y(()=>Promise.resolve().then(()=>(gle(),hle)),void 0,import.meta.url),"./界固政.ts":()=>Y(()=>Promise.resolve().then(()=>(ble(),_le)),void 0,import.meta.url),"./界国色.ts":()=>Y(()=>Promise.resolve().then(()=>(wle(),xle)),void 0,import.meta.url),"./界天香.ts":()=>Y(()=>Promise.resolve().then(()=>(Dle(),Tle)),void 0,import.meta.url),"./界奇才.ts":()=>Y(()=>Promise.resolve().then(()=>(kle(),Ole)),void 0,import.meta.url),"./界奸雄.ts":()=>Y(()=>Promise.resolve().then(()=>(jle(),Ale)),void 0,import.meta.url),"./界好施.ts":()=>Y(()=>Promise.resolve().then(()=>(Fle(),Ple)),void 0,import.meta.url),"./界完杀.ts":()=>Y(()=>Promise.resolve().then(()=>(Rle(),Ile)),void 0,import.meta.url),"./界宗室.ts":()=>Y(()=>Promise.resolve().then(()=>(Ule(),zle)),void 0,import.meta.url),"./界将驰.ts":()=>Y(()=>Promise.resolve().then(()=>(Gle(),Wle)),void 0,import.meta.url),"./界屯田.ts":()=>Y(()=>Promise.resolve().then(()=>(Jle(),Kle)),void 0,import.meta.url),"./界崩坏.ts":()=>Y(()=>Promise.resolve().then(()=>(Xle(),Yle)),void 0,import.meta.url),"./界巧变.ts":()=>Y(()=>Promise.resolve().then(()=>(nue(),Zle)),void 0,import.meta.url),"./界巧说.ts":()=>Y(()=>Promise.resolve().then(()=>(aue(),rue)),void 0,import.meta.url),"./界帷幕.ts":()=>Y(()=>Promise.resolve().then(()=>(cue(),oue)),void 0,import.meta.url),"./界弓骑.ts":()=>Y(()=>Promise.resolve().then(()=>(fue(),lue)),void 0,import.meta.url),"./界强袭.ts":()=>Y(()=>Promise.resolve().then(()=>(mue(),pue)),void 0,import.meta.url),"./界强识.ts":()=>Y(()=>Promise.resolve().then(()=>(gue(),hue)),void 0,import.meta.url),"./界当先.ts":()=>Y(()=>Promise.resolve().then(()=>(vue(),_ue)),void 0,import.meta.url),"./界志继.ts":()=>Y(()=>Promise.resolve().then(()=>(xue(),yue)),void 0,import.meta.url),"./界忘隙.ts":()=>Y(()=>Promise.resolve().then(()=>(Cue(),Sue)),void 0,import.meta.url),"./界恂恂.ts":()=>Y(()=>Promise.resolve().then(()=>(Tue(),wue)),void 0,import.meta.url),"./界恩怨.ts":()=>Y(()=>Promise.resolve().then(()=>(Mue(),Eue)),void 0,import.meta.url),"./界悲歌.ts":()=>Y(()=>Promise.resolve().then(()=>(Pue(),Nue)),void 0,import.meta.url),"./界惴恐.ts":()=>Y(()=>Promise.resolve().then(()=>(Lue(),Fue)),void 0,import.meta.url),"./界护驾.ts":()=>Y(()=>Promise.resolve().then(()=>(zue(),Rue)),void 0,import.meta.url),"./界挑衅.ts":()=>Y(()=>Promise.resolve().then(()=>(Hue(),Bue)),void 0,import.meta.url),"./界据守.ts":()=>Y(()=>Promise.resolve().then(()=>(Gue(),Uue)),void 0,import.meta.url),"./界放权.ts":()=>Y(()=>Promise.resolve().then(()=>(que(),Kue)),void 0,import.meta.url),"./界放逐.ts":()=>Y(()=>Promise.resolve().then(()=>(Yue(),Jue)),void 0,import.meta.url),"./界救援.ts":()=>Y(()=>Promise.resolve().then(()=>(Zue(),Xue)),void 0,import.meta.url),"./界断粮.ts":()=>Y(()=>Promise.resolve().then(()=>(nde(),Que)),void 0,import.meta.url),"./界旋风.ts":()=>Y(()=>Promise.resolve().then(()=>(ide(),rde)),void 0,import.meta.url),"./界明策.ts":()=>Y(()=>Promise.resolve().then(()=>(cde(),ade)),void 0,import.meta.url),"./界智迟.ts":()=>Y(()=>Promise.resolve().then(()=>(mde(),lde)),void 0,import.meta.url),"./界暴虐.ts":()=>Y(()=>Promise.resolve().then(()=>(gde(),hde)),void 0,import.meta.url),"./界樵拾.ts":()=>Y(()=>Promise.resolve().then(()=>(yde(),_de)),void 0,import.meta.url),"./界武圣.ts":()=>Y(()=>Promise.resolve().then(()=>(xde(),bde)),void 0,import.meta.url),"./界殚心.ts":()=>Y(()=>Promise.resolve().then(()=>(wde(),Sde)),void 0,import.meta.url),"./界毅重.ts":()=>Y(()=>Promise.resolve().then(()=>(Dde(),Tde)),void 0,import.meta.url),"./界求援.ts":()=>Y(()=>Promise.resolve().then(()=>(kde(),Ode)),void 0,import.meta.url),"./界洛神.ts":()=>Y(()=>Promise.resolve().then(()=>(Mde(),Ade)),void 0,import.meta.url),"./界涅槃.ts":()=>Y(()=>Promise.resolve().then(()=>(Pde(),Nde)),void 0,import.meta.url),"./界渐营.ts":()=>Y(()=>Promise.resolve().then(()=>(Bde(),Fde)),void 0,import.meta.url),"./界潜心.ts":()=>Y(()=>Promise.resolve().then(()=>(Hde(),Vde)),void 0,import.meta.url),"./界潜袭.ts":()=>Y(()=>Promise.resolve().then(()=>(Gde(),Ude)),void 0,import.meta.url),"./界激将.ts":()=>Y(()=>Promise.resolve().then(()=>(qde(),Kde)),void 0,import.meta.url),"./界激昂.ts":()=>Y(()=>Promise.resolve().then(()=>(Xde(),Jde)),void 0,import.meta.url),"./界火计.ts":()=>Y(()=>Promise.resolve().then(()=>(Qde(),Zde)),void 0,import.meta.url),"./界灭计.ts":()=>Y(()=>Promise.resolve().then(()=>(efe(),$de)),void 0,import.meta.url),"./界烈弓.ts":()=>Y(()=>Promise.resolve().then(()=>(rfe(),tfe)),void 0,import.meta.url),"./界焚城.ts":()=>Y(()=>Promise.resolve().then(()=>(afe(),ife)),void 0,import.meta.url),"./界燕语.ts":()=>Y(()=>Promise.resolve().then(()=>(lfe(),ofe)),void 0,import.meta.url),"./界父魂.ts":()=>Y(()=>Promise.resolve().then(()=>(dfe(),ufe)),void 0,import.meta.url),"./界狂骨.ts":()=>Y(()=>Promise.resolve().then(()=>(pfe(),ffe)),void 0,import.meta.url),"./界献图.ts":()=>Y(()=>Promise.resolve().then(()=>(hfe(),mfe)),void 0,import.meta.url),"./界献州.ts":()=>Y(()=>Promise.resolve().then(()=>(_fe(),gfe)),void 0,import.meta.url),"./界甘露.ts":()=>Y(()=>Promise.resolve().then(()=>(bfe(),vfe)),void 0,import.meta.url),"./界疠火.ts":()=>Y(()=>Promise.resolve().then(()=>(Sfe(),xfe)),void 0,import.meta.url),"./界直言.ts":()=>Y(()=>Promise.resolve().then(()=>(Dfe(),Cfe)),void 0,import.meta.url),"./界直谏.ts":()=>Y(()=>Promise.resolve().then(()=>(kfe(),Ofe)),void 0,import.meta.url),"./界看破.ts":()=>Y(()=>Promise.resolve().then(()=>(Mfe(),Afe)),void 0,import.meta.url),"./界眩惑.ts":()=>Y(()=>Promise.resolve().then(()=>(Bfe(),Nfe)),void 0,import.meta.url),"./界矢北.ts":()=>Y(()=>Promise.resolve().then(()=>(Wfe(),Vfe)),void 0,import.meta.url),"./界矫诏.ts":()=>Y(()=>Promise.resolve().then(()=>(Yfe(),Gfe)),void 0,import.meta.url),"./界破军.ts":()=>Y(()=>Promise.resolve().then(()=>($fe(),Xfe)),void 0,import.meta.url),"./界神速.ts":()=>Y(()=>Promise.resolve().then(()=>(npe(),epe)),void 0,import.meta.url),"./界禁酒.ts":()=>Y(()=>Promise.resolve().then(()=>(ape(),rpe)),void 0,import.meta.url),"./界秘计.ts":()=>Y(()=>Promise.resolve().then(()=>(cpe(),ope)),void 0,import.meta.url),"./界称象.ts":()=>Y(()=>Promise.resolve().then(()=>(dpe(),lpe)),void 0,import.meta.url),"./界空城.ts":()=>Y(()=>Promise.resolve().then(()=>(ppe(),fpe)),void 0,import.meta.url),"./界突袭.ts":()=>Y(()=>Promise.resolve().then(()=>(hpe(),mpe)),void 0,import.meta.url),"./界窃听.ts":()=>Y(()=>Promise.resolve().then(()=>(ype(),gpe)),void 0,import.meta.url),"./界精策.ts":()=>Y(()=>Promise.resolve().then(()=>(xpe(),bpe)),void 0,import.meta.url),"./界红颜.ts":()=>Y(()=>Promise.resolve().then(()=>(wpe(),Spe)),void 0,import.meta.url),"./界纵玄.ts":()=>Y(()=>Promise.resolve().then(()=>(Ope(),Tpe)),void 0,import.meta.url),"./界纵适.ts":()=>Y(()=>Promise.resolve().then(()=>(Ape(),kpe)),void 0,import.meta.url),"./界结姻.ts":()=>Y(()=>Promise.resolve().then(()=>(Npe(),jpe)),void 0,import.meta.url),"./界绝情.ts":()=>Y(()=>Promise.resolve().then(()=>(Fpe(),Ppe)),void 0,import.meta.url),"./界绝策.ts":()=>Y(()=>Promise.resolve().then(()=>(Lpe(),Ipe)),void 0,import.meta.url),"./界缔盟.ts":()=>Y(()=>Promise.resolve().then(()=>(Bpe(),Rpe)),void 0,import.meta.url),"./界翦灭.ts":()=>Y(()=>Promise.resolve().then(()=>(Hpe(),Vpe)),void 0,import.meta.url),"./界耀武.ts":()=>Y(()=>Promise.resolve().then(()=>(Wpe(),Upe)),void 0,import.meta.url),"./界自守.ts":()=>Y(()=>Promise.resolve().then(()=>(Kpe(),Gpe)),void 0,import.meta.url),"./界节命.ts":()=>Y(()=>Promise.resolve().then(()=>(Jpe(),qpe)),void 0,import.meta.url),"./界若愚.ts":()=>Y(()=>Promise.resolve().then(()=>(Xpe(),Ype)),void 0,import.meta.url),"./界苦肉.ts":()=>Y(()=>Promise.resolve().then(()=>(Qpe(),Zpe)),void 0,import.meta.url),"./界英姿.ts":()=>Y(()=>Promise.resolve().then(()=>(eme(),$pe)),void 0,import.meta.url),"./界荐言.ts":()=>Y(()=>Promise.resolve().then(()=>(ime(),tme)),void 0,import.meta.url),"./界落英.ts":()=>Y(()=>Promise.resolve().then(()=>(sme(),ame)),void 0,import.meta.url),"./界蛊惑.ts":()=>Y(()=>Promise.resolve().then(()=>(gme(),cme)),void 0,import.meta.url),"./界血裔.ts":()=>Y(()=>Promise.resolve().then(()=>(xme(),_me)),void 0,import.meta.url),"./界补益.ts":()=>Y(()=>Promise.resolve().then(()=>(Cme(),Sme)),void 0,import.meta.url),"./界裸衣.ts":()=>Y(()=>Promise.resolve().then(()=>(Eme(),wme)),void 0,import.meta.url),"./界观星.ts":()=>Y(()=>Promise.resolve().then(()=>(kme(),Dme)),void 0,import.meta.url),"./界解烦.ts":()=>Y(()=>Promise.resolve().then(()=>(Nme(),Ame)),void 0,import.meta.url),"./界诛害.ts":()=>Y(()=>Promise.resolve().then(()=>(Lme(),Pme)),void 0,import.meta.url),"./界谦逊.ts":()=>Y(()=>Promise.resolve().then(()=>(zme(),Rme)),void 0,import.meta.url),"./界贞烈.ts":()=>Y(()=>Promise.resolve().then(()=>(Vme(),Bme)),void 0,import.meta.url),"./界趫猛.ts":()=>Y(()=>Promise.resolve().then(()=>(Kme(),Hme)),void 0,import.meta.url),"./界连环.ts":()=>Y(()=>Promise.resolve().then(()=>(Yme(),qme)),void 0,import.meta.url),"./界连营.ts":()=>Y(()=>Promise.resolve().then(()=>(Zme(),Xme)),void 0,import.meta.url),"./界遗计.ts":()=>Y(()=>Promise.resolve().then(()=>($me(),Qme)),void 0,import.meta.url),"./界酒池.ts":()=>Y(()=>Promise.resolve().then(()=>(the(),ehe)),void 0,import.meta.url),"./界酒诗.ts":()=>Y(()=>Promise.resolve().then(()=>(ahe(),nhe)),void 0,import.meta.url),"./界醇醪.ts":()=>Y(()=>Promise.resolve().then(()=>(che(),ohe)),void 0,import.meta.url),"./界铁骑.ts":()=>Y(()=>Promise.resolve().then(()=>(uhe(),lhe)),void 0,import.meta.url),"./界镇军.ts":()=>Y(()=>Promise.resolve().then(()=>(phe(),dhe)),void 0,import.meta.url),"./界闭月.ts":()=>Y(()=>Promise.resolve().then(()=>(hhe(),mhe)),void 0,import.meta.url),"./界除疠.ts":()=>Y(()=>Promise.resolve().then(()=>(vhe(),ghe)),void 0,import.meta.url),"./界陷阵.ts":()=>Y(()=>Promise.resolve().then(()=>(xhe(),yhe)),void 0,import.meta.url),"./界集智.ts":()=>Y(()=>Promise.resolve().then(()=>(whe(),She)),void 0,import.meta.url),"./界雷击.ts":()=>Y(()=>Promise.resolve().then(()=>(Ehe(),The)),void 0,import.meta.url),"./界鞬出.ts":()=>Y(()=>Promise.resolve().then(()=>(khe(),Dhe)),void 0,import.meta.url),"./界鬼才.ts":()=>Y(()=>Promise.resolve().then(()=>(jhe(),Ahe)),void 0,import.meta.url),"./界鬼道.ts":()=>Y(()=>Promise.resolve().then(()=>(Fhe(),Mhe)),void 0,import.meta.url),"./界魂姿.ts":()=>Y(()=>Promise.resolve().then(()=>(Bhe(),Lhe)),void 0,import.meta.url),"./界黄天.ts":()=>Y(()=>Promise.resolve().then(()=>(Uhe(),Vhe)),void 0,import.meta.url),"./界龙胆.ts":()=>Y(()=>Promise.resolve().then(()=>(Ghe(),Whe)),void 0,import.meta.url),"./白银狮子.ts":()=>Y(()=>Promise.resolve().then(()=>(Yhe(),Khe)),void 0,import.meta.url),"./直谏.ts":()=>Y(()=>Promise.resolve().then(()=>(Qhe(),Xhe)),void 0,import.meta.url),"./看破.ts":()=>Y(()=>Promise.resolve().then(()=>(tge(),$he)),void 0,import.meta.url),"./破势.ts":()=>Y(()=>Promise.resolve().then(()=>(rge(),nge)),void 0,import.meta.url),"./神速.ts":()=>Y(()=>Promise.resolve().then(()=>(lge(),ige)),void 0,import.meta.url),"./祸首.ts":()=>Y(()=>Promise.resolve().then(()=>(dge(),uge)),void 0,import.meta.url),"./离间.ts":()=>Y(()=>Promise.resolve().then(()=>(pge(),fge)),void 0,import.meta.url),"./空城.ts":()=>Y(()=>Promise.resolve().then(()=>(hge(),mge)),void 0,import.meta.url),"./突袭.ts":()=>Y(()=>Promise.resolve().then(()=>(bge(),gge)),void 0,import.meta.url),"./立军.ts":()=>Y(()=>Promise.resolve().then(()=>(Sge(),xge)),void 0,import.meta.url),"./箜声.ts":()=>Y(()=>Promise.resolve().then(()=>(Oge(),Cge)),void 0,import.meta.url),"./系统规则.ts":()=>Y(()=>Promise.resolve().then(()=>(AC(),gae)),void 0,import.meta.url),"./红颜.ts":()=>Y(()=>Promise.resolve().then(()=>(Age(),kge)),void 0,import.meta.url),"./结姻.ts":()=>Y(()=>Promise.resolve().then(()=>(Nge(),jge)),void 0,import.meta.url),"./缔盟.ts":()=>Y(()=>Promise.resolve().then(()=>(Fge(),Pge)),void 0,import.meta.url),"./罪论.ts":()=>Y(()=>Promise.resolve().then(()=>(Lge(),Ige)),void 0,import.meta.url),"./耀武.ts":()=>Y(()=>Promise.resolve().then(()=>(zge(),Rge)),void 0,import.meta.url),"./肉林.ts":()=>Y(()=>Promise.resolve().then(()=>(Wge(),Bge)),void 0,import.meta.url),"./良姻.ts":()=>Y(()=>Promise.resolve().then(()=>(qge(),Gge)),void 0,import.meta.url),"./节命.ts":()=>Y(()=>Promise.resolve().then(()=>(Yge(),Jge)),void 0,import.meta.url),"./若愚.ts":()=>Y(()=>Promise.resolve().then(()=>(Zge(),Xge)),void 0,import.meta.url),"./苦肉.ts":()=>Y(()=>Promise.resolve().then(()=>($ge(),Qge)),void 0,import.meta.url),"./英姿.ts":()=>Y(()=>Promise.resolve().then(()=>(t_e(),e_e)),void 0,import.meta.url),"./英魂.ts":()=>Y(()=>Promise.resolve().then(()=>(j0(),Ihe)),void 0,import.meta.url),"./荐降.ts":()=>Y(()=>Promise.resolve().then(()=>(i_e(),n_e)),void 0,import.meta.url),"./藤甲.ts":()=>Y(()=>Promise.resolve().then(()=>(c_e(),a_e)),void 0,import.meta.url),"./蛊惑.ts":()=>Y(()=>Promise.resolve().then(()=>(h_e(),l_e)),void 0,import.meta.url),"./行殇.ts":()=>Y(()=>Promise.resolve().then(()=>(__e(),g_e)),void 0,import.meta.url),"./装备通用.ts":()=>Y(()=>Promise.resolve().then(()=>(S_e(),v_e)),void 0,import.meta.url),"./裸衣.ts":()=>Y(()=>Promise.resolve().then(()=>(w_e(),C_e)),void 0,import.meta.url),"./观星.ts":()=>Y(()=>Promise.resolve().then(()=>(E_e(),T_e)),void 0,import.meta.url),"./解围.ts":()=>Y(()=>Promise.resolve().then(()=>(A_e(),D_e)),void 0,import.meta.url),"./诈降.ts":()=>Y(()=>Promise.resolve().then(()=>(N_e(),j_e)),void 0,import.meta.url),"./诸葛连弩.ts":()=>Y(()=>Promise.resolve().then(()=>(L_e(),P_e)),void 0,import.meta.url),"./谦节.ts":()=>Y(()=>Promise.resolve().then(()=>(B_e(),R_e)),void 0,import.meta.url),"./谦逊.ts":()=>Y(()=>Promise.resolve().then(()=>(H_e(),V_e)),void 0,import.meta.url),"./贞良.ts":()=>Y(()=>Promise.resolve().then(()=>(W_e(),U_e)),void 0,import.meta.url),"./贯石斧.ts":()=>Y(()=>Promise.resolve().then(()=>(Y_e(),G_e)),void 0,import.meta.url),"./进趋.ts":()=>Y(()=>Promise.resolve().then(()=>(Z_e(),X_e)),void 0,import.meta.url),"./连环.ts":()=>Y(()=>Promise.resolve().then(()=>($_e(),Q_e)),void 0,import.meta.url),"./连营.ts":()=>Y(()=>Promise.resolve().then(()=>(tve(),eve)),void 0,import.meta.url),"./遗礼.ts":()=>Y(()=>Promise.resolve().then(()=>(rve(),nve)),void 0,import.meta.url),"./遗计.ts":()=>Y(()=>Promise.resolve().then(()=>(ave(),ive)),void 0,import.meta.url),"./酒池.ts":()=>Y(()=>Promise.resolve().then(()=>(sve(),ove)),void 0,import.meta.url),"./酣战.ts":()=>Y(()=>Promise.resolve().then(()=>(uve(),cve)),void 0,import.meta.url),"./铁索连环.ts":()=>Y(()=>Promise.resolve().then(()=>(fve(),dve)),void 0,import.meta.url),"./铁骑.ts":()=>Y(()=>Promise.resolve().then(()=>(_ve(),pve)),void 0,import.meta.url),"./镇骨.ts":()=>Y(()=>Promise.resolve().then(()=>(bve(),vve)),void 0,import.meta.url),"./闭月.ts":()=>Y(()=>Promise.resolve().then(()=>(Sve(),xve)),void 0,import.meta.url),"./雄乱.ts":()=>Y(()=>Promise.resolve().then(()=>(Tve(),Cve)),void 0,import.meta.url),"./集智.ts":()=>Y(()=>Promise.resolve().then(()=>(Ave(),Eve)),void 0,import.meta.url),"./雌雄双股剑.ts":()=>Y(()=>Promise.resolve().then(()=>(Mve(),jve)),void 0,import.meta.url),"./雷击.ts":()=>Y(()=>Promise.resolve().then(()=>(Pve(),Nve)),void 0,import.meta.url),"./青囊.ts":()=>Y(()=>Promise.resolve().then(()=>(zve(),Fve)),void 0,import.meta.url),"./青釭剑.ts":()=>Y(()=>Promise.resolve().then(()=>(Uve(),Bve)),void 0,import.meta.url),"./青龙偃月刀.ts":()=>Y(()=>Promise.resolve().then(()=>(Jve(),Wve)),void 0,import.meta.url),"./鞬出.ts":()=>Y(()=>Promise.resolve().then(()=>(Zve(),Yve)),void 0,import.meta.url),"./颂威.ts":()=>Y(()=>Promise.resolve().then(()=>($ve(),Qve)),void 0,import.meta.url),"./飘零.ts":()=>Y(()=>Promise.resolve().then(()=>(nye(),eye)),void 0,import.meta.url),"./飞军.ts":()=>Y(()=>Promise.resolve().then(()=>(lye(),rye)),void 0,import.meta.url),"./马匹技能.ts":()=>Y(()=>Promise.resolve().then(()=>(yye(),uye)),void 0,import.meta.url),"./马术.ts":()=>Y(()=>Promise.resolve().then(()=>(Cye(),bye)),void 0,import.meta.url),"./驱虎.ts":()=>Y(()=>Promise.resolve().then(()=>(kye(),wye)),void 0,import.meta.url),"./鬼才.ts":()=>Y(()=>Promise.resolve().then(()=>(Pye(),Aye)),void 0,import.meta.url),"./鬼道.ts":()=>Y(()=>Promise.resolve().then(()=>(Bye(),Fye)),void 0,import.meta.url),"./魂姿.ts":()=>Y(()=>Promise.resolve().then(()=>(Kye(),Vye)),void 0,import.meta.url),"./鸿举.ts":()=>Y(()=>Promise.resolve().then(()=>(Qye(),qye)),void 0,import.meta.url),"./麒麟弓.ts":()=>Y(()=>Promise.resolve().then(()=>(rbe(),$ye)),void 0,import.meta.url),"./黄天.ts":()=>Y(()=>Promise.resolve().then(()=>(ube(),ibe)),void 0,import.meta.url),"./龙胆.ts":()=>Y(()=>Promise.resolve().then(()=>(gbe(),dbe)),void 0,import.meta.url)})}));function bbe(e){return`./${e.slice(7)}.ts`}async function xbe(e){let t;try{t=(await Y(async()=>{let{default:e}=await Promise.resolve().then(()=>(ybe(),_be));return{default:e}},void 0,import.meta.url)).default}catch{t=void 0}if(t){let n=t[bbe(e)];if(!n)throw Error(`技能模块 ${e} 不在 vite-glob 映射中(文件缺失?)`);return n()}let{fileURLToPath:n,pathToFileURL:r}=await Y(async()=>{let{fileURLToPath:e,pathToFileURL:t}=await import(`node:url`);return{fileURLToPath:e,pathToFileURL:t}},[],import.meta.url),{resolve:i}=await Y(async()=>{let{resolve:e}=await import(`node:path`);return{resolve:e}},[],import.meta.url),a=i(n(new URL(`data:video/mp2t;base64,Ly8gc3JjL2VuZ2luZS9pbmRleC50cyDigJQg5byV5pOO5a+55aSW5ZSv5LiA5YWl5Y+jKOe6r+mXqOmdoiByZS1leHBvcnQp44CCCi8vIHNlc3Npb24g5bGC6YCa6L+H5q2k5paH5Lu26K6/6Zeu5byV5pOOIEFQSTppbXBvcnQgeyBjcmVhdGUgfSBmcm9tICcuL2VuZ2luZSfjgIIKLy8g5YaF6YOo5raI6LS56ICF5LiN5bqU5LuO5q2k5paH5Lu2IGltcG9ydCDigJTigJQg55u05o6l5L2/55SoIGNvcmUvIOWtkOaooeWdl+OAggpleHBvcnQgewogIGNyZWF0ZSwKICBib290c3RyYXAsCiAgZGlzcGF0Y2gsCiAgcmVzdG9yZSwKICByZWdpc3RlclNraWxsc0Zyb21TdGF0ZSwKICBidWlsZFZpZXcsCiAgZmlyZVRpbWVvdXQsCiAgY2hlY2tHYW1lT3ZlciwKfSBmcm9tICcuL2NvcmUnOwpleHBvcnQgdHlwZSB7IEdhbWVDb25maWcgfSBmcm9tICcuL2NvcmUnOwo=`,``+import.meta.url)),`${e}.ts`);return Y(()=>import(r(a).href),[],import.meta.url)}async function Sbe(e){let t=Vee(e);if(!t)throw Error(`技能 "${e}" 无模块声明(registry 聚合结果中不存在)`);let[n,r]=t.split(`#`),i=await xbe(n),a=r?i[r]:i;if(!a||typeof a.createSkill!=`function`)throw Error(`技能模块 ${t} 形状不符:期望${r?`导出 "${r}" 且`:``}含 createSkill 函数`);return a}var Cbe=t((()=>{Sm(),Em()}));function wbe(e){return g9.add(e),()=>{g9.delete(e)}}function Tbe(){return h9}async function Ebe(e){let t=p9.get(e);if(t)return t;let n=m9.get(e),r=n?await n():await Sbe(e);return p9.set(e,r),h9++,g9.forEach(e=>e()),r}function Dbe(e){return m9.has(e)||ym(e)}function u9(e){if(_9.has(e))return _9.get(e);let t=p9.get(e);if(t)try{let n=t.createSkill(e,0).description;return _9.set(e,n),n}catch{return}}function d9(e,t,n){let r=me(e,t,n);r&&(r(),he(e,t,n)),Kg(t)||O(e,t,n)}async function f9(e,t,n){if(!Dbe(t))return null;d9(e,t,n);let r=await Ebe(t),i=r.createSkill(t,n);if(r.onInit){let a=r.onInit(i,e);pe(e,t,n,typeof a==`function`?a:()=>{})}return ge(e,t,i.isLocked??!1),i}var p9,m9,h9,g9,_9,v9=t((()=>{F(),Cbe(),Sm(),Yg(),p9=new Map,m9=new Map,h9=0,g9=new Set,_9=new Map}));v9();var y9=new Map;function Obe(e,t,n){return`${e}:${t}:${n}`}function kbe(e,t){return{viewer:t,onEvent(){return()=>{}},defineAction(n,r,i){let a=i??e;y9.set(Obe(a,t,n),{skillId:a,ownerId:t,actionType:n,label:r.label,style:r.style,prompt:r.prompt,transform:r.transform,activeWhen:r.activeWhen,respondFor:r.respondFor})},playEffect(){}}}async function Abe(e,t){for(let n of t)try{let t=await Ebe(n);if(!t.onMount)continue;let r=t.createSkill(n,e),i=kbe(n,e);t.onMount(r,i)}catch{}}function jbe(e){let t=[];for(let[,n]of y9)n.ownerId===e&&t.push(n);return t}function Mbe(e,t){for(let n of y9.values())if(n.skillId===e&&n.actionType===t)return n}function Nbe(){y9.clear()}function b9(e){let t=e.atom?.requestType;return typeof t==`string`?t:``}function Pbe(e){let t=e.atom?.type??``,n=b9(e),r=e.atom,i=r?.target,a=r?.cancelTarget;return`${t}:${n}:t=${typeof i==`number`?String(i):``}:c=${typeof a==`number`?String(a):``}`}function Fbe(e){let t=[e.prompt,e.atom?.prompt];for(let e of t){let t=e?.cardFilter?.candidates;if(Array.isArray(t))return t}}function x9(e){let t=e.prompt;if((t.type===`useCard`||t.type===`useCardAndTarget`)&&t.cardFilter?.filter)return t.cardFilter.filter}function Ibe(e,t){if(e.startsWith(`询问`)){let t=e.slice(2);return t?e=>e.name===t:void 0}if(e===`请求回应`){if(!t)return;if(t===`__弃牌`)return()=>!0;if(t===`桃/求桃`)return e=>e.name===`桃`||e.name===`酒`;let e=t.indexOf(`/`),n=e>=0?t.slice(0,e):t;return n?e=>e.name===n:void 0}}function Lbe(e,t){return t.find(t=>t.skillId===e&&t.actionType===`respond`)||Mbe(e,`respond`)}function Rbe(e,t){if(!e)return null;let n=e.atom?.type??``,r=b9(e),i=null;if(n.startsWith(`询问`))i=n.slice(2);else if(r===`__弃牌`)i=`系统规则`;else if(n===`请求回应`){if(!r)return null;let e=r.search(/[/_]/);i=e>=0?r.slice(0,e):r||null}if(!i)return null;let a=`桃/求桃`;if(r===a){let n=t.filter(e=>e.respondFor===a),r=Fbe(e),o=r?new Set(r):null,s=o?e=>o.has(e.id):e=>e.name===`桃`||e.name===`酒`,c=e=>n.some(t=>x9(t)?.(e));return{skillId:i,cardFilter:e=>s(e)||c(e),rescueSkillForCard:e=>e.name===`桃`||e.name===`酒`?e.name:n.find(t=>x9(t)?.(e))?.skillId}}let o=Fbe(e);if(o){let e=new Set(o);return{skillId:i,cardFilter:t=>e.has(t.id)}}let s=Lbe(i,t),c=s?x9(s):void 0,l=Ibe(n,r);return{skillId:i,cardFilter:c??l}}EN();var S9=Nle(),zbe={"♠":`#ccc`,"♣":`#ccc`,"♥":`#e74c3c`,"♦":`#e74c3c`},Bbe={魏:`#2c3e50`,蜀:`#27ae60`,吴:`#c0392b`,群:`#8e44ad`};function C9(e){return e.startsWith(`界`)?e.slice(1):e}var w9={source:`libnoname/noname 90b58bb9934edb1712fd187a80c8323b7aeabaf3: apps/core/image/character/<id>.jpg and apps/core/image/card/<id>.png`,generals:{曹操:`caocao`,司马懿:`simayi`,夏侯惇:`xiahoudun`,张辽:`zhangliao`,许褚:`xuzhu`,郭嘉:`guojia`,甄姬:`zhenji`,夏侯渊:`re_xiahouyuan`,曹仁:`old_caoren`,荀彧:`xunyu`,典韦:`dianwei`,曹丕:`caopi`,徐晃:`re_xuhuang`,张郃:`zhanghe`,邓艾:`dengai`,界曹操:`re_caocao`,界司马懿:`re_simayi`,界夏侯惇:`re_xiahoudun`,界张辽:`re_zhangliao`,界许褚:`re_xuzhu`,界郭嘉:`re_guojia`,界甄姬:`re_zhenji`,界夏侯渊:`ol_xiahouyuan`,界曹仁:`caoren`,界荀彧:`ol_xunyu`,界典韦:`ol_dianwei`,界曹丕:`re_caopi`,界徐晃:`ol_xuhuang`,界张郃:`re_zhanghe`,界邓艾:`ol_dengai`,界于禁:`yujin_yujin`,界张春华:`re_zhangchunhua`,界曹冲:`re_caochong`,界曹彰:`re_caozhang`,界曹植:`dc_caozhi`,界李典:`re_lidian`,界王异:`re_wangyi`,界郭淮:`re_guohuai`,界郭皇后:`re_guohuanghou`,毌丘俭:`guanqiujian`,王基:`wangji`,蒯越蒯良:`kuailiangkuaiyue`,郝昭:`haozhao`,刘备:`liubei`,界刘备:`re_liubei`,关羽:`guanyu`,界关羽:`re_guanyu`,张飞:`zhangfei`,界张飞:`re_zhangfei`,赵云:`zhaoyun`,界赵云:`re_zhaoyun`,黄月英:`huangyueying`,界黄月英:`re_huangyueying`,马超:`machao`,界马超:`re_machao`,界马岱:`re_madai`,黄忠:`re_huangzhong`,界黄忠:`ol_huangzhong`,魏延:`re_weiyan`,界魏延:`ol_weiyan`,卧龙诸葛:`sp_zhugeliang`,界卧龙诸葛:`ol_sp_zhugeliang`,诸葛亮:`zhugeliang`,界诸葛亮:`re_zhugeliang`,庞统:`pangtong`,界庞统:`ol_pangtong`,孟获:`menghuo`,界孟获:`re_menghuo`,祝融:`zhurong`,界祝融:`ol_zhurong`,姜维:`jiangwei`,界姜维:`ol_jiangwei`,刘禅:`liushan`,界刘禅:`ol_liushan`,界关兴张苞:`re_guanzhang`,界夏侯氏:`re_xiahoushi`,界廖化:`re_liaohua`,界张松:`re_zhangsong`,界徐庶:`re_xushu`,界法正:`re_fazheng`,界简雍:`re_jianyong`,王平:`wangping`,诸葛瞻:`zhugezhan`,陈到:`chendao`,卧龙诸葛亮:`sp_zhugeliang`,严颜:`yanyan`,孙权:`sunquan`,界孙权:`re_sunquan`,甘宁:`ganning`,界甘宁:`re_ganning`,吕蒙:`lvmeng`,界吕蒙:`re_lvmeng`,黄盖:`huanggai`,界黄盖:`re_huanggai`,周瑜:`zhouyu`,界周瑜:`re_zhouyu`,大乔:`daqiao`,界大乔:`re_daqiao`,陆逊:`luxun`,界陆逊:`re_luxun`,孙尚香:`sunshangxiang`,界孙尚香:`re_sunshangxiang`,小乔:`xiaoqiao`,界小乔:`ol_xiaoqiao`,周泰:`old_zhoutai`,界周泰:`zhoutai`,太史慈:`taishici`,界太史慈:`re_taishici`,鲁肃:`re_lusu`,界鲁肃:`ol_lusu`,孙坚:`sunjian`,界孙坚:`ol_sunjian`,孙策:`sunce`,界孙策:`re_sunce`,张昭张纮:`zhangzhang`,界张昭张纮:`ol_zhangzhang`,界凌统:`xin_lingtong`,界吴国太:`xin_wuguotai`,界徐盛:`xin_xusheng`,界程普:`re_chengpu`,界虞翻:`xin_yufan`,界韩当:`xin_handang`,陆抗:`lukang`,陆绩:`luji`,张昭张弘:`zhangzhang`,周妃:`zhoufei`,孙亮:`sunliang`,华佗:`huatuo`,吕布:`lvbu`,貂蝉:`diaochan`,界貂蝉:`re_diaochan`,张角:`sp_zhangjiao`,于吉:`re_yuji`,界于吉:`xin_yuji`,袁绍:`re_yuanshao`,界袁绍:`ol_yuanshao`,庞德:`re_pangde`,界庞德:`ol_pangde`,颜良文丑:`yanwen`,界颜良文丑:`ol_yanwen`,董卓:`dongzhuo`,界董卓:`ol_dongzhuo`,贾诩:`jiaxu`,界贾诩:`re_jiaxu`,左慈:`zuoci`,蔡文姬:`caiwenji`,界蔡文姬:`ol_caiwenji`,界伏皇后:`re_fuhuanghou`,界公孙瓒:`re_gongsunzan`,界刘表:`xin_liubiao`,界华佗:`re_huatuo`,界华雄:`re_huaxiong`,界吕布:`re_lvbu`,界左慈:`re_zuoci`,界张角:`re_zhangjiao`,界李儒:`dc_liru`,界沮授:`re_jushou`,界蔡夫人:`re_caifuren`,界陈宫:`re_chengong`,界高顺:`xin_gaoshun`,华雄:`huaxiong`,袁术:`re_yuanshu`,卢植:`yl_luzhi`,张绣:`zhangxiu`,许攸:`xuyou`},cards:{万箭齐发:`wanjian`,丈八蛇矛:`zhangba`,乐不思蜀:`lebu`,五谷丰登:`wugu`,仁王盾:`renwang`,借刀杀人:`jiedao`,八卦阵:`bagua`,兵粮寸断:`bingliang`,决斗:`juedou`,南蛮入侵:`nanman`,古锭刀:`guding`,大宛:`dawan`,寒冰剑:`hanbing`,方天画戟:`fangtian`,无中生有:`wuzhong`,无懈可击:`wuxie`,朱雀羽扇:`zhuque`,杀:`sha`,桃:`tao`,桃园结义:`taoyuan`,火攻:`huogong`,爪黄飞电:`zhuahuang`,白银狮子:`baiyin`,的卢:`dilu`,紫骍:`zixin`,绝影:`jueying`,藤甲:`tengjia`,诸葛连弩:`zhuge`,贯石斧:`guanshi`,赤兔:`chitu`,过河拆桥:`guohe`,酒:`jiu`,铁索连环:`tiesuo`,闪:`shan`,闪电:`shandian`,雌雄双股剑:`cixiong`,青釭剑:`qinggang`,青龙偃月刀:`qinglong`,顺手牵羊:`shunshou`,骅骝:`hualiu`,麒麟弓:`qilin`}},Vbe=w9.generals,Hbe=w9.cards,T9=e=>e&&Vbe[e]?`art/general/${Vbe[e]}.webp`:null,E9=e=>e&&Hbe[e]?`art/card/${Hbe[e]}.webp`:null,Ube=`art/theme/cardback.webp`,D9={魏:`wei`,蜀:`shu`,吴:`wu`,群:`qun`,神:`shen`},Wbe=()=>null,Gbe=n((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),$=n(((e,t)=>{t.exports=Gbe()}))(),Kbe=`bw4u80p`,qbe=`bn4ntvc`;function Jbe(){let e=Wbe(),t=(0,$.jsxs)(`svg`,{className:qbe,viewBox:`0 0 100 140`,preserveAspectRatio:`none`,"aria-hidden":`true`,children:[(0,$.jsxs)(`defs`,{children:[(0,$.jsxs)(`pattern`,{id:`cb-paper`,width:`5`,height:`5`,patternUnits:`userSpaceOnUse`,children:[(0,$.jsx)(`rect`,{width:`5`,height:`5`,fill:`#f5e6c8`}),(0,$.jsx)(`circle`,{cx:`1`,cy:`2`,r:`0.4`,fill:`#e8d4a8`,opacity:`0.18`}),(0,$.jsx)(`circle`,{cx:`3`,cy:`4`,r:`0.3`,fill:`#e8d4a8`,opacity:`0.12`})]}),(0,$.jsxs)(`radialGradient`,{id:`cb-seal`,cx:`0.5`,cy:`0.4`,r:`0.7`,children:[(0,$.jsx)(`stop`,{offset:`0`,stopColor:`#8b1a1a`}),(0,$.jsx)(`stop`,{offset:`1`,stopColor:`#5c0f0f`})]})]}),(0,$.jsx)(`rect`,{x:`0`,y:`0`,width:`100`,height:`140`,fill:`url(#cb-paper)`}),(0,$.jsx)(`rect`,{x:`1.5`,y:`1.5`,width:`97`,height:`137`,fill:`none`,stroke:`#6b4e1a`,strokeWidth:`1`}),(0,$.jsx)(`rect`,{x:`7`,y:`7`,width:`86`,height:`126`,fill:`none`,stroke:`#a8842a`,strokeWidth:`1.2`}),[[14,14],[86,14],[14,126],[86,126]].map(([e,t],n)=>(0,$.jsxs)(`g`,{children:[(0,$.jsx)(`circle`,{cx:e,cy:t,r:`4.5`,fill:`#f5e6c8`,stroke:`#a8842a`,strokeWidth:`0.7`}),(0,$.jsx)(`circle`,{cx:e,cy:t,r:`3.2`,fill:`none`,stroke:`#6b4e1a`,strokeWidth:`0.4`})]},n)),(0,$.jsx)(`circle`,{cx:`50`,cy:`70`,r:`24`,fill:`url(#cb-seal)`,stroke:`#5c0f0f`,strokeWidth:`0.8`}),(0,$.jsx)(`circle`,{cx:`50`,cy:`70`,r:`21`,fill:`none`,stroke:`#f5e6c8`,strokeWidth:`0.6`,opacity:`0.6`})]});return e?(0,$.jsx)(`object`,{className:Kbe,data:e,type:`image/png`,"aria-label":`牌背`,children:t}):t}var Ybe=(0,K.createContext)(null);function Xbe({value:e,children:t}){return(0,$.jsx)(Ybe.Provider,{value:e,children:t})}function O9(){let e=(0,K.useContext)(Ybe);if(e===null)throw Error(`useGameView 必须在 <GameViewProvider> 内使用:该组件是 GameView 渲染树的子组件,正常由 GameView 自动提供;若需独立渲染(如测试),请构造 GameViewCtxValue 并用 <GameViewProvider value={...}> 包裹,或直接渲染组件的内部 impl。`);return e}function Zbe(e){let{view:t,canOperate:n,perspectiveName:r,send:i}=O9(),{pending:a,pendingTargetIdx:o,perspectiveHand:s,pendingRespondInfo:c,broadcastKey:l,skippedBroadcast:u,processingPicks:d,autoSkipPrefs:f,onToggleAutoSkip:p}=e,m=o<0&&u.has(l),[h,g]=(0,K.useState)([]);(0,K.useEffect)(()=>{g([])},[a]);let _=(()=>{let e=a.atom;if(e.type!==`请求回应`||e.requestType!==`无懈可击`)return;let n=e.cancelTarget;if(!(typeof n!=`number`||n<0))return`抵消 对 ${t.players.find(e=>e.index===n)?.name??`P${n}`} 的 ${(t.zones?.processing??[]).map(e=>t.cardMap[e]).filter(e=>!!e).find(e=>e.name!==`闪`&&e.name!==`杀`&&e.name!==`无懈可击`)?.name??`锦囊`}`})();return(0,$.jsxs)(`div`,{className:Iee,children:[(0,$.jsxs)(`div`,{className:zee,children:[`⚡ 需要回应 — `,r]}),(0,$.jsxs)(`div`,{className:Lee,children:[a.prompt.title,_&&(0,$.jsxs)(`span`,{children:[` — `,_]}),!_&&a.prompt.description&&(0,$.jsxs)(`span`,{children:[` — `,a.prompt.description]})]}),n&&p&&(()=>{let e=b9(a);if(!e)return null;let t=!!f?.optInSkip[e];return(0,$.jsxs)(`label`,{className:`nm-autoSkipToggle`,children:[(0,$.jsx)(`input`,{type:`checkbox`,checked:t,onChange:()=>p(e)}),(0,$.jsx)(`span`,{children:`以后自动跳过此类询问`})]})})(),m?(0,$.jsx)(`div`,{className:gm,children:`已跳过,等待其他玩家回应...`}):n?(()=>{let e=c?.skillId??`系统规则`,n=c?.cardFilter;if(a.prompt.type===`pickTargetCard`){let t=a.prompt;return(0,$.jsxs)(`div`,{className:fm,children:[t.equipment.length>0&&(0,$.jsx)(`span`,{className:`nm-promptDescFull`,children:`装备区:`}),t.equipment.map(({slot:t,cardId:n,cardName:r})=>(0,$.jsxs)(`button`,{className:pm,onClick:()=>i(e,`respond`,{zone:`equipment`,cardId:n}),children:[t,`:`,r]},n)),t.judge.length>0&&(0,$.jsx)(`span`,{className:`nm-promptDescFull`,children:`判定区:`}),t.judge.map(({cardId:t,cardName:n})=>(0,$.jsx)(`button`,{className:pm,onClick:()=>i(e,`respond`,{zone:`judge`,cardId:t}),children:n},t)),t.handCount>0&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{className:`nm-promptDescFull`,children:`手牌(凭位置盲选):`}),(0,$.jsx)(`div`,{className:`nm-pickHandRow`,children:Array.from({length:t.handCount},(t,n)=>(0,$.jsxs)(`button`,{className:`nm-pickHandCard`,onClick:()=>i(e,`respond`,{zone:`hand`,handIndex:n}),title:`第 ${n+1} 张`,children:[(0,$.jsx)(Jbe,{}),(0,$.jsx)(`span`,{className:`nm-pickHandIndex`,children:n+1})]},n))})]})]})}if(a.prompt.type===`pickProcessingCard`){let t=a.prompt,n=d?.allCards??t.cards,r=d?.pickedBy;return(0,$.jsxs)(`div`,{className:fm,children:[n.length>0&&(0,$.jsx)(`span`,{className:`nm-promptDescFull`,children:`处理区可选牌:`}),n.map(({cardId:t,cardName:n,suit:a,rank:o})=>{let s=r?.get(t),c=!!s;return(0,$.jsxs)(`button`,{className:c?mm:pm,disabled:c,onClick:()=>!c&&i(e,`respond`,{cardId:t}),children:[n,` `,a,o,c&&(0,$.jsxs)(`span`,{className:`nm-pickedByTag`,children:[`已被`,s,`选走`]})]},t)})]})}if(a.prompt.type===`confirm`){let t=a.prompt.confirmLabel??`确认`,n=a.prompt.cancelLabel??`取消`,r=a.prompt.confirmDisabled===!0;return(0,$.jsxs)(`div`,{className:dm,children:[(0,$.jsx)(`button`,{className:r?mm:hm,disabled:r,onClick:()=>!r&&i(e,`respond`,{choice:!0}),children:t}),(0,$.jsx)(`button`,{className:pm,onClick:()=>i(e,`respond`,{choice:!1}),children:n})]})}if(a.prompt.type===`chooseOption`){let t=a.prompt,n=t.characterCards;return(0,$.jsx)(`div`,{className:fm,children:n?t.options.map(t=>{let r=n[t.value],a=Bbe[r?.faction??`群`]||`#8e44ad`;return(0,$.jsxs)(`button`,{className:Eee,style:{background:`${a}20`,borderColor:a},onClick:()=>i(e,`respond`,{option:t.value}),children:[(0,$.jsx)(`span`,{className:Dee,children:t.label}),r&&(0,$.jsx)(`span`,{className:`nm-chooseOptionCardSkills`,children:r.skills.map(C9).join(` · `)})]},t.value)}):t.options.map(t=>(0,$.jsx)(`button`,{className:hm,onClick:()=>i(e,`respond`,{option:t.value}),children:t.label},t.value))})}if(a.prompt.type===`choosePlayer`){let n=a.prompt,r=n.candidates??[],o=t.players,s=n.max??1,c=n.min??1;if(s<=1)return(0,$.jsxs)(`div`,{className:fm,children:[r.length===0&&(0,$.jsx)(`span`,{className:`nm-promptDescInline`,children:`无可选目标`}),r.map(t=>(0,$.jsx)(`button`,{className:pm,onClick:()=>i(e,`respond`,{target:t,targets:[t]}),children:o[t]?.name??`P${t}`},t)),c===0&&(0,$.jsx)(`button`,{className:`nm-promptBtn`,onClick:()=>i(e,`respond`,{targets:[]}),children:`不选择`})]});let l=e=>g(t=>t.includes(e)?t.filter(t=>t!==e):t.length<s?[...t,e]:t),u=h.length>=c&&h.length<=s;return(0,$.jsxs)(`div`,{className:fm,children:[r.length===0&&(0,$.jsx)(`span`,{className:`nm-promptDescInline`,children:`无可选目标`}),r.map(e=>(0,$.jsx)(`button`,{className:h.includes(e)?hm:pm,onClick:()=>l(e),children:o[e]?.name??`P${e}`},e)),(0,$.jsxs)(`button`,{className:u?hm:mm,disabled:!u,onClick:()=>u&&i(e,`respond`,{targets:h}),children:[`确认(`,h.length,`/`,s,`)`]}),c===0&&(0,$.jsx)(`button`,{className:`nm-promptBtn`,onClick:()=>i(e,`respond`,{targets:[]}),children:`不选择`})]})}let r=n?s.filter(n).length:0,o=a.prompt.type===`useCardAndTarget`;return(0,$.jsx)(`div`,{className:dm,children:(0,$.jsx)(`span`,{className:Ree,children:r>0?o?`选择高亮的牌(共 ${r} 张可选),再选目标,点「打出」确认;或点「交出武器」跳过`:`选择高亮的牌(共 ${r} 张可选),再点「打出」确认,或点「不回应」跳过`:`当前没有可出的牌回应,点「不回应」跳过`})})})():(0,$.jsxs)(`div`,{className:gm,children:[`等待 `,r,` 回应...`]})]})}var k9=function(){let e=Array.prototype.slice.call(arguments).filter(Boolean),t={},n=[];e.forEach(e=>{(e?e.split(` `):[]).forEach(e=>{if(e.startsWith(`atm_`)){let[,n]=e.split(`_`);t[n]=e}else n.push(e)})});let r=[];for(let e in t)Object.prototype.hasOwnProperty.call(t,e)&&r.push(t[e]);return r.push(...n),r.join(` `)};Yg(),J();function A9(e){switch(e.type){case`useCard`:case`useCardAndTarget`:return e.cardFilter.filter??null;default:return null}}function j9(e,t){return e.find(e=>{if(e.actionType!==`use`)return!1;let n=A9(e.prompt);return n?n(t):!1})}function Qbe(e){let t=Wg(e.name);return t?t.timing!==`生效前`:!0}var $be=new Set([`respond`,`transform`,`distribute`]);function exe(e){return $be.has(e)||e.startsWith(`transform:`)}function txe(e,t,n){return e.filter(e=>{if(exe(e.actionType)||n&&e===n)return!1;let r=A9(e.prompt);return r?r(t):!1})}function M9(e,t){return e.activeWhen?e.activeWhen(t):q(t)}function N9(e,t){let n=e?.slots,r=!!n&&n.length>1,i=n?.length??0,a=!!t;return{needsTarget:a?!1:r||(e?e.max>=1:!1),hasSlots:r,slotCount:i,selfTarget:a,multiTarget:!r&&!a&&(e?.max??0)>=2,targetFilter:e??null}}function nxe(e,t,n,r,i,a,o=[]){let s=e[t]?.name??``;if(r.hasSlots){if(!i||!a)return null;let t=e.findIndex(e=>e.name===i),r=e.findIndex(e=>e.name===a);return t<0||r<0?null:{cardId:n.id,target:t,killTarget:r}}if(r.selfTarget){let r=e.findIndex(e=>e.name===s);return{cardId:n.id,targets:[r>=0?r:t]}}if(r.multiTarget){let t=r.targetFilter?.min??1;if(o.length<t)return null;let i=o.map(t=>e.findIndex(e=>e.name===t)).filter(e=>e>=0);return i.length<t?null:{cardId:n.id,targets:i}}if(r.needsTarget){if(!i)return null;let t=e.findIndex(e=>e.name===i);return t<0?null:n.type===`锦囊牌`&&n.trickSubtype===`延时锦囊`?{cardId:n.id,target:t}:{cardId:n.id,targets:[t]}}return{cardId:n.id}}function rxe(e,t,n){if(Array.isArray(e.cardIds)&&e.cardIds.length>0)return e.cardIds;if(e.source===`handAndEquip`){let e=Object.values(n).filter(e=>typeof e==`string`);return[...t.map(e=>e.id),...e]}return t.map(e=>e.id)}function ixe(e){let t=e.prompt;return t.type===`selectTarget`&&t.paramVariants?.length?t.paramVariants.map(e=>({label:e.label,params:e.params,...e.cardFilter?{cardFilter:e.cardFilter}:{}})):t.type===`chooseOption`?t.options.map(e=>({label:e.value,params:{option:e.value},description:e.label})):[{label:``,params:{}}]}function P9({isMyTurn:e,phase:t,pending:n}){return!(!e||t!==`出牌`||n&&n.isBlocking!==!1)}function axe(e){return e.canOperate&&P9(e)}function oxe(e){return!!e.selectedCardId&&P9(e)}function F9(e,t){if(e===`杀`){if(t===`火焰`)return`火杀`;if(t===`雷电`)return`雷杀`}return e}var sxe={火焰:`fire`,雷电:`thunder`},I9=e=>e===`♥`||e===`♦`;function cxe({name:e,suit:t,rank:n,damageType:r}){let i=E9(e),a=F9(e,r);return(0,$.jsxs)($.Fragment,{children:[i?(0,$.jsx)(`div`,{className:`nm-card-art`,style:{backgroundImage:`url(${i})`}}):(0,$.jsx)(`div`,{className:`nm-card-big`,children:a.slice(0,2)}),(0,$.jsx)(`div`,{className:`nm-card-name${a.length>3?` long`:``}`,children:a}),t&&(0,$.jsxs)(`div`,{className:`nm-card-info${I9(t)?` red`:``}`,children:[(0,$.jsx)(`span`,{className:`nm-suit`,children:t}),n]})]})}function lxe({suit:e,damageType:t},n=``){let r=t?sxe[t]:void 0;return`nm-card${I9(e)?` red`:``}${r?` ${r}`:``}${n?` ${n}`:``}`}function uxe({face:e,className:t=``,style:n,title:r}){return(0,$.jsx)(`div`,{className:lxe(e,t),style:n,title:r,children:(0,$.jsx)(cxe,{...e})})}function dxe({name:e,suit:t,rank:n,size:r=`normal`,damageType:i}){return(0,$.jsx)(`div`,{className:lxe({name:e,suit:t,damageType:i},`nm-card-fill ${r}`),children:(0,$.jsx)(cxe,{name:e,suit:t,rank:n,damageType:i})})}var fxe=l(),pxe=500,mxe=`c1sgrnfw`,hxe=`cpua85b`,gxe=`c1xbhg54`,_xe=`c17nl2uc`,vxe=`c1gq2t9n`,yxe=`c1vhr7s6`;function bxe(e){let[t,n]=(0,K.useState)(!1),[r,i]=(0,K.useState)({top:0,centerX:0}),a=(0,K.useRef)(null),o=(0,K.useRef)(null),s=(0,K.useRef)(null),c=(0,K.useRef)(0),l=(0,K.useCallback)(()=>{o.current!==null&&(window.clearTimeout(o.current),o.current=null)},[]),u=(0,K.useCallback)(e=>{let t=a.current;if(!t)return;let r=t.getBoundingClientRect();s.current=e,i({top:r.top,centerX:r.left+r.width/2}),n(!0)},[]);(0,K.useEffect)(()=>l,[l]),(0,K.useEffect)(()=>{if(!t)return;let e=e=>{a.current?.contains(e.target)||n(!1)},r=()=>n(!1);return window.addEventListener(`pointerdown`,e),window.addEventListener(`scroll`,r,!0),()=>{window.removeEventListener(`pointerdown`,e),window.removeEventListener(`scroll`,r,!0)}},[t]);let d=(0,K.useCallback)(()=>{window.matchMedia(`(hover: hover)`).matches&&u(`hover`)},[u]),f=(0,K.useCallback)(()=>{s.current===`hover`&&n(!1)},[]),p=(0,K.useCallback)(()=>{l(),o.current=window.setTimeout(()=>{o.current=null,c.current=Date.now()+1e3,u(`touch`)},pxe)},[l,u]),m=(0,K.useCallback)(()=>l(),[l]),h=(0,K.useCallback)(e=>{(t||o.current!==null)&&e.preventDefault()},[t]),g=(0,K.useCallback)(()=>Date.now()<c.current?(c.current=0,!0):t?(n(!1),s.current===`touch`):!1,[t]),_=t?(0,fxe.createPortal)((0,$.jsxs)(`div`,{className:mxe,style:{top:r.top-8,left:r.centerX,transform:`translate(-50%, -100%)`},children:[(0,$.jsxs)(`span`,{className:hxe,style:{color:e.suitColor},children:[e.name,` `,e.suit,e.rank]}),e.description&&(0,$.jsx)(`span`,{className:gxe,children:e.description}),e.hint&&(0,$.jsxs)(`span`,{className:vxe,children:[`⚠ `,e.hint]}),e.originName&&(0,$.jsxs)(`span`,{className:_xe,children:[`(原: `,e.originName,`)`]})]}),document.body):null;return{bind:{ref:a,onMouseEnter:d,onMouseLeave:f,onTouchStart:p,onTouchEnd:m,onTouchMove:m,onContextMenu:h},consumeClick:g,overlay:_}}var xxe=`h13senao`;function Sxe(e){let{card:t,index:n,totalHand:r,isSelected:i,isDiscardSelected:a,isRespondSelected:o,canPlay:s,isAwaiting:c,canDiscardClick:l,isTransformMatch:u,isTransformActive:d,isTransformDisabled:f,transformWrapperName:p,isDistributeCandidate:m=!1,isDistributeSelected:h=!1,isDistributeAllocated:g=!1,isDistributeActive:_=!1,onCardClick:v,onCardDoubleClick:y,isTimeoutFallback:ee=!1,hint:b=null}=e,x=s||c||l||d||_&&m,S=_&&!m,C=zbe[t.suit]??`#ccc`,w=u&&p?p:t.name,te=r>1?-10+20*(n/(r-1)):0,ne=bxe({name:w,suit:t.suit,rank:t.rank,description:t.description,originName:u&&p?t.name:void 0,suitColor:C,hint:b});return(0,$.jsxs)(`div`,{ref:ne.bind.ref,"data-card-id":t.id,className:k9(kee,xxe,yxe,i&&`nm-handCardSelected`,!s&&!c&&!l&&!d&&!m&&`nm-handCardDisabled`,l&&!a&&`nm-handCardDiscardable`,s&&!c&&!l&&!d&&!_&&`nm-handCardPlayable`,c&&`nm-handCardRespondable`,a&&`nm-discardCardSelected`,o&&`nm-handCardRespondSelected`,u&&`nm-handCardTransform`,f&&`nm-handCardTransformDisabled`,m&&`nm-handCardDistributeCandidate`,h&&`nm-handCardDistributeSelected`,g&&`nm-handCardDistributeAllocated`,S&&`nm-handCardDisabled`,ee&&`nm-handCardTimeoutFallback`),style:{"--fan-angle":`${te}deg`,"--card-z":n,"--suit-color":C},onClick:()=>{ne.consumeClick()||x&&!f&&!S&&v(t)},onDoubleClick:()=>{ne.consumeClick()||x&&!f&&!S&&y?.(t)},onMouseEnter:ne.bind.onMouseEnter,onMouseLeave:ne.bind.onMouseLeave,onTouchStart:ne.bind.onTouchStart,onTouchEnd:ne.bind.onTouchEnd,onTouchMove:ne.bind.onTouchMove,onContextMenu:ne.bind.onContextMenu,children:[(0,$.jsx)(dxe,{name:t.name,suit:t.suit,rank:t.rank,size:`normal`,damageType:t.damageType}),u&&p&&(0,$.jsxs)(`div`,{className:`nm-handCardMeta`,children:[(0,$.jsx)(`div`,{className:`nm-cardName`,children:w}),(0,$.jsxs)(`div`,{className:`nm-cardOrigin`,children:[`(原: `,t.name,`)`]})]}),ne.overlay]})}function Cxe(e,t){return e.card.id===t.card.id&&e.index===t.index&&e.totalHand===t.totalHand&&e.isSelected===t.isSelected&&e.isDiscardSelected===t.isDiscardSelected&&e.isRespondSelected===t.isRespondSelected&&e.canPlay===t.canPlay&&e.isAwaiting===t.isAwaiting&&e.canDiscardClick===t.canDiscardClick&&e.isTransformMatch===t.isTransformMatch&&e.isTransformActive===t.isTransformActive&&e.isTransformDisabled===t.isTransformDisabled&&e.transformWrapperName===t.transformWrapperName&&e.isDistributeCandidate===t.isDistributeCandidate&&e.isDistributeSelected===t.isDistributeSelected&&e.isDistributeAllocated===t.isDistributeAllocated&&e.isDistributeActive===t.isDistributeActive&&e.isTimeoutFallback===t.isTimeoutFallback&&e.hint===t.hint&&e.onCardClick===t.onCardClick&&e.onCardDoubleClick===t.onCardDoubleClick}var wxe=(0,K.memo)(Sxe,Cxe);function Txe({play:e,phase:t,isSpectating:n,perspectiveHand:r,spectatorHandCount:i,handListRef:a,orderedHand:o,handleDragStart:s,handleDrop:c,canPlayHandCard:l,isRespondableCard:u,canDiscardClick:d,disabledReason:f,onCardDoubleClick:p,timeoutFallbackIds:m,isMyAwaiting:h,isMyTurn:g,onReorderHand:_}){let{perspectiveName:v,canOperate:y}=O9(),{selectedCardId:ee,selectedForDiscard:b,transformMode:x,activeDistribute:S,isDistributeActive:C,distSelected:w,distAllocations:te,distExternalCandidates:ne,selectedRespondCardId:T,isRespondTransformContext:re,handleCardClick:ie}=e;return(0,$.jsxs)(`div`,{className:Aee,children:[(0,$.jsx)(`div`,{className:jee,children:(0,$.jsxs)(`div`,{className:Pee,children:[(0,$.jsx)(`span`,{className:Fee,children:t}),(0,$.jsxs)(`span`,{className:Nee,children:[n?`👁 旁观 · ${v} 手牌 ${i} 张`:`手牌 (${r.length})`,C&&S&&(0,$.jsxs)(`span`,{className:k9(`nm-debugHint`,`nm-distHint`),children:[` `,`· `,S.prompt.title,` · 已选 `,w.size]})]})]})}),C&&ne.length>0&&(0,$.jsxs)(`div`,{className:`nm-distExternalWrap`,children:[(0,$.jsxs)(`span`,{className:`nm-distExternalLabel`,children:[S?.prompt.title??`候选牌`,` · 已选 `,w.size]}),(0,$.jsx)(`div`,{className:`nm-distExternalList`,children:ne.map(e=>{let t=w.has(e.id),n=te.some(t=>t.cardIds.includes(e.id));return(0,$.jsxs)(`div`,{"data-card-id":e.id,className:k9(`nm-distExternalCard`,t&&`nm-handCardDistributeSelected`,n&&`nm-handCardDistributeAllocated`,!t&&!n&&`nm-handCardDistributeCandidate`),style:{"--suit-color":zbe[e.suit]??`#ccc`},onClick:()=>ie(e),title:`${F9(e.name,e.damageType)} ${e.suit}${e.rank}`,children:[(0,$.jsx)(`div`,{className:`nm-cardName`,children:F9(e.name,e.damageType)}),(0,$.jsxs)(`div`,{className:`nm-cardSuit`,children:[e.suit,e.rank]})]},e.id)})})]}),(0,$.jsxs)(`div`,{className:Mee,ref:a,children:[o.map((e,t)=>{let n=ee===e.id||!!(x&&x.minCards>1&&x.selectedCardIds.includes(e.id)),r=b.includes(e.id),i=h&&!C&&T===e.id,a=l(e),v=u(e),ne=!!x?.cardFilter(e),ae=x!==null&&y&&(g||re),E=ne&&(x?.minCards===1||!!x?.selectedCardIds.includes(e.id)),oe=ae&&!ne,se=S?new Set(S.cardIds):null,ce=C&&!!se?.has(e.id),D=C&&w.has(e.id),O=C&&te.some(t=>t.cardIds.includes(e.id)),k=!!m?.has(e.id)&&!r;return(0,$.jsx)(`div`,{draggable:!!_&&!n&&!r&&!D,onDragStart:()=>s(t),onDragOver:e=>e.preventDefault(),onDrop:()=>c(t),children:(0,$.jsx)(wxe,{card:e,index:t,totalHand:o.length,isSelected:n,isDiscardSelected:r,isRespondSelected:i,canPlay:a,isAwaiting:v,canDiscardClick:d,isTransformMatch:E,isTransformActive:ae,isTransformDisabled:oe,transformWrapperName:x?.transform?x.transform(e).name:x?.wrapperName,isDistributeCandidate:ce,isDistributeSelected:D,isDistributeAllocated:O,isDistributeActive:C,onCardClick:ie,onCardDoubleClick:p,isTimeoutFallback:k,hint:k?`超时未确认将自动弃置此牌`:f?.(e)??null})},e.id)}),n?(0,$.jsx)(`div`,{className:Oee,children:`手牌已隐藏 · 申请查看该玩家视角可见手牌`}):r.length===0&&(0,$.jsx)(`div`,{className:`nm-emptyHand`,children:`无手牌`})]})]})}function Exe(e,t){let[n,r]=(0,K.useState)({damageFlashIndices:new Map,healFlashIndices:new Map,hpChangeNumbers:new Map,phaseVersion:0,turnVersion:0,discardPhase:!1}),i=(0,K.useRef)(new Map),a=(0,K.useRef)(e.phase),o=(0,K.useRef)(e.turn.round);return(0,K.useEffect)(()=>{let t=new Map(e.players.map((e,t)=>[t,e.health])),n=i.current,a=[],o=[],s=new Map;for(let[e,r]of t){let t=n.get(e);t!==void 0&&(r<t?(a.push(e),s.set(e,t-r)):r>t&&(o.push(e),s.set(e,r-t)))}if(i.current=t,a.length===0&&o.length===0)return;let c=null;r(e=>{let t=new Map;for(let n of a)t.set(n,(e.damageFlashIndices.get(n)??0)+1);let n=new Map;for(let t of o)n.set(t,(e.healFlashIndices.get(t)??0)+1);let r=new Map;for(let[e,i]of s)r.set(e,{kind:o.includes(e)?`heal`:`damage`,amount:i,version:t.get(e)??n.get(e)??0});return c=r,{...e,damageFlashIndices:new Map([...e.damageFlashIndices,...t]),healFlashIndices:new Map([...e.healFlashIndices,...n]),hpChangeNumbers:new Map([...e.hpChangeNumbers,...r])}}),setTimeout(()=>{r(e=>{let t=new Map(e.damageFlashIndices);for(let e of a)t.delete(e);let n=new Map(e.healFlashIndices);for(let e of o)n.delete(e);return{...e,damageFlashIndices:t,healFlashIndices:n}})},650),setTimeout(()=>{let e=c;e&&r(t=>{let n=new Map(t.hpChangeNumbers);for(let[t,r]of e)n.get(t)?.version===r.version&&n.delete(t);return{...t,hpChangeNumbers:n}})},1050)},[e.players]),(0,K.useEffect)(()=>{e.phase!==a.current&&(r(t=>({...t,phaseVersion:t.phaseVersion+1,discardPhase:e.phase===`弃牌`})),a.current=e.phase,e.phase!==`弃牌`&&setTimeout(()=>r(e=>({...e,discardPhase:!1})),400))},[e.phase]),(0,K.useEffect)(()=>{e.turn.round!==o.current&&(r(e=>({...e,turnVersion:e.turnVersion+1})),o.current=e.turn.round)},[e.turn.round]),n}var Dxe=620;function Oxe(e){let t=e.kind===`seat`?`[data-seat-index="${e.index}"]`:e.kind===`offscreen`?``:`[data-zone-anchor="${e.kind}"]`,n=(t?document.querySelector(t):null)?.getBoundingClientRect();return n&&n.width?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:innerWidth/2,y:e.kind===`offscreen`?-80:innerHeight*.42}}var L9=()=>Number(getComputedStyle(document.documentElement).getPropertyValue(`--nm-scale`))||1;function kxe(e){let t=document.createElement(`div`);if(!e)return t.className=`nm-card back`,t.style.backgroundImage=`url(${Ube})`,t;t.className=`nm-card${I9(e.suit)?` red`:``}`;let n=E9(e.name),r=document.createElement(`div`);r.className=n?`nm-card-art`:`nm-card-big`,n?r.style.backgroundImage=`url(${n})`:r.textContent=e.name.slice(0,2);let i=document.createElement(`div`);if(i.className=`nm-card-name${e.name.length>3?` long`:``}`,i.textContent=e.name,t.append(r,i),e.suit){let n=document.createElement(`div`);n.className=`nm-card-info${I9(e.suit)?` red`:``}`,n.textContent=`${e.suit}${e.rank}`,t.append(n)}return t}var R9=new Map;function Axe(e,t){let n=e.getBoundingClientRect();R9.set(t.id,{x:n.left+n.width/2,y:n.top+n.height/2}),R9.size>50&&R9.delete(R9.keys().next().value)}function z9(e,t,n,r){let i=Math.min(r??n.length,8);if(i<=0||t.kind===`discard`)return;let a=Oxe(e),o=Oxe(t),s=L9(),c=document.createElement(`div`);c.className=`nm-fly`,c.style.cssText=`left:${a.x}px;top:${a.y}px;--dx:${o.x-a.x}px;--dy:${o.y-a.y}px;--s:${s*.8};--n:${i};animation-duration:${Dxe}ms`;for(let e=0;e<i;e++){let t=kxe(n[e]??null);t.style.setProperty(`--i`,String(e)),c.append(t)}document.body.append(c);let l=()=>c.remove();c.addEventListener(`animationend`,l),setTimeout(l,920)}var jxe=300;function Mxe(e,t){let n=e.cardMap[t];return n?{name:n.name,suit:n.suit,rank:n.rank}:null}function B9(e){return{kind:`seat`,index:e}}function Nxe(e,t){switch(e.atomType??e.type){case`摸牌`:{let t=e.player,n=e.cards,r=e.count??n?.length??1,i=n?n.map(e=>({name:e.name,suit:e.suit??``,rank:e.rank??``})):Array(r).fill(null);return z9({kind:`deck`},B9(t),i,r),!0}case`获得`:{let n=e.player,r=e.from,i=e.cardId,a=i?Mxe(t,i):null;return z9(r===void 0?{kind:`deck`}:B9(r),B9(n),[a],1),!0}case`弃置`:{let n=e.player,r=e.cardIds??[],i=e.cardNames,a=r.map((e,n)=>Mxe(t,e)||(i?.[n]?{name:i[n],suit:``,rank:``}:null));return z9(B9(n),{kind:`discard`},a,r.length),!0}case`移出至暂存区`:{let t=e.target,n=e.cards;if(n&&n.length>0){let e=n.map(e=>({name:e.name,suit:e.suit,rank:e.rank}));z9(B9(t),{kind:`offscreen`},e,e.length)}else{let n=(e.handCount??0)+(e.equipEntries??[]).length;n>0&&z9(B9(t),{kind:`offscreen`},[],n)}return!0}case`归还暂存牌`:{let t=e.player,n=e.cards,r=e.toDiscard===!0?{kind:`discard`}:B9(t);if(n&&n.length>0){let e=n.map(e=>({name:e.name,suit:e.suit,rank:e.rank}));z9({kind:`offscreen`},r,e,e.length)}else z9({kind:`offscreen`},r,[],e.count??1);return!0}default:return!1}}function Pxe(e,t){let n=(0,K.useRef)(new Set);(0,K.useEffect)(()=>{let r=e.filter(e=>!n.current.has(e.seq));if(r.length===0)return;let i=n.current;for(let e of r)i.add(e.seq);if(i.size>jxe){let e=[...i].sort((e,t)=>e-t);n.current=new Set(e.slice(Math.floor(e.length/2)))}let a=requestAnimationFrame(()=>{for(let{event:e}of r)Nxe(e,t)});return()=>cancelAnimationFrame(a)},[e])}function Fxe(e,t){let n=e.players.map(e=>`${e.name}:${e.skills.join(`,`)}`).join(`|`),[r,i]=(0,K.useState)([]);return(0,K.useEffect)(()=>{let n=!1;return Nbe(),(async()=>{for(let t of e.players)await Abe(t.index,t.skills);n||i(jbe(t))})(),()=>{n=!0}},[n,t]),{skillActions:r}}function Ixe(e){return e?.atom?e.atom:null}function Lxe(e,t,n){let r=e.pending,i=r?.target??-1,a=r!==null&&r.isBlocking!==!1&&(i<0||i===t),o=Ixe(r),s=o?.requestType,c=r?.mandatory===!0&&r?.prompt?.type===`useCard`,l=r!==null&&s===`__弃牌`||c,u=l?o?.prompt?.cardFilter?.min??0:0,d=l?o?.prompt?.cardFilter?.max??u:0,f=r?Pbe(r):``,[p,m]=(0,K.useState)(new Set);return(0,K.useEffect)(()=>{m(new Set)},[f]),{pending:r,pendingTargetIdx:i,isPerspectiveAwaiting:a,isDiscardPhase:l,discardMin:u,discardMax:d,skippedBroadcast:p,markBroadcastSkipped:(0,K.useMemo)(()=>e=>{m(t=>new Set(t).add(e))},[]),deadline:r?.deadline??e.deadline??null,deadlineTotalMs:r?.totalMs??e.deadlineTotalMs,pendingRespondInfo:(0,K.useMemo)(()=>Rbe(r,n),[r,n]),broadcastKey:(0,K.useMemo)(()=>r?Pbe(r):``,[r])}}var Rxe=(0,K.createContext)({submitted:new Set,markSubmitted:()=>{},clearAll:()=>{}});function zxe(){return(0,K.useContext)(Rxe).submitted}function Bxe(e,t){let n=zxe(),r=e.pending?.atom?.type===`选将询问`&&!e.players[e.pending.target]?.character&&!n.has(e.pending.target)?e.pending:null,i=r!==null,a=r?r.atom.candidates??[]:[],o=r?r.target:-1;return{isCharSelectPending:i,charSelect:i?{candidates:a,target:o,pending:r}:null,charSelectInProgress:e.phase===`准备`&&e.players.some(e=>!e.character),perspectiveCharSelected:!!e.players[t]?.character}}function Vxe(e,t){let n=e.players;return(0,K.useMemo)(()=>{let e=n.length;if(e===0)return[];let r=[n[t]];for(let i=1;i<e;i++)r.push(n[(t-i+e)%e]);return r},[n,t])}function Hxe(e,t){let[n,r]=(0,K.useState)(null),i=(0,K.useRef)(null),a=(0,K.useRef)(null),o=e.map(e=>e.id),s=n!==null&&n.length===o.length&&o.every(e=>n.includes(e)),c=s?n.map(t=>e.find(e=>e.id===t)).filter(Boolean):e;return(0,K.useEffect)(()=>{if(n&&s){let t=e.map(e=>e.id);t.length===n.length&&t.every((e,t)=>e===n[t])&&r(null)}n&&!s&&r(null)},[n,s,e]),{orderedHand:c,handleDragStart:(0,K.useCallback)(e=>{i.current=e},[]),handleDrop:(0,K.useCallback)(e=>{let n=i.current;if(i.current=null,n===null||n===e)return;let o=c.map(e=>e.id),[s]=o.splice(n,1);o.splice(e,0,s),r(o),t&&(a.current&&clearTimeout(a.current),a.current=setTimeout(()=>{t(o),a.current=null},400))},[c,t])}}J();function Uxe(e,t,n){return e.includes(t)?e.filter(e=>e!==t):n===void 0||n<=0||e.length<n?[...e,t]:[...e.slice(1),t]}function V9(e,t){return t===void 0||t<=0?[...e]:e.slice(0,t)}function H9(e,t,n){let r=new Set(t),i=e.filter(e=>!r.has(e));return n===void 0||n<=0?i:i.length>n?i.slice(-n):i}function Wxe(e,t,n){let{view:r,perspectiveIdx:i,perspectiveHand:a,skillActions:o}=n,{pending:s,isDiscardPhase:c,discardMin:l,discardMax:u,isPerspectiveAwaiting:d,pendingRespondInfo:f,broadcastKey:p,markBroadcastSkipped:m,pendingTargetIdx:h,send:g,handListRef:_}=n,v=d&&t,y=s?.atom,ee=(()=>{if(!v||!s)return null;let e=y?.type??``;if(e.startsWith(`询问`))return e.slice(2)||null;if(e===`请求回应`){let e=b9(s);if(!e)return null;let t=e.search(/[/_]/);return(t>=0?e.slice(0,t):e)||null}return null})(),b=ee!==null&&!!s&&(s.target===i||s.target<0),[x,S]=(0,K.useState)(null),[C,w]=(0,K.useState)(null),[te,ne]=(0,K.useState)(null),[T,re]=(0,K.useState)(null),[ie,ae]=(0,K.useState)([]),[E,oe]=(0,K.useState)([]),[se,ce]=(0,K.useState)(null),[D,O]=(0,K.useState)(null),[k,le]=(0,K.useState)(null),[ue,de]=(0,K.useState)(null),[A,j]=(0,K.useState)(new Set),[M,N]=(0,K.useState)([]),[fe,pe]=(0,K.useState)(null),[me,he]=(0,K.useState)(null),ge=(0,K.useMemo)(()=>r.players[i]?.equipment??{},[r.players,i]),P=(()=>{if(ue){let{skillId:e,actionType:t,prompt:n}=ue;return{skillId:e,actionType:t,prompt:n,cardIds:rxe(n,a,ge),externalTargetSelection:(n.mode??`allocate`)===`allocate`}}if(v&&s?.prompt.type===`distribute`){let e=f?.skillId??`系统规则`,t=rxe(s.prompt,a,ge);return{skillId:e,actionType:`respond`,prompt:s.prompt,cardIds:t,externalTargetSelection:!1}}return null})(),_e=P!==null,F=(0,K.useMemo)(()=>{if(!P)return[];let e=new Set;for(let t of a)e.add(t.id);for(let t of Object.values(ge))typeof t==`string`&&e.add(t);let t=[];for(let n of P.cardIds){if(e.has(n))continue;let i=r.cardMap[n];i&&t.push(i)}return t},[P,a,ge,r.cardMap]);(0,K.useEffect)(()=>{oe([])},[s]),(0,K.useEffect)(()=>{ce(null),O(null)},[s]),(0,K.useEffect)(()=>{j(new Set),N([]),pe(null)},[P?`${P.skillId}:${P.actionType}:${P.prompt.mode??`allocate`}`:``]),(0,K.useEffect)(()=>{re(null)},[x]),(0,K.useEffect)(()=>{ae([])},[x]),(0,K.useEffect)(()=>{if(!k)return;let e=o.find(e=>e.skillId===k.skillId&&e.actionType===k.actionType);(!e||!M9(e,{view:r,perspectiveIdx:i}))&&(le(null),S(null),w(null))},[k,r,i,o]),(0,K.useEffect)(()=>{if(!ue)return;let e=o.find(e=>e.skillId===ue.skillId&&e.actionType===ue.actionType);(!e||!M9(e,{view:r,perspectiveIdx:i}))&&(de(null),j(new Set),N([]),pe(null))},[ue,r,i,o]),(0,K.useEffect)(()=>{P9({isMyTurn:e,phase:r.phase,pending:s})||(S(null),w(null))},[e,r.phase,s]),(0,K.useEffect)(()=>{x&&!a.some(e=>e.id===x)&&(S(null),w(null)),he(null)},[x,a]);let ve=x?a.find(e=>e.id===x)??null:null,ye=(()=>{if(!k)return null;let e=k.minCards>1?k.selectedCardIds:x?[x]:[];if(e.length===0||!k.transform)return k.wrapperName;let t=a.find(t=>t.id===e[0])??(Object.values(ge).includes(e[0])?r.cardMap[e[0]]:void 0);return!t||!k.cardFilter(t)?k.wrapperName:k.transform(t).name})(),be=(()=>{if(k)return ye&&(k.minCards>1||ve)?o.find(e=>e.actionType===`use`&&e.skillId===ye):void 0;if(ve)return me&&A9(me.prompt)?.(ve)?me:j9(o,ve)})(),xe=be?.prompt.type===`useCardAndTarget`?be.prompt.targetFilter:null,Se=be?N9(xe,be.prompt.type===`useCardAndTarget`&&be.prompt.selfTarget):null,Ce=be?M9(be,{view:r,perspectiveIdx:i}):!1,we=(()=>{if(!ve)return[];let e={view:r,perspectiveIdx:i};return txe(o,ve,be).filter(t=>M9(t,e))})(),Te=(()=>{if(!x||!a.find(e=>e.id===x)||!be)return null;let e=N9(xe,be.prompt.type===`useCardAndTarget`&&be.prompt.selfTarget),t,n;if(e.hasSlots)t=!!C&&!!T,n=C&&T?` → A=${C} B=${T}`:` (请选 A/B 两个目标)`;else if(e.selfTarget)t=!0,n=``;else if(e.multiTarget){let r=e.targetFilter?.min??1;t=ie.length>=r,n=ie.length>0?` → ${ie.join(`、`)}`:` (请选目标)`}else t=!e.needsTarget||!!C,n=C?` → ${C}`:e.needsTarget?` (请选目标)`:``;return{canPlay:t,targetLabel:n}})(),Ee=v&&s?.prompt?.type===`useCardAndTarget`?s.prompt.targetFilter:null,De=v&&s?.prompt?.type===`useCardAndTarget`&&!s.prompt.selfTarget,Oe=De?!!D:!0,ke=(0,K.useCallback)(e=>r.players.findIndex(t=>t.name===e),[r.players]),Ae=(0,K.useCallback)((e,t,n)=>{if(e.type!==`selectTarget`||!e.paramVariants)return;let i=(e.paramVariants.find(e=>e.params===t)??e.paramVariants.find(e=>JSON.stringify(e.params)===JSON.stringify(t)))?.cardFilter;if(!i||n.cardId!==void 0)return;let o=x?a.find(e=>e.id===x):void 0,s=o&&i(o)?o:void 0,c=Object.values(ge).map(e=>typeof e==`string`?r.cardMap[e]:void 0).find(e=>!!e&&i(e)),l=s??c;l&&(n.cardId=l.id)},[x,a,ge,r.cardMap]),je=(0,K.useCallback)((e,t,n)=>{let r=ke(t);if(r<0)return;let i={...n,target:r,targets:[r]};Ae(e.prompt,n,i),g(e.skillId,e.actionType,i),w(null),S(null),ne(null)},[ke,g,Ae]),Me=(0,K.useCallback)(e=>{if(te){let t=te.action.prompt;if(!r.players[e]?.alive)return!1;if(t.type===`selectTarget`)return e===i&&!t.targetFilter.allowSelf?!1:t.targetFilter.filter?t.targetFilter.filter(r,e):!0;if(t.type===`choosePlayer`)return t.candidates?t.candidates.includes(e):!(t.filter&&!t.filter(r,e))}if(_e&&P)return(P.prompt.mode??`allocate`)===`select`||!P.prompt.allowSelf&&e===i||P.prompt.targetFilter&&!P.prompt.targetFilter(r,e)?!1:r.players[e]?.alive===!0;let t=xe;if(v&&Ee){let t=Ee;if(e===i||!r.players[e]?.alive)return!1;let n=t.filter;return n?n(r,e):!0}if(t?.slots&&t.slots.length>1){let n=+!!C;if(n===1&&r.players[e]?.name===C)return!1;let i=t.slots[n],a=n===1?[r.players.findIndex(e=>e.name===C)]:[];return i?.filter?i.filter(r,e,{selected:a}):!0}if(Se?.multiTarget&&t){let n=r.players[e]?.name;if(n&&ie.includes(n))return!0;let a=ve?.name===`杀`?xee(r,i,ve??void 0):t.max;return ie.length>=a||e===i&&!t.allowSelf?!1:t.filter?t.filter(r,e):!0}if(e===i&&!(be?.prompt.type===`useCardAndTarget`&&(be.prompt.selfTarget||t?.allowSelf)))return!1;let n=t?.filter;return n?n(r,e):!0},[_e,P,i,r,xe,be,C,Se,ie,ve,v,Ee,te]),Ne=(0,K.useCallback)(()=>{if(!x)return;let e=a.find(e=>e.id===x);if(!e||!be||!Ce)return;let t=N9(xe,be.prompt.type===`useCardAndTarget`&&be.prompt.selfTarget),n=nxe(r.players,i,e,t,C,T,ie);if(n===null)return;let o=_.current?.querySelector(`[data-card-id="${e.id}"]`);o&&Axe(o,e),g(be.skillId,be.actionType,n),S(null),w(null)},[x,a,be,Ce,xe,r.players,i,C,T,ie,_,g]),Pe=(0,K.useCallback)(e=>{let t=r.players.findIndex(t=>t.name===e);if(!(t>=0&&!Me(t))){if(te){let t=te.action.prompt;if((t.type===`selectTarget`?t.targetFilter.max??1:t.type===`choosePlayer`?t.max??1:1)<=1){je(te.action,e,te.params);return}}if(_e&&P){if((P.prompt.mode??`allocate`)===`select`)return;if(P.externalTargetSelection){if(!P.prompt.allowSelf&&t===i)return;pe(fe===e?null:e);return}if(A.size>0){let e=P.prompt.maxPerTarget??99;N(n=>n.filter(e=>e.target===t).reduce((e,t)=>e+t.cardIds.length,0)+A.size>e?n:[...n,{target:t,cardIds:[...A]}]),j(new Set)}return}if(v&&Ee){if(!Me(t))return;ce(e=>e),O(D===e?null:e);return}if(k){w(C===e?null:e);return}if(Se?.hasSlots){+!!C==0?C===e?(w(null),re(null)):(w(e),re(null)):re(T===e?null:e);return}if(Se?.multiTarget){ae(t=>{if(t.includes(e))return t.filter(t=>t!==e);let n=Se.targetFilter?.max??t.length;return t.length>=n?t:[...t,e]});return}w(C===e?null:e)}},[r.players,Me,_e,P,i,fe,C,T,A,Se,k,v,Ee,D,te,je]),Fe=(0,K.useCallback)((e,t)=>{let{skillId:n,actionType:r,prompt:i}=e,o={...t??{}};if(Ae(i,t??{},o),i.type===`selectTarget`||i.type===`choosePlayer`){let t=i.type===`selectTarget`?i.targetFilter.max??1:i.max??1;if(!C){ne({action:e,params:o}),S(null);return}if(t<=1){je(e,C,o);return}ne(null)}switch(i.type){case`useCard`:if(e.transform){let t=i.cardFilter.min??1,o=i.cardFilter.max??1,s=i.cardFilter.filter,c=s?a.find(e=>s(e)):a[0];le({skillId:n,actionType:r,cardFilter:s??(()=>!0),comboFilter:i.cardFilter.comboFilter,transform:e.transform,wrapperName:c?e.transform(c).name:n,minCards:t,maxCards:o,selectedCardIds:[]}),S(null),w(null);return}if(!x)return;o.cardId=x,o.cardIds=[x];break;case`selectTarget`:if(!C)return;o.target=ke(C),o.targets=[o.target];break;case`useCardAndTarget`:if(e.transform&&i.cardFilter?.filter){let t=a.find(e=>i.cardFilter.filter(e)),o=t?e.transform(t).name:e.skillId,s=i.cardFilter.min??1,c=i.cardFilter.max??1;le({skillId:n,actionType:r,cardFilter:i.cardFilter.filter,comboFilter:i.cardFilter.comboFilter,transform:e.transform,wrapperName:o,minCards:s,maxCards:c,selectedCardIds:[],targetFilter:i.targetFilter}),S(null),w(null);return}if(!x)return;if(!C){he(e);return}{let e=ke(C);if(e<0)return;o.cardId=x;let t=a.find(e=>e.id===x);t?.type===`锦囊牌`&&t.trickSubtype===`延时锦囊`?o.target=e:o.targets=[e]}break;case`choosePlayer`:if(!C)return;o.target=ke(C);break;case`distribute`:de({skillId:n,actionType:r,prompt:i}),S(null),w(null);return;case`chooseOption`:if(typeof o.option!=`string`)return;break;default:break}g(n,r,o),S(null),w(null)},[x,C,ke,a,g,je]),Ie=(0,K.useCallback)(e=>{let t=k?.comboFilter;if(!t||e.length===0)return!0;let n=new Set(Object.values(ge).filter(Boolean)),i=[];for(let t of e){let e=a.find(e=>e.id===t)??(n.has(t)?r.cardMap[t]:void 0);if(!e)return!1;i.push(e)}return t(i)},[k,a,ge,r.cardMap]),Le=(0,K.useCallback)(e=>{if(!k||!ye)return;if(b&&ye===ee){if(k.minCards>1){let e=k.selectedCardIds;if(e.length<k.minCards||e.length>k.maxCards||!Ie(e))return;g(ye,`respond`,{cardId:`${e.join(`#`)}#${k.skillId}`},[{skillId:k.skillId,actionType:k.actionType,params:{cardIds:e}}]),le(null),S(null),w(null);return}if(!x||!a.find(e=>e.id===x))return;g(ye,`respond`,{cardId:`${x}#${k.skillId}`},[{skillId:k.skillId,actionType:k.actionType,params:{cardId:x}}]),le(null),S(null),w(null);return}if(!(Ce||b))return;let t=Se?Se.needsTarget&&!Se.selfTarget:k.targetFilter?k.targetFilter.max>=1:!0,n=t?ke(e):-1;if(!(t&&n<0)){if(k.minCards>1){let e=k.selectedCardIds;if(e.length<k.minCards||e.length>k.maxCards||!Ie(e))return;let r={cardId:`${e.join(`#`)}#${k.skillId}`};Se?.selfTarget?r.targets=[i]:t&&(r.targets=[n]),g(ye,`use`,r,[{skillId:k.skillId,actionType:k.actionType,params:{cardIds:e}}])}else{if(!x||!a.find(e=>e.id===x))return;let e={cardId:`${x}#${k.skillId}`};Se?.selfTarget?e.targets=[i]:t&&(e.targets=[n]),g(ye,`use`,e,[{skillId:k.skillId,actionType:k.actionType,params:{cardId:x}}])}le(null),S(null),w(null)}},[k,ye,Ie,b,ee,ke,x,a,i,Se,Ce,g]),Re=(0,K.useCallback)(e=>{if(!s)return;if(c){if(E.length>=l)We();else{let e=a.slice(-l).map(e=>e.id);g(f?.skillId??`系统规则`,`respond`,{cardIds:e}),oe([])}return}let t=f;if(t)if(e){let n=a.find(t=>t.id===e);if(!n||t.cardFilter&&!t.cardFilter(n))return;let i=t.rescueSkillForCard?.(n);if(De){if(!D)return;let n=r.players.findIndex(e=>e.name===D);if(n<0)return;g(i??t.skillId,`respond`,{cardId:e,targets:[n]})}else g(i??t.skillId,`respond`,{cardId:e})}else h<0?(g(`__skip`,`skip`,{}),m(p)):g(t.skillId,`respond`,{})},[s,c,E,l,a,g,f,h,m,p,De,D,r.players]),ze=(0,K.useCallback)(()=>{e&&g(`回合管理`,`end`,{})},[e,g]),Be=(0,K.useCallback)(()=>{if(!se||De&&!D)return;let e=se;ce(null),O(null),Re(e)},[se,De,D,Re]),Ve=(0,K.useCallback)(()=>{ce(null),O(null)},[]),He=(0,K.useCallback)(n=>{if(ne(null),!t||_e||c&&d||k)return;if(v){if(!f?.cardFilter?.(n))return;if(De){ce(n.id);return}ce(null),Re(n.id);return}if(!e)return;let a=j9(o,n);if(!a||!M9(a,{view:r,perspectiveIdx:i}))return;let s=N9(a.prompt.type===`useCardAndTarget`?a.prompt.targetFilter:null,a.prompt.type===`useCardAndTarget`&&!!a.prompt.selfTarget);if(s.needsTarget&&!s.selfTarget){S(n.id),w(null);return}let l=nxe(r.players,i,n,s,null,null,[]);if(!l)return;let u=_.current?.querySelector(`[data-card-id="${n.id}"]`);u&&Axe(u,n),g(a.skillId,a.actionType,l),S(null),w(null)},[t,_e,c,d,k,v,b,f,De,Re,e,o,r,i,_,g]),Ue=(0,K.useCallback)(n=>{if(ne(null),_e&&P){if(!new Set(P.cardIds).has(n.id))return;R(n.id);return}if(c&&d&&t){oe(e=>Uxe(e,n.id,u));return}if(k&&t&&(e||b)){if(!k.cardFilter(n))return;k.minCards>1?(S(null),le(e=>e&&{...e,selectedCardIds:Uxe(e.selectedCardIds,n.id,e.maxCards)}),w(null)):x===n.id?(S(null),w(null)):(S(n.id),w(null));return}if(v){f?.cardFilter&&f.cardFilter(n)&&ce(e=>e===n.id?null:n.id);return}!e||!t||(x===n.id?(S(null),w(null)):(S(n.id),w(null)))},[_e,P,c,d,t,u,b,v,f,k,e,x]),We=(0,K.useCallback)(()=>{if(!s||!c||E.length<l||E.length>u)return;let e=E;g(f?.skillId??`系统规则`,`respond`,{cardIds:e}),oe([])},[s,c,E,l,u,g,f]),Ge=(0,K.useCallback)(()=>{oe(V9(a.map(e=>e.id),u))},[a,u]),I=(0,K.useCallback)(()=>{oe(e=>H9(a.map(e=>e.id),e,u))},[a,u]),L=(0,K.useCallback)(()=>{le(e=>{if(!e)return e;let t=a.filter(e.cardFilter);if(e.comboFilter){for(let n=0;n<t.length;n++)for(let r=n+1;r<t.length;r++)if(e.comboFilter([t[n],t[r]]))return{...e,selectedCardIds:[t[n].id,t[r].id]}}return{...e,selectedCardIds:V9(t.map(e=>e.id),e.maxCards)}})},[a]),Ke=(0,K.useCallback)(()=>{le(e=>{if(!e)return e;let t=a.filter(e.cardFilter).map(e=>e.id);return{...e,selectedCardIds:H9(t,e.selectedCardIds,e.maxCards)}})},[a]),R=(0,K.useCallback)(e=>{if(!P)return;let t=P.prompt.maxTotal??99;j(n=>{let r=new Set(n);if(r.has(e))r.delete(e);else{if(r.size>=t)return n;r.add(e)}return r})},[P]),qe=(0,K.useCallback)(()=>{if(!P)return;let e=P.prompt.maxTotal??99;j(new Set(V9(P.cardIds,e)))},[P]),Je=(0,K.useCallback)(()=>{if(!P)return;let e=P.prompt.maxTotal??99;j(new Set(H9(P.cardIds,[...A],e)))},[P,A]),Ye=(0,K.useCallback)(e=>{if(!P)return;let t=P.prompt.maxPerTarget??99;A.size!==0&&(N(n=>n.filter(t=>t.target===e).reduce((e,t)=>e+t.cardIds.length,0)+A.size>t?n:[...n,{target:e,cardIds:[...A]}]),j(new Set))},[P,A]),z=(0,K.useCallback)(()=>{if(!P)return;let{skillId:e,actionType:t,prompt:n,externalTargetSelection:r}=P,i=n.mode??`allocate`,a=n.minTotal??1;if(i===`select`){if(A.size<a)return;g(e,t,{cardIds:[...A]})}else if(r){if(A.size<a||!fe)return;let n=ke(fe);if(n<0)return;g(e,t,{allocation:[{target:n,cardIds:[...A]}]})}else{if(M.flatMap(e=>e.cardIds).length<a)return;g(e,t,{allocation:M})}j(new Set),N([]),pe(null),de(null)},[P,A,fe,M,ke,g]),Xe=(0,K.useCallback)(()=>{j(new Set),N([]),pe(null)},[]),Ze=(0,K.useCallback)(()=>{le(null),S(null),w(null)},[]),Qe=(0,K.useCallback)(()=>{S(null),w(null),ne(null)},[]),B=(()=>{if(!k||_e)return null;let e=k.minCards>1?k.selectedCardIds:x?[x]:[],t=e.length>=k.minCards&&e.length<=k.maxCards,n=Ie(e),r=!b&&(Se?Se.needsTarget&&!Se.selfTarget:k.targetFilter?k.targetFilter.max>=1:!0);return{needsTarget:r,canSubmit:(Ce||b)&&t&&n&&(!r||!!C)}})(),$e=(()=>{if(!P)return null;let e=P.prompt.mode??`allocate`,t=P.prompt.minTotal??1,n=P.prompt.maxTotal??99;if(e===`select`)return{canSubmit:A.size>=t&&A.size<=n,label:`确认(${A.size})`};if(P.externalTargetSelection)return{canSubmit:A.size>=t&&A.size<=n&&!!fe,label:`确定(${A.size})${fe?` → ${fe}`:``}`};let r=M.flatMap(e=>e.cardIds).length;return{canSubmit:r>=t,label:`提交分配(${r})`}})(),V=(0,K.useCallback)(()=>oe([]),[]);return{selectedCardId:x,selectedTarget:C,selectedKillTarget:T,selectedMultiTargets:ie,selectedForDiscard:E,transformMode:k,transformWrapperName:ye,distributeMode:ue,activeDistribute:P,isDistributeActive:_e,distSelected:A,distAllocations:M,distTargetName:fe,distExternalCandidates:F,selectedCard:ve,selectedUseAction:be,selectedTargetFilter:xe,playRules:Se,selectedActive:Ce,playButtonState:Te,isRespondTransformContext:b,selectedRespondCardId:se,respondTargetName:D,respondNeedsTarget:De,respondTargetReady:Oe,altActions:we,handleCardClick:Ue,handlePlayCard:Ne,handleTargetClick:Pe,handleSkillAction:Fe,handleTransformPlay:Le,handleRespond:Re,handlePlayRespond:Be,handleEndTurn:ze,handleConfirmDiscard:We,handleDiscardSelectAll:Ge,handleDiscardInvert:I,handleTransformSelectAll:L,handleTransformInvert:Ke,isTargetable:Me,skillTargetMode:te!==null,clearRespondSelection:Ve,handleCardDoubleClick:He,transformSubmit:B,distSubmit:$e,handleDistToggle:R,handleDistSelectAll:qe,handleDistInvert:Je,handleDistAllocate:Ye,handleDistSubmit:z,handleDistClear:Xe,cancelTransform:Ze,cancelSelection:Qe,clearDiscard:V,setDistributeMode:de}}function Gxe(e){return e===` `?`space`:e.toLowerCase()}function Kxe(e){if(!(e instanceof HTMLElement))return!1;let t=e.tagName.toLowerCase();return t===`input`||t===`textarea`||t===`select`||e.isContentEditable}function qxe(e){let t=(0,K.useRef)(e);t.current=e,(0,K.useEffect)(()=>{let e=e=>{if(e.metaKey||e.ctrlKey||e.altKey||Kxe(e.target))return;let n=t.current[Gxe(e.key)];n?.(e)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[])}function Jxe(e,t){let n=e.cardMap[t];return n?{cardId:t,cardName:n.name,suit:n.suit,rank:n.rank}:null}function Yxe(e){return(0,K.useMemo)(()=>{if(e.pending?.prompt?.type!==`pickProcessingCard`)return null;let t=e.settlementStack.find(e=>e.skillId===`五谷丰登`);if(!t)return null;let n=t.params.revealedIds,r=t.params.pickedBy??{},i=new Map;for(let[e,t]of Object.entries(r))typeof t==`string`&&i.set(e,t);let a=[];if(n&&n.length>0)for(let t of n){let n=Jxe(e,t);n&&a.push(n)}else for(let n of t.cards){let r=Jxe(e,n);r&&r.cardName!==t.skillId&&a.push(r)}return{allCards:a,pickedBy:i}},[e])}var Xxe=[500,2e3],Zxe={optInSkip:{}};function Qxe(e){return!(e.isBlocking===!1||e.mandatory===!0)}function $xe(e,t){let[n,r]=e;return Math.round(n+t()*(r-n))}function eSe(e){let{pending:t,canRespond:n,handCount:r,prefs:i}=e;if(!t||!Qxe(t))return{kind:`wait`};let a=e.delayRange??Xxe,o=e.rng??Math.random,s=b9(t);return s&&i.optInSkip[s]?{kind:`act-delayed`,ms:$xe(a,o)}:n?{kind:`wait`}:r===0?{kind:`act-now`}:{kind:`act-delayed`,ms:$xe(a,o)}}function tSe(e,t,n,r,i){if(!i)return!1;if(i.prompt?.type!==`useCard`)return!0;let a=e.players[t]?.hand??[];if(r?.cardFilter&&a.some(r.cardFilter))return!0;let o={view:e,perspectiveIdx:t};return n.some(e=>e.actionType===`transform`&&M9(e,o))}function nSe(e){let{view:t,viewer:n,skillActions:r,pendingRespondInfo:i,prefs:a}=e,o=t.pending;return eSe({pending:o,canRespond:tSe(t,n,r,i,o),handCount:t.players[n]?.handCount??0,prefs:a,delayRange:e.delayRange,rng:e.rng})}var U9=`sgs:auto-skip`;function rSe(){try{let e=localStorage.getItem(U9);if(!e)return Zxe;let t=JSON.parse(e).optInSkip;return{optInSkip:t&&typeof t==`object`?{...t}:{}}}catch{return Zxe}}function iSe(e){try{localStorage.setItem(U9,JSON.stringify(e))}catch{}}function aSe(){let[e,t]=(0,K.useState)(()=>rSe());return(0,K.useEffect)(()=>{let e=e=>{e.key===U9&&t(rSe())};return window.addEventListener(`storage`,e),()=>window.removeEventListener(`storage`,e)},[]),{prefs:e,toggleOptIn:(0,K.useCallback)(e=>{t(t=>{let n={optInSkip:{...t.optInSkip,[e]:!t.optInSkip[e]}};return iSe(n),n})},[]),isOptedIn:(0,K.useCallback)(t=>!!e.optInSkip[t],[e])}}function oSe(e){let{view:t,perspectiveIdx:n,skillActions:r,pendingRespondInfo:i,prefs:a,canOperate:o,isPerspectiveAwaiting:s,markBroadcastSkipped:c,broadcastKey:l,send:u}=e,d=(0,K.useRef)(null),f=(0,K.useRef)(null),p=(0,K.useRef)(t);p.current=t,(0,K.useEffect)(()=>{if(d.current&&=(clearTimeout(d.current),null),!o||!s)return;let e=t.pending;if(!e)return;let m=e.deadline??0;if(m===f.current)return;let h=nSe({view:t,viewer:n,skillActions:r,pendingRespondInfo:i,prefs:a});if(h.kind===`wait`)return;f.current=m;let g=()=>{(p.current.pending?.deadline??null)===(e.deadline??null)&&(u(`__skip`,`skip`,{}),e.target<0&&c(l))};h.kind===`act-now`?g():d.current=setTimeout(()=>{d.current=null,g()},h.ms)},[t,n,r,i,a,o,s,l]),(0,K.useEffect)(()=>()=>{d.current&&clearTimeout(d.current)},[])}Fc();var sSe={主公:`主`,忠臣:`忠`,反贼:`反`,内奸:`内`},W9={主公:`zhu`,忠臣:`zhong`,反贼:`fan`,内奸:`nei`},cSe=[[`武器`,`武`],[`防具`,`防`],[`防御马`,`+1`],[`进攻马`,`-1`],[`宝物`,`宝`]],lSe={准备:`准备`,判定:`判定`,摸牌:`摸牌`,出牌:`出牌`,弃牌:`弃牌`,回合结束:`结束`};function G9({deadline:e,totalMs:t}){let n=Tee(e,t||15e3);return e==null?null:(0,$.jsx)(`div`,{className:`nm-timer`,children:(0,$.jsx)(`div`,{className:`nm-timer-fill`,ref:n})})}function uSe({hp:e,max:t}){let n=e>t/2?`high`:e>t/4&&e>1?`mid`:`low`;return t>5?(0,$.jsxs)(`div`,{className:`nm-hp text ${n}`,children:[(0,$.jsx)(`i`,{className:`nm-jade`}),(0,$.jsxs)(`span`,{children:[Math.max(e,0),`/`,t]})]}):(0,$.jsx)(`div`,{className:`nm-hp ${n}`,children:Array.from({length:t},(t,n)=>(0,$.jsx)(`i`,{className:`nm-jade${n>=Math.max(e,0)?` lost`:``}`},n))})}function dSe(e){return e.faction??(e.character?Oc(e.character)?.faction:void 0)??`群`}var fSe=e=>e.marks.some(e=>e.id===`chained`),pSe=e=>(e.tags??[]).some(e=>e.endsWith(`/翻面`));function mSe(e,t){let n=D9[dSe(e)]??`qun`,r={dead:!e.alive,dying:e.alive&&e.health<=0,chained:fSe(e),flipped:pSe(e),...t};return`${n} ${Object.entries(r).filter(([,e])=>e).map(([e])=>e).join(` `)}`}function hSe({p:e,mine:t}){let n=e.identity;return!n&&!e.identityHidden&&!t?null:(0,$.jsx)(`div`,{className:`nm-identity ${n?W9[n]:`unknown`}`,title:n??`身份未知`,children:n?sSe[n]??n[0]:`?`})}function gSe({p:e,view:t}){let n=e.pendingTricks??[];return n.length?(0,$.jsx)(`div`,{className:`nm-judges`,children:n.map(e=>{let n=t.cardMap[e];return(0,$.jsxs)(`span`,{className:`nm-judge`,title:n?`${n.name} ${n.suit}${n.rank}`:e,children:[n&&E9(n.name)&&(0,$.jsx)(`i`,{style:{backgroundImage:`url(${E9(n.name)})`}}),(0,$.jsx)(`b`,{children:(n?.name??`?`)[0]})]},e)})}):null}var _Se=(e,t)=>e===`防御马`?`${t}+`:e===`进攻马`?`${t}-`:t;function vSe({p:e,view:t}){let n=cSe.filter(([t])=>e.equipment[t]);return n.length?(0,$.jsx)(`div`,{className:`nm-equips`,children:n.map(([n,r])=>{let i=t.cardMap[e.equipment[n]];return(0,$.jsxs)(`div`,{className:`nm-equip`,title:i?`${i.name}(${n})${i.description?`\n${i.description}`:``}`:n,children:[(0,$.jsx)(`span`,{className:`nm-equip-slot`,children:r}),(0,$.jsx)(`span`,{className:`nm-equip-name`,children:i?_Se(n,i.name):n}),i&&(0,$.jsxs)(`span`,{className:`nm-equip-info${I9(i.suit)?` red`:``}`,children:[i.suit,i.rank]})]},n)})}):null}function ySe({change:e}){return e?(0,$.jsx)(`div`,{className:`nm-hpfloat ${e.kind}`,children:e.kind===`heal`?`+${e.amount}`:`-${e.amount}`},e.version):null}function bSe({p:e,view:t,isCurrent:n,phase:r,hpChange:i,children:a}){let o=T9(e.character),s=dSe(e),c=e.character||``;return(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`div`,{className:`nm-avatar`,style:o?{backgroundImage:`url(${o})`}:void 0,children:!o&&c&&(0,$.jsx)(`span`,{className:`nm-avatar-none`,children:c})}),(0,$.jsx)(`div`,{className:`nm-frame`}),c&&(0,$.jsx)(`div`,{className:`nm-faction ${D9[s]??`qun`}`,children:s}),c&&(0,$.jsx)(`div`,{className:`nm-name${c.length>4?` long`:``}`,children:c}),c&&(0,$.jsx)(uSe,{hp:e.health,max:e.maxHealth}),(0,$.jsx)(`div`,{className:`nm-count`,title:`手牌 ${e.handCount}`,children:e.handCount}),a,(0,$.jsx)(gSe,{p:e,view:t}),fSe(e)&&(0,$.jsx)(`div`,{className:`nm-chain`}),pSe(e)&&(0,$.jsx)(`div`,{className:`nm-flipped`,children:`翻面`}),e.alive&&e.health<=0&&(0,$.jsx)(`div`,{className:`nm-dying`,children:`濒死`}),!e.alive&&(0,$.jsxs)(`div`,{className:`nm-dead ${e.identity?W9[e.identity]:``}`,children:[e.identity?(0,$.jsx)(`b`,{children:e.identity}):null,`阵亡`]}),n&&e.alive&&(0,$.jsx)(`div`,{className:`nm-phase-mark`,children:lSe[r]??r}),(0,$.jsx)(ySe,{change:i})]})}function xSe(e){let{view:t}=O9(),{player:n,index:r,style:i,isCurrent:a,phase:o,needsTarget:s,targetable:c,selected:l,onClick:u,damaged:d,healed:f,hpChange:p,deadline:m,totalMs:h,distance:g,reason:_,label:v=n.name}=e,y=s&&n.alive&&c,ee=mSe(n,{current:a,selectable:y,selected:l,unselectable:s&&n.alive&&!c,damaged:!!d,healed:!!f});return(0,$.jsxs)(`div`,{className:`nm-seat${s&&y?` pick`:``}`,style:i,"data-seat-index":r,"data-player-name":n.name,onClick:()=>y&&u(),title:s&&!c&&_?`不可选择:${_}`:void 0,children:[(0,$.jsx)(`div`,{className:`nm-player ${ee}`,children:(0,$.jsxs)(bSe,{p:n,view:t,isCurrent:a,phase:o,hpChange:p,children:[(0,$.jsx)(hSe,{p:n}),(0,$.jsx)(vSe,{p:n,view:t}),s&&g!=null&&n.alive&&(0,$.jsxs)(`div`,{className:`nm-distance`,children:[`距`,g]})]})}),v&&v!==n.character&&(0,$.jsx)(`div`,{className:`nm-seat-label`,children:v}),(0,$.jsx)(G9,{deadline:m,totalMs:h})]},d?`d${d}`:void 0)}v9();function SSe(){(0,K.useSyncExternalStore)(wbe,Tbe)}Fc(),Np(),v9();var CSe=new Set(Tp);function wSe(e){let{view:t,canOperate:n,skillActions:r}=O9();SSe();let{player:i,index:a,isCurrent:o,phase:s,spectating:c,onSkillAction:l,onEquipClick:u,distCandidates:d,distSelected:f,isDistributeActive:p,targetable:m,selected:h,onTarget:g,damaged:_,healed:v,hpChange:y,timer:ee,hand:b}=e,x={view:t,perspectiveIdx:a},S=i.identity===`主公`,C=i.skills.filter(e=>!CSe.has(e)&&!S9.has(e)&&(S||!Pc.has(e))),w=r.filter(e=>e.prompt.type===`confirm`||e.prompt.type===`chooseOption`||e.prompt.type===`choosePlayer`||e.prompt.type===`selectTarget`||e.prompt.type===`useCardAndTarget`&&!!e.transform||e.prompt.type===`useCard`&&!!e.transform||e.prompt.type===`distribute`),te=e=>n&&M9(e,x),ne=n&&P9({isMyTurn:o,phase:t.phase,pending:t.pending}),T=C.flatMap(e=>{let t=w.filter(t=>t.skillId===e),n=u9(e)??t[0]?.prompt.title,r=C9(e),a=t.flatMap(e=>ixe(e).map(n=>({...n,action:e,label:n.label||(t.length>1?e.label||e.actionType:``)}))).filter(e=>te(e.action));return a.length?a.map(t=>(0,$.jsx)(`button`,{className:`nm-skill on${t.action.style===`danger`?` danger`:``}`,title:t.description??n,onClick:()=>l(t.action,t.params),children:t.label?t.label.startsWith(r)?t.label:`${r}·${t.label}`:r},t.label?`${e}:${t.label}`:e)):t[0]&&ne?[(0,$.jsx)(`button`,{className:`nm-skill`,disabled:!0,title:i.turnUsage?.[`${e}/usedThisTurn`]?`本回合已发动过(每回合限一次)`:n??``,children:r},e)]:[(0,$.jsx)(`span`,{className:`nm-skill passive`,title:n,children:r},e)]}),re=new Map;for(let e of r)S9.has(e.skillId)&&n&&M9(e,x)&&re.set(e.skillId,e);let ie=cSe.map(([e])=>{let n=i.equipment[e],r=n?t.cardMap[n]:void 0;if(!n)return(0,$.jsx)(`div`,{className:`nm-myequip empty`,title:e},e);let a=p?void 0:re.get(r?.name??``),o=p&&!!d?.has(n),s=r&&S9.has(r.name)?u9(r.name):r?.description;return(0,$.jsxs)(`div`,{className:`nm-myequip${a?` usable`:``}${o?` candidate`:``}${f.has(n)?` picked`:``}`,onClick:a?()=>l(a):o?()=>u(n):void 0,title:`${r?.name??n}(${e})${s?`\n${s}`:``}`,children:[(0,$.jsx)(`span`,{className:`nm-equip-name`,children:r?_Se(e,r.name):n}),r&&(0,$.jsxs)(`span`,{className:`nm-equip-info${I9(r.suit)?` red`:``}`,children:[r.suit,r.rank]})]},e)});return(0,$.jsxs)(`div`,{className:`nm-me${c?` spectating`:``}`,children:[(0,$.jsx)(`div`,{className:`nm-player mine ${mSe(i,{current:o,selectable:m,selected:h,damaged:!!_,healed:!!v})}`,"data-seat-index":a,"data-player-name":i.name,onClick:g,children:(0,$.jsx)(bSe,{p:i,view:t,isCurrent:o,phase:s,hpChange:y,children:(0,$.jsx)(hSe,{p:i,mine:!0})})},_?`d${_}`:void 0),(0,$.jsx)(`div`,{className:`nm-myequips`,children:ie}),(0,$.jsxs)(`div`,{className:`nm-hand`,children:[ee,b]}),(0,$.jsx)(`div`,{className:`nm-skills`,children:T}),(0,$.jsx)(`div`,{className:`nm-me-label`,children:c?`旁观 · ${i.name}`:i.name})]})}function TSe({play:e,pending:t,isRespondPending:n,respondCandidateCount:r,showCancelSelection:i,showEndTurn:a,isDiscardPhase:o,isPerspectiveAwaiting:s,discardMin:c,discardMax:l}){let{canOperate:u}=O9(),{selectedCardId:d,selectedTarget:f,selectedForDiscard:p,transformMode:m,transformWrapperName:h,distributeMode:g,activeDistribute:_,isDistributeActive:v,distSelected:y,distAllocations:ee,distTargetName:b,selectedActive:x,playButtonState:S,transformSubmit:C,selectedRespondCardId:w,respondTargetReady:te,altActions:ne,handlePlayCard:T,handleSkillAction:re,handleTransformPlay:ie,isRespondTransformContext:ae,handleRespond:E,handlePlayRespond:oe,handleEndTurn:se,handleConfirmDiscard:ce,handleDiscardSelectAll:D,handleTransformSelectAll:O,handleTransformInvert:k,handleDistSubmit:le,handleDistClear:ue,handleDistSelectAll:de,handleDistInvert:A,cancelSelection:j,setDistributeMode:M}=e,N=[],fe=t?.prompt?.type===`useCardAndTarget`;if(n&&(r!==0&&N.push({key:`respond`,label:`确定`,kind:`ok`,onClick:oe,disabled:!w||!te}),N.push({key:`skip`,label:fe?`交出武器`:`取消`,kind:`cancel`,onClick:()=>E(),title:r===0?`没有可回应的牌`:void 0})),u&&m&&m.minCards>1){let e=m.selectedCardIds;N.push({key:`t-all`,label:`全选`,kind:`plain`,onClick:O,disabled:e.length>=m.maxCards}),N.push({key:`t-inv`,label:`反选`,kind:`plain`,onClick:k,disabled:e.length===0})}if(u&&(x||ae)&&m&&m.minCards>1){let e=C?.canSubmit??!1,t=C?.needsTarget??!1;N.push({key:`t-go`,label:`确定`,kind:`ok`,onClick:()=>e&&ie(t?f:``),disabled:!e,title:`使用${h??m.wrapperName}`})}if(u&&(x||ae)&&m?.minCards===1&&d&&(ae?N.push({key:`t-one`,label:`确定`,kind:`ok`,onClick:()=>ie(``),title:`使用${h??m.wrapperName}`}):N.push({key:`t-one`,label:`确定`,kind:`ok`,onClick:()=>f&&ie(f),disabled:!f,title:`使用${h??m.wrapperName}`})),u&&x&&!m&&d&&S&&N.push({key:`play`,label:`确定`,kind:`ok`,onClick:T,disabled:!S.canPlay,title:`出牌${S.targetLabel}`}),u&&!m&&d)for(let e of ne)N.push({key:`${e.skillId}:${e.actionType}`,label:C9(e.label),kind:`plain`,onClick:()=>re(e)});if(!m&&i&&N.push({key:`cancel`,label:`取消`,kind:`cancel`,onClick:j}),a&&N.push({key:`end`,label:`结束回合`,kind:`end`,onClick:se}),u&&o&&s){let e=p.length;N.push({key:`discard`,label:`确定`,kind:`ok`,onClick:ce,disabled:e<c||e>l,title:`弃置 ${e}/${c}`}),N.push({key:`d-all`,label:`全选`,kind:`plain`,onClick:D,disabled:e>=l})}if(u&&v&&_){let e=_.prompt.mode??`allocate`,t=_.prompt.minTotal??1,n=_.prompt.maxTotal??99,r=e===`select`?y.size>=t&&y.size<=n:_.externalTargetSelection?y.size>=t&&y.size<=n&&!!b:ee.flatMap(e=>e.cardIds).length>=t;e===`select`&&(N.push({key:`x-all`,label:`全选`,kind:`plain`,onClick:de,disabled:y.size>=_.cardIds.length}),N.push({key:`x-inv`,label:`反选`,kind:`plain`,onClick:A,disabled:y.size===0})),N.push({key:`x-clear`,label:`重选`,kind:`plain`,onClick:ue,disabled:y.size===0&&ee.length===0}),N.push({key:`x-go`,label:`确定`,kind:`ok`,onClick:le,disabled:!r,title:_.prompt.title}),g&&N.push({key:`x-cancel`,label:`取消`,kind:`cancel`,onClick:()=>M(null)})}return N.length?(0,$.jsx)(`div`,{className:`nm-control`,children:N.map(({key:e,label:t,kind:n,onClick:r,disabled:i,title:a})=>(0,$.jsx)(`button`,{className:`nm-btn ${n}`,onClick:r,disabled:i,title:a,children:t},e))}):null}Fc(),v9();function ESe({candidates:e,target:t,mine:n,deadline:r,totalMs:i,onAction:a}){let[o,s]=(0,K.useState)(null),[c,l]=(0,K.useState)(!1);return c||!n?(0,$.jsx)(`div`,{className:`nm-dialog-wait`,children:`等待其他角色选择武将…`}):(0,$.jsx)(`div`,{className:`nm-dialog-mask`,children:(0,$.jsxs)(`div`,{className:`nm-dialog choose`,children:[(0,$.jsx)(`div`,{className:`nm-dialog-title`,children:`请选择武将`}),(0,$.jsx)(`div`,{className:`nm-choose-row`,children:e.map(e=>{let t=Oc(e.name),n=t?.faction??`群`,r=T9(e.name);return(0,$.jsxs)(`button`,{className:`nm-choose ${D9[n]??`qun`}${o===e.name?` selected`:``}`,onClick:()=>s(e.name),onDoubleClick:()=>s(e.name),children:[(0,$.jsx)(`div`,{className:`nm-avatar`,style:r?{backgroundImage:`url(${r})`}:void 0}),(0,$.jsx)(`div`,{className:`nm-frame`}),(0,$.jsx)(`div`,{className:`nm-faction ${D9[n]??`qun`}`,children:n}),(0,$.jsx)(`div`,{className:`nm-name${e.name.length>4?` long`:``}`,children:e.name}),t&&(0,$.jsx)(uSe,{hp:t.maxHealth,max:t.maxHealth}),(0,$.jsx)(`div`,{className:`nm-choose-skills`,children:e.skills.map(e=>(0,$.jsx)(`span`,{title:u9(e)??``,children:C9(e)},e))})]},e.name)})}),(0,$.jsx)(G9,{deadline:r,totalMs:i}),(0,$.jsx)(`div`,{className:`nm-control in-dialog`,children:(0,$.jsx)(`button`,{className:`nm-btn ok`,disabled:!o,onClick:()=>{o&&(l(!0),a({skillId:`系统规则`,actionType:`选将`,ownerId:t,params:{character:o}}))},children:`确定`})})]})})}function K9(e){let t=document.querySelector(e)?.getBoundingClientRect();return t&&t.width?{x:t.left+t.width/2,y:t.top+t.height/2}:null}function DSe({item:e}){let t=(0,K.useRef)(null);return(0,K.useLayoutEffect)(()=>{let n=t.current,r=e.cardId&&R9.get(e.cardId)||(e.from===null?K9(`[data-zone-anchor="deck"]`):K9(`[data-seat-index="${e.from}"]`));if(!n||!r||!n.animate)return;let i=n.getBoundingClientRect(),a=L9(),o=(r.x-(i.left+i.width/2))/a,s=(r.y-(i.top+i.height/2))/a;n.animate([{transform:`translate(${o}px, ${s}px) scale(0.55)`,opacity:.4},{transform:`none`,opacity:1}],{duration:420,easing:`cubic-bezier(.2,.7,.3,1)`})},[]),(0,$.jsxs)(`div`,{className:`nm-played`,ref:t,children:[(0,$.jsx)(uxe,{face:e.face}),(0,$.jsx)(`div`,{className:`nm-played-caption`,children:e.caption})]})}function OSe({items:e,reveal:t}){return(0,$.jsxs)(`div`,{className:`nm-center`,children:[(0,$.jsxs)(`div`,{className:`nm-played-row`,children:[e.map(e=>(0,$.jsx)(DSe,{item:e},e.id)),t&&(0,$.jsxs)(`div`,{className:`nm-played shown`,children:[(0,$.jsx)(uxe,{face:t.face}),(0,$.jsx)(`div`,{className:`nm-played-caption`,children:t.caption})]})]}),(0,$.jsx)(`div`,{className:`nm-discard`,"data-zone-anchor":`discard`})]})}function kSe({lines:e,words:t}){let n=(0,K.useRef)(null),[,r]=(0,K.useState)(0);(0,K.useEffect)(()=>r(e=>e+1),[e,t]);let i=n.current?.getBoundingClientRect(),a=L9(),o=e=>{let t=K9(`[data-seat-index="${e}"] .nm-avatar`)??K9(`[data-seat-index="${e}"]`);return t&&i?{x:(t.x-i.left)/a,y:(t.y-i.top)/a}:null};return(0,$.jsxs)($.Fragment,{children:[t.map(e=>{let t=o(e.seat);return t?(0,$.jsx)(`div`,{className:`nm-cardeffect ${e.text===`杀`||e.text.endsWith(`杀`)?`sha`:``}`,style:{left:t.x,top:t.y},children:e.text},e.id):null}),(0,$.jsx)(`svg`,{className:`nm-lines`,ref:n,children:e.map(e=>{let t=o(e.from),n=o(e.to);if(!t||!n)return null;let r=Math.hypot(n.x-t.x,n.y-t.y);return(0,$.jsxs)(`g`,{className:`nm-line ${e.kind}`,style:{"--len":`${r}`},children:[(0,$.jsx)(`line`,{x1:t.x,y1:t.y,x2:n.x,y2:n.y,strokeDasharray:r}),(0,$.jsx)(`circle`,{cx:n.x,cy:n.y,r:`6`})]},e.id)})})]})}var ASe=[...Object.keys(w9.cards),`火杀`,`雷杀`],jSe=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);function MSe({view:e}){let[t,n]=(0,K.useState)(!1),r=(0,K.useRef)(null),i=e.log.slice(t?-80:-4),a=e.players.map(e=>e.character).filter(Boolean).join(`|`),o=(0,K.useMemo)(()=>{let e=[...a.split(`|`).filter(Boolean),...ASe].sort((e,t)=>t.length-e.length);return RegExp(`(${e.map(jSe).join(`|`)})`,`g`)},[a]),s=(0,K.useMemo)(()=>new Set(ASe),[]);return(0,K.useEffect)(()=>{r.current&&(r.current.scrollTop=r.current.scrollHeight)},[i.length,t]),(0,$.jsxs)(`div`,{className:`nm-log${t?` open`:``}`,children:[(0,$.jsx)(`button`,{className:`nm-log-toggle`,onClick:()=>n(!t),title:t?`收起记录`:`展开记录`,children:`记录`}),i.length>0&&(0,$.jsx)(`div`,{className:`nm-log-lines`,ref:r,children:i.map((t,n)=>{let r=e.players[t.player];return(0,$.jsxs)(`div`,{className:`nm-log-line`,children:[r&&(0,$.jsx)(`span`,{className:`who`,children:r.character||r.name}),t.text.split(o).map((e,t)=>t%2?(0,$.jsx)(`span`,{className:s.has(e)?`card`:`who`,children:e},t):e)]},e.log.length-i.length+n)})})]})}var q9=4200,J9=1400,Y9=1100,NSe={杀:`sha`,火杀:`sha`,雷杀:`sha`,闪:`shan`,桃:`tao`,酒:`jiu`},PSe=0,X9=()=>`fx${++PSe}`;function FSe(e,t){let[n,r]=(0,K.useState)([]),[i,a]=(0,K.useState)([]),[o,s]=(0,K.useState)([]),c=(0,K.useRef)(-1),l=(0,K.useRef)(t);return l.current=t,(0,K.useEffect)(()=>{let t=e??[];if(!t.length)return;t.every(e=>e.seq<=c.current)&&(c.current=Math.min(...t.map(e=>e.seq))-1,r([]),a([]),s([]));let n=t.filter(e=>e.seq>c.current);if(!n.length)return;c.current=Math.max(...n.map(e=>e.seq));let i=l.current,o=e=>i.players[e]?.character||i.players[e]?.name||``,u=Date.now(),d=[],f=[],p=[],m=new Map;for(let{event:e}of n){let t=e,n=t.card,r=typeof t.cardId==`string`?i.cardMap[t.cardId]:void 0,a=(e,t)=>{let n=t?i.cardMap[t]:void 0,r=e?.name??n?.name;return r?{name:r,suit:e?.suit??n?.suit,rank:e?.rank??n?.rank,damageType:n?.damageType}:null};if(t.type===`打出`||t.type===`弃牌`||t.type===`展示`){let e=a(n??void 0,t.cardId),r=t.type===`打出`?``:t.type===`弃牌`?` 弃置`:` 展示`;e&&d.push({id:X9(),face:e,caption:`${o(t.player)}${r}`,from:t.player,cardId:t.cardId,at:u});let i=e&&(e.damageType===`火焰`?`火杀`:e.damageType===`雷电`?`雷杀`:e.name);t.type===`打出`&&i&&NSe[i]&&p.push({id:X9(),seat:t.player,text:i,at:u})}else if(t.type===`弃置`){let e=t.cardIds??[],n=t.cardNames??[];for(let r=0;r<Math.max(e.length,n.length);r++){let s=a(n[r]?{name:n[r],...ISe(i.cardMap[e[r]])}:void 0,e[r]);s&&d.push({id:X9(),face:s,caption:`${o(t.player)} 弃置`,from:t.player,cardId:e[r],at:u})}}else if(t.type===`判定`){let e=a(n??void 0,t.cardId);e&&d.push({id:X9(),face:e,caption:`${o(t.player)} ${t.judgeType??``}判定`,from:null,cardId:t.cardId,at:u})}else if(t.type===`指定目标`&&typeof t.source==`number`&&typeof t.target==`number`){let e=t.cardName??r?.name;if(t.source!==t.target&&f.push({id:X9(),from:t.source,to:t.target,kind:e===`杀`?`sha`:`trick`,at:u}),typeof t.cardId==`string`){let e=m.get(t.cardId);m.set(t.cardId,e?`${e}、${o(t.target)}`:`${o(t.source)} → ${o(t.target)}`)}}}(d.length||m.size)&&r(e=>{let t=[...e.filter(e=>u-e.at<q9),...d];return m.size&&(t=t.map(e=>e.cardId&&m.has(e.cardId)?{...e,caption:m.get(e.cardId)}:e)),t.slice(-7)}),f.length&&a(e=>[...e.filter(e=>u-e.at<J9),...f]),p.length&&s(e=>[...e.filter(e=>u-e.at<Y9),...p])},[e]),(0,K.useEffect)(()=>{if(!n.length&&!i.length&&!o.length)return;let e=setInterval(()=>{let e=Date.now();r(t=>t.some(t=>e-t.at>=q9)?t.filter(t=>e-t.at<q9):t),a(t=>t.some(t=>e-t.at>=J9)?t.filter(t=>e-t.at<J9):t),s(t=>t.some(t=>e-t.at>=Y9)?t.filter(t=>e-t.at<Y9):t)},300);return()=>clearInterval(e)},[n.length,i.length,o.length]),{center:n,lines:i,words:o}}var ISe=e=>e?{suit:e.suit,rank:e.rank}:{};Qp(),J(),um();var LSe={桃:0,杀:1,闪:2,无懈可击:3},RSe={准备:`准备阶段`,判定:`判定阶段`,摸牌:`摸牌阶段`,出牌:`出牌阶段`,弃牌:`弃牌阶段`,回合结束:`结束阶段`};function zSe(e,t){let n=t===1?90:t===2?150:t>=6?200:t===5?195:180,r=(t===1?90:n-e*(2*n-180)/(t-1))*Math.PI/180;return{x:50+41*Math.cos(r),y:52-33*Math.sin(r),scale:t<=4?1:t===5?.9:t===6?.82:.75}}function BSe({view:e,onAction:t,readOnly:n=!1,currentEvent:r,ingestedEvents:i,top:a,side:o,overlay:s,labels:c}){let l=e.viewer>=0&&e.viewer<e.players.length?e.viewer:0,u=e.viewer<0,d=(0,K.useRef)(e);d.current=e;let{skillActions:f}=Fxe(e,l),{pending:p,pendingTargetIdx:m,isPerspectiveAwaiting:h,isDiscardPhase:g,discardMin:_,discardMax:v,skippedBroadcast:y,markBroadcastSkipped:ee,deadline:b,deadlineTotalMs:x,pendingRespondInfo:S,broadcastKey:C}=Lxe(e,l,f),{prefs:w,toggleOptIn:te}=aSe(),{isCharSelectPending:ne,charSelect:T}=Bxe(e,l),re=Vxe(e,l),ie=Exe(e,l);Pxe(i??[],e);let ae=FSe(i,e),[E,oe]=(0,K.useState)(null);(0,K.useEffect)(()=>{let e=(i??[]).filter(e=>e.event.type===`展示`);e.length>0&&oe(e[e.length-1].event),(i??[]).some(e=>e.event.type===`展示结束`)&&oe(null)},[i]);let se=(0,K.useRef)(null),ce=e.players[l],D=ce.name??`P${l}`,O=e.currentPlayerIndex===l,k=e.players[e.currentPlayerIndex],le=k.name,ue=ce.hand??[],{orderedHand:de,handleDragStart:A,handleDrop:j}=Hxe(ue,void 0),M=!n,N=(0,K.useCallback)((e,n,r,i)=>{oe(null),t({skillId:e,actionType:n,ownerId:l,params:r,preceding:i})},[t,l]),fe=Yxe(e);oSe({view:e,perspectiveIdx:l,skillActions:f,pendingRespondInfo:S,prefs:w,canOperate:M,isPerspectiveAwaiting:h,markBroadcastSkipped:ee,broadcastKey:C,send:N});let pe=Wxe(O,M,{view:e,perspectiveIdx:l,perspectiveHand:ue,skillActions:f,pending:p,isDiscardPhase:g,discardMin:_,discardMax:v,isPerspectiveAwaiting:h,pendingRespondInfo:S,broadcastKey:C,markBroadcastSkipped:ee,pendingTargetIdx:m,send:N,handListRef:se}),{selectedCardId:me,selectedCard:he,selectedTarget:ge,selectedKillTarget:P,selectedMultiTargets:_e,selectedForDiscard:F,transformMode:ve,transformWrapperName:ye,activeDistribute:be,isDistributeActive:xe,distTargetName:Se,selectedRespondCardId:Ce,respondTargetName:we,respondNeedsTarget:Te,respondTargetReady:Ee,playButtonState:De,playRules:Oe,handleCardClick:ke,handlePlayCard:Ae,handleTargetClick:je,handleSkillAction:Me,isRespondTransformContext:Ne,handleRespond:Pe,handlePlayRespond:Fe,handleEndTurn:Ie,isTargetable:Le,skillTargetMode:Re,clearRespondSelection:ze,handleCardDoubleClick:Be,handleTransformPlay:Ve,handleConfirmDiscard:He,handleDistSubmit:Ue,transformSubmit:We,distSubmit:Ge,cancelTransform:I,cancelSelection:L,distSelected:Ke}=pe,R=h&&M,qe=m<0&&y.has(C),Je=g&&h&&M,Ye=(0,K.useCallback)(t=>{let n=j9(f,t);return O&&M&&Qbe(t)&&(!n||M9(n,{view:e,perspectiveIdx:l}))},[O,M,f,e,l]),z=(0,K.useCallback)(e=>!xe&&R&&!!S?.cardFilter?.(e),[xe,R,S]),Xe=(0,K.useCallback)(t=>{if(Ye(t)||!O||e.phase!==`出牌`||p)return null;if(!Qbe(t))return`仅用于响应,出牌阶段不能主动使用`;let n=j9(f,t);if(n&&M9(n,{view:e,perspectiveIdx:l}))return null;if(t.name===`杀`){let t=am(e,l),n=om(e,l);return Number.isFinite(t)&&n>=t?`本回合杀次数已用完(${n}/${t})`:`本回合不能使用杀(次数已尽或被限制)`}return t.name===`桃`&&ce.health>=ce.maxHealth?`体力已满,不需要使用桃`:t.name===`酒`&&ce.turnUsage?.[`酒/usedThisTurn`]?`本回合已使用过酒`:`当前不满足使用条件(阶段/次数/目标限制)`},[Ye,O,e,p,f,l,ce]),Ze=wee(b),Qe=(0,K.useMemo)(()=>{if(!g||!h||Ze==null||Ze>5||F.length>=_)return null;let e=[...ue].sort((e,t)=>(LSe[t.name]??9)-(LSe[e.name]??9));return new Set(e.slice(0,_).map(e=>e.id))},[g,h,Ze,F.length,_,ue]),B=(0,K.useCallback)(t=>{let n={distance:null,reason:null},r=e.players[t];if(!r)return n;let i=cm(e.players,l,t);if(!Number.isFinite(i))return n;if(!r.alive)return{distance:i,reason:`已阵亡`};if(Le(t))return{distance:i,reason:null};if(t===l)return{distance:i,reason:`不能选择自己`};if(he?.name===`杀`||Ne){let t=e.players[l]?.distanceVars?.attackRange??1;if(i>t)return{distance:i,reason:`距离 ${i},超出攻击范围 ${t}`}}return{distance:i,reason:`不满足目标条件`}},[e,l,Le,he,Ne]),$e=(0,K.useCallback)(e=>{let t=d.current.cardMap[e];t&&ke(t)},[ke]),V=!!r&&(()=>{let e=r.event.atomType??r.event.type;try{return Zp(e)?.effect?.animation===`flip`}catch{return!1}})(),et=axe({canOperate:M,isMyTurn:O,phase:e.phase,pending:p}),tt=oxe({selectedCardId:me,isMyTurn:O,phase:e.phase,pending:p}),nt=R&&!g&&!qe&&(p?.prompt?.type===`useCard`||p?.prompt?.type===`useCardAndTarget`),rt=(0,K.useMemo)(()=>!nt||!S?.cardFilter?null:ue.filter(S.cardFilter).length,[nt,S,ue]);qxe(n?{}:{enter:()=>{if(ve){We?.canSubmit&&Ve(We.needsTarget?ge:``);return}if(nt){Ce&&Ee&&Fe();return}if(g&&h){F.length>=_&&F.length<=v&&He();return}if(xe){Ge?.canSubmit&&Ue();return}De?.canPlay&&Ae()},escape:()=>{ve?I():Ce||we?ze():(tt||Re)&&L()},space:e=>{nt&&(e.preventDefault(),Pe())},e:()=>{et&&Ie()},...Object.fromEntries([1,2,3,4,5,6,7,8,9,0].map(t=>[String(t),()=>{let n=ue[t===0?9:t-1];if(!n)return;let r=O&&e.phase===`出牌`&&!p,i=!!ve&&(O||Ne);(r&&Ye(n)||z(n)||Je||i||xe)&&ke(n)}]))});let it=!!Oe&&Oe.needsTarget||xe&&!!be?.externalTargetSelection||Te||Re,at=xe&&be?.externalTargetSelection?Se?[Se]:[]:Oe?.hasSlots?[ge,P].filter(e=>!!e):Oe?.multiTarget?_e:Te?we?[we]:[]:ge?[ge]:[],ot=M&&it&&Le(l),st=(0,K.useMemo)(()=>({view:e,perspectiveIdx:l,perspectiveName:D,isSpectating:u,canOperate:M,currentPlayerName:le,skillActions:f,send:N}),[e,l,D,u,M,le,f,N]),ct=t=>V||!e.pending||qe&&t===l&&e.pending.target<0?null:e.pending.target<0?e.players[t]?.alive?e.pending.deadline??null:null:e.pending.target===t?e.pending.deadline??null:null,lt=re.slice(1),ut=M&&h&&p&&!g&&!V&&p.atom?.type!==`选将询问`&&p.prompt.type!==`distribute`,dt=E?.card,ft=e.zones?.deckCount??0;return(0,$.jsx)(Xbe,{value:st,children:(0,$.jsx)(USe,{children:(0,$.jsxs)(`div`,{className:`nm-arena${u?` spectating`:``}${n?` readonly`:``}`,children:[(0,$.jsxs)(`div`,{className:`nm-topbar`,children:[(0,$.jsxs)(`div`,{className:`nm-pile`,"data-zone-anchor":`deck`,children:[(0,$.jsx)(`span`,{children:`剩余`}),(0,$.jsx)(`b`,{children:ft}),(0,$.jsx)(`span`,{children:`张`})]}),(0,$.jsxs)(`div`,{className:`nm-round`,children:[(0,$.jsxs)(`span`,{className:`nm-discards`,children:[`弃牌`,(0,$.jsx)(`b`,{children:e.zones?.discardPileCount??0})]}),`第`,(0,$.jsx)(`b`,{children:e.turn?.round??1}),`轮 `,(0,$.jsx)(`span`,{className:`nm-turn-of`,children:k.character||le}),(0,$.jsx)(`span`,{className:`nm-phase`,children:RSe[e.phase]??e.phase})]}),(0,$.jsx)(`div`,{className:`nm-top-slot`,children:a}),o&&(0,$.jsx)(`div`,{className:`nm-top-side`,children:o})]}),lt.map((t,n)=>{let r=e.players.findIndex(e=>e.name===t.name),{x:i,y:a,scale:o}=zSe(n,lt.length),s=it?B(r):{distance:null,reason:null};return(0,$.jsx)(xSe,{player:t,index:r,style:{left:`${i}%`,top:`${a}%`,"--seat-scale":o},isCurrent:r===e.currentPlayerIndex,phase:e.phase,needsTarget:it,targetable:Le(r),selected:at.includes(t.name),onClick:()=>je(t.name),damaged:ie.damageFlashIndices.get(r),healed:ie.healFlashIndices.get(r),hpChange:ie.hpChangeNumbers.get(r),deadline:ct(r),totalMs:e.pending?.totalMs,distance:s.distance,reason:s.reason,label:c?.[r]},t.name)}),(0,$.jsx)(OSe,{items:ae.center,reveal:dt?{face:dt,caption:`${e.players[E.player]?.character??``} 展示`}:null}),(0,$.jsx)(kSe,{lines:ae.lines,words:ae.words}),(0,$.jsxs)(`div`,{className:`nm-dock`,children:[ut&&(0,$.jsx)(Zbe,{pending:p,pendingTargetIdx:m,perspectiveHand:ue,pendingRespondInfo:S,broadcastKey:C,skippedBroadcast:y,processingPicks:fe,autoSkipPrefs:w,onToggleAutoSkip:te}),M&&g&&h&&(0,$.jsxs)(`div`,{className:`nm-tip`,children:[`请弃置 `,(0,$.jsx)(`b`,{children:_===v?_:`${_}~${v}`}),` 张手牌(已选 `,F.length,`)`]}),M&&O&&e.phase===`出牌`&&!p&&!me&&!ve&&!Re&&(0,$.jsx)(`div`,{className:`nm-tip`,children:`出牌阶段,请选择要使用的牌`}),M&&me&&it&&!at.length&&(0,$.jsx)(`div`,{className:`nm-tip`,children:`请选择目标`}),ve&&(0,$.jsxs)(`div`,{className:`nm-tip`,children:[C9(ve.skillId),`:选`,ve.minCards>1?`${ve.minCards}张牌`:`一张牌`,`当【`,ye??ve.wrapperName,`】`,ve.minCards>1?`(${ve.selectedCardIds.length}/${ve.maxCards})`:``]}),M&&(0,$.jsx)(TSe,{play:pe,pending:p,isRespondPending:nt,respondCandidateCount:rt,showCancelSelection:tt,showEndTurn:et,isDiscardPhase:g,isPerspectiveAwaiting:h,discardMin:_,discardMax:v})]}),(0,$.jsx)(wSe,{player:ce,index:l,isCurrent:O,phase:e.phase,spectating:u,onSkillAction:Me,onEquipClick:$e,distCandidates:be?new Set(be.cardIds):null,distSelected:Ke,isDistributeActive:xe,targetable:ot,selected:at.includes(D),onTarget:()=>ot&&je(D),damaged:ie.damageFlashIndices.get(l),healed:ie.healFlashIndices.get(l),hpChange:ie.hpChangeNumbers.get(l),timer:(h||O&&e.phase===`出牌`)&&!qe&&!n&&!V?(0,$.jsx)(G9,{deadline:b,totalMs:x}):null,hand:u?(0,$.jsx)(`div`,{className:`nm-backs`,children:Array.from({length:Math.min(ce.handCount,20)},(e,t)=>(0,$.jsx)(`div`,{className:`nm-card back`},t))}):(0,$.jsx)(Txe,{play:pe,phase:e.phase,isSpectating:u,perspectiveHand:ue,spectatorHandCount:ce.handCount,handListRef:se,orderedHand:de,handleDragStart:A,handleDrop:j,canPlayHandCard:Ye,isRespondableCard:z,canDiscardClick:Je,disabledReason:Xe,onCardDoubleClick:Be,timeoutFallbackIds:Qe,isMyAwaiting:R,isMyTurn:O})}),(0,$.jsx)(MSe,{view:e}),ne&&T&&T.target>=0&&!n&&(0,$.jsx)(ESe,{candidates:T.candidates,target:T.target,mine:T.target===l,deadline:T.pending?.deadline??null,totalMs:T.pending?.totalMs??6e4,onAction:t}),s]})})})}var VSe=720,HSe=1180;function USe({children:e}){let t=(0,K.useRef)(null),[n,r]=(0,K.useState)({w:HSe,h:VSe,s:1});return(0,K.useEffect)(()=>{let e=t.current,n=()=>{let t=e.clientWidth,n=e.clientHeight;if(!t||!n)return;let i=Math.min(n/VSe,t/HSe);r({w:t/i,h:n/i,s:i}),document.documentElement.style.setProperty(`--nm-scale`,String(i))};n();let i=new ResizeObserver(n);return i.observe(e),()=>i.disconnect()},[]),(0,$.jsx)(`div`,{className:`nm-scaler`,ref:t,children:(0,$.jsx)(`div`,{className:`nm-canvas`,style:{width:n.w,height:n.h,transform:`scale(${n.s})`,"--gv-scale":String(n.s)},children:e})})}function WSe({r:e}){return(0,$.jsxs)(`div`,{className:`nm-replay`,children:[(0,$.jsx)(`button`,{className:`nm-mini`,onClick:()=>e.goTo(0),title:`回到开局`,disabled:e.step<=0,children:`⏮`}),(0,$.jsx)(`button`,{className:`nm-mini`,onClick:e.prev,title:`上一步`,disabled:e.step<=0,children:`◀`}),(0,$.jsx)(`button`,{className:`nm-mini play`,onClick:e.togglePlay,title:e.playing?`暂停`:`播放`,children:e.playing?`❚❚`:`▶`}),(0,$.jsx)(`button`,{className:`nm-mini`,onClick:e.next,title:`下一步`,disabled:e.step>=e.total,children:`▶▏`}),(0,$.jsx)(`input`,{type:`range`,min:0,max:e.total,value:e.step,onChange:t=>e.goTo(Number(t.target.value)),"aria-label":`进度`}),(0,$.jsxs)(`span`,{className:`nm-step`,children:[e.step,`/`,e.total]})]})}function GSe({r:e,names:t}){return(0,$.jsxs)(`div`,{className:`nm-replay`,children:[(0,$.jsx)(`select`,{value:e.speed,onChange:t=>e.setSpeed(Number(t.target.value)),title:`速度`,children:[.5,1,2,4].map(e=>(0,$.jsxs)(`option`,{value:e,children:[e,`×`]},e))}),(0,$.jsx)(`select`,{value:e.seat,onChange:t=>e.setSeat(Number(t.target.value)),title:`视角`,children:e.seats.map(e=>(0,$.jsx)(`option`,{value:e,children:e<0?`旁观`:`${e+1}号位 ${t[e]??``}`},e))})]})}function KSe({seats:e,seat:t,view:n,onPick:r}){return e.length<2?null:(0,$.jsx)(`div`,{className:`nm-replay`,children:e.map(e=>(0,$.jsx)(`button`,{className:`nm-mini${e===t?` on`:``}`,onClick:()=>r(e),children:n.players[Number(e)]?.character||`${Number(e)+1}号位`},e))})}var Z9={主公:`主公`,忠臣:`主公`,反贼:`反贼`,内奸:`内奸`},qSe={2:[0,1],3:[0,1],4:[1,1],5:[1,2],6:[1,3],7:[2,3],8:[2,4]};function JSe(e){let t=e.players.find(e=>e.identity===`主公`);if(!t)return``;if(t.alive)return`主公`;let n=e.players.filter(e=>e.alive),[r,i]=qSe[e.players.length]??[1,2],a=t=>e.players.filter(e=>!e.alive&&e.identity===t).length;return n.length===1&&a(`忠臣`)===r&&a(`反贼`)===i?`内奸`:`反贼`}function YSe({view:e,camp:t,identities:n,me:r,labels:i}){let a=t=>n?.[String(t)]||e.players[t]?.identity||``,o=r>=0?Z9[a(r)]:``,s=t?o?o===t?`游戏胜利`:`游戏失败`:`${t===`主公`?`主公、忠臣`:t}获胜`:`游戏结束`;return(0,$.jsx)(`div`,{className:`nm-dialog-mask result`,children:(0,$.jsxs)(`div`,{className:`nm-dialog result ${o&&t?o===t?`win`:`lose`:``}`,children:[(0,$.jsx)(`div`,{className:`nm-result-title`,children:s}),(0,$.jsx)(`table`,{className:`nm-result`,children:(0,$.jsx)(`tbody`,{children:e.players.map((e,n)=>{let r=a(n),o=T9(e.character);return(0,$.jsxs)(`tr`,{className:`${Z9[r]===t?`won`:``}${e.alive?``:` dead`}`,children:[(0,$.jsx)(`td`,{children:(0,$.jsx)(`span`,{className:`nm-result-face`,style:o?{backgroundImage:`url(${o})`}:void 0})}),(0,$.jsx)(`td`,{className:`nm-result-name`,children:e.character}),(0,$.jsx)(`td`,{children:i?.[n]??(e.name===e.character?``:e.name)}),(0,$.jsxs)(`td`,{children:[(0,$.jsx)(`span`,{className:`nm-identity inline ${r?W9[r]:`unknown`}`,children:r?sSe[r]:``}),r||`未知`]}),(0,$.jsx)(`td`,{children:e.alive?`存活`:`阵亡`}),(0,$.jsx)(`td`,{children:Z9[r]===t?`胜`:r?`负`:``})]},n)})})})]})})}var Q9=window;Q9.shoalLive??=e=>{addEventListener(`message`,t=>{t.data?.shoal===`live`&&e(t.data)}),parent!==window&&parent.postMessage({shoal:`ready`,live:!0},`*`)},Q9.shoalAct??=(e,t,n)=>parent.postMessage({shoal:`act`,seat:e,version:t,action:n},`*`);var XSe=()=>{},$9=`public`;bee.loadIndex({packs:[]}),document.head.append(Object.assign(document.createElement(`link`),{rel:`stylesheet`,href:`art/art.css`}));function ZSe(e,t){if(!e)return e;let{view:n,seq:r}=e;for(let e of t){let t=_ee(n,r,{type:`event`,epoch:0,...e});t.view&&(n=t.view),r=t.lastSeq}return{view:n,seq:r}}var QSe=e=>e.filter(e=>e.view).map(e=>({seq:e.seq,event:e.view}));function $Se(e,t){let n=e.n<0,r={...e,views:{...e.views},fresh:{},asks:{...e.asks},you:t.you??e.you},i=(e,t)=>{n||(r.fresh[e]=[...r.fresh[e]??[],...QSe(t)])};for(let e of t.messages){if(e.n!==void 0){if(e.n<=r.n)continue;r.n=e.n}let t=e.event;t?.type===`start`?r.views[$9]={view:t.view,seq:t.seq}:t?.type===`events`?(r.views[$9]=ZSe(r.views[$9],t.events),i($9,t.events)):(t?.type===`moved`||t?.type===`control`)&&r.asks[t.seat]?.version===(t.version??r.asks[t.seat]?.version)?delete r.asks[t.seat]:e.end?(r.end=e.end,r.asks={}):e.to!==void 0&&e.version!==void 0?r.asks[e.to]={...e,at:Date.now()}:e.to!==void 0&&e.obs?.view?r.views[e.to]={view:e.obs.view,seq:e.obs.seq}:e.to!==void 0&&e.obs?.events&&(r.views[e.to]=ZSe(r.views[e.to],e.obs.events),i(e.to,e.obs.events))}return r}function eCe(e,t){let n=t?Number(t.obs?.limit??30)*1e3:0,r=t?t.at+n:null;return{...e,deadline:r,deadlineTotalMs:n,pending:e.pending?{...e.pending,deadline:r??void 0,totalMs:n}:null}}var tCe=e=>{let t=Object.entries(e.scores??{}).find(([,e])=>e>0)?.[0]??e.winner,n=t===void 0?void 0:e.identities?.[t];return n===`忠臣`?`主公`:n??``};function nCe(){let[e,t]=(0,K.useReducer)($Se,{views:{},fresh:{},asks:{},you:[],n:-1}),[n,r]=(0,K.useState)(null),[i,a]=(0,K.useState)(!1);(0,K.useEffect)(()=>{Q9.shoalLive((e,n)=>{let r=e;t(Array.isArray(r)?{messages:r,you:n}:{messages:r.messages??[],you:r.you??n})})},[]);let o=n&&e.you.includes(n)?n:e.you.find(t=>e.views[t])??e.you[0],s=o===void 0?void 0:e.views[o],c=s?o:$9,l=s??e.views[$9];if(!l)return(0,$.jsx)(`div`,{className:`shoal-wait`,children:`等待房间开局…`});let u=o===void 0?void 0:e.asks[o],d=e=>{!u||o===void 0||(Q9.shoalAct(o,u.version,e),t({messages:[{event:{type:`moved`,seat:o,version:u.version}}]}))},f=eCe(l.view,u),p=u?.legal?.map((e,t)=>({l:e,i:t})).filter(({l:e})=>rCe(e))??[],m=(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(KSe,{seats:e.you,seat:o,view:f,onPick:r}),p.length>0&&(0,$.jsxs)(`div`,{className:`nm-moves`,children:[(0,$.jsx)(`button`,{className:`nm-mini`,onClick:()=>a(!i),title:`The room's list of moves for this seat`,children:i?`收起`:`操作 ${p.length}`}),i&&(0,$.jsx)(`div`,{className:`nm-moves-list`,children:p.map(({l:e,i:t})=>(0,$.jsx)(`button`,{onClick:()=>d(t),title:JSON.stringify(e.message),children:e.description},t))})]})]});return(0,$.jsx)(`div`,{className:`nm-root`,children:(0,$.jsx)(BSe,{view:f,onAction:d,readOnly:!s,ingestedEvents:e.fresh[c],top:m,overlay:e.end?(0,$.jsx)(YSe,{view:f,camp:tCe(e.end),identities:e.end.identities,me:f.viewer}):null})})}function rCe(e){let t=e.message.params??{};return e.validTargets.length&&!Array.isArray(t.targets)?!1:!Object.values(t).some(e=>Array.isArray(e)&&!e.length)}function iCe({file:e}){let t=gee(e),n=e.shoal?.seat;if((0,K.useEffect)(()=>{n!==void 0&&t.seats.includes(n)&&t.setSeat(n)},[]),!t.view)return(0,$.jsx)(`div`,{className:`shoal-wait`,children:`…`});let r=e.shoal?.names??t.view.players.map(e=>e.name),i=t.step>=t.total&&t.total>0;return(0,$.jsx)(`div`,{className:`nm-root`,children:(0,$.jsx)(BSe,{view:t.view,onAction:XSe,readOnly:!0,currentEvent:t.currentEvent,ingestedEvents:t.ingestedEvents,labels:e.shoal?.names,top:(0,$.jsx)(WSe,{r:t}),side:(0,$.jsx)(GSe,{r:t,names:r}),overlay:i?(0,$.jsx)(YSe,{view:t.view,camp:JSe(t.view),me:t.view.viewer,labels:e.shoal?.names}):null})})}function aCe(){let e=new URLSearchParams(location.search).has(`live`),[t,n]=(0,K.useState)(null),[r,i]=(0,K.useState)(``);return(0,K.useEffect)(()=>{e||Q9.shoalReplay?.(e=>{try{n(JSON.parse(e))}catch{i(`这个文件不是三国杀录像`)}})},[e]),e?(0,$.jsx)(nCe,{}):r?(0,$.jsx)(`div`,{className:`shoal-wait`,children:r}):t?(0,$.jsx)(iCe,{file:t}):(0,$.jsx)(`div`,{className:`shoal-wait`,children:`等待录像…`})}(0,uee.createRoot)(document.getElementById(`root`)).render((0,$.jsx)(aCe,{}));