valtech-components 4.0.452 → 4.0.453
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/organisms/mini-games/bubble-blitz-game.component.mjs +18 -9
- package/esm2022/lib/components/organisms/mini-games/chessimals-engine.mjs +109 -16
- package/esm2022/lib/components/organisms/mini-games/chessimals-game.component.mjs +23 -25
- package/esm2022/lib/components/organisms/mini-games/christianity-game.component.mjs +1735 -0
- package/esm2022/lib/components/organisms/mini-games/memory-game.component.mjs +18 -9
- package/esm2022/lib/components/organisms/mini-games/mini-games.i18n.mjs +159 -13
- package/esm2022/lib/components/organisms/mini-games/simon-game.component.mjs +18 -9
- package/esm2022/lib/components/organisms/mini-games/types.mjs +1 -1
- package/esm2022/lib/directives/light-ripple.directive.mjs +57 -0
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/mini-games/public-api.mjs +34 -2
- package/esm2022/public-api.mjs +3 -1
- package/fesm2022/valtech-components-mini-games.mjs +34 -2
- package/fesm2022/valtech-components-mini-games.mjs.map +1 -1
- package/fesm2022/valtech-components.mjs +2127 -78
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/mini-games/bubble-blitz-game.component.d.ts +2 -0
- package/lib/components/organisms/mini-games/chessimals-game.component.d.ts +3 -3
- package/lib/components/organisms/mini-games/christianity-game.component.d.ts +113 -0
- package/lib/components/organisms/mini-games/memory-game.component.d.ts +2 -0
- package/lib/components/organisms/mini-games/simon-game.component.d.ts +2 -0
- package/lib/components/organisms/mini-games/types.d.ts +74 -1
- package/lib/directives/light-ripple.directive.d.ts +8 -0
- package/lib/version.d.ts +1 -1
- package/mini-games/public-api.d.ts +4 -0
- package/package.json +2 -1
- package/public-api.d.ts +2 -0
- package/src/lib/assets/games/christianity/card-symbol.svg +51 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, InjectionToken, makeEnvironmentProviders, APP_INITIALIZER, ErrorHandler, Injectable, DestroyRef, Inject, signal, computed, PLATFORM_ID, isDevMode, Optional, runInInjectionContext, effect, Pipe, TemplateRef, ViewContainerRef, input, Directive, EventEmitter, Component, Input, Output, ChangeDetectionStrategy, HostBinding,
|
|
2
|
+
import { inject, InjectionToken, makeEnvironmentProviders, APP_INITIALIZER, ErrorHandler, Injectable, DestroyRef, Inject, signal, computed, PLATFORM_ID, isDevMode, Optional, runInInjectionContext, effect, Pipe, TemplateRef, ViewContainerRef, input, Directive, ElementRef, Renderer2, HostListener, EventEmitter, Component, Input, Output, ChangeDetectionStrategy, HostBinding, SecurityContext, NgZone, ViewChild, ChangeDetectorRef, output, ContentChild, model, ViewEncapsulation, untracked, viewChild, Injector, isSignal } from '@angular/core';
|
|
3
3
|
import { BehaviorSubject, throwError, Subject, map, distinctUntilChanged, filter as filter$1, take as take$1, firstValueFrom, of, from, EMPTY, Observable, interval, defer, timer, merge, concat, debounceTime, switchMap as switchMap$1, catchError as catchError$1, takeUntil, isObservable, forkJoin, race, tap as tap$1, Subscription, shareReplay as shareReplay$1 } from 'rxjs';
|
|
4
4
|
import { catchError, switchMap, finalize, filter, take, timeout, map as map$1, tap, shareReplay, distinctUntilChanged as distinctUntilChanged$1, retry, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs/operators';
|
|
5
5
|
import * as i1$3 from '@angular/common/http';
|
|
@@ -49,6 +49,7 @@ import { Capacitor } from '@capacitor/core';
|
|
|
49
49
|
import { ImageCropperComponent } from 'ngx-image-cropper';
|
|
50
50
|
import Compressor from 'compressorjs';
|
|
51
51
|
import { Calendar } from 'vanilla-calendar-pro';
|
|
52
|
+
import { CdkDrag, CdkDropList } from '@angular/cdk/drag-drop';
|
|
52
53
|
import 'prismjs/components/prism-scss';
|
|
53
54
|
import 'prismjs/components/prism-json';
|
|
54
55
|
import { BrowserMultiFormatReader } from '@zxing/browser';
|
|
@@ -58,7 +59,7 @@ import fixWebmDuration from 'fix-webm-duration';
|
|
|
58
59
|
* Current version of valtech-components.
|
|
59
60
|
* This is automatically updated during the publish process.
|
|
60
61
|
*/
|
|
61
|
-
const VERSION = '4.0.
|
|
62
|
+
const VERSION = '4.0.453';
|
|
62
63
|
|
|
63
64
|
// Control de estado de refresco (singleton a nivel de módulo)
|
|
64
65
|
let isRefreshing = false;
|
|
@@ -10117,6 +10118,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10117
10118
|
}]
|
|
10118
10119
|
}], ctorParameters: () => [] });
|
|
10119
10120
|
|
|
10121
|
+
class LightRippleDirective {
|
|
10122
|
+
constructor() {
|
|
10123
|
+
this.host = inject(ElementRef);
|
|
10124
|
+
this.renderer = inject(Renderer2);
|
|
10125
|
+
}
|
|
10126
|
+
createRipple(event) {
|
|
10127
|
+
const element = this.host.nativeElement;
|
|
10128
|
+
const rect = element.getBoundingClientRect();
|
|
10129
|
+
const size = Math.max(rect.width, rect.height) * 1.55;
|
|
10130
|
+
const ripple = this.renderer.createElement('span');
|
|
10131
|
+
const x = event.clientX - rect.left - size / 2;
|
|
10132
|
+
const y = event.clientY - rect.top - size / 2;
|
|
10133
|
+
if (getComputedStyle(element).position === 'static') {
|
|
10134
|
+
this.renderer.setStyle(element, 'position', 'relative');
|
|
10135
|
+
}
|
|
10136
|
+
this.renderer.setStyle(element, 'overflow', 'hidden');
|
|
10137
|
+
this.renderer.setStyle(element, 'isolation', 'isolate');
|
|
10138
|
+
this.renderer.setStyle(element, 'touch-action', 'manipulation');
|
|
10139
|
+
this.renderer.setStyle(ripple, 'position', 'absolute');
|
|
10140
|
+
this.renderer.setStyle(ripple, 'left', `${x}px`);
|
|
10141
|
+
this.renderer.setStyle(ripple, 'top', `${y}px`);
|
|
10142
|
+
this.renderer.setStyle(ripple, 'width', `${size}px`);
|
|
10143
|
+
this.renderer.setStyle(ripple, 'height', `${size}px`);
|
|
10144
|
+
this.renderer.setStyle(ripple, 'border-radius', '999px');
|
|
10145
|
+
this.renderer.setStyle(ripple, 'pointer-events', 'none');
|
|
10146
|
+
this.renderer.setStyle(ripple, 'z-index', '1');
|
|
10147
|
+
this.renderer.setStyle(ripple, 'background', 'radial-gradient(circle, rgba(255,255,255,0.98) 0 0.16rem, rgba(191,219,254,0.9) 0.18rem 0.34rem, rgba(96,165,250,0.46) 0.36rem 23%, rgba(96,165,250,0.18) 38%, transparent 70%)');
|
|
10148
|
+
this.renderer.setStyle(ripple, 'box-shadow', '0 0 0.75rem rgba(255,255,255,0.85), 0 0 1.8rem rgba(96,165,250,0.52)');
|
|
10149
|
+
this.renderer.appendChild(element, ripple);
|
|
10150
|
+
ripple
|
|
10151
|
+
.animate([
|
|
10152
|
+
{ opacity: 0.88, transform: 'scale(0.08)' },
|
|
10153
|
+
{ opacity: 0.48, transform: 'scale(0.48)' },
|
|
10154
|
+
{ opacity: 0, transform: 'scale(1)' },
|
|
10155
|
+
], { duration: 680, easing: 'cubic-bezier(0.16, 0.84, 0.24, 1)' })
|
|
10156
|
+
.finished.finally(() => {
|
|
10157
|
+
if (ripple.parentNode === element) {
|
|
10158
|
+
this.renderer.removeChild(element, ripple);
|
|
10159
|
+
}
|
|
10160
|
+
});
|
|
10161
|
+
}
|
|
10162
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LightRippleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
10163
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: LightRippleDirective, isStandalone: true, selector: "[valLightRipple]", host: { listeners: { "pointerdown": "createRipple($event)" } }, ngImport: i0 }); }
|
|
10164
|
+
}
|
|
10165
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LightRippleDirective, decorators: [{
|
|
10166
|
+
type: Directive,
|
|
10167
|
+
args: [{
|
|
10168
|
+
selector: '[valLightRipple]',
|
|
10169
|
+
standalone: true,
|
|
10170
|
+
}]
|
|
10171
|
+
}], propDecorators: { createRipple: [{
|
|
10172
|
+
type: HostListener,
|
|
10173
|
+
args: ['pointerdown', ['$event']]
|
|
10174
|
+
}] } });
|
|
10175
|
+
|
|
10120
10176
|
/**
|
|
10121
10177
|
* Presets de botón por defecto provistos por la librería.
|
|
10122
10178
|
*
|
|
@@ -61031,18 +61087,66 @@ const CHESSIMALS_BOT_PROFILES = [
|
|
|
61031
61087
|
labelKey: 'chessimalsBotSentinel',
|
|
61032
61088
|
descriptionKey: 'chessimalsBotSentinelBody',
|
|
61033
61089
|
},
|
|
61090
|
+
{
|
|
61091
|
+
id: 'oracle',
|
|
61092
|
+
difficulty: 'hard',
|
|
61093
|
+
avatar: '🔮',
|
|
61094
|
+
labelKey: 'chessimalsBotOracle',
|
|
61095
|
+
descriptionKey: 'chessimalsBotOracleBody',
|
|
61096
|
+
},
|
|
61097
|
+
{
|
|
61098
|
+
id: 'ambusher',
|
|
61099
|
+
difficulty: 'hard',
|
|
61100
|
+
avatar: '🪤',
|
|
61101
|
+
labelKey: 'chessimalsBotAmbusher',
|
|
61102
|
+
descriptionKey: 'chessimalsBotAmbusherBody',
|
|
61103
|
+
},
|
|
61104
|
+
{
|
|
61105
|
+
id: 'locksmith',
|
|
61106
|
+
difficulty: 'hard',
|
|
61107
|
+
avatar: '🔐',
|
|
61108
|
+
labelKey: 'chessimalsBotLocksmith',
|
|
61109
|
+
descriptionKey: 'chessimalsBotLocksmithBody',
|
|
61110
|
+
},
|
|
61111
|
+
{
|
|
61112
|
+
id: 'storm',
|
|
61113
|
+
difficulty: 'hard',
|
|
61114
|
+
avatar: '🌩️',
|
|
61115
|
+
labelKey: 'chessimalsBotStorm',
|
|
61116
|
+
descriptionKey: 'chessimalsBotStormBody',
|
|
61117
|
+
},
|
|
61118
|
+
{
|
|
61119
|
+
id: 'matriarch',
|
|
61120
|
+
difficulty: 'hard',
|
|
61121
|
+
avatar: '👑',
|
|
61122
|
+
labelKey: 'chessimalsBotMatriarch',
|
|
61123
|
+
descriptionKey: 'chessimalsBotMatriarchBody',
|
|
61124
|
+
},
|
|
61125
|
+
{
|
|
61126
|
+
id: 'endgame',
|
|
61127
|
+
difficulty: 'hard',
|
|
61128
|
+
avatar: '⌛',
|
|
61129
|
+
labelKey: 'chessimalsBotEndgame',
|
|
61130
|
+
descriptionKey: 'chessimalsBotEndgameBody',
|
|
61131
|
+
},
|
|
61034
61132
|
];
|
|
61035
61133
|
const BOT_STYLES = {
|
|
61036
|
-
explorer: { advancement: 1.05, capture: 0.82, safety: 0.62, power: 0.8, center: 1.15, unlock: 1.05, reply: 0.7, randomness: 260, spread: 0.68 },
|
|
61037
|
-
impulsive: { advancement: 0.9, capture: 1.45, safety: 0.48, power: 1.15, center: 0.8, unlock: 0.9, reply: 0.55, randomness: 290, spread: 0.62 },
|
|
61038
|
-
runner: { advancement: 1.55, capture: 0.78, safety: 0.5, power: 0.95, center: 0.7, unlock: 1.1, reply: 0.55, randomness: 250, spread: 0.6 },
|
|
61039
|
-
hunter: { advancement: 0.95, capture: 1.45, safety: 0.9, power: 1.05, center: 0.95, unlock: 0.95, reply: 1, randomness: 90, spread: 0.3 },
|
|
61040
|
-
guardian: { advancement: 0.88, capture: 1, safety: 1.45, power: 0.85, center: 1.05, unlock: 1, reply: 1.15, randomness: 70, spread: 0.26 },
|
|
61041
|
-
jumper: { advancement: 1.12, capture: 1, safety: 0.92, power: 1.42, center: 1.18, unlock: 1.08, reply: 0.95, randomness: 95, spread: 0.32 },
|
|
61042
|
-
strategist: { advancement: 1.05, capture: 1.08, safety: 1.22, power: 1.08, center: 1.16, unlock: 1.1, reply: 1.25, randomness: 22, spread: 0.14 },
|
|
61043
|
-
predator: { advancement: 0.98, capture: 1.68, safety: 1.02, power: 1.34, center: 1, unlock: 1, reply: 1.12, randomness: 28, spread: 0.16 },
|
|
61044
|
-
sprinter: { advancement: 1.72, capture: 0.9, safety: 0.95, power: 1.08, center: 0.86, unlock: 1.18, reply: 1, randomness: 26, spread: 0.15 },
|
|
61045
|
-
sentinel: { advancement: 0.9, capture: 1.12, safety: 1.72, power: 0.95, center: 1.28, unlock: 1.05, reply: 1.38, randomness: 18, spread: 0.12 },
|
|
61134
|
+
explorer: { advancement: 1.05, capture: 0.82, safety: 0.62, power: 0.8, center: 1.15, unlock: 1.05, reply: 0.7, randomness: 260, spread: 0.68, mobility: 0.75, trap: 0.5, endgame: 0.55 },
|
|
61135
|
+
impulsive: { advancement: 0.9, capture: 1.45, safety: 0.48, power: 1.15, center: 0.8, unlock: 0.9, reply: 0.55, randomness: 290, spread: 0.62, mobility: 0.85, trap: 0.62, endgame: 0.5 },
|
|
61136
|
+
runner: { advancement: 1.55, capture: 0.78, safety: 0.5, power: 0.95, center: 0.7, unlock: 1.1, reply: 0.55, randomness: 250, spread: 0.6, mobility: 0.72, trap: 0.45, endgame: 1.1 },
|
|
61137
|
+
hunter: { advancement: 0.95, capture: 1.45, safety: 0.9, power: 1.05, center: 0.95, unlock: 0.95, reply: 1, randomness: 90, spread: 0.3, mobility: 0.95, trap: 0.82, endgame: 0.76 },
|
|
61138
|
+
guardian: { advancement: 0.88, capture: 1, safety: 1.45, power: 0.85, center: 1.05, unlock: 1, reply: 1.15, randomness: 70, spread: 0.26, mobility: 0.82, trap: 0.72, endgame: 0.72 },
|
|
61139
|
+
jumper: { advancement: 1.12, capture: 1, safety: 0.92, power: 1.42, center: 1.18, unlock: 1.08, reply: 0.95, randomness: 95, spread: 0.32, mobility: 1.15, trap: 0.9, endgame: 0.82 },
|
|
61140
|
+
strategist: { advancement: 1.05, capture: 1.08, safety: 1.22, power: 1.08, center: 1.16, unlock: 1.1, reply: 1.25, randomness: 22, spread: 0.14, mobility: 1.08, trap: 1.06, endgame: 1 },
|
|
61141
|
+
predator: { advancement: 0.98, capture: 1.68, safety: 1.02, power: 1.34, center: 1, unlock: 1, reply: 1.12, randomness: 28, spread: 0.16, mobility: 1.02, trap: 1.18, endgame: 0.82 },
|
|
61142
|
+
sprinter: { advancement: 1.72, capture: 0.9, safety: 0.95, power: 1.08, center: 0.86, unlock: 1.18, reply: 1, randomness: 26, spread: 0.15, mobility: 0.95, trap: 0.78, endgame: 1.42 },
|
|
61143
|
+
sentinel: { advancement: 0.9, capture: 1.12, safety: 1.72, power: 0.95, center: 1.28, unlock: 1.05, reply: 1.38, randomness: 18, spread: 0.12, mobility: 0.86, trap: 1.04, endgame: 0.84 },
|
|
61144
|
+
oracle: { advancement: 1, capture: 1.12, safety: 1.42, power: 1.1, center: 1.18, unlock: 1.08, reply: 1.8, randomness: 8, spread: 0.08, mobility: 1.06, trap: 1.22, endgame: 1.08 },
|
|
61145
|
+
ambusher: { advancement: 0.9, capture: 1.48, safety: 1.08, power: 1.46, center: 1.05, unlock: 1.02, reply: 1.32, randomness: 14, spread: 0.1, mobility: 1.12, trap: 1.72, endgame: 0.92 },
|
|
61146
|
+
locksmith: { advancement: 0.88, capture: 1.04, safety: 1.55, power: 1.02, center: 1.48, unlock: 1.12, reply: 1.52, randomness: 12, spread: 0.1, mobility: 1.58, trap: 1.24, endgame: 0.86 },
|
|
61147
|
+
storm: { advancement: 1.18, capture: 1.38, safety: 0.98, power: 1.62, center: 1.08, unlock: 1.18, reply: 1.22, randomness: 18, spread: 0.13, mobility: 1.36, trap: 1.28, endgame: 1.02 },
|
|
61148
|
+
matriarch: { advancement: 0.96, capture: 1.18, safety: 1.64, power: 1.18, center: 1.22, unlock: 1.08, reply: 1.66, randomness: 10, spread: 0.08, mobility: 1.02, trap: 1.36, endgame: 1 },
|
|
61149
|
+
endgame: { advancement: 1.46, capture: 1, safety: 1.28, power: 1.04, center: 0.94, unlock: 1.08, reply: 1.44, randomness: 10, spread: 0.09, mobility: 0.98, trap: 1.02, endgame: 1.86 },
|
|
61046
61150
|
};
|
|
61047
61151
|
const DEFAULT_BOT_PROFILE_BY_DIFFICULTY = {
|
|
61048
61152
|
easy: 'explorer',
|
|
@@ -61128,8 +61232,17 @@ function chooseChessimalsBotMove(state, difficulty = 'normal', profileId = DEFAU
|
|
|
61128
61232
|
if (moves.length === 0)
|
|
61129
61233
|
return undefined;
|
|
61130
61234
|
const style = BOT_STYLES[profileId] ?? BOT_STYLES[DEFAULT_BOT_PROFILE_BY_DIFFICULTY[difficulty]];
|
|
61131
|
-
const
|
|
61132
|
-
.map((move) => ({ move, score:
|
|
61235
|
+
const quickScored = moves
|
|
61236
|
+
.map((move) => ({ move, score: scoreBotMove(state, move, difficulty, style) }))
|
|
61237
|
+
.sort((a, b) => b.score - a.score);
|
|
61238
|
+
const lookaheadLimit = difficulty === 'hard' ? 32 : difficulty === 'normal' ? 24 : 0;
|
|
61239
|
+
const scored = quickScored
|
|
61240
|
+
.map((item, index) => ({
|
|
61241
|
+
move: item.move,
|
|
61242
|
+
score: index < lookaheadLimit
|
|
61243
|
+
? scoreBotMoveWithLookahead(state, item.move, difficulty, style)
|
|
61244
|
+
: item.score,
|
|
61245
|
+
}))
|
|
61133
61246
|
.sort((a, b) => b.score - a.score);
|
|
61134
61247
|
if (difficulty === 'easy') {
|
|
61135
61248
|
const playable = scored.filter((item) => item.score > -3000);
|
|
@@ -61327,7 +61440,7 @@ function getPowerMoves(state, piece, animal) {
|
|
|
61327
61440
|
const directions = getPowerDirections(animal);
|
|
61328
61441
|
const moves = [];
|
|
61329
61442
|
for (const direction of directions) {
|
|
61330
|
-
for (let distance = 1; distance
|
|
61443
|
+
for (let distance = 1; distance < state.boardSize; distance += 1) {
|
|
61331
61444
|
const target = {
|
|
61332
61445
|
row: piece.position.row + direction.row * distance,
|
|
61333
61446
|
col: piece.position.col + direction.col * distance,
|
|
@@ -61388,7 +61501,7 @@ function getKangarooMoves(state, piece) {
|
|
|
61388
61501
|
}
|
|
61389
61502
|
return moves;
|
|
61390
61503
|
}
|
|
61391
|
-
function scoreBotMove(state, move, difficulty, style) {
|
|
61504
|
+
function scoreBotMove(state, move, difficulty, style, includeTacticalPressure = true) {
|
|
61392
61505
|
const color = state.currentTurn;
|
|
61393
61506
|
const targetPiece = move.capturesPieceId
|
|
61394
61507
|
? activePieces(state).find((piece) => piece.id === move.capturesPieceId)
|
|
@@ -61414,6 +61527,14 @@ function scoreBotMove(state, move, difficulty, style) {
|
|
|
61414
61527
|
score += 14 * style.power;
|
|
61415
61528
|
if (wouldUnlockPower(state, color, move.to))
|
|
61416
61529
|
score += 90 * style.unlock;
|
|
61530
|
+
if (includeTacticalPressure && state.boardSize <= 6) {
|
|
61531
|
+
score += countPowerReachAfterMove(state, move, color) * (difficulty === 'hard' ? 8 : 4) * style.mobility;
|
|
61532
|
+
score += countProtectedThreatsAfterMove(state, move, color) * (difficulty === 'hard' ? 36 : 18) * style.trap;
|
|
61533
|
+
score += scoreEndgamePressure(state, move, color) * style.endgame;
|
|
61534
|
+
}
|
|
61535
|
+
else {
|
|
61536
|
+
score += scoreEndgamePressure(state, move, color) * style.endgame;
|
|
61537
|
+
}
|
|
61417
61538
|
if (difficulty === 'hard' && isSquareVulnerableAfterMove(state, move)) {
|
|
61418
61539
|
score -= (targetPiece ? 80 : 140) * style.safety;
|
|
61419
61540
|
}
|
|
@@ -61444,7 +61565,7 @@ function scoreBotMoveWithLookahead(state, move, difficulty, style) {
|
|
|
61444
61565
|
score += centerControl * (difficulty === 'hard' ? 18 : 10) * style.center;
|
|
61445
61566
|
}
|
|
61446
61567
|
const opponentBestReply = opponentMoves
|
|
61447
|
-
.map((opponentMove) => scoreBotMove(afterMove, opponentMove, difficulty, style))
|
|
61568
|
+
.map((opponentMove) => scoreBotMove(afterMove, opponentMove, difficulty, style, false))
|
|
61448
61569
|
.sort((a, b) => b - a)[0];
|
|
61449
61570
|
if (opponentBestReply) {
|
|
61450
61571
|
const replyWeight = difficulty === 'easy' ? 0.12 : difficulty === 'normal' ? 0.32 : 0.48;
|
|
@@ -61456,6 +61577,34 @@ function scoreBotMoveWithLookahead(state, move, difficulty, style) {
|
|
|
61456
61577
|
}
|
|
61457
61578
|
return score;
|
|
61458
61579
|
}
|
|
61580
|
+
function countPowerReachAfterMove(state, move, color) {
|
|
61581
|
+
try {
|
|
61582
|
+
const afterMove = applyChessimalsMove(state, move);
|
|
61583
|
+
const evaluationState = { ...afterMove, currentTurn: color };
|
|
61584
|
+
return getChessimalsAllLegalMoves(evaluationState, color).filter((nextMove) => nextMove.kind === 'power').length;
|
|
61585
|
+
}
|
|
61586
|
+
catch {
|
|
61587
|
+
return 0;
|
|
61588
|
+
}
|
|
61589
|
+
}
|
|
61590
|
+
function countProtectedThreatsAfterMove(state, move, color) {
|
|
61591
|
+
try {
|
|
61592
|
+
const afterMove = applyChessimalsMove(state, move);
|
|
61593
|
+
const evaluationState = { ...afterMove, currentTurn: color };
|
|
61594
|
+
const ourMoves = getChessimalsAllLegalMoves(evaluationState, color);
|
|
61595
|
+
const enemyPieces = activePieces(afterMove).filter((piece) => piece.color !== color && !piece.captured);
|
|
61596
|
+
return enemyPieces.filter((piece) => ourMoves.some((nextMove) => nextMove.capturesPieceId === piece.id)).length;
|
|
61597
|
+
}
|
|
61598
|
+
catch {
|
|
61599
|
+
return 0;
|
|
61600
|
+
}
|
|
61601
|
+
}
|
|
61602
|
+
function scoreEndgamePressure(state, move, color) {
|
|
61603
|
+
const remainingEnemyPieces = activePieces(state).filter((piece) => piece.color !== color && !piece.captured).length;
|
|
61604
|
+
const urgency = remainingEnemyPieces <= Math.max(2, Math.floor(state.boardSize / 2)) ? 1.6 : 1;
|
|
61605
|
+
const distanceToPromotion = color === 'white' ? move.to.row : state.boardSize - 1 - move.to.row;
|
|
61606
|
+
return Math.max(0, state.boardSize - distanceToPromotion) * 14 * urgency;
|
|
61607
|
+
}
|
|
61459
61608
|
function pickNoisyBotMove(scored, spread) {
|
|
61460
61609
|
if (scored.length === 0)
|
|
61461
61610
|
return undefined;
|
|
@@ -62545,6 +62694,63 @@ const MINI_GAMES_I18N = {
|
|
|
62545
62694
|
bubbleDescription: 'Revienta grupos de burbujas, encadena combos y sube tu puntaje.',
|
|
62546
62695
|
chessimalsTitle: 'Chessimals',
|
|
62547
62696
|
chessimalsDescription: 'Una carrera de peones con cartas de animales y poderes tácticos.',
|
|
62697
|
+
christianityTitle: 'Christianity',
|
|
62698
|
+
christianityDescription: 'Un juego de cartas familiar con líderes, ofrendas y decisiones tácticas.',
|
|
62699
|
+
christianityEyebrow: 'MVP de mesa',
|
|
62700
|
+
christianityTable: 'Mesa de Christianity',
|
|
62701
|
+
christianityTurn: 'Turno',
|
|
62702
|
+
christianityOfferings: 'Ofrendas',
|
|
62703
|
+
christianityHand: 'Mano',
|
|
62704
|
+
christianityOpponentBattle: 'Zona de batalla rival',
|
|
62705
|
+
christianityYourBattle: 'Tu zona de batalla',
|
|
62706
|
+
christianityOpponentHand: 'Mano rival',
|
|
62707
|
+
christianitySharedZone: 'Zona compartida',
|
|
62708
|
+
christianityMatch: 'Match',
|
|
62709
|
+
christianityMatchScore: 'Marcador de match',
|
|
62710
|
+
christianityHistory: 'Historia',
|
|
62711
|
+
christianityDeck: 'Mazo',
|
|
62712
|
+
christianityPlace: 'Lugar',
|
|
62713
|
+
christianityEmpty: 'Vacío',
|
|
62714
|
+
christianityYourHand: 'Tu mano',
|
|
62715
|
+
christianityCost: 'Coste',
|
|
62716
|
+
christianityOfferingCard: 'Ofrenda',
|
|
62717
|
+
christianityCharacterCard: 'Personaje',
|
|
62718
|
+
christianityLeaderCard: 'Líder',
|
|
62719
|
+
christianityHiddenCard: 'Carta oculta',
|
|
62720
|
+
christianityPreviewCard: 'Ver carta',
|
|
62721
|
+
christianityEndTurn: 'Terminar turno',
|
|
62722
|
+
christianityPlayCard: 'Jugar carta',
|
|
62723
|
+
christianityPlayOffering: 'Jugar ofrenda',
|
|
62724
|
+
christianityPlayHere: 'Jugar aquí',
|
|
62725
|
+
christianityReset: 'Reiniciar mock',
|
|
62726
|
+
christianityWaitTurn: 'Espera el turno rival.',
|
|
62727
|
+
christianityChooseTarget: 'Elige un objetivo para atacar.',
|
|
62728
|
+
christianityChooseCharacterTarget: 'El rival tiene personajes: debes atacarlos antes que al líder.',
|
|
62729
|
+
christianityReadyToPlay: 'Puedes jugar esta carta.',
|
|
62730
|
+
christianityChooseSlot: 'Elige una casilla disponible para jugar esta carta.',
|
|
62731
|
+
christianityPlaceOffering: 'Puedes jugar esta ofrenda con el botón de acción.',
|
|
62732
|
+
christianityNeedOfferings: 'Necesitas más ofrendas para jugar esa carta.',
|
|
62733
|
+
christianityChooseCard: 'Elige una carta o un personaje listo para actuar.',
|
|
62734
|
+
christianityLeaderProtected: 'No puedes atacar directamente al líder mientras tenga personajes en batalla.',
|
|
62735
|
+
christianityLeaderBody: 'Si su vida llega a 0, la partida termina.',
|
|
62736
|
+
christianityOfferingReady: 'Lista',
|
|
62737
|
+
christianityOfferingExhausted: 'Agotada',
|
|
62738
|
+
christianityOfferingBody: 'Se agota para pagar costes y vuelve a estar lista al comenzar tu turno.',
|
|
62739
|
+
christianityOfferingNoAbility: 'Esta ofrenda no tiene habilidad activable.',
|
|
62740
|
+
christianityUseAbility: 'Usar',
|
|
62741
|
+
christianityCloseOfferings: 'Cerrar ofrendas',
|
|
62742
|
+
christianityCharacterBody: 'Entra a batalla y debe esperar un turno para atacar.',
|
|
62743
|
+
christianityCharacterReady: 'Listo para atacar.',
|
|
62744
|
+
christianityCharacterExhausted: 'No puede atacar todavía.',
|
|
62745
|
+
christianityCardRemaining: 'carta restante',
|
|
62746
|
+
christianityCardsRemaining: 'cartas restantes',
|
|
62747
|
+
christianityDeckBody: 'El mazo es una pila compartida. Ambos jugadores roban desde aquí, por eso importa adaptarse a lo que aparece y cuidar el ritmo de la partida.',
|
|
62748
|
+
christianityDeckRuleShared: 'Todas las cartas jugables viven en este mazo compartido, incluyendo personajes y ofrendas.',
|
|
62749
|
+
christianityDeckRuleDraw: 'Al comenzar cada turno, el jugador activo roba la primera carta disponible.',
|
|
62750
|
+
christianityDeckRuleEmpty: 'Si el mazo se queda sin cartas, se revisa la condición de victoria por vida al final del turno.',
|
|
62751
|
+
christianityClosePreview: 'Cerrar previsualizacion de carta',
|
|
62752
|
+
christianityCloseHistory: 'Cerrar historia',
|
|
62753
|
+
christianityHistoryEmpty: 'Todavía no hay cartas en historia.',
|
|
62548
62754
|
soonTitle: 'Próximamente',
|
|
62549
62755
|
openGame: 'Jugar',
|
|
62550
62756
|
close: 'Cerrar',
|
|
@@ -62669,10 +62875,10 @@ const MINI_GAMES_I18N = {
|
|
|
62669
62875
|
chessimalsRulePowersTitle: 'Cuándo se activan los poderes',
|
|
62670
62876
|
chessimalsRulePowersBody: 'Tus cartas se desbloquean cuando uno de tus peones cruza la línea central o cuando un peón rival entra en tu mitad del tablero.',
|
|
62671
62877
|
chessimalsRuleCardsTitle: 'Cartas de animales',
|
|
62672
|
-
chessimalsRuleEagle: 'Águila: se mueve
|
|
62673
|
-
chessimalsRuleBull: 'Toro: se mueve
|
|
62878
|
+
chessimalsRuleEagle: 'Águila: se mueve en diagonal por todo el tablero, hacia adelante o atrás, sin entrar a la última fila.',
|
|
62879
|
+
chessimalsRuleBull: 'Toro: se mueve en línea recta por todo el tablero, incluso hacia los lados, sin entrar a la última fila.',
|
|
62674
62880
|
chessimalsRuleKangaroo: 'Canguro: salta en L, como el caballo del ajedrez. Puede saltar por encima de piezas y caer libre o capturar una pieza rival.',
|
|
62675
|
-
chessimalsRuleLion: 'León: se mueve
|
|
62881
|
+
chessimalsRuleLion: 'León: se mueve en cualquier dirección por todo el tablero, sin entrar a la última fila.',
|
|
62676
62882
|
chessimalsRuleLimitsTitle: 'Reglas de equilibrio',
|
|
62677
62883
|
chessimalsRuleLimitsBody: 'Cada carta se usa una sola vez por partida. Ningún poder puede entrar directamente a la última fila: el paso final para ganar siempre debe ser un avance normal.',
|
|
62678
62884
|
chessimalsBoardSize: 'Tamaño del tablero',
|
|
@@ -62785,6 +62991,18 @@ const MINI_GAMES_I18N = {
|
|
|
62785
62991
|
chessimalsBotSprinterBody: 'Optimiza rutas de promoción.',
|
|
62786
62992
|
chessimalsBotSentinel: 'Centinela',
|
|
62787
62993
|
chessimalsBotSentinelBody: 'Defiende sólido y castiga errores.',
|
|
62994
|
+
chessimalsBotOracle: 'Oráculo',
|
|
62995
|
+
chessimalsBotOracleBody: 'Lee respuestas y evita trampas profundas.',
|
|
62996
|
+
chessimalsBotAmbusher: 'Emboscador',
|
|
62997
|
+
chessimalsBotAmbusherBody: 'Prepara capturas dobles con poderes largos.',
|
|
62998
|
+
chessimalsBotLocksmith: 'Cerrajero',
|
|
62999
|
+
chessimalsBotLocksmithBody: 'Cierra el centro y reduce tus rutas.',
|
|
63000
|
+
chessimalsBotStorm: 'Tormenta',
|
|
63001
|
+
chessimalsBotStormBody: 'Usa poderes largos para presionar todo el tablero.',
|
|
63002
|
+
chessimalsBotMatriarch: 'Matriarca',
|
|
63003
|
+
chessimalsBotMatriarchBody: 'Protege su estructura y gana por desgaste.',
|
|
63004
|
+
chessimalsBotEndgame: 'Finalista',
|
|
63005
|
+
chessimalsBotEndgameBody: 'Convierte ventajas pequeñas en promoción.',
|
|
62788
63006
|
chessimalsBotExplorerTendency: 'Tiende a variar rutas, probar el centro y cometer errores suaves.',
|
|
62789
63007
|
chessimalsBotImpulsiveTendency: 'Tiende a capturar rápido, incluso cuando puede quedar expuesto.',
|
|
62790
63008
|
chessimalsBotRunnerTendency: 'Tiende a avanzar hacia la promoción antes que defender.',
|
|
@@ -62795,6 +63013,12 @@ const MINI_GAMES_I18N = {
|
|
|
62795
63013
|
chessimalsBotPredatorTendency: 'Tiende a forzar capturas y usar poderes agresivos.',
|
|
62796
63014
|
chessimalsBotSprinterTendency: 'Tiende a encontrar caminos rápidos de promoción.',
|
|
62797
63015
|
chessimalsBotSentinelTendency: 'Tiende a defender sólido y castigar errores.',
|
|
63016
|
+
chessimalsBotOracleTendency: 'Tiende a anticipar respuestas y elegir jugadas difíciles de refutar.',
|
|
63017
|
+
chessimalsBotAmbusherTendency: 'Tiende a dejar piezas bajo amenaza múltiple antes de capturar.',
|
|
63018
|
+
chessimalsBotLocksmithTendency: 'Tiende a cortar rutas por el centro y dejarte sin buenas casillas.',
|
|
63019
|
+
chessimalsBotStormTendency: 'Tiende a convertir poderes largos en presión desde varios ángulos.',
|
|
63020
|
+
chessimalsBotMatriarchTendency: 'Tiende a conservar piezas y cambiar solo cuando queda mejor.',
|
|
63021
|
+
chessimalsBotEndgameTendency: 'Tiende a simplificar y correr hacia la promoción cuando ve ventaja.',
|
|
62798
63022
|
chessimalsBotReportTitle: 'Reporte del bot',
|
|
62799
63023
|
chessimalsBotReportVs: 'Contra {bot}',
|
|
62800
63024
|
chessimalsBotReportBody: '{outcome}. Hizo {captures} capturas y usó {powers} poderes. {style}',
|
|
@@ -62825,8 +63049,6 @@ const MINI_GAMES_I18N = {
|
|
|
62825
63049
|
chessimalsChallengeNewRecord: 'Nueva mejor marca',
|
|
62826
63050
|
chessimalsChallengeNextRival: 'Siguiente rival',
|
|
62827
63051
|
chessimalsChallengeNextRivalLabel: 'Próximo rival',
|
|
62828
|
-
chessimalsChallengeRetryRival: 'Reintentar rival',
|
|
62829
|
-
chessimalsChallengeRetryRivalLabel: 'Mismo rival',
|
|
62830
63052
|
chessimalsChallengePlayAgain: 'Jugar desafío otra vez',
|
|
62831
63053
|
chessimalsChallengePowersUsed: 'Poderes',
|
|
62832
63054
|
chessimalsChallengePowerCaptures: 'Capturas poder',
|
|
@@ -62889,7 +63111,7 @@ const MINI_GAMES_I18N = {
|
|
|
62889
63111
|
chessimalsTutorialStep4Title: 'Devuelve el turno',
|
|
62890
63112
|
chessimalsTutorialStep4Body: 'Mueve el peón negro de la columna F una casilla hacia abajo para continuar.',
|
|
62891
63113
|
chessimalsTutorialStep5Title: 'Usa el poder Canguro',
|
|
62892
|
-
chessimalsTutorialStep5Body: 'Selecciona la carta Canguro y salta en L para capturar el peón negro.',
|
|
63114
|
+
chessimalsTutorialStep5Body: 'Selecciona la carta Canguro y salta en L para capturar el peón negro. Las otras cartas pueden cruzar todo el tablero, pero ningún poder puede entrar a la última fila.',
|
|
62893
63115
|
chessimalsTutorialStep6Title: 'Prepara la llegada',
|
|
62894
63116
|
chessimalsTutorialStep6Body: 'Mueve el último peón negro hacia abajo. Después tendrás camino para ganar.',
|
|
62895
63117
|
chessimalsTutorialStep7Title: 'Llega a la última fila',
|
|
@@ -62953,6 +63175,63 @@ const MINI_GAMES_I18N = {
|
|
|
62953
63175
|
bubbleDescription: 'Pop bubble groups, chain combos, and push your score higher.',
|
|
62954
63176
|
chessimalsTitle: 'Chessimals',
|
|
62955
63177
|
chessimalsDescription: 'A pawn race with animal cards and tactical powers.',
|
|
63178
|
+
christianityTitle: 'Christianity',
|
|
63179
|
+
christianityDescription: 'A family card game with leaders, offerings, and tactical choices.',
|
|
63180
|
+
christianityEyebrow: 'Table MVP',
|
|
63181
|
+
christianityTable: 'Christianity table',
|
|
63182
|
+
christianityTurn: 'Turn',
|
|
63183
|
+
christianityOfferings: 'Offerings',
|
|
63184
|
+
christianityHand: 'Hand',
|
|
63185
|
+
christianityOpponentBattle: 'Opponent battle zone',
|
|
63186
|
+
christianityYourBattle: 'Your battle zone',
|
|
63187
|
+
christianityOpponentHand: 'Opponent hand',
|
|
63188
|
+
christianitySharedZone: 'Shared zone',
|
|
63189
|
+
christianityMatch: 'Match',
|
|
63190
|
+
christianityMatchScore: 'Match score',
|
|
63191
|
+
christianityHistory: 'History',
|
|
63192
|
+
christianityDeck: 'Deck',
|
|
63193
|
+
christianityPlace: 'Place',
|
|
63194
|
+
christianityEmpty: 'Empty',
|
|
63195
|
+
christianityYourHand: 'Your hand',
|
|
63196
|
+
christianityCost: 'Cost',
|
|
63197
|
+
christianityOfferingCard: 'Offering',
|
|
63198
|
+
christianityCharacterCard: 'Character',
|
|
63199
|
+
christianityLeaderCard: 'Leader',
|
|
63200
|
+
christianityHiddenCard: 'Hidden card',
|
|
63201
|
+
christianityPreviewCard: 'Preview card',
|
|
63202
|
+
christianityEndTurn: 'End turn',
|
|
63203
|
+
christianityPlayCard: 'Play card',
|
|
63204
|
+
christianityPlayOffering: 'Play offering',
|
|
63205
|
+
christianityPlayHere: 'Play here',
|
|
63206
|
+
christianityReset: 'Reset mock',
|
|
63207
|
+
christianityWaitTurn: 'Wait for the opponent turn.',
|
|
63208
|
+
christianityChooseTarget: 'Choose a target to attack.',
|
|
63209
|
+
christianityChooseCharacterTarget: 'The opponent has characters: attack them before the leader.',
|
|
63210
|
+
christianityReadyToPlay: 'You can play this card.',
|
|
63211
|
+
christianityChooseSlot: 'Choose an available slot to play this card.',
|
|
63212
|
+
christianityPlaceOffering: 'You can play this offering with the action button.',
|
|
63213
|
+
christianityNeedOfferings: 'You need more offerings to play that card.',
|
|
63214
|
+
christianityChooseCard: 'Choose a card or a ready character.',
|
|
63215
|
+
christianityLeaderProtected: 'You cannot attack the leader directly while they have characters in battle.',
|
|
63216
|
+
christianityLeaderBody: 'If this leader reaches 0 life, the game ends.',
|
|
63217
|
+
christianityOfferingReady: 'Ready',
|
|
63218
|
+
christianityOfferingExhausted: 'Exhausted',
|
|
63219
|
+
christianityOfferingBody: 'Exhaust it to pay costs. It readies again at the start of your turn.',
|
|
63220
|
+
christianityOfferingNoAbility: 'This offering has no active ability.',
|
|
63221
|
+
christianityUseAbility: 'Use',
|
|
63222
|
+
christianityCloseOfferings: 'Close offerings',
|
|
63223
|
+
christianityCharacterBody: 'Enters battle and must wait one turn before attacking.',
|
|
63224
|
+
christianityCharacterReady: 'Ready to attack.',
|
|
63225
|
+
christianityCharacterExhausted: 'Cannot attack yet.',
|
|
63226
|
+
christianityCardRemaining: 'card remaining',
|
|
63227
|
+
christianityCardsRemaining: 'cards remaining',
|
|
63228
|
+
christianityDeckBody: 'The deck is a shared pile. Both players draw from it, so the match rewards adapting to what appears and managing the pace.',
|
|
63229
|
+
christianityDeckRuleShared: 'All playable cards live in this shared deck, including characters and offerings.',
|
|
63230
|
+
christianityDeckRuleDraw: 'At the start of each turn, the active player draws the first available card.',
|
|
63231
|
+
christianityDeckRuleEmpty: 'If the deck runs out, the leader life victory condition is checked at the end of the turn.',
|
|
63232
|
+
christianityClosePreview: 'Close card preview',
|
|
63233
|
+
christianityCloseHistory: 'Close history',
|
|
63234
|
+
christianityHistoryEmpty: 'There are no cards in history yet.',
|
|
62956
63235
|
soonTitle: 'Coming soon',
|
|
62957
63236
|
openGame: 'Play',
|
|
62958
63237
|
close: 'Close',
|
|
@@ -63077,10 +63356,10 @@ const MINI_GAMES_I18N = {
|
|
|
63077
63356
|
chessimalsRulePowersTitle: 'When powers unlock',
|
|
63078
63357
|
chessimalsRulePowersBody: 'Your cards unlock when one of your pawns crosses the center line, or when a rival pawn enters your half of the board.',
|
|
63079
63358
|
chessimalsRuleCardsTitle: 'Animal cards',
|
|
63080
|
-
chessimalsRuleEagle: 'Eagle: moves
|
|
63081
|
-
chessimalsRuleBull: 'Bull: moves
|
|
63359
|
+
chessimalsRuleEagle: 'Eagle: moves diagonally across the whole board, forward or backward, without entering the final row.',
|
|
63360
|
+
chessimalsRuleBull: 'Bull: moves in a straight line across the whole board, including sideways, without entering the final row.',
|
|
63082
63361
|
chessimalsRuleKangaroo: 'Kangaroo: jumps in an L shape, like a chess knight. It can jump over pieces and land on an empty square or capture a rival piece.',
|
|
63083
|
-
chessimalsRuleLion: 'Lion: moves
|
|
63362
|
+
chessimalsRuleLion: 'Lion: moves in any direction across the whole board, without entering the final row.',
|
|
63084
63363
|
chessimalsRuleLimitsTitle: 'Balance rules',
|
|
63085
63364
|
chessimalsRuleLimitsBody: 'Each card can be used once per game. No power can land directly on the final row: the winning step must always be a normal forward move.',
|
|
63086
63365
|
chessimalsBoardSize: 'Board size',
|
|
@@ -63193,6 +63472,18 @@ const MINI_GAMES_I18N = {
|
|
|
63193
63472
|
chessimalsBotSprinterBody: 'Optimizes promotion routes.',
|
|
63194
63473
|
chessimalsBotSentinel: 'Sentinel',
|
|
63195
63474
|
chessimalsBotSentinelBody: 'Defends solidly and punishes mistakes.',
|
|
63475
|
+
chessimalsBotOracle: 'Oracle',
|
|
63476
|
+
chessimalsBotOracleBody: 'Reads replies and avoids deep traps.',
|
|
63477
|
+
chessimalsBotAmbusher: 'Ambusher',
|
|
63478
|
+
chessimalsBotAmbusherBody: 'Sets up double captures with long powers.',
|
|
63479
|
+
chessimalsBotLocksmith: 'Locksmith',
|
|
63480
|
+
chessimalsBotLocksmithBody: 'Closes the center and reduces your routes.',
|
|
63481
|
+
chessimalsBotStorm: 'Storm',
|
|
63482
|
+
chessimalsBotStormBody: 'Uses long powers to pressure the whole board.',
|
|
63483
|
+
chessimalsBotMatriarch: 'Matriarch',
|
|
63484
|
+
chessimalsBotMatriarchBody: 'Protects structure and wins by attrition.',
|
|
63485
|
+
chessimalsBotEndgame: 'Endgame',
|
|
63486
|
+
chessimalsBotEndgameBody: 'Turns small edges into promotion.',
|
|
63196
63487
|
chessimalsBotExplorerTendency: 'Tends to vary routes, test the center, and make soft mistakes.',
|
|
63197
63488
|
chessimalsBotImpulsiveTendency: 'Tends to capture quickly, even when it can become exposed.',
|
|
63198
63489
|
chessimalsBotRunnerTendency: 'Tends to push toward promotion before defending.',
|
|
@@ -63203,6 +63494,12 @@ const MINI_GAMES_I18N = {
|
|
|
63203
63494
|
chessimalsBotPredatorTendency: 'Tends to force captures and use aggressive powers.',
|
|
63204
63495
|
chessimalsBotSprinterTendency: 'Tends to find fast promotion paths.',
|
|
63205
63496
|
chessimalsBotSentinelTendency: 'Tends to defend solidly and punish mistakes.',
|
|
63497
|
+
chessimalsBotOracleTendency: 'Tends to anticipate replies and choose hard-to-refute moves.',
|
|
63498
|
+
chessimalsBotAmbusherTendency: 'Tends to leave pieces under multiple threats before capturing.',
|
|
63499
|
+
chessimalsBotLocksmithTendency: 'Tends to close central routes and leave you without good squares.',
|
|
63500
|
+
chessimalsBotStormTendency: 'Tends to turn long powers into pressure from several angles.',
|
|
63501
|
+
chessimalsBotMatriarchTendency: 'Tends to preserve pieces and trade only when it improves.',
|
|
63502
|
+
chessimalsBotEndgameTendency: 'Tends to simplify and race toward promotion when ahead.',
|
|
63206
63503
|
chessimalsBotReportTitle: 'Bot report',
|
|
63207
63504
|
chessimalsBotReportVs: 'Against {bot}',
|
|
63208
63505
|
chessimalsBotReportBody: '{outcome}. It made {captures} captures and used {powers} powers. {style}',
|
|
@@ -63233,8 +63530,6 @@ const MINI_GAMES_I18N = {
|
|
|
63233
63530
|
chessimalsChallengeNewRecord: 'New personal best',
|
|
63234
63531
|
chessimalsChallengeNextRival: 'Next rival',
|
|
63235
63532
|
chessimalsChallengeNextRivalLabel: 'Next rival',
|
|
63236
|
-
chessimalsChallengeRetryRival: 'Retry rival',
|
|
63237
|
-
chessimalsChallengeRetryRivalLabel: 'Same rival',
|
|
63238
63533
|
chessimalsChallengePlayAgain: 'Play challenge again',
|
|
63239
63534
|
chessimalsChallengePowersUsed: 'Powers',
|
|
63240
63535
|
chessimalsChallengePowerCaptures: 'Power captures',
|
|
@@ -63297,7 +63592,7 @@ const MINI_GAMES_I18N = {
|
|
|
63297
63592
|
chessimalsTutorialStep4Title: 'Return the turn',
|
|
63298
63593
|
chessimalsTutorialStep4Body: 'Move the black pawn on file F one square downward to continue.',
|
|
63299
63594
|
chessimalsTutorialStep5Title: 'Use the Kangaroo power',
|
|
63300
|
-
chessimalsTutorialStep5Body: 'Select the Kangaroo card and jump in an L shape to capture the black pawn.',
|
|
63595
|
+
chessimalsTutorialStep5Body: 'Select the Kangaroo card and jump in an L shape to capture the black pawn. The other cards can cross the whole board, but no power can enter the final row.',
|
|
63301
63596
|
chessimalsTutorialStep6Title: 'Prepare the finish',
|
|
63302
63597
|
chessimalsTutorialStep6Body: 'Move the last black pawn downward. Then your path to win is open.',
|
|
63303
63598
|
chessimalsTutorialStep7Title: 'Reach the last row',
|
|
@@ -64480,6 +64775,7 @@ class ChessimalsGameComponent {
|
|
|
64480
64775
|
});
|
|
64481
64776
|
this.botThinking = signal(false);
|
|
64482
64777
|
this.confirmAction = signal(undefined);
|
|
64778
|
+
this.confirmedAction = signal(undefined);
|
|
64483
64779
|
this.onlineJoinCode = signal('');
|
|
64484
64780
|
this.onlineLoading = signal(false);
|
|
64485
64781
|
this.onlineAction = signal(undefined);
|
|
@@ -65174,7 +65470,6 @@ class ChessimalsGameComponent {
|
|
|
65174
65470
|
const roundStats = this.createChallengeRoundStats(game);
|
|
65175
65471
|
const nextLives = won ? run.livesRemaining : Math.max(0, run.livesRemaining - 1);
|
|
65176
65472
|
const nextStreak = won ? run.currentStreak + 1 : 0;
|
|
65177
|
-
const nextRound = won ? Math.min(this.challengeLadder.length, run.currentRound + 1) : run.currentRound;
|
|
65178
65473
|
const completed = won && run.currentRound >= this.challengeLadder.length;
|
|
65179
65474
|
const failed = !won && nextLives <= 0;
|
|
65180
65475
|
const finishedAt = new Date().toISOString();
|
|
@@ -65195,7 +65490,7 @@ class ChessimalsGameComponent {
|
|
|
65195
65490
|
losses: run.losses + (won ? 0 : 1),
|
|
65196
65491
|
currentStreak: nextStreak,
|
|
65197
65492
|
bestStreakInRun: Math.max(run.bestStreakInRun, nextStreak),
|
|
65198
|
-
currentRound: completed || failed ? run.currentRound :
|
|
65493
|
+
currentRound: completed || failed ? run.currentRound : Math.min(this.challengeLadder.length, run.currentRound + 1),
|
|
65199
65494
|
roundResults: [...run.roundResults, roundResult],
|
|
65200
65495
|
updatedAt: finishedAt,
|
|
65201
65496
|
finishedAt: completed || failed ? finishedAt : undefined,
|
|
@@ -65458,13 +65753,12 @@ class ChessimalsGameComponent {
|
|
|
65458
65753
|
closeConfirmModal() {
|
|
65459
65754
|
this.confirmAction.set(undefined);
|
|
65460
65755
|
}
|
|
65461
|
-
|
|
65462
|
-
if (token !== 'confirm') {
|
|
65463
|
-
this.closeConfirmModal();
|
|
65464
|
-
return;
|
|
65465
|
-
}
|
|
65466
|
-
const action = this.confirmAction();
|
|
65756
|
+
handleConfirmModalDismissed() {
|
|
65467
65757
|
this.confirmAction.set(undefined);
|
|
65758
|
+
const action = this.confirmedAction();
|
|
65759
|
+
this.confirmedAction.set(undefined);
|
|
65760
|
+
if (!action)
|
|
65761
|
+
return;
|
|
65468
65762
|
if (action === 'restart') {
|
|
65469
65763
|
this.restartGame();
|
|
65470
65764
|
return;
|
|
@@ -65486,6 +65780,15 @@ class ChessimalsGameComponent {
|
|
|
65486
65780
|
this.createNewChallengeRun();
|
|
65487
65781
|
}
|
|
65488
65782
|
}
|
|
65783
|
+
confirmPendingAction(token) {
|
|
65784
|
+
if (token !== 'confirm') {
|
|
65785
|
+
this.closeConfirmModal();
|
|
65786
|
+
return;
|
|
65787
|
+
}
|
|
65788
|
+
const action = this.confirmAction();
|
|
65789
|
+
this.confirmedAction.set(action);
|
|
65790
|
+
this.confirmAction.set(undefined);
|
|
65791
|
+
}
|
|
65489
65792
|
resignGame() {
|
|
65490
65793
|
const game = this.game();
|
|
65491
65794
|
if (game.status === 'finished')
|
|
@@ -66449,16 +66752,6 @@ class ChessimalsGameComponent {
|
|
|
66449
66752
|
.replace('{wins}', String(run?.wins ?? 0))
|
|
66450
66753
|
.replace('{powers}', String(this.totalChallengePowers(stats)));
|
|
66451
66754
|
}
|
|
66452
|
-
challengeNextRivalLabel() {
|
|
66453
|
-
return this.challengeLastWon()
|
|
66454
|
-
? this.t('chessimalsChallengeNextRivalLabel')
|
|
66455
|
-
: this.t('chessimalsChallengeRetryRivalLabel');
|
|
66456
|
-
}
|
|
66457
|
-
challengeContinueLabel() {
|
|
66458
|
-
return this.challengeLastWon()
|
|
66459
|
-
? this.t('chessimalsChallengeNextRival')
|
|
66460
|
-
: this.t('chessimalsChallengeRetryRival');
|
|
66461
|
-
}
|
|
66462
66755
|
challengeHasNewRecord() {
|
|
66463
66756
|
return this.challengeNewRecord();
|
|
66464
66757
|
}
|
|
@@ -67312,7 +67605,7 @@ class ChessimalsGameComponent {
|
|
|
67312
67605
|
<div class="chessimals-challenge-rival chessimals-challenge-rival--next">
|
|
67313
67606
|
<span aria-hidden="true">{{ botProfileAvatar(nextBot.profileId) }}</span>
|
|
67314
67607
|
<div>
|
|
67315
|
-
<small>{{
|
|
67608
|
+
<small>{{ t('chessimalsChallengeNextRivalLabel') }}</small>
|
|
67316
67609
|
<strong>{{ challengeBotName(nextBot) }}</strong>
|
|
67317
67610
|
<p>{{ t(nextBot.introKey) }}</p>
|
|
67318
67611
|
</div>
|
|
@@ -67320,7 +67613,7 @@ class ChessimalsGameComponent {
|
|
|
67320
67613
|
}
|
|
67321
67614
|
@if (challengePhase() === 'between') {
|
|
67322
67615
|
<button class="chessimals-primary" type="button" (click)="continueChallenge()">
|
|
67323
|
-
{{
|
|
67616
|
+
{{ t('chessimalsChallengeNextRival') }}
|
|
67324
67617
|
</button>
|
|
67325
67618
|
} @else {
|
|
67326
67619
|
<button class="chessimals-primary" type="button" (click)="startChallenge()">
|
|
@@ -67577,7 +67870,7 @@ class ChessimalsGameComponent {
|
|
|
67577
67870
|
<ion-modal
|
|
67578
67871
|
[isOpen]="!!confirmAction()"
|
|
67579
67872
|
cssClass="val-modal-adaptive"
|
|
67580
|
-
(didDismiss)="
|
|
67873
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
67581
67874
|
>
|
|
67582
67875
|
<ng-template>
|
|
67583
67876
|
<val-modal-layout
|
|
@@ -68273,7 +68566,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
68273
68566
|
<div class="chessimals-challenge-rival chessimals-challenge-rival--next">
|
|
68274
68567
|
<span aria-hidden="true">{{ botProfileAvatar(nextBot.profileId) }}</span>
|
|
68275
68568
|
<div>
|
|
68276
|
-
<small>{{
|
|
68569
|
+
<small>{{ t('chessimalsChallengeNextRivalLabel') }}</small>
|
|
68277
68570
|
<strong>{{ challengeBotName(nextBot) }}</strong>
|
|
68278
68571
|
<p>{{ t(nextBot.introKey) }}</p>
|
|
68279
68572
|
</div>
|
|
@@ -68281,7 +68574,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
68281
68574
|
}
|
|
68282
68575
|
@if (challengePhase() === 'between') {
|
|
68283
68576
|
<button class="chessimals-primary" type="button" (click)="continueChallenge()">
|
|
68284
|
-
{{
|
|
68577
|
+
{{ t('chessimalsChallengeNextRival') }}
|
|
68285
68578
|
</button>
|
|
68286
68579
|
} @else {
|
|
68287
68580
|
<button class="chessimals-primary" type="button" (click)="startChallenge()">
|
|
@@ -68538,7 +68831,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
68538
68831
|
<ion-modal
|
|
68539
68832
|
[isOpen]="!!confirmAction()"
|
|
68540
68833
|
cssClass="val-modal-adaptive"
|
|
68541
|
-
(didDismiss)="
|
|
68834
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
68542
68835
|
>
|
|
68543
68836
|
<ng-template>
|
|
68544
68837
|
<val-modal-layout
|
|
@@ -68564,6 +68857,1735 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
68564
68857
|
type: Input
|
|
68565
68858
|
}] } });
|
|
68566
68859
|
|
|
68860
|
+
const STARTER_CARDS = {
|
|
68861
|
+
o_simple: {
|
|
68862
|
+
id: 'o_simple',
|
|
68863
|
+
name: 'Ofrenda simple',
|
|
68864
|
+
type: 'offering',
|
|
68865
|
+
cost: 0,
|
|
68866
|
+
attack: 0,
|
|
68867
|
+
life: 1,
|
|
68868
|
+
verseText: 'Una ofrenda sencilla queda lista para sostener tus siguientes jugadas.',
|
|
68869
|
+
scripture: 'Genesis 4:4',
|
|
68870
|
+
edition: 'GEN',
|
|
68871
|
+
collectorNumber: '001/020',
|
|
68872
|
+
year: '2026',
|
|
68873
|
+
author: 'MVP',
|
|
68874
|
+
rarity: 'normal',
|
|
68875
|
+
},
|
|
68876
|
+
o_forbidden: {
|
|
68877
|
+
id: 'o_forbidden',
|
|
68878
|
+
name: 'El fruto prohibido',
|
|
68879
|
+
type: 'offering',
|
|
68880
|
+
cost: 0,
|
|
68881
|
+
attack: 0,
|
|
68882
|
+
life: 2,
|
|
68883
|
+
abilityName: 'Conocimiento del bien y del mal',
|
|
68884
|
+
abilityText: 'Al usarla, disminuye en 1 los puntos de vida de tu Líder.',
|
|
68885
|
+
abilityCost: 0,
|
|
68886
|
+
verseText: 'Dios el Señor puso al hombre en el jardín de Edén para que lo labrara y lo cuidara.',
|
|
68887
|
+
scripture: 'Genesis 2:17 NBV',
|
|
68888
|
+
edition: 'GEN',
|
|
68889
|
+
collectorNumber: '012/180',
|
|
68890
|
+
year: '2026',
|
|
68891
|
+
author: 'MVP',
|
|
68892
|
+
rarity: 'uncommon',
|
|
68893
|
+
},
|
|
68894
|
+
p_scout: {
|
|
68895
|
+
id: 'p_scout',
|
|
68896
|
+
name: 'Scout',
|
|
68897
|
+
type: 'character',
|
|
68898
|
+
cost: 1,
|
|
68899
|
+
attack: 1,
|
|
68900
|
+
life: 1,
|
|
68901
|
+
verseText: 'Un explorador humilde abre camino antes de que llegue la batalla.',
|
|
68902
|
+
scripture: 'Genesis 13:17',
|
|
68903
|
+
edition: 'GEN',
|
|
68904
|
+
collectorNumber: '002/020',
|
|
68905
|
+
year: '2026',
|
|
68906
|
+
author: 'MVP',
|
|
68907
|
+
rarity: 'normal',
|
|
68908
|
+
},
|
|
68909
|
+
p_guard: { id: 'p_guard', name: 'Guard', type: 'character', cost: 2, attack: 1, life: 3, edition: 'GEN', collectorNumber: '003/020', year: '2026', author: 'MVP', rarity: 'normal' },
|
|
68910
|
+
p_warrior: { id: 'p_warrior', name: 'Warrior', type: 'character', cost: 2, attack: 2, life: 2, edition: 'GEN', collectorNumber: '004/020', year: '2026', author: 'MVP', rarity: 'normal' },
|
|
68911
|
+
p_elder: { id: 'p_elder', name: 'Elder', type: 'character', cost: 3, attack: 2, life: 4, edition: 'GEN', collectorNumber: '005/020', year: '2026', author: 'MVP', rarity: 'uncommon' },
|
|
68912
|
+
p_champion: { id: 'p_champion', name: 'Champion', type: 'character', cost: 4, attack: 4, life: 4, edition: 'GEN', collectorNumber: '006/020', year: '2026', author: 'MVP', rarity: 'rare' },
|
|
68913
|
+
};
|
|
68914
|
+
const STARTING_SHARED_DECK = [
|
|
68915
|
+
'o_simple',
|
|
68916
|
+
'p_scout',
|
|
68917
|
+
'o_forbidden',
|
|
68918
|
+
'o_simple',
|
|
68919
|
+
'p_guard',
|
|
68920
|
+
'p_warrior',
|
|
68921
|
+
'o_simple',
|
|
68922
|
+
'p_elder',
|
|
68923
|
+
'p_scout',
|
|
68924
|
+
'o_simple',
|
|
68925
|
+
'p_champion',
|
|
68926
|
+
'p_guard',
|
|
68927
|
+
'o_simple',
|
|
68928
|
+
'p_warrior',
|
|
68929
|
+
'p_scout',
|
|
68930
|
+
'o_simple',
|
|
68931
|
+
'p_elder',
|
|
68932
|
+
'p_guard',
|
|
68933
|
+
'o_simple',
|
|
68934
|
+
];
|
|
68935
|
+
const STARTING_GAME = {
|
|
68936
|
+
gameId: 'mock-christianity',
|
|
68937
|
+
status: 'in_progress',
|
|
68938
|
+
mode: 'local_pass',
|
|
68939
|
+
turnOwner: 'P1',
|
|
68940
|
+
revision: 0,
|
|
68941
|
+
turnCount: 1,
|
|
68942
|
+
matchScore: { P1: 1, P2: 0 },
|
|
68943
|
+
sharedDeck: STARTING_SHARED_DECK,
|
|
68944
|
+
historyZone: [],
|
|
68945
|
+
players: {
|
|
68946
|
+
P1: {
|
|
68947
|
+
seat: 'P1',
|
|
68948
|
+
displayName: 'Jugador',
|
|
68949
|
+
avatar: 'J',
|
|
68950
|
+
avatarColor: '#2563eb',
|
|
68951
|
+
leaderName: 'Adam',
|
|
68952
|
+
leaderHp: 15,
|
|
68953
|
+
leaderMaxHp: 15,
|
|
68954
|
+
offerings: [
|
|
68955
|
+
{ instanceId: 'p1_offering_001', cardId: 'o_simple', name: 'Ofrenda simple', owner: 'P1', ready: true, value: 1 },
|
|
68956
|
+
{
|
|
68957
|
+
instanceId: 'p1_offering_002',
|
|
68958
|
+
cardId: 'o_forbidden',
|
|
68959
|
+
name: 'El fruto prohibido',
|
|
68960
|
+
owner: 'P1',
|
|
68961
|
+
ready: true,
|
|
68962
|
+
value: 2,
|
|
68963
|
+
abilityName: 'Conocimiento del bien y del mal',
|
|
68964
|
+
abilityText: 'Al usarla, disminuye en 1 los puntos de vida de tu Lider.',
|
|
68965
|
+
abilityCost: 0,
|
|
68966
|
+
},
|
|
68967
|
+
],
|
|
68968
|
+
offeringPlayedThisTurn: false,
|
|
68969
|
+
hand: ['o_simple', 'p_scout', 'p_warrior', 'p_guard'],
|
|
68970
|
+
battleZone: [],
|
|
68971
|
+
},
|
|
68972
|
+
P2: {
|
|
68973
|
+
seat: 'P2',
|
|
68974
|
+
displayName: 'Rival',
|
|
68975
|
+
avatar: 'R',
|
|
68976
|
+
avatarColor: '#b45309',
|
|
68977
|
+
leaderName: 'Noah',
|
|
68978
|
+
leaderHp: 15,
|
|
68979
|
+
leaderMaxHp: 15,
|
|
68980
|
+
offerings: [{ instanceId: 'p2_offering_001', cardId: 'o_simple', name: 'Ofrenda simple', owner: 'P2', ready: true, value: 1 }],
|
|
68981
|
+
offeringPlayedThisTurn: false,
|
|
68982
|
+
handCount: 4,
|
|
68983
|
+
battleZone: [
|
|
68984
|
+
{
|
|
68985
|
+
instanceId: 'opp_001',
|
|
68986
|
+
cardId: 'p_scout',
|
|
68987
|
+
name: 'Scout',
|
|
68988
|
+
owner: 'P2',
|
|
68989
|
+
controller: 'P2',
|
|
68990
|
+
attack: 1,
|
|
68991
|
+
currentHp: 1,
|
|
68992
|
+
maxHp: 1,
|
|
68993
|
+
canAttack: false,
|
|
68994
|
+
},
|
|
68995
|
+
],
|
|
68996
|
+
},
|
|
68997
|
+
},
|
|
68998
|
+
log: ['Partida iniciada.'],
|
|
68999
|
+
};
|
|
69000
|
+
class ChristianityGameComponent {
|
|
69001
|
+
constructor() {
|
|
69002
|
+
this.i18n = inject(I18nService);
|
|
69003
|
+
this.game = signal(structuredClone(STARTING_GAME));
|
|
69004
|
+
this.selectedHandCard = signal(null);
|
|
69005
|
+
this.selectedAttacker = signal(null);
|
|
69006
|
+
this.selectedPreview = signal(null);
|
|
69007
|
+
this.selectedInfo = signal(null);
|
|
69008
|
+
this.previewTilt = signal({ rotateX: 5, rotateY: -5, shiftX: 0, shiftY: 0 });
|
|
69009
|
+
this.hoveredHandIndex = signal(null);
|
|
69010
|
+
this.draggingCardId = signal(null);
|
|
69011
|
+
this.showHistory = signal(false);
|
|
69012
|
+
this.offeringsSeat = signal(null);
|
|
69013
|
+
this.canDropOnBattleSlot = (drag) => {
|
|
69014
|
+
const card = this.cardDefinition(drag.data);
|
|
69015
|
+
return card.type === 'character' && this.canPlay(card);
|
|
69016
|
+
};
|
|
69017
|
+
this.canDropOnOfferings = (drag) => {
|
|
69018
|
+
const card = this.cardDefinition(drag.data);
|
|
69019
|
+
return card.type === 'offering' && this.canPlay(card);
|
|
69020
|
+
};
|
|
69021
|
+
this.player = computed(() => this.game().players.P1);
|
|
69022
|
+
this.opponent = computed(() => this.game().players.P2);
|
|
69023
|
+
this.currentPlayer = computed(() => this.game().players[this.game().turnOwner]);
|
|
69024
|
+
this.isOwnTurn = computed(() => this.game().turnOwner === 'P1');
|
|
69025
|
+
this.hasOpponentGuards = computed(() => this.opponent().battleZone.length > 0);
|
|
69026
|
+
this.opponentHandCount = computed(() => this.opponent().handCount ?? this.opponent().hand?.length ?? 0);
|
|
69027
|
+
this.selectedCardDefinition = computed(() => {
|
|
69028
|
+
const selected = this.selectedHandCard();
|
|
69029
|
+
return selected ? this.cardDefinition(selected) : null;
|
|
69030
|
+
});
|
|
69031
|
+
this.selectedPreviewCard = computed(() => {
|
|
69032
|
+
const cardId = this.selectedPreview()?.cardId;
|
|
69033
|
+
return cardId ? this.cardDefinition(cardId) : null;
|
|
69034
|
+
});
|
|
69035
|
+
this.statusText = computed(() => {
|
|
69036
|
+
const attacker = this.selectedAttacker();
|
|
69037
|
+
const handCard = this.selectedCardDefinition();
|
|
69038
|
+
if (!this.isOwnTurn()) {
|
|
69039
|
+
return this.t('christianityWaitTurn');
|
|
69040
|
+
}
|
|
69041
|
+
if (attacker) {
|
|
69042
|
+
return this.hasOpponentGuards() ? this.t('christianityChooseCharacterTarget') : this.t('christianityChooseTarget');
|
|
69043
|
+
}
|
|
69044
|
+
if (handCard) {
|
|
69045
|
+
if (!this.canPlay(handCard)) {
|
|
69046
|
+
return this.t('christianityNeedOfferings');
|
|
69047
|
+
}
|
|
69048
|
+
return handCard.type === 'offering' ? this.t('christianityPlaceOffering') : this.t('christianityChooseSlot');
|
|
69049
|
+
}
|
|
69050
|
+
return this.t('christianityChooseCard');
|
|
69051
|
+
});
|
|
69052
|
+
this.i18n.registerDefaults('MiniGames', MINI_GAMES_I18N);
|
|
69053
|
+
}
|
|
69054
|
+
t(key) {
|
|
69055
|
+
this.i18n.lang();
|
|
69056
|
+
return this.i18n.t(key, 'MiniGames');
|
|
69057
|
+
}
|
|
69058
|
+
cardDefinition(cardId) {
|
|
69059
|
+
return STARTER_CARDS[cardId] ?? STARTER_CARDS['p_scout'];
|
|
69060
|
+
}
|
|
69061
|
+
cardTypeLabel(card) {
|
|
69062
|
+
return card.type === 'offering' ? this.t('christianityOfferingCard') : this.t('christianityCharacterCard');
|
|
69063
|
+
}
|
|
69064
|
+
battleSlots(seat) {
|
|
69065
|
+
const cards = this.game().players[seat].battleZone;
|
|
69066
|
+
return Array.from({ length: 4 }, (_, index) => ({
|
|
69067
|
+
trackId: cards[index]?.instanceId ?? `${seat}-empty-${index}`,
|
|
69068
|
+
card: cards[index],
|
|
69069
|
+
}));
|
|
69070
|
+
}
|
|
69071
|
+
battleSlotDropId(index) {
|
|
69072
|
+
return `christianity-battle-slot-${index}`;
|
|
69073
|
+
}
|
|
69074
|
+
dropTargetIds() {
|
|
69075
|
+
return ['christianity-offerings-drop', ...this.battleSlots('P1').map((_, index) => this.battleSlotDropId(index))];
|
|
69076
|
+
}
|
|
69077
|
+
hiddenHandCards(count) {
|
|
69078
|
+
return Array.from({ length: count });
|
|
69079
|
+
}
|
|
69080
|
+
fanTransform(index, total, opponent) {
|
|
69081
|
+
if (total <= 1)
|
|
69082
|
+
return 'none';
|
|
69083
|
+
const center = (total - 1) / 2;
|
|
69084
|
+
const offset = index - center;
|
|
69085
|
+
const rotate = offset * (opponent ? 8 : 5);
|
|
69086
|
+
const lift = Math.abs(offset) * 0.25;
|
|
69087
|
+
const hoverLift = opponent ? 0 : this.handWaveLift(index);
|
|
69088
|
+
const scale = opponent ? 1 : this.handWaveScale(index);
|
|
69089
|
+
const fanLift = opponent ? Math.abs(offset) * 0.34 : lift + hoverLift;
|
|
69090
|
+
const fanSpread = opponent ? offset * 0.08 : 0;
|
|
69091
|
+
return `translate(${fanSpread}rem, ${fanLift}rem) rotate(${rotate}deg) scale(${scale})`;
|
|
69092
|
+
}
|
|
69093
|
+
handCardZIndex(index) {
|
|
69094
|
+
const hovered = this.hoveredHandIndex();
|
|
69095
|
+
if (hovered === null)
|
|
69096
|
+
return 2;
|
|
69097
|
+
const distance = Math.abs(index - hovered);
|
|
69098
|
+
return Math.max(2, 8 - distance);
|
|
69099
|
+
}
|
|
69100
|
+
setHoveredHandIndex(index) {
|
|
69101
|
+
this.hoveredHandIndex.set(index);
|
|
69102
|
+
}
|
|
69103
|
+
clearHoveredHandIndex() {
|
|
69104
|
+
this.hoveredHandIndex.set(null);
|
|
69105
|
+
}
|
|
69106
|
+
releaseHoveredHand(event) {
|
|
69107
|
+
if (event.pointerType !== 'mouse') {
|
|
69108
|
+
window.setTimeout(() => this.clearHoveredHandIndex(), 180);
|
|
69109
|
+
}
|
|
69110
|
+
}
|
|
69111
|
+
handWaveLift(index) {
|
|
69112
|
+
const hovered = this.hoveredHandIndex();
|
|
69113
|
+
if (hovered === null)
|
|
69114
|
+
return 0;
|
|
69115
|
+
const distance = Math.abs(index - hovered);
|
|
69116
|
+
if (distance === 0)
|
|
69117
|
+
return -1.15;
|
|
69118
|
+
if (distance === 1)
|
|
69119
|
+
return -0.58;
|
|
69120
|
+
if (distance === 2)
|
|
69121
|
+
return -0.22;
|
|
69122
|
+
return 0;
|
|
69123
|
+
}
|
|
69124
|
+
handWaveScale(index) {
|
|
69125
|
+
const hovered = this.hoveredHandIndex();
|
|
69126
|
+
if (hovered === null)
|
|
69127
|
+
return 1;
|
|
69128
|
+
const distance = Math.abs(index - hovered);
|
|
69129
|
+
if (distance === 0)
|
|
69130
|
+
return 1.06;
|
|
69131
|
+
if (distance === 1)
|
|
69132
|
+
return 1.03;
|
|
69133
|
+
return 1;
|
|
69134
|
+
}
|
|
69135
|
+
readyOfferings(player) {
|
|
69136
|
+
return player.offerings.reduce((total, offering) => total + (offering.ready ? offering.value : 0), 0);
|
|
69137
|
+
}
|
|
69138
|
+
totalOfferings(player) {
|
|
69139
|
+
return player.offerings.reduce((total, offering) => total + offering.value, 0);
|
|
69140
|
+
}
|
|
69141
|
+
canPlay(card) {
|
|
69142
|
+
if (!this.isOwnTurn())
|
|
69143
|
+
return false;
|
|
69144
|
+
if (card.type === 'offering')
|
|
69145
|
+
return !this.player().offeringPlayedThisTurn;
|
|
69146
|
+
return this.readyOfferings(this.player()) >= card.cost && this.player().battleZone.length < 4;
|
|
69147
|
+
}
|
|
69148
|
+
canPlaySelected() {
|
|
69149
|
+
const selected = this.selectedHandCard();
|
|
69150
|
+
return !!selected && this.canPlay(this.cardDefinition(selected));
|
|
69151
|
+
}
|
|
69152
|
+
selectedActionLabel() {
|
|
69153
|
+
const selected = this.selectedCardDefinition();
|
|
69154
|
+
if (!selected)
|
|
69155
|
+
return this.t('christianityPlayCard');
|
|
69156
|
+
return selected.type === 'offering' ? this.t('christianityPlayOffering') : this.t('christianityPlayCard');
|
|
69157
|
+
}
|
|
69158
|
+
selectedActionDisabled() {
|
|
69159
|
+
const selected = this.selectedCardDefinition();
|
|
69160
|
+
if (!selected || !this.canPlay(selected))
|
|
69161
|
+
return true;
|
|
69162
|
+
return selected.type === 'character';
|
|
69163
|
+
}
|
|
69164
|
+
previewActionDisabled() {
|
|
69165
|
+
const preview = this.selectedPreview();
|
|
69166
|
+
if (preview?.source !== 'hand' || !preview.cardId)
|
|
69167
|
+
return true;
|
|
69168
|
+
return !this.canPlay(this.cardDefinition(preview.cardId));
|
|
69169
|
+
}
|
|
69170
|
+
canPlaceSelectedCharacter() {
|
|
69171
|
+
const selected = this.selectedCardDefinition();
|
|
69172
|
+
return !!selected && selected.type === 'character' && this.canPlay(selected);
|
|
69173
|
+
}
|
|
69174
|
+
canPlaceSelectedOffering() {
|
|
69175
|
+
const selected = this.selectedCardDefinition();
|
|
69176
|
+
return !!selected && selected.type === 'offering' && this.canPlay(selected);
|
|
69177
|
+
}
|
|
69178
|
+
isDraggingCharacter() {
|
|
69179
|
+
const cardId = this.draggingCardId();
|
|
69180
|
+
if (!cardId)
|
|
69181
|
+
return false;
|
|
69182
|
+
const card = this.cardDefinition(cardId);
|
|
69183
|
+
return card.type === 'character' && this.canPlay(card);
|
|
69184
|
+
}
|
|
69185
|
+
isDraggingOffering() {
|
|
69186
|
+
const cardId = this.draggingCardId();
|
|
69187
|
+
if (!cardId)
|
|
69188
|
+
return false;
|
|
69189
|
+
const card = this.cardDefinition(cardId);
|
|
69190
|
+
return card.type === 'offering' && this.canPlay(card);
|
|
69191
|
+
}
|
|
69192
|
+
startDraggingCard(cardId) {
|
|
69193
|
+
this.selectedAttacker.set(null);
|
|
69194
|
+
this.selectedHandCard.set(cardId);
|
|
69195
|
+
this.draggingCardId.set(cardId);
|
|
69196
|
+
this.closePreview();
|
|
69197
|
+
}
|
|
69198
|
+
endDraggingCard() {
|
|
69199
|
+
this.draggingCardId.set(null);
|
|
69200
|
+
}
|
|
69201
|
+
dropOnBattleSlot(event, slotIndex) {
|
|
69202
|
+
const card = this.cardDefinition(event.item.data);
|
|
69203
|
+
if (card.type !== 'character')
|
|
69204
|
+
return;
|
|
69205
|
+
this.playCardFromHand(event.item.data, slotIndex);
|
|
69206
|
+
}
|
|
69207
|
+
dropOnOfferings(event) {
|
|
69208
|
+
const card = this.cardDefinition(event.item.data);
|
|
69209
|
+
if (card.type !== 'offering')
|
|
69210
|
+
return;
|
|
69211
|
+
this.playCardFromHand(event.item.data);
|
|
69212
|
+
}
|
|
69213
|
+
selectHandCard(cardId) {
|
|
69214
|
+
const wasSelected = this.selectedHandCard() === cardId;
|
|
69215
|
+
this.selectedAttacker.set(null);
|
|
69216
|
+
this.selectedHandCard.set(wasSelected ? null : cardId);
|
|
69217
|
+
this.closePreview();
|
|
69218
|
+
}
|
|
69219
|
+
playSelectedCard(slotIndex) {
|
|
69220
|
+
const cardId = this.selectedHandCard();
|
|
69221
|
+
if (!cardId)
|
|
69222
|
+
return;
|
|
69223
|
+
this.playCardFromHand(cardId, slotIndex);
|
|
69224
|
+
}
|
|
69225
|
+
playCardFromHand(cardId, slotIndex) {
|
|
69226
|
+
const card = this.cardDefinition(cardId);
|
|
69227
|
+
if (!this.canPlay(card))
|
|
69228
|
+
return;
|
|
69229
|
+
this.game.update(game => {
|
|
69230
|
+
const next = structuredClone(game);
|
|
69231
|
+
const player = next.players.P1;
|
|
69232
|
+
const handIndex = player.hand?.indexOf(cardId) ?? -1;
|
|
69233
|
+
if (handIndex < 0 || !player.hand)
|
|
69234
|
+
return game;
|
|
69235
|
+
player.hand.splice(handIndex, 1);
|
|
69236
|
+
if (card.type === 'offering') {
|
|
69237
|
+
player.offerings.push({
|
|
69238
|
+
instanceId: `p1_offering_${next.revision + 1}`,
|
|
69239
|
+
cardId: card.id,
|
|
69240
|
+
name: card.name,
|
|
69241
|
+
owner: 'P1',
|
|
69242
|
+
ready: true,
|
|
69243
|
+
value: card.life,
|
|
69244
|
+
abilityName: card.abilityName,
|
|
69245
|
+
abilityText: card.abilityText,
|
|
69246
|
+
abilityCost: card.abilityCost,
|
|
69247
|
+
});
|
|
69248
|
+
player.offeringPlayedThisTurn = true;
|
|
69249
|
+
}
|
|
69250
|
+
else {
|
|
69251
|
+
this.spendOfferings(player, card.cost);
|
|
69252
|
+
const insertIndex = Math.min(slotIndex ?? player.battleZone.length, player.battleZone.length);
|
|
69253
|
+
player.battleZone.splice(insertIndex, 0, {
|
|
69254
|
+
instanceId: `p1_${next.revision + 1}_${player.battleZone.length}`,
|
|
69255
|
+
cardId: card.id,
|
|
69256
|
+
name: card.name,
|
|
69257
|
+
owner: 'P1',
|
|
69258
|
+
controller: 'P1',
|
|
69259
|
+
attack: card.attack,
|
|
69260
|
+
currentHp: card.life,
|
|
69261
|
+
maxHp: card.life,
|
|
69262
|
+
canAttack: false,
|
|
69263
|
+
});
|
|
69264
|
+
}
|
|
69265
|
+
next.revision++;
|
|
69266
|
+
next.log = [
|
|
69267
|
+
card.type === 'offering' ? `${card.name} queda lista como ofrenda.` : `${card.name} entra en batalla.`,
|
|
69268
|
+
...next.log,
|
|
69269
|
+
].slice(0, 4);
|
|
69270
|
+
return next;
|
|
69271
|
+
});
|
|
69272
|
+
this.selectedHandCard.set(null);
|
|
69273
|
+
this.draggingCardId.set(null);
|
|
69274
|
+
this.closePreview();
|
|
69275
|
+
}
|
|
69276
|
+
playPreviewCard() {
|
|
69277
|
+
const preview = this.selectedPreview();
|
|
69278
|
+
if (preview?.source !== 'hand' || !preview.cardId)
|
|
69279
|
+
return;
|
|
69280
|
+
const card = this.cardDefinition(preview.cardId);
|
|
69281
|
+
if (!this.canPlay(card))
|
|
69282
|
+
return;
|
|
69283
|
+
this.selectedHandCard.set(preview.cardId);
|
|
69284
|
+
if (card.type === 'character') {
|
|
69285
|
+
this.closePreview();
|
|
69286
|
+
return;
|
|
69287
|
+
}
|
|
69288
|
+
this.playSelectedCard();
|
|
69289
|
+
}
|
|
69290
|
+
handleOfferingPile(seat) {
|
|
69291
|
+
this.openOfferings(seat);
|
|
69292
|
+
}
|
|
69293
|
+
selectAttacker(card) {
|
|
69294
|
+
this.selectedHandCard.set(null);
|
|
69295
|
+
this.inspectCharacter(card);
|
|
69296
|
+
if (!this.isOwnTurn() || !card.canAttack)
|
|
69297
|
+
return;
|
|
69298
|
+
this.selectedAttacker.set(this.selectedAttacker()?.instanceId === card.instanceId ? null : card);
|
|
69299
|
+
}
|
|
69300
|
+
handleOpponentCharacter(card) {
|
|
69301
|
+
this.inspectCharacter(card);
|
|
69302
|
+
if (this.selectedAttacker()) {
|
|
69303
|
+
this.attackCharacter(card);
|
|
69304
|
+
}
|
|
69305
|
+
}
|
|
69306
|
+
handleOpponentLeader() {
|
|
69307
|
+
this.inspectLeader('P2');
|
|
69308
|
+
if (this.selectedAttacker() && !this.hasOpponentGuards()) {
|
|
69309
|
+
this.attackLeader();
|
|
69310
|
+
}
|
|
69311
|
+
}
|
|
69312
|
+
attackLeader() {
|
|
69313
|
+
const attacker = this.selectedAttacker();
|
|
69314
|
+
if (!attacker)
|
|
69315
|
+
return;
|
|
69316
|
+
if (this.hasOpponentGuards()) {
|
|
69317
|
+
this.selectedPreview.set({
|
|
69318
|
+
title: this.opponent().leaderName,
|
|
69319
|
+
eyebrow: this.t('christianityLeaderCard'),
|
|
69320
|
+
meta: `${this.opponent().leaderHp}/${this.opponent().leaderMaxHp}`,
|
|
69321
|
+
body: this.t('christianityLeaderProtected'),
|
|
69322
|
+
});
|
|
69323
|
+
return;
|
|
69324
|
+
}
|
|
69325
|
+
this.game.update(game => {
|
|
69326
|
+
const next = structuredClone(game);
|
|
69327
|
+
const liveAttacker = next.players.P1.battleZone.find(card => card.instanceId === attacker.instanceId);
|
|
69328
|
+
if (!liveAttacker || !liveAttacker.canAttack)
|
|
69329
|
+
return game;
|
|
69330
|
+
next.players.P2.leaderHp = Math.max(0, next.players.P2.leaderHp - liveAttacker.attack);
|
|
69331
|
+
liveAttacker.canAttack = false;
|
|
69332
|
+
next.revision++;
|
|
69333
|
+
next.log = [`${liveAttacker.name} ataca al lider rival.`, ...next.log].slice(0, 4);
|
|
69334
|
+
return next;
|
|
69335
|
+
});
|
|
69336
|
+
this.selectedAttacker.set(null);
|
|
69337
|
+
}
|
|
69338
|
+
attackCharacter(target) {
|
|
69339
|
+
const attacker = this.selectedAttacker();
|
|
69340
|
+
if (!attacker)
|
|
69341
|
+
return;
|
|
69342
|
+
this.game.update(game => {
|
|
69343
|
+
const next = structuredClone(game);
|
|
69344
|
+
const liveAttacker = next.players.P1.battleZone.find(card => card.instanceId === attacker.instanceId);
|
|
69345
|
+
const liveTarget = next.players.P2.battleZone.find(card => card.instanceId === target.instanceId);
|
|
69346
|
+
if (!liveAttacker || !liveTarget || !liveAttacker.canAttack)
|
|
69347
|
+
return game;
|
|
69348
|
+
liveTarget.currentHp -= liveAttacker.attack;
|
|
69349
|
+
liveAttacker.currentHp -= liveTarget.attack;
|
|
69350
|
+
liveAttacker.canAttack = false;
|
|
69351
|
+
this.cleanupDestroyed(next.players.P1, next);
|
|
69352
|
+
this.cleanupDestroyed(next.players.P2, next);
|
|
69353
|
+
next.revision++;
|
|
69354
|
+
next.log = [`${liveAttacker.name} combate contra ${liveTarget.name}.`, ...next.log].slice(0, 4);
|
|
69355
|
+
return next;
|
|
69356
|
+
});
|
|
69357
|
+
this.selectedAttacker.set(null);
|
|
69358
|
+
}
|
|
69359
|
+
endTurn() {
|
|
69360
|
+
this.selectedHandCard.set(null);
|
|
69361
|
+
this.selectedAttacker.set(null);
|
|
69362
|
+
this.selectedPreview.set(null);
|
|
69363
|
+
this.selectedInfo.set(null);
|
|
69364
|
+
this.game.update(game => {
|
|
69365
|
+
const next = structuredClone(game);
|
|
69366
|
+
next.turnOwner = next.turnOwner === 'P1' ? 'P2' : 'P1';
|
|
69367
|
+
next.turnCount++;
|
|
69368
|
+
const current = next.players[next.turnOwner];
|
|
69369
|
+
current.offeringPlayedThisTurn = false;
|
|
69370
|
+
current.offerings = current.offerings.map(offering => ({ ...offering, ready: true }));
|
|
69371
|
+
current.battleZone = current.battleZone.map(card => ({ ...card, canAttack: true }));
|
|
69372
|
+
const drawnCard = next.sharedDeck.shift();
|
|
69373
|
+
if (drawnCard) {
|
|
69374
|
+
if (current.hand) {
|
|
69375
|
+
current.hand.push(drawnCard);
|
|
69376
|
+
}
|
|
69377
|
+
else {
|
|
69378
|
+
current.handCount = (current.handCount ?? 0) + 1;
|
|
69379
|
+
}
|
|
69380
|
+
}
|
|
69381
|
+
next.revision++;
|
|
69382
|
+
next.log = [
|
|
69383
|
+
drawnCard ? `${current.displayName} roba una carta.` : `El mazo esta vacio.`,
|
|
69384
|
+
`Turno de ${current.displayName}.`,
|
|
69385
|
+
...next.log,
|
|
69386
|
+
].slice(0, 4);
|
|
69387
|
+
return next;
|
|
69388
|
+
});
|
|
69389
|
+
}
|
|
69390
|
+
resetMock() {
|
|
69391
|
+
this.game.set(structuredClone(STARTING_GAME));
|
|
69392
|
+
this.selectedHandCard.set(null);
|
|
69393
|
+
this.selectedAttacker.set(null);
|
|
69394
|
+
this.selectedPreview.set(null);
|
|
69395
|
+
this.selectedInfo.set(null);
|
|
69396
|
+
this.showHistory.set(false);
|
|
69397
|
+
this.offeringsSeat.set(null);
|
|
69398
|
+
}
|
|
69399
|
+
closePreview() {
|
|
69400
|
+
this.selectedPreview.set(null);
|
|
69401
|
+
this.resetPreviewTilt();
|
|
69402
|
+
}
|
|
69403
|
+
closeInfo() {
|
|
69404
|
+
this.selectedInfo.set(null);
|
|
69405
|
+
}
|
|
69406
|
+
openOfferings(seat) {
|
|
69407
|
+
this.selectedPreview.set(null);
|
|
69408
|
+
this.selectedInfo.set(null);
|
|
69409
|
+
this.showHistory.set(false);
|
|
69410
|
+
this.offeringsSeat.set(seat);
|
|
69411
|
+
}
|
|
69412
|
+
openHistory() {
|
|
69413
|
+
this.selectedPreview.set(null);
|
|
69414
|
+
this.selectedInfo.set(null);
|
|
69415
|
+
this.offeringsSeat.set(null);
|
|
69416
|
+
this.showHistory.set(true);
|
|
69417
|
+
}
|
|
69418
|
+
closeOfferings() {
|
|
69419
|
+
this.offeringsSeat.set(null);
|
|
69420
|
+
}
|
|
69421
|
+
tiltPreview(event) {
|
|
69422
|
+
const bounds = event.currentTarget.getBoundingClientRect();
|
|
69423
|
+
const x = (event.clientX - bounds.left) / bounds.width - 0.5;
|
|
69424
|
+
const y = (event.clientY - bounds.top) / bounds.height - 0.5;
|
|
69425
|
+
this.previewTilt.set({
|
|
69426
|
+
rotateX: 5 - y * 18,
|
|
69427
|
+
rotateY: -5 + x * 18,
|
|
69428
|
+
shiftX: x * 10,
|
|
69429
|
+
shiftY: y * 10,
|
|
69430
|
+
});
|
|
69431
|
+
}
|
|
69432
|
+
resetPreviewTilt() {
|
|
69433
|
+
this.previewTilt.set({ rotateX: 5, rotateY: -5, shiftX: 0, shiftY: 0 });
|
|
69434
|
+
}
|
|
69435
|
+
cleanupDestroyed(player, game) {
|
|
69436
|
+
const destroyed = player.battleZone.filter(card => card.currentHp <= 0);
|
|
69437
|
+
if (!destroyed.length)
|
|
69438
|
+
return;
|
|
69439
|
+
game.historyZone.push(...destroyed.map(card => card.cardId));
|
|
69440
|
+
player.battleZone = player.battleZone.filter(card => card.currentHp > 0);
|
|
69441
|
+
}
|
|
69442
|
+
inspectLeader(seat) {
|
|
69443
|
+
this.selectedInfo.set(null);
|
|
69444
|
+
const player = this.game().players[seat];
|
|
69445
|
+
this.selectedPreview.set({
|
|
69446
|
+
title: player.leaderName,
|
|
69447
|
+
eyebrow: this.t('christianityLeaderCard'),
|
|
69448
|
+
meta: `${player.leaderHp}/${player.leaderMaxHp}`,
|
|
69449
|
+
body: seat === 'P2' && this.hasOpponentGuards() ? this.t('christianityLeaderProtected') : this.t('christianityLeaderBody'),
|
|
69450
|
+
});
|
|
69451
|
+
}
|
|
69452
|
+
inspectOffering(offering) {
|
|
69453
|
+
this.selectedInfo.set(null);
|
|
69454
|
+
this.selectedPreview.set({
|
|
69455
|
+
title: offering.name,
|
|
69456
|
+
eyebrow: this.t('christianityOfferingCard'),
|
|
69457
|
+
meta: offering.ready ? this.t('christianityOfferingReady') : this.t('christianityOfferingExhausted'),
|
|
69458
|
+
body: offering.abilityText || this.t('christianityOfferingBody'),
|
|
69459
|
+
});
|
|
69460
|
+
}
|
|
69461
|
+
canUseOfferingAbility(offering, seat) {
|
|
69462
|
+
if (seat !== 'P1' || !this.isOwnTurn())
|
|
69463
|
+
return false;
|
|
69464
|
+
if (!offering.ready || !offering.abilityName)
|
|
69465
|
+
return false;
|
|
69466
|
+
return this.readyOfferings(this.game().players[seat]) >= (offering.abilityCost ?? 0);
|
|
69467
|
+
}
|
|
69468
|
+
useOfferingAbility(offering, seat) {
|
|
69469
|
+
if (!this.canUseOfferingAbility(offering, seat))
|
|
69470
|
+
return;
|
|
69471
|
+
this.game.update(game => {
|
|
69472
|
+
const next = structuredClone(game);
|
|
69473
|
+
const player = next.players[seat];
|
|
69474
|
+
const liveOffering = player.offerings.find(card => card.instanceId === offering.instanceId);
|
|
69475
|
+
if (!liveOffering || !liveOffering.ready)
|
|
69476
|
+
return game;
|
|
69477
|
+
const offeringId = liveOffering.instanceId;
|
|
69478
|
+
this.spendOfferings(player, liveOffering.abilityCost ?? 0);
|
|
69479
|
+
player.offerings = player.offerings.map(card => (card.instanceId === offeringId ? { ...card, ready: false } : card));
|
|
69480
|
+
player.leaderHp = Math.max(0, player.leaderHp - 1);
|
|
69481
|
+
next.revision++;
|
|
69482
|
+
next.log = [`${liveOffering.name}: ${liveOffering.abilityName}.`, ...next.log].slice(0, 4);
|
|
69483
|
+
return next;
|
|
69484
|
+
});
|
|
69485
|
+
}
|
|
69486
|
+
inspectDeck() {
|
|
69487
|
+
const remainingCards = this.game().sharedDeck.length;
|
|
69488
|
+
this.selectedPreview.set(null);
|
|
69489
|
+
this.selectedInfo.set({
|
|
69490
|
+
title: this.t('christianityDeck'),
|
|
69491
|
+
eyebrow: this.t('christianitySharedZone'),
|
|
69492
|
+
meta: `${remainingCards} ${remainingCards === 1 ? this.t('christianityCardRemaining') : this.t('christianityCardsRemaining')}`,
|
|
69493
|
+
body: this.t('christianityDeckBody'),
|
|
69494
|
+
facts: [
|
|
69495
|
+
this.t('christianityDeckRuleShared'),
|
|
69496
|
+
this.t('christianityDeckRuleDraw'),
|
|
69497
|
+
this.t('christianityDeckRuleEmpty'),
|
|
69498
|
+
],
|
|
69499
|
+
});
|
|
69500
|
+
}
|
|
69501
|
+
inspectHandCard(cardId, fromHand = false) {
|
|
69502
|
+
this.selectedInfo.set(null);
|
|
69503
|
+
const card = this.cardDefinition(cardId);
|
|
69504
|
+
if (fromHand) {
|
|
69505
|
+
this.selectedAttacker.set(null);
|
|
69506
|
+
this.selectedHandCard.set(cardId);
|
|
69507
|
+
}
|
|
69508
|
+
this.selectedPreview.set({
|
|
69509
|
+
title: card.name,
|
|
69510
|
+
eyebrow: card.type === 'offering' ? this.t('christianityOfferingCard') : this.t('christianityCharacterCard'),
|
|
69511
|
+
meta: card.type === 'offering' ? `+${card.life}` : `${this.t('christianityCost')} ${card.cost} · ${card.attack}/${card.life}`,
|
|
69512
|
+
body: card.type === 'offering' ? this.t('christianityOfferingBody') : this.t('christianityCharacterBody'),
|
|
69513
|
+
cardId,
|
|
69514
|
+
source: fromHand ? 'hand' : 'pile',
|
|
69515
|
+
});
|
|
69516
|
+
}
|
|
69517
|
+
inspectHistoryCard(cardId) {
|
|
69518
|
+
this.showHistory.set(false);
|
|
69519
|
+
this.inspectHandCard(cardId);
|
|
69520
|
+
}
|
|
69521
|
+
inspectCharacter(card) {
|
|
69522
|
+
this.selectedInfo.set(null);
|
|
69523
|
+
this.selectedPreview.set({
|
|
69524
|
+
title: card.name,
|
|
69525
|
+
eyebrow: this.t('christianityCharacterCard'),
|
|
69526
|
+
meta: `${card.attack}/${card.currentHp}`,
|
|
69527
|
+
body: card.canAttack ? this.t('christianityCharacterReady') : this.t('christianityCharacterExhausted'),
|
|
69528
|
+
});
|
|
69529
|
+
}
|
|
69530
|
+
spendOfferings(player, cost) {
|
|
69531
|
+
let remaining = cost;
|
|
69532
|
+
player.offerings = player.offerings.map(offering => {
|
|
69533
|
+
if (remaining <= 0 || !offering.ready)
|
|
69534
|
+
return offering;
|
|
69535
|
+
remaining -= offering.value;
|
|
69536
|
+
return { ...offering, ready: false };
|
|
69537
|
+
});
|
|
69538
|
+
}
|
|
69539
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChristianityGameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
69540
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ChristianityGameComponent, isStandalone: true, selector: "val-christianity-game", ngImport: i0, template: `
|
|
69541
|
+
<main class="christianity-shell">
|
|
69542
|
+
<section class="christianity-header">
|
|
69543
|
+
<div>
|
|
69544
|
+
<p>{{ t('christianityEyebrow') }}</p>
|
|
69545
|
+
<h1>{{ t('christianityTitle') }}</h1>
|
|
69546
|
+
</div>
|
|
69547
|
+
<div class="christianity-turn" [class.is-own-turn]="isOwnTurn()">
|
|
69548
|
+
<span>{{ t('christianityTurn') }}</span>
|
|
69549
|
+
<strong>{{ currentPlayer().displayName }}</strong>
|
|
69550
|
+
</div>
|
|
69551
|
+
</section>
|
|
69552
|
+
|
|
69553
|
+
<section class="christianity-match-strip" [attr.aria-label]="t('christianityMatchScore')">
|
|
69554
|
+
<article class="christianity-match-player">
|
|
69555
|
+
<span class="christianity-avatar" [style.background]="player().avatarColor">{{ player().avatar }}</span>
|
|
69556
|
+
<div>
|
|
69557
|
+
<strong>{{ player().displayName }}</strong>
|
|
69558
|
+
<small>{{ player().leaderName }} · {{ player().leaderHp }}/{{ player().leaderMaxHp }}</small>
|
|
69559
|
+
</div>
|
|
69560
|
+
</article>
|
|
69561
|
+
<div class="christianity-scoreboard">
|
|
69562
|
+
<span>{{ t('christianityMatch') }}</span>
|
|
69563
|
+
<strong>{{ game().matchScore.P1 }}-{{ game().matchScore.P2 }}</strong>
|
|
69564
|
+
</div>
|
|
69565
|
+
<article class="christianity-match-player christianity-match-player--opponent">
|
|
69566
|
+
<span class="christianity-avatar" [style.background]="opponent().avatarColor">{{ opponent().avatar }}</span>
|
|
69567
|
+
<div>
|
|
69568
|
+
<strong>{{ opponent().displayName }}</strong>
|
|
69569
|
+
<small>{{ opponent().leaderName }} · {{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</small>
|
|
69570
|
+
</div>
|
|
69571
|
+
</article>
|
|
69572
|
+
</section>
|
|
69573
|
+
|
|
69574
|
+
<section class="christianity-hand-shelf christianity-hand-shelf--opponent">
|
|
69575
|
+
<div class="christianity-hand-meter christianity-hand-meter--opponent">
|
|
69576
|
+
<span>{{ t('christianityHand') }}</span>
|
|
69577
|
+
<strong>{{ opponentHandCount() }}</strong>
|
|
69578
|
+
</div>
|
|
69579
|
+
<section class="christianity-hand-fan christianity-hand-fan--opponent" [attr.aria-label]="t('christianityOpponentHand')">
|
|
69580
|
+
@for (_ of hiddenHandCards(opponentHandCount()); track $index) {
|
|
69581
|
+
<button
|
|
69582
|
+
type="button"
|
|
69583
|
+
class="christianity-card-preview-card christianity-card-frame christianity-card-frame--back"
|
|
69584
|
+
valLightRipple
|
|
69585
|
+
[style.transform]="fanTransform($index, opponentHandCount(), true)"
|
|
69586
|
+
[attr.aria-label]="t('christianityHiddenCard')"
|
|
69587
|
+
>
|
|
69588
|
+
<img class="christianity-card-back-symbol" src="assets/games/christianity/card-symbol.svg" alt="" />
|
|
69589
|
+
</button>
|
|
69590
|
+
}
|
|
69591
|
+
</section>
|
|
69592
|
+
</section>
|
|
69593
|
+
|
|
69594
|
+
<section class="christianity-table" [attr.aria-label]="t('christianityTable')">
|
|
69595
|
+
<section class="christianity-player-side christianity-player-side--opponent">
|
|
69596
|
+
<section class="christianity-player-rack christianity-player-rack--opponent">
|
|
69597
|
+
<div class="christianity-offerings-zone">
|
|
69598
|
+
<button type="button" class="christianity-offering-pile" valLightRipple (click)="openOfferings('P2')">
|
|
69599
|
+
<i aria-hidden="true"></i>
|
|
69600
|
+
<i aria-hidden="true"></i>
|
|
69601
|
+
<i aria-hidden="true"></i>
|
|
69602
|
+
<span>{{ t('christianityOfferings') }}</span>
|
|
69603
|
+
<strong>{{ readyOfferings(opponent()) }}/{{ totalOfferings(opponent()) }}</strong>
|
|
69604
|
+
</button>
|
|
69605
|
+
</div>
|
|
69606
|
+
<button type="button" class="christianity-leader-card christianity-card-frame christianity-card-frame--leader" valLightRipple [class.is-target]="selectedAttacker() && !hasOpponentGuards()" (click)="handleOpponentLeader()">
|
|
69607
|
+
<header class="christianity-card-frame-header">
|
|
69608
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
69609
|
+
<strong>{{ opponent().leaderName }}</strong>
|
|
69610
|
+
<span>{{ opponent().leaderHp }}</span>
|
|
69611
|
+
</header>
|
|
69612
|
+
<section class="christianity-card-frame-art">
|
|
69613
|
+
<span>{{ opponent().leaderName }}</span>
|
|
69614
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
69615
|
+
</section>
|
|
69616
|
+
<section class="christianity-card-frame-effect">
|
|
69617
|
+
<strong>{{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</strong>
|
|
69618
|
+
</section>
|
|
69619
|
+
</button>
|
|
69620
|
+
<span class="christianity-rack-spacer" aria-hidden="true"></span>
|
|
69621
|
+
</section>
|
|
69622
|
+
|
|
69623
|
+
<section class="christianity-battle-zone christianity-battle-zone--opponent" [attr.aria-label]="t('christianityOpponentBattle')">
|
|
69624
|
+
@for (slot of battleSlots('P2'); track slot.trackId) {
|
|
69625
|
+
@if (slot.card) {
|
|
69626
|
+
<button
|
|
69627
|
+
type="button"
|
|
69628
|
+
class="christianity-card-preview-card christianity-card-preview-card--battle christianity-card-frame christianity-card-frame--battle"
|
|
69629
|
+
valLightRipple
|
|
69630
|
+
[class.is-target]="selectedAttacker()"
|
|
69631
|
+
(click)="handleOpponentCharacter(slot.card)"
|
|
69632
|
+
>
|
|
69633
|
+
<header class="christianity-card-frame-header">
|
|
69634
|
+
<small>{{ t('christianityCost') }} {{ cardDefinition(slot.card.cardId).cost }}</small>
|
|
69635
|
+
<strong>{{ slot.card.name }}</strong>
|
|
69636
|
+
<span>{{ cardDefinition(slot.card.cardId).cost }}</span>
|
|
69637
|
+
</header>
|
|
69638
|
+
<section class="christianity-card-frame-art">
|
|
69639
|
+
<span>{{ slot.card.name }}</span>
|
|
69640
|
+
<small>{{ t('christianityCharacterCard') }}</small>
|
|
69641
|
+
</section>
|
|
69642
|
+
<section class="christianity-card-frame-effect">
|
|
69643
|
+
<strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
|
|
69644
|
+
</section>
|
|
69645
|
+
</button>
|
|
69646
|
+
} @else {
|
|
69647
|
+
<span class="christianity-slot"></span>
|
|
69648
|
+
}
|
|
69649
|
+
}
|
|
69650
|
+
</section>
|
|
69651
|
+
</section>
|
|
69652
|
+
|
|
69653
|
+
<section class="christianity-shared-zone" [attr.aria-label]="t('christianitySharedZone')">
|
|
69654
|
+
<button type="button" class="christianity-zone-pile christianity-zone-pile--history" valLightRipple (click)="openHistory()">
|
|
69655
|
+
<i aria-hidden="true"></i>
|
|
69656
|
+
<i aria-hidden="true"></i>
|
|
69657
|
+
<i aria-hidden="true"></i>
|
|
69658
|
+
<span>{{ t('christianityHistory') }}</span>
|
|
69659
|
+
<strong>{{ game().historyZone.length }}</strong>
|
|
69660
|
+
</button>
|
|
69661
|
+
<button type="button" class="christianity-zone-pile christianity-zone-pile--deck" valLightRipple aria-live="polite" (click)="inspectDeck()">
|
|
69662
|
+
<i aria-hidden="true"></i>
|
|
69663
|
+
<i aria-hidden="true"></i>
|
|
69664
|
+
<i aria-hidden="true"></i>
|
|
69665
|
+
<span>{{ t('christianityDeck') }}</span>
|
|
69666
|
+
<strong>{{ game().sharedDeck.length }}</strong>
|
|
69667
|
+
</button>
|
|
69668
|
+
<div class="christianity-zone-card">
|
|
69669
|
+
<span>{{ t('christianityPlace') }}</span>
|
|
69670
|
+
<strong>{{ t('christianityEmpty') }}</strong>
|
|
69671
|
+
</div>
|
|
69672
|
+
</section>
|
|
69673
|
+
|
|
69674
|
+
<section class="christianity-player-side">
|
|
69675
|
+
<section class="christianity-battle-zone" [class.is-placing-card]="canPlaceSelectedCharacter() || isDraggingCharacter()" [attr.aria-label]="t('christianityYourBattle')">
|
|
69676
|
+
@for (slot of battleSlots('P1'); track slot.trackId) {
|
|
69677
|
+
@if (slot.card) {
|
|
69678
|
+
<button
|
|
69679
|
+
type="button"
|
|
69680
|
+
class="christianity-card-preview-card christianity-card-preview-card--battle christianity-card-frame christianity-card-frame--battle"
|
|
69681
|
+
valLightRipple
|
|
69682
|
+
[class.is-selected]="selectedAttacker()?.instanceId === slot.card.instanceId"
|
|
69683
|
+
[class.is-exhausted]="!slot.card.canAttack"
|
|
69684
|
+
(click)="selectAttacker(slot.card)"
|
|
69685
|
+
>
|
|
69686
|
+
<header class="christianity-card-frame-header">
|
|
69687
|
+
<small>{{ t('christianityCost') }} {{ cardDefinition(slot.card.cardId).cost }}</small>
|
|
69688
|
+
<strong>{{ slot.card.name }}</strong>
|
|
69689
|
+
<span>{{ cardDefinition(slot.card.cardId).cost }}</span>
|
|
69690
|
+
</header>
|
|
69691
|
+
<section class="christianity-card-frame-art">
|
|
69692
|
+
<span>{{ slot.card.name }}</span>
|
|
69693
|
+
<small>{{ t('christianityCharacterCard') }}</small>
|
|
69694
|
+
</section>
|
|
69695
|
+
<section class="christianity-card-frame-effect">
|
|
69696
|
+
<strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
|
|
69697
|
+
</section>
|
|
69698
|
+
</button>
|
|
69699
|
+
} @else {
|
|
69700
|
+
<button
|
|
69701
|
+
type="button"
|
|
69702
|
+
class="christianity-slot"
|
|
69703
|
+
cdkDropList
|
|
69704
|
+
[id]="battleSlotDropId($index)"
|
|
69705
|
+
[cdkDropListData]="$index"
|
|
69706
|
+
[cdkDropListConnectedTo]="['christianity-hand-source']"
|
|
69707
|
+
[cdkDropListEnterPredicate]="canDropOnBattleSlot"
|
|
69708
|
+
[class.christianity-slot--play-target]="canPlaceSelectedCharacter() || isDraggingCharacter()"
|
|
69709
|
+
valLightRipple
|
|
69710
|
+
(cdkDropListDropped)="dropOnBattleSlot($event, $index)"
|
|
69711
|
+
(click)="playSelectedCard($index)"
|
|
69712
|
+
>
|
|
69713
|
+
@if (canPlaceSelectedCharacter() || isDraggingCharacter()) {
|
|
69714
|
+
<span>{{ t('christianityPlayHere') }}</span>
|
|
69715
|
+
}
|
|
69716
|
+
</button>
|
|
69717
|
+
}
|
|
69718
|
+
}
|
|
69719
|
+
</section>
|
|
69720
|
+
|
|
69721
|
+
<section class="christianity-player-rack">
|
|
69722
|
+
<div class="christianity-offerings-zone">
|
|
69723
|
+
<button
|
|
69724
|
+
type="button"
|
|
69725
|
+
class="christianity-offering-pile"
|
|
69726
|
+
cdkDropList
|
|
69727
|
+
id="christianity-offerings-drop"
|
|
69728
|
+
valLightRipple
|
|
69729
|
+
[cdkDropListConnectedTo]="['christianity-hand-source']"
|
|
69730
|
+
[class.is-play-target]="canPlaceSelectedOffering() || isDraggingOffering()"
|
|
69731
|
+
[cdkDropListEnterPredicate]="canDropOnOfferings"
|
|
69732
|
+
(cdkDropListDropped)="dropOnOfferings($event)"
|
|
69733
|
+
(click)="handleOfferingPile('P1')"
|
|
69734
|
+
>
|
|
69735
|
+
<i aria-hidden="true"></i>
|
|
69736
|
+
<i aria-hidden="true"></i>
|
|
69737
|
+
<i aria-hidden="true"></i>
|
|
69738
|
+
<span>{{ t('christianityOfferings') }}</span>
|
|
69739
|
+
<strong>{{ readyOfferings(player()) }}/{{ totalOfferings(player()) }}</strong>
|
|
69740
|
+
</button>
|
|
69741
|
+
</div>
|
|
69742
|
+
<button type="button" class="christianity-leader-card christianity-card-frame christianity-card-frame--leader" valLightRipple (click)="inspectLeader('P1')">
|
|
69743
|
+
<header class="christianity-card-frame-header">
|
|
69744
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
69745
|
+
<strong>{{ player().leaderName }}</strong>
|
|
69746
|
+
<span>{{ player().leaderHp }}</span>
|
|
69747
|
+
</header>
|
|
69748
|
+
<section class="christianity-card-frame-art">
|
|
69749
|
+
<span>{{ player().leaderName }}</span>
|
|
69750
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
69751
|
+
</section>
|
|
69752
|
+
<section class="christianity-card-frame-effect">
|
|
69753
|
+
<strong>{{ player().leaderHp }}/{{ player().leaderMaxHp }}</strong>
|
|
69754
|
+
</section>
|
|
69755
|
+
</button>
|
|
69756
|
+
<div class="christianity-player-command">
|
|
69757
|
+
<div class="christianity-player-badge">
|
|
69758
|
+
<span class="christianity-avatar" [style.background]="player().avatarColor">{{ player().avatar }}</span>
|
|
69759
|
+
<strong>{{ player().displayName }}</strong>
|
|
69760
|
+
</div>
|
|
69761
|
+
<button
|
|
69762
|
+
type="button"
|
|
69763
|
+
class="christianity-end-turn"
|
|
69764
|
+
(click)="endTurn()"
|
|
69765
|
+
>
|
|
69766
|
+
{{ t('christianityEndTurn') }}
|
|
69767
|
+
</button>
|
|
69768
|
+
</div>
|
|
69769
|
+
</section>
|
|
69770
|
+
</section>
|
|
69771
|
+
</section>
|
|
69772
|
+
|
|
69773
|
+
<section class="christianity-hand-shelf">
|
|
69774
|
+
<div class="christianity-hand-meter">
|
|
69775
|
+
<span>{{ t('christianityHand') }}</span>
|
|
69776
|
+
<strong>{{ player().hand?.length ?? 0 }}</strong>
|
|
69777
|
+
</div>
|
|
69778
|
+
<section
|
|
69779
|
+
class="christianity-hand-fan"
|
|
69780
|
+
cdkDropList
|
|
69781
|
+
id="christianity-hand-source"
|
|
69782
|
+
[cdkDropListConnectedTo]="dropTargetIds()"
|
|
69783
|
+
[attr.aria-label]="t('christianityYourHand')"
|
|
69784
|
+
(pointerleave)="clearHoveredHandIndex()"
|
|
69785
|
+
>
|
|
69786
|
+
@for (cardId of player().hand ?? []; track cardId + $index) {
|
|
69787
|
+
@let card = cardDefinition(cardId);
|
|
69788
|
+
<div
|
|
69789
|
+
class="christianity-hand-card-wrap"
|
|
69790
|
+
[class.is-selected]="selectedHandCard() === cardId"
|
|
69791
|
+
[class.is-dragging]="draggingCardId() === cardId"
|
|
69792
|
+
[style.z-index]="handCardZIndex($index)"
|
|
69793
|
+
[style.transform]="fanTransform($index, player().hand?.length ?? 0, false)"
|
|
69794
|
+
(pointerenter)="setHoveredHandIndex($index)"
|
|
69795
|
+
(pointerdown)="setHoveredHandIndex($index)"
|
|
69796
|
+
(pointerup)="releaseHoveredHand($event)"
|
|
69797
|
+
>
|
|
69798
|
+
<button
|
|
69799
|
+
type="button"
|
|
69800
|
+
class="christianity-card-preview-card christianity-card-preview-card--hand christianity-card-frame"
|
|
69801
|
+
cdkDrag
|
|
69802
|
+
valLightRipple
|
|
69803
|
+
[cdkDragData]="cardId"
|
|
69804
|
+
[cdkDragDisabled]="!canPlay(card)"
|
|
69805
|
+
[class.is-selected]="selectedHandCard() === cardId"
|
|
69806
|
+
[class.is-disabled]="!canPlay(card)"
|
|
69807
|
+
(cdkDragStarted)="startDraggingCard(cardId)"
|
|
69808
|
+
(cdkDragEnded)="endDraggingCard()"
|
|
69809
|
+
(click)="selectHandCard(cardId)"
|
|
69810
|
+
>
|
|
69811
|
+
<header class="christianity-card-frame-header">
|
|
69812
|
+
<small>{{ card.type === 'offering' ? t('christianityOfferingCard') : t('christianityCost') + ' ' + card.cost }}</small>
|
|
69813
|
+
<strong>{{ card.name }}</strong>
|
|
69814
|
+
<span>{{ card.type === 'offering' ? '+' + card.life : card.cost }}</span>
|
|
69815
|
+
</header>
|
|
69816
|
+
<section class="christianity-card-frame-art">
|
|
69817
|
+
<span>{{ card.name }}</span>
|
|
69818
|
+
<small>{{ cardTypeLabel(card) }}</small>
|
|
69819
|
+
</section>
|
|
69820
|
+
<section class="christianity-card-frame-effect">
|
|
69821
|
+
<strong>
|
|
69822
|
+
@if (card.type === 'offering') {
|
|
69823
|
+
+{{ card.life }}
|
|
69824
|
+
} @else {
|
|
69825
|
+
{{ card.attack }} / {{ card.life }}
|
|
69826
|
+
}
|
|
69827
|
+
</strong>
|
|
69828
|
+
</section>
|
|
69829
|
+
<footer class="christianity-card-frame-footer">
|
|
69830
|
+
<span>{{ card.edition ?? 'MVP' }}</span>
|
|
69831
|
+
<span>{{ card.collectorNumber ?? card.id }}</span>
|
|
69832
|
+
</footer>
|
|
69833
|
+
</button>
|
|
69834
|
+
<button
|
|
69835
|
+
type="button"
|
|
69836
|
+
class="christianity-card-eye"
|
|
69837
|
+
[attr.aria-label]="t('christianityPreviewCard')"
|
|
69838
|
+
(click)="inspectHandCard(cardId, true); $event.stopPropagation()"
|
|
69839
|
+
></button>
|
|
69840
|
+
</div>
|
|
69841
|
+
}
|
|
69842
|
+
</section>
|
|
69843
|
+
</section>
|
|
69844
|
+
|
|
69845
|
+
@if (selectedPreview()) {
|
|
69846
|
+
<button type="button" class="christianity-preview-backdrop" [attr.aria-label]="t('christianityClosePreview')" (click)="closePreview()"></button>
|
|
69847
|
+
<aside
|
|
69848
|
+
class="christianity-floating-card-shell"
|
|
69849
|
+
aria-live="polite"
|
|
69850
|
+
>
|
|
69851
|
+
<button type="button" class="christianity-floating-card-close" (click)="closePreview()">
|
|
69852
|
+
{{ t('close') }}
|
|
69853
|
+
</button>
|
|
69854
|
+
<div
|
|
69855
|
+
class="christianity-floating-card"
|
|
69856
|
+
[style.--preview-rotate-x]="previewTilt().rotateX + 'deg'"
|
|
69857
|
+
[style.--preview-rotate-y]="previewTilt().rotateY + 'deg'"
|
|
69858
|
+
[style.--preview-shift-x]="previewTilt().shiftX + 'px'"
|
|
69859
|
+
[style.--preview-shift-y]="previewTilt().shiftY + 'px'"
|
|
69860
|
+
(pointermove)="tiltPreview($event)"
|
|
69861
|
+
(pointerleave)="resetPreviewTilt()"
|
|
69862
|
+
>
|
|
69863
|
+
@if (selectedPreviewCard(); as previewCard) {
|
|
69864
|
+
<header class="christianity-full-card-header">
|
|
69865
|
+
<span class="christianity-full-card-type-icon" aria-hidden="true"></span>
|
|
69866
|
+
<strong>{{ previewCard.name }}</strong>
|
|
69867
|
+
<span class="christianity-full-card-cost">{{ previewCard.type === 'offering' ? '+' + previewCard.life : previewCard.cost }}</span>
|
|
69868
|
+
</header>
|
|
69869
|
+
<section class="christianity-full-card-art" [class.has-image]="previewCard.imageUrl">
|
|
69870
|
+
@if (previewCard.imageUrl) {
|
|
69871
|
+
<img [src]="previewCard.imageUrl" [alt]="previewCard.name" />
|
|
69872
|
+
} @else {
|
|
69873
|
+
<span>{{ previewCard.name }}</span>
|
|
69874
|
+
}
|
|
69875
|
+
<small>{{ cardTypeLabel(previewCard) }}</small>
|
|
69876
|
+
</section>
|
|
69877
|
+
<section class="christianity-full-card-verse">
|
|
69878
|
+
<p>{{ previewCard.verseText ?? selectedPreview()?.body }}</p>
|
|
69879
|
+
@if (previewCard.scripture) {
|
|
69880
|
+
<strong>{{ previewCard.scripture }}</strong>
|
|
69881
|
+
}
|
|
69882
|
+
</section>
|
|
69883
|
+
<section class="christianity-full-card-effect">
|
|
69884
|
+
<div class="christianity-full-card-stats">
|
|
69885
|
+
@if (previewCard.type === 'character') {
|
|
69886
|
+
<strong>{{ previewCard.attack }}</strong>
|
|
69887
|
+
<strong>{{ previewCard.life }}</strong>
|
|
69888
|
+
} @else {
|
|
69889
|
+
<strong>+{{ previewCard.life }}</strong>
|
|
69890
|
+
}
|
|
69891
|
+
</div>
|
|
69892
|
+
<div>
|
|
69893
|
+
@if (previewCard.abilityName) {
|
|
69894
|
+
<strong>{{ previewCard.abilityName }}</strong>
|
|
69895
|
+
}
|
|
69896
|
+
<p>{{ previewCard.abilityText ?? selectedPreview()?.body }}</p>
|
|
69897
|
+
</div>
|
|
69898
|
+
<span
|
|
69899
|
+
class="christianity-full-card-rarity"
|
|
69900
|
+
[class.is-normal]="!previewCard.rarity || previewCard.rarity === 'normal'"
|
|
69901
|
+
[class.is-uncommon]="previewCard.rarity === 'uncommon'"
|
|
69902
|
+
[class.is-rare]="previewCard.rarity === 'rare'"
|
|
69903
|
+
[class.is-legendary]="previewCard.rarity === 'legendary'"
|
|
69904
|
+
aria-hidden="true"
|
|
69905
|
+
></span>
|
|
69906
|
+
</section>
|
|
69907
|
+
<footer class="christianity-full-card-footer">
|
|
69908
|
+
<span>{{ previewCard.edition ?? 'MVP' }}</span>
|
|
69909
|
+
<span>{{ previewCard.collectorNumber ?? previewCard.id }}</span>
|
|
69910
|
+
<span>{{ previewCard.year ?? '2026' }} CHRISTIANITY</span>
|
|
69911
|
+
<span>{{ previewCard.author ?? 'MVP' }}</span>
|
|
69912
|
+
</footer>
|
|
69913
|
+
} @else {
|
|
69914
|
+
<small>{{ selectedPreview()?.eyebrow }}</small>
|
|
69915
|
+
<strong>{{ selectedPreview()?.title }}</strong>
|
|
69916
|
+
<span>{{ selectedPreview()?.meta }}</span>
|
|
69917
|
+
<p>{{ selectedPreview()?.body }}</p>
|
|
69918
|
+
}
|
|
69919
|
+
</div>
|
|
69920
|
+
@if (selectedPreview()?.source === 'hand') {
|
|
69921
|
+
<div class="christianity-floating-card-actions">
|
|
69922
|
+
<button type="button" [disabled]="previewActionDisabled()" (click)="playPreviewCard()">
|
|
69923
|
+
{{ selectedActionLabel() }}
|
|
69924
|
+
</button>
|
|
69925
|
+
</div>
|
|
69926
|
+
}
|
|
69927
|
+
</aside>
|
|
69928
|
+
}
|
|
69929
|
+
|
|
69930
|
+
@if (selectedInfo(); as info) {
|
|
69931
|
+
<button type="button" class="christianity-info-backdrop" [attr.aria-label]="t('close')" (click)="closeInfo()"></button>
|
|
69932
|
+
<aside class="christianity-info-panel" aria-live="polite">
|
|
69933
|
+
<button type="button" class="christianity-dialog-close christianity-info-close" (click)="closeInfo()">
|
|
69934
|
+
{{ t('close') }}
|
|
69935
|
+
</button>
|
|
69936
|
+
<div class="christianity-rule-note">
|
|
69937
|
+
<span class="christianity-rule-note-icon" aria-hidden="true">i</span>
|
|
69938
|
+
<div>
|
|
69939
|
+
<small>{{ info.eyebrow }}</small>
|
|
69940
|
+
<h2>{{ info.title }}</h2>
|
|
69941
|
+
<strong>{{ info.meta }}</strong>
|
|
69942
|
+
<p>{{ info.body }}</p>
|
|
69943
|
+
<ul>
|
|
69944
|
+
@for (fact of info.facts; track fact) {
|
|
69945
|
+
<li>{{ fact }}</li>
|
|
69946
|
+
}
|
|
69947
|
+
</ul>
|
|
69948
|
+
</div>
|
|
69949
|
+
</div>
|
|
69950
|
+
</aside>
|
|
69951
|
+
}
|
|
69952
|
+
|
|
69953
|
+
<section class="christianity-actions" aria-live="polite">
|
|
69954
|
+
<p>{{ statusText() }}</p>
|
|
69955
|
+
<div>
|
|
69956
|
+
<button type="button" [disabled]="selectedActionDisabled()" (click)="playSelectedCard()">
|
|
69957
|
+
{{ selectedActionLabel() }}
|
|
69958
|
+
</button>
|
|
69959
|
+
<button type="button" (click)="resetMock()">
|
|
69960
|
+
{{ t('christianityReset') }}
|
|
69961
|
+
</button>
|
|
69962
|
+
</div>
|
|
69963
|
+
</section>
|
|
69964
|
+
|
|
69965
|
+
@if (showHistory()) {
|
|
69966
|
+
<button type="button" class="christianity-history-backdrop" [attr.aria-label]="t('christianityCloseHistory')" (click)="showHistory.set(false)"></button>
|
|
69967
|
+
<section class="christianity-history-drawer">
|
|
69968
|
+
<header>
|
|
69969
|
+
<h2>{{ t('christianityHistory') }}</h2>
|
|
69970
|
+
<div class="christianity-dialog-actions">
|
|
69971
|
+
<span>{{ game().historyZone.length }}</span>
|
|
69972
|
+
<button type="button" class="christianity-dialog-close" (click)="showHistory.set(false)">
|
|
69973
|
+
{{ t('close') }}
|
|
69974
|
+
</button>
|
|
69975
|
+
</div>
|
|
69976
|
+
</header>
|
|
69977
|
+
@if (game().historyZone.length) {
|
|
69978
|
+
<div class="christianity-history-grid">
|
|
69979
|
+
@for (cardId of game().historyZone; track cardId + $index) {
|
|
69980
|
+
@let card = cardDefinition(cardId);
|
|
69981
|
+
<button type="button" class="christianity-card-preview-card christianity-card-frame christianity-card-frame--list" valLightRipple (click)="inspectHistoryCard(cardId)">
|
|
69982
|
+
<header class="christianity-card-frame-header">
|
|
69983
|
+
<small>{{ card.type === 'offering' ? t('christianityOfferingCard') : t('christianityCost') + ' ' + card.cost }}</small>
|
|
69984
|
+
<strong>{{ card.name }}</strong>
|
|
69985
|
+
<span>{{ card.type === 'offering' ? '+' + card.life : card.cost }}</span>
|
|
69986
|
+
</header>
|
|
69987
|
+
<section class="christianity-card-frame-art">
|
|
69988
|
+
<span>{{ card.name }}</span>
|
|
69989
|
+
<small>{{ cardTypeLabel(card) }}</small>
|
|
69990
|
+
</section>
|
|
69991
|
+
<section class="christianity-card-frame-effect">
|
|
69992
|
+
<strong>
|
|
69993
|
+
@if (card.type === 'offering') {
|
|
69994
|
+
+{{ card.life }}
|
|
69995
|
+
} @else {
|
|
69996
|
+
{{ card.attack }} / {{ card.life }}
|
|
69997
|
+
}
|
|
69998
|
+
</strong>
|
|
69999
|
+
</section>
|
|
70000
|
+
</button>
|
|
70001
|
+
}
|
|
70002
|
+
</div>
|
|
70003
|
+
} @else {
|
|
70004
|
+
<p>{{ t('christianityHistoryEmpty') }}</p>
|
|
70005
|
+
}
|
|
70006
|
+
</section>
|
|
70007
|
+
}
|
|
70008
|
+
|
|
70009
|
+
@if (offeringsSeat()) {
|
|
70010
|
+
@let offeringPlayer = game().players[offeringsSeat()!];
|
|
70011
|
+
<button type="button" class="christianity-history-backdrop" [attr.aria-label]="t('christianityCloseOfferings')" (click)="closeOfferings()"></button>
|
|
70012
|
+
<section class="christianity-history-drawer christianity-offerings-drawer">
|
|
70013
|
+
<header>
|
|
70014
|
+
<h2>{{ t('christianityOfferings') }}</h2>
|
|
70015
|
+
<div class="christianity-dialog-actions">
|
|
70016
|
+
<span>{{ readyOfferings(offeringPlayer) }}/{{ totalOfferings(offeringPlayer) }}</span>
|
|
70017
|
+
<button type="button" class="christianity-dialog-close" (click)="closeOfferings()">
|
|
70018
|
+
{{ t('close') }}
|
|
70019
|
+
</button>
|
|
70020
|
+
</div>
|
|
70021
|
+
</header>
|
|
70022
|
+
<div class="christianity-offering-list">
|
|
70023
|
+
@for (offering of offeringPlayer.offerings; track offering.instanceId) {
|
|
70024
|
+
<article class="christianity-offering-row" [class.is-exhausted]="!offering.ready">
|
|
70025
|
+
<button type="button" class="christianity-offering-card christianity-card-frame christianity-card-frame--list" valLightRipple (click)="inspectOffering(offering)">
|
|
70026
|
+
<header class="christianity-card-frame-header">
|
|
70027
|
+
<small>{{ t('christianityOfferingCard') }}</small>
|
|
70028
|
+
<strong>{{ offering.name }}</strong>
|
|
70029
|
+
<span>+{{ offering.value }}</span>
|
|
70030
|
+
</header>
|
|
70031
|
+
<section class="christianity-card-frame-art">
|
|
70032
|
+
<span>{{ offering.name }}</span>
|
|
70033
|
+
<small>{{ t('christianityOfferingCard') }}</small>
|
|
70034
|
+
</section>
|
|
70035
|
+
<section class="christianity-card-frame-effect">
|
|
70036
|
+
<strong>+{{ offering.value }}</strong>
|
|
70037
|
+
@if (offering.abilityName) {
|
|
70038
|
+
<p>{{ offering.abilityName }}</p>
|
|
70039
|
+
}
|
|
70040
|
+
</section>
|
|
70041
|
+
</button>
|
|
70042
|
+
<div>
|
|
70043
|
+
<strong>{{ offering.ready ? t('christianityOfferingReady') : t('christianityOfferingExhausted') }}</strong>
|
|
70044
|
+
<p>{{ offering.abilityText || t('christianityOfferingNoAbility') }}</p>
|
|
70045
|
+
@if (offering.abilityName) {
|
|
70046
|
+
<button
|
|
70047
|
+
type="button"
|
|
70048
|
+
[disabled]="!canUseOfferingAbility(offering, offeringsSeat()!)"
|
|
70049
|
+
(click)="useOfferingAbility(offering, offeringsSeat()!)"
|
|
70050
|
+
>
|
|
70051
|
+
{{ t('christianityUseAbility') }}
|
|
70052
|
+
</button>
|
|
70053
|
+
}
|
|
70054
|
+
</div>
|
|
70055
|
+
</article>
|
|
70056
|
+
}
|
|
70057
|
+
</div>
|
|
70058
|
+
</section>
|
|
70059
|
+
}
|
|
70060
|
+
</main>
|
|
70061
|
+
`, isInline: true, styles: [":host{--christianity-theme-ink: var(--val-text-color, #1f2933);--christianity-theme-surface: #ffffff;--christianity-theme-parchment: #fffaf0;--christianity-theme-olive: #5f6f2a;--christianity-theme-gold: #d6a21d;--christianity-theme-gold-soft: rgba(214, 162, 29, .18);--christianity-theme-gold-ring: rgba(214, 162, 29, .48);--christianity-theme-glow: rgba(245, 199, 85, .32);--christianity-theme-focus: #2563eb;--christianity-theme-shadow: rgba(82, 64, 28, .18);--christianity-theme-shadow-strong: rgba(82, 64, 28, .3);--christianity-card-aspect: 5 / 7.45;display:block;max-width:100%;min-width:0;overflow-x:clip;color:var(--christianity-theme-ink)}.christianity-shell{box-sizing:border-box;display:grid;gap:.65rem;width:100%;max-width:100%;min-width:0;padding:.75rem .25rem;border:1px solid rgba(36,48,68,.12);border-radius:.75rem;background:#f6f8fb;overflow-x:clip;overflow-y:visible}.christianity-header,.christianity-match-strip,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-header h1,.christianity-header p,.christianity-match-player strong,.christianity-match-player small,.christianity-scoreboard span,.christianity-history h2,.christianity-actions p{margin:0}.christianity-header h1{font-size:1.35rem;line-height:1.1}.christianity-header p,.christianity-turn span,.christianity-offerings span,.christianity-hidden-hand span,.christianity-deck span,.christianity-place span,.christianity-pile span,.christianity-leader span{color:#1f2933a3;font-size:.75rem}.christianity-turn,.christianity-leader,.christianity-offerings,.christianity-hidden-hand,.christianity-pile,.christianity-deck,.christianity-place{display:grid;gap:.15rem;min-width:5.25rem;padding:.55rem .65rem;border:1px solid rgba(36,48,68,.12);border-radius:.5rem;background:#fff}.christianity-turn.is-own-turn{border-color:#12806c59;background:#ecfdf5}.christianity-match-strip{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);padding:.45rem;border:1px solid rgba(36,48,68,.1);border-radius:.75rem;background:#fff}.christianity-match-player{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.5rem;align-items:center;min-width:0}.christianity-match-player--opponent{direction:rtl}.christianity-match-player--opponent div{direction:ltr;text-align:right}.christianity-match-player div{display:grid;min-width:0}.christianity-match-player strong,.christianity-match-player small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.christianity-match-player small,.christianity-scoreboard span{color:#1f293394;font-size:.72rem}.christianity-scoreboard{display:grid;justify-items:center;min-width:4.2rem;padding:0 .55rem;border-right:1px solid rgba(36,48,68,.1);border-left:1px solid rgba(36,48,68,.1)}.christianity-scoreboard strong{font-size:1.2rem;line-height:1}.christianity-table{box-sizing:border-box;display:grid;gap:.45rem;width:100%;max-width:100%;min-width:0;padding:.45rem .35rem;border-radius:.75rem;background:#dceafb;overflow-x:clip;overflow-y:visible}.christianity-player-side{box-sizing:border-box;display:grid;gap:.35rem;width:100%;max-width:100%;min-width:0;padding:.35rem .3rem;border-radius:.7rem;background:#ffffff57;grid-template-rows:minmax(7rem,1fr) auto;min-height:13.75rem}.christianity-player-side--opponent{grid-template-rows:auto minmax(7rem,1fr)}.christianity-player{display:grid;gap:.65rem}.christianity-battle-zone{--christianity-battle-card-width: clamp(4.8rem, 15vw, 6.6rem);box-sizing:border-box;display:grid;grid-template-columns:repeat(4,var(--christianity-battle-card-width));gap:.5rem;align-items:center;justify-content:center;width:100%;max-width:100%;min-width:0;min-height:clamp(9.1rem,29vw,11rem);padding:.55rem .4rem;border-radius:.75rem;background:#ffffffc2;transition:background .16s ease,box-shadow .16s ease}.christianity-battle-zone.is-placing-card{background:linear-gradient(180deg,#fffaf0f5,#ffffffd6),#ffffffc2;box-shadow:inset 0 0 0 .14rem var(--christianity-theme-gold-soft),0 .8rem 1.7rem #5f6f2a1f}.christianity-shared-zone{padding:.55rem .4rem;border-radius:.75rem;background:#ffffffe6}.christianity-card,.christianity-end-turn,.christianity-actions button,.christianity-pile,.christianity-leader--target{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card{display:grid;align-content:space-between;min-height:5.8rem;padding:.5rem;text-align:left;box-shadow:0 .5rem 1.25rem #24304414}.christianity-card span{font-weight:700}.christianity-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-card.is-selected{border-color:var(--christianity-theme-gold);box-shadow:0 0 0 .18rem var(--christianity-theme-gold-soft),0 .85rem 1.4rem var(--christianity-theme-shadow)}.christianity-card.is-disabled,.christianity-card.is-exhausted{opacity:.55}.christianity-card.is-target{border-color:#dc2626}.christianity-offering-cards{display:grid;grid-auto-flow:column;grid-auto-columns:.7rem;gap:.16rem;align-items:end;min-height:1.05rem}.christianity-offering-cards i{display:block;width:.65rem;height:.95rem;border:1px solid rgba(16,42,67,.22);border-radius:.18rem;background:#f8fafc}.christianity-offering-cards i.is-used{background:#cbd5e1;transform:rotate(90deg);transform-origin:center}.christianity-slot{display:grid;place-items:center;justify-self:center;width:var(--christianity-battle-card-width);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);border:1px dashed rgba(36,48,68,.22);border-radius:.5rem;background:#ffffff73;color:inherit;font:inherit}.christianity-slot--play-target{position:relative;border-color:var(--christianity-theme-gold-ring);background:linear-gradient(180deg,#fffaf0eb,#f8fafcd1),#ffffffb3;color:#5d4305;font-weight:800;overflow:hidden;box-shadow:inset 0 0 0 .12rem #d6a21d33,0 .7rem 1.25rem var(--christianity-theme-shadow);animation:christianity-target-pulse 1.45s ease-in-out infinite}.christianity-slot--play-target:before{content:\"\";position:absolute;inset:.35rem;border:1px solid rgba(214,162,29,.22);border-radius:.4rem;background:linear-gradient(135deg,rgba(214,162,29,.1),transparent 46%),radial-gradient(circle at 50% 42%,var(--christianity-theme-glow),transparent 58%)}.christianity-slot--play-target span{position:relative;z-index:2;padding:.16rem .44rem;border-radius:999px;background:#ffffffc7;font-size:.78rem}@keyframes christianity-target-pulse{0%,to{box-shadow:inset 0 0 0 .12rem #d6a21d33,0 .7rem 1.25rem var(--christianity-theme-shadow)}50%{box-shadow:inset 0 0 0 .16rem #d6a21d57,0 .9rem 1.65rem var(--christianity-theme-shadow-strong)}}.christianity-hand{display:grid;grid-auto-columns:minmax(6rem,8rem);grid-auto-flow:column;gap:.55rem;overflow-x:auto;padding-bottom:.25rem}.christianity-actions{align-items:flex-start;padding:.75rem;border-radius:.75rem;background:#fff}.christianity-actions div{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end}.christianity-actions button,.christianity-end-turn{min-height:2.4rem;padding:0 .75rem;font-weight:700}.christianity-actions button:not(:disabled),.christianity-end-turn{background:#102a43;color:#fff}.christianity-history{padding:.75rem;border-radius:.75rem;background:#fff}.christianity-hand-fan{position:relative;display:flex;justify-content:center;min-height:10.8rem;padding:.25rem .25rem 2.1rem;isolation:isolate;overflow:visible}.christianity-hand-shelf{position:relative;display:grid;z-index:12;min-height:12rem;margin-top:-1.15rem;padding:1.45rem .25rem 1rem;overflow:visible}.christianity-hand-shelf--opponent{z-index:8;min-height:6.85rem;margin-top:0;margin-bottom:0;padding:.45rem .25rem .85rem}.christianity-hand-fan--opponent{min-height:5.9rem;padding-bottom:.75rem;align-items:start}.christianity-card-preview-card,.christianity-card-mini,.christianity-offering-pile,.christianity-offering-card,.christianity-leader-card,.christianity-zone-card,.christianity-zone-pile,.christianity-end-turn{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card-preview-card{display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;gap:.28rem;align-content:stretch;width:clamp(4.9rem,17vw,7.1rem);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);padding:.48rem;text-align:left;transform-origin:50% 115%;transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;box-shadow:0 .5rem 1.25rem #2430441a}.christianity-card-frame{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;gap:.28rem;align-content:stretch;overflow:hidden;padding:.48rem;text-align:left;background:linear-gradient(180deg,#fffffffa,#f8fafcfa),radial-gradient(circle at 15% 0%,rgba(214,162,29,.12),transparent 44%);box-shadow:0 .5rem 1.25rem #2430441a,inset 0 0 0 .18rem #ffffff9e}.christianity-card-frame-header{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.16rem;align-items:start;min-width:0}.christianity-card-frame-header small{grid-column:1;min-width:0;overflow:hidden;color:#1f2933a3;font-size:clamp(.52rem,1.5vw,.68rem);line-height:1;text-overflow:ellipsis;white-space:nowrap}.christianity-card-frame-header strong{grid-column:1;justify-self:start;align-self:start;min-width:0;padding:0;overflow:hidden;border-radius:0;background:transparent;font-size:clamp(.82rem,2.5vw,1.05rem);line-height:1.02;text-overflow:ellipsis;white-space:nowrap}.christianity-card-frame-header span{grid-column:2;grid-row:1 / span 2;display:grid;place-items:center;min-width:1.3rem;height:1.3rem;padding:0 .22rem;border-radius:999px;background:#ffd91a;color:#243044;font-size:.8rem;font-weight:900;line-height:1;box-shadow:inset 0 -.08rem #52401c2e}.christianity-card-frame-art{position:relative;display:grid;place-items:center;min-height:0;overflow:hidden;border-radius:.36rem;background:linear-gradient(135deg,#5f6f2a2e,#d6a21d24),radial-gradient(circle at 50% 18%,rgba(255,255,255,.72),transparent 48%),#dbe7ef;box-shadow:inset 0 0 0 1px #24304414}.christianity-card-frame-art>span{max-width:78%;overflow:hidden;color:#2430447a;font-size:clamp(.82rem,2.2vw,1.05rem);font-weight:900;line-height:1.02;text-align:center;text-overflow:ellipsis}.christianity-card-frame-art small{position:absolute;right:0;bottom:.28rem;max-width:78%;padding:.1rem .34rem;overflow:hidden;border-radius:999px 0 0 999px;background:#ffffffe6;color:#1f2933a8;font-size:.48rem;font-style:italic;font-weight:900;line-height:1;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.christianity-card-frame-effect{display:grid;align-content:center;gap:.1rem;min-height:1.45rem;padding:.24rem;overflow:hidden;border-radius:.34rem;background:radial-gradient(circle at 50% 70%,rgba(36,48,68,.06),transparent 44%),#ffffffdb}.christianity-card-frame-effect strong{justify-self:end;align-self:end;padding:.12rem .32rem;border-radius:999px;background:#edf2f7;font-size:clamp(.66rem,2vw,.82rem);line-height:1.05}.christianity-card-frame-effect p{margin:0;overflow:hidden;color:#1f2933b8;font-size:.58rem;line-height:1.1;text-overflow:ellipsis;white-space:nowrap}.christianity-card-frame-footer{display:flex;justify-content:space-between;gap:.22rem;color:#1f293385;font-size:.46rem;font-weight:800;line-height:1}.christianity-card-frame--battle{gap:.22rem;padding:.42rem}.christianity-card-frame--battle .christianity-card-frame-art{min-height:2.6rem}.christianity-card-frame--leader .christianity-card-frame-art{background:linear-gradient(135deg,#2563eb24,#d6a21d29),radial-gradient(circle at 50% 18%,rgba(255,255,255,.78),transparent 48%),#e7eef8}.christianity-card-frame--list{width:clamp(4.4rem,22vw,5.8rem);padding:.38rem}.christianity-card-frame--list .christianity-card-frame-art{min-height:2.5rem}.christianity-hand-card-wrap{position:relative;display:grid;justify-items:center;flex:0 0 auto;margin-inline:-.42rem;padding-bottom:2rem;transform-origin:50% 115%;transition:transform .16s ease,filter .16s ease}.christianity-hand-card-wrap:hover,.christianity-hand-card-wrap.is-selected,.christianity-hand-card-wrap.is-dragging{z-index:3}.christianity-hand-card-wrap:hover .christianity-card-preview-card--hand,.christianity-hand-card-wrap.is-selected .christianity-card-preview-card--hand,.christianity-hand-card-wrap.is-dragging .christianity-card-preview-card--hand{border-color:var(--christianity-theme-gold);box-shadow:0 0 0 .12rem var(--christianity-theme-gold-soft),0 1rem 2rem var(--christianity-theme-shadow)}.christianity-card-preview-card--hand{touch-action:none}.christianity-card-preview-card--hand.cdk-drag-disabled{cursor:not-allowed}.christianity-card-preview-card.cdk-drag-preview{width:clamp(4.9rem,17vw,7.1rem);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);border:1px solid var(--christianity-theme-gold-ring);box-shadow:0 0 0 .16rem #fff4c2ad,0 1.5rem 3rem var(--christianity-theme-shadow-strong);transform:rotate(2deg) scale(1.03)}.christianity-card-preview-card.cdk-drag-placeholder{width:clamp(4.9rem,17vw,7.1rem);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);opacity:.22}.christianity-slot.cdk-drop-list-dragging,.christianity-offering-pile.cdk-drop-list-dragging{border-color:var(--christianity-theme-gold-ring)}.christianity-slot.cdk-drop-list-receiving,.christianity-offering-pile.cdk-drop-list-receiving{box-shadow:inset 0 0 0 .18rem #d6a21d57,0 1rem 1.9rem var(--christianity-theme-shadow-strong)}.christianity-card-eye{position:absolute;right:50%;bottom:.38rem;width:2.15rem;height:1.55rem;border:1px solid color-mix(in srgb,var(--christianity-theme-focus) 52%,transparent);border-radius:999px;background:#fffffff0;box-shadow:0 .55rem 1.1rem #102a4324;opacity:0;transform:translate(50%,-.2rem) scale(.92);transition:opacity .14s ease,transform .14s ease,border-color .14s ease}.christianity-card-eye:before{content:\"\";position:absolute;top:50%;left:50%;width:1.1rem;height:1.1rem;border:.12rem solid var(--christianity-theme-focus);border-radius:82% 0;background:#fffffff0;transform:translate(-50%,-50%) rotate(45deg)}.christianity-card-eye:after{content:\"\";position:absolute;top:50%;left:50%;width:.42rem;height:.42rem;border:.09rem solid rgba(255,255,255,.95);border-radius:999px;background:radial-gradient(circle at 35% 32%,#ffffff 0 .06rem,transparent .07rem),var(--christianity-theme-focus);transform:translate(-50%,-50%)}.christianity-hand-card-wrap:hover .christianity-card-eye,.christianity-hand-card-wrap.is-selected .christianity-card-eye,.christianity-card-eye:focus-visible{opacity:1;transform:translate(50%) scale(1)}.christianity-offering-pile.is-play-target{border-color:var(--christianity-theme-gold-ring);background:linear-gradient(180deg,#fffaf0f5,#fffffff0),radial-gradient(circle at 82% 14%,rgba(250,204,21,.28) 0 .7rem,transparent .72rem);box-shadow:inset 0 0 0 .12rem #d6a21d3d,0 .8rem 1.55rem var(--christianity-theme-shadow);animation:christianity-target-pulse 1.45s ease-in-out infinite}.christianity-card-preview-card--back{width:clamp(4rem,14vw,5.7rem);min-height:0;aspect-ratio:var(--christianity-card-aspect);place-items:center;padding:.55rem;box-shadow:0 .8rem 1.55rem #24304424;transform-origin:50% -18%;background:radial-gradient(circle at 50% 44%,rgba(143,215,242,.22),transparent 40%),linear-gradient(135deg,#102a431f,#102a4305),repeating-linear-gradient(45deg,#dbeafe 0 .34rem,#f8fafc .34rem .68rem)}.christianity-card-back-symbol{width:min(72%,3.65rem);height:auto;opacity:.92;filter:drop-shadow(0 .25rem .35rem rgba(16,42,67,.16)) saturate(.95)}.christianity-card-preview-card--battle{justify-self:center;width:var(--christianity-battle-card-width);min-width:0;height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);margin-inline:0}.christianity-card-preview-card>span,.christianity-card-mini>span,.christianity-offering-pile>span,.christianity-offering-card>span,.christianity-leader-card>span,.christianity-zone-card>span,.christianity-zone-pile>span{position:relative;z-index:2;align-self:start;font-weight:700;line-height:1.05}.christianity-card-preview-card>strong,.christianity-card-mini>strong,.christianity-offering-pile>strong,.christianity-offering-card>strong,.christianity-leader-card>strong,.christianity-zone-card>strong,.christianity-zone-pile>strong{position:relative;z-index:3;justify-self:end;align-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-player-rack{box-sizing:border-box;display:grid;grid-template-columns:minmax(5.9rem,7rem) minmax(5rem,1fr) minmax(4.2rem,7rem);gap:.45rem;align-items:end;justify-items:stretch;width:100%;max-width:100%;min-width:0}.christianity-player-rack--opponent{align-items:start}.christianity-hand-meter{position:absolute;top:0;right:.35rem;z-index:4;display:inline-grid;grid-auto-flow:column;gap:.25rem;align-items:center;min-height:1.7rem;padding:.18rem .46rem;border:1px solid rgba(36,48,68,.12);border-radius:999px;background:#ffffffe6;box-shadow:0 .35rem .8rem #102a4314}.christianity-hand-meter--opponent{top:.15rem}.christianity-hand-meter span{color:#1f293394;font-size:.68rem}.christianity-hand-meter strong{font-size:.86rem}.christianity-player-badge,.christianity-player-command{display:grid;gap:.35rem;justify-items:center;min-width:0}.christianity-player-badge{align-content:start;color:#1f2933c2;font-size:.74rem}.christianity-player-badge--opponent{justify-self:center;grid-auto-flow:column;align-items:center;justify-content:center}.christianity-player-badge strong{max-width:6.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.christianity-avatar{display:grid;place-items:center;width:1.85rem;height:1.85rem;border-radius:999px;color:#fff;font-size:.76rem;font-weight:800;box-shadow:0 .35rem .9rem #102a4329}.christianity-offerings-zone{display:flex;flex-wrap:wrap;gap:.25rem;justify-content:flex-start;justify-self:start;width:100%}.christianity-card-mini,.christianity-offering-pile,.christianity-offering-card,.christianity-leader-card,.christianity-zone-card,.christianity-zone-pile{display:grid;align-content:space-between;min-height:4.9rem;padding:.48rem;text-align:left}.christianity-card-frame{display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;align-content:stretch}.christianity-offering-pile,.christianity-zone-card,.christianity-zone-pile{grid-template-rows:auto minmax(2.6rem,1fr) auto;align-content:stretch;gap:.32rem}.christianity-card-mini{width:3.5rem}.christianity-offering-pile{position:relative;isolation:isolate;overflow:hidden;justify-self:start;width:min(100%,5.9rem);min-height:7.1rem;padding:.95rem .52rem .6rem;background:linear-gradient(180deg,#fff,#f8fafc),linear-gradient(135deg,rgba(250,204,21,.18),transparent 42%)}.christianity-offering-pile i{position:absolute;top:2.45rem;left:.72rem;z-index:-1;width:2.55rem;height:3.55rem;border:1px solid rgba(16,42,67,.18);border-radius:.35rem;background:linear-gradient(180deg,#ffffffeb,#f1f5f9eb),radial-gradient(circle at 78% 18%,#facc15 0 .38rem,transparent .4rem);box-shadow:0 .35rem .85rem #102a431a;transform:rotate(-5deg)}.christianity-offering-pile i:nth-child(2){transform:translate(.28rem,.08rem) rotate(3deg)}.christianity-offering-pile i:nth-child(3){transform:translate(.55rem,.18rem) rotate(-1deg)}.christianity-leader-card{align-self:center;justify-self:center;width:clamp(4.75rem,17vw,6rem);min-height:0;aspect-ratio:var(--christianity-card-aspect)}.christianity-rack-spacer{display:block;min-height:1px}.christianity-battle-zone{grid-template-columns:repeat(4,var(--christianity-battle-card-width))}.christianity-shared-zone{box-sizing:border-box;display:grid;grid-template-columns:repeat(3,minmax(4.3rem,1fr));align-items:stretch;width:100%;max-width:100%;min-width:0}.christianity-zone-card,.christianity-zone-pile{min-height:6.45rem;padding:.7rem .52rem .55rem}.christianity-zone-pile{position:relative;isolation:isolate;overflow:hidden;box-shadow:inset 0 0 0 999px #ffffff1f}.christianity-zone-pile i{position:absolute;top:2.2rem;right:.72rem;z-index:-1;width:2.7rem;height:3.7rem;border:1px solid rgba(16,42,67,.18);border-radius:.35rem;background:#f8fafc;box-shadow:0 .35rem .85rem #102a431c;transform:rotate(4deg)}.christianity-zone-pile i:nth-child(2){transform:translate(-.28rem,.12rem) rotate(-3deg)}.christianity-zone-pile i:nth-child(3){background:linear-gradient(135deg,#102a4329,#102a4308),repeating-linear-gradient(45deg,#dbeafe 0 .33rem,#fff .33rem .66rem);transform:translate(-.54rem,.24rem) rotate(2deg)}.christianity-floating-card-shell{position:fixed;top:50%;left:50%;z-index:80;display:grid;gap:.55rem;width:min(26rem,calc(100vw - 1.25rem));padding-top:2.35rem;transform:translate(-50%,-50%)}.christianity-floating-card{position:relative;z-index:1;display:grid;grid-template-rows:auto minmax(9rem,1.25fr) auto minmax(7rem,.9fr) auto;gap:.58rem;width:100%;min-height:min(29rem,calc(100vh - 3.5rem));padding:.72rem;border:1px solid rgba(36,48,68,.18);border-radius:.75rem;background:linear-gradient(180deg,#fffffff5,#f8fafcf5),radial-gradient(circle at 20% 0%,var(--christianity-theme-gold-soft),transparent 45%);box-shadow:0 0 0 .18rem #fff4c294,0 0 2.2rem var(--christianity-theme-glow),0 2.4rem 5rem #102a4357,inset 0 0 0 .35rem #ffffff8c;touch-action:none;transform:translate(var(--preview-shift-x, 0px),var(--preview-shift-y, 0px)) perspective(48rem) rotateX(var(--preview-rotate-x, 5deg)) rotateY(var(--preview-rotate-y, -5deg));transition:transform 90ms ease-out}.christianity-full-card-header{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:.42rem;align-items:center}.christianity-full-card-header strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:clamp(1.25rem,5vw,1.85rem);line-height:1.04}.christianity-full-card-type-icon,.christianity-full-card-cost{display:grid;place-items:center;border-radius:999px}.christianity-full-card-type-icon{width:1.6rem;height:1.6rem;background:radial-gradient(circle at 50% 50%,rgba(95,111,42,.72) 0 .22rem,transparent .24rem),#2430441a}.christianity-full-card-cost{width:2.1rem;height:2.1rem;background:#ffd91a;color:#243044;font-size:1.35rem;font-weight:900;box-shadow:inset 0 -.12rem #52401c2e}.christianity-full-card-art{position:relative;display:grid;place-items:center;min-height:9rem;overflow:hidden;border-radius:.48rem;background:linear-gradient(135deg,#5f6f2a33,#d6a21d29),radial-gradient(circle at 50% 25%,rgba(255,255,255,.76),transparent 42%),#dbe7ef;box-shadow:inset 0 0 0 1px #24304414}.christianity-full-card-art img{width:100%;height:100%;object-fit:cover}.christianity-full-card-art>span{max-width:80%;color:#24304494;font-size:clamp(1.1rem,5vw,1.8rem);font-weight:900;line-height:1.05;text-align:center}.christianity-full-card-art small{position:absolute;right:0;bottom:.55rem;min-width:5rem;padding:.16rem .48rem;border-radius:999px 0 0 999px;background:#ffffffe6;box-shadow:0 .3rem .8rem #102a431f;color:#1f2933bd;font-size:.68rem;font-style:italic;font-weight:900;text-align:center;text-transform:uppercase}.christianity-full-card-verse,.christianity-full-card-effect{display:grid;gap:.32rem}.christianity-full-card-verse p,.christianity-full-card-effect p{margin:0;line-height:1.25}.christianity-full-card-verse{color:#171923;font-family:Georgia,Times New Roman,serif;font-size:clamp(.72rem,2.7vw,.86rem)}.christianity-full-card-verse strong{font-family:inherit;font-size:.78rem;font-weight:900}.christianity-full-card-effect{position:relative;align-content:start;min-height:7rem;padding:.6rem .7rem;overflow:hidden;border-radius:.45rem;background:radial-gradient(circle at 50% 72%,rgba(36,48,68,.07),transparent 34%),#ffffffdb}.christianity-full-card-stats{display:flex;gap:1rem;min-height:1.35rem}.christianity-full-card-stats strong{font-size:1rem;line-height:1}.christianity-full-card-effect>div:last-of-type{display:grid;gap:.12rem}.christianity-full-card-effect>div:last-of-type strong{font-size:.82rem}.christianity-full-card-effect p{font-size:clamp(.78rem,2.9vw,.92rem)}.christianity-full-card-rarity{position:absolute;top:.62rem;right:.62rem;width:.46rem;height:.46rem;border-radius:.12rem;transform:rotate(45deg)}.christianity-full-card-rarity.is-normal{background:#d1d5db}.christianity-full-card-rarity.is-uncommon{background:#22c55e}.christianity-full-card-rarity.is-rare{background:#3b82f6}.christianity-full-card-rarity.is-legendary{background:#eab308}.christianity-full-card-footer{display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;gap:.34rem;align-items:center;color:#1f2933ad;font-size:.58rem;line-height:1;text-transform:uppercase}.christianity-full-card-footer span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.christianity-floating-card-close{position:absolute;top:0;right:.15rem;z-index:4;min-height:2rem;padding:0 .6rem;border:1px solid rgba(36,48,68,.14);border-radius:999px;background:#ffffffe6;color:#1f2933c7;font:inherit;font-size:.76rem;font-weight:800;box-shadow:0 .45rem 1rem #102a431a}.christianity-preview-backdrop,.christianity-history-backdrop,.christianity-info-backdrop{position:fixed;inset:0;border:0;border-radius:0;background:#0f172a75}.christianity-preview-backdrop{z-index:79}.christianity-info-backdrop{z-index:50}.christianity-info-panel{position:fixed;top:50%;left:50%;z-index:51;width:min(31rem,calc(100vw - 1.25rem));max-height:min(34rem,calc(100vh - 2rem));padding-top:2.35rem;transform:translate(-50%,-50%)}.christianity-info-close{position:absolute;top:0;right:.15rem;z-index:2}.christianity-rule-note{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.85rem;max-height:inherit;padding:1rem;overflow-y:auto;border:1px solid rgba(36,48,68,.14);border-radius:.9rem;background:linear-gradient(180deg,#fffffff7,#f8fafcf7),radial-gradient(circle at 8% 0%,rgba(37,99,235,.1),transparent 38%);box-shadow:0 1.2rem 2.6rem #102a433d,inset 0 0 0 .25rem #ffffff85}.christianity-rule-note-icon{display:grid;place-items:center;width:2.1rem;height:2.1rem;border-radius:999px;background:color-mix(in srgb,var(--christianity-theme-focus) 12%,#ffffff);color:var(--christianity-theme-focus);font-size:1rem;font-weight:900;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--christianity-theme-focus) 24%,transparent)}.christianity-rule-note small,.christianity-rule-note strong,.christianity-rule-note p,.christianity-rule-note h2{margin:0}.christianity-rule-note small{color:#1f29339e;font-size:.78rem;font-weight:800;text-transform:uppercase}.christianity-rule-note h2{margin-top:.18rem;font-size:clamp(1.5rem,7vw,2.2rem);line-height:1.05}.christianity-rule-note strong{display:inline-flex;width:fit-content;margin-top:.55rem;padding:.22rem .55rem;border-radius:999px;background:#edf2f7;font-size:.92rem}.christianity-rule-note p{margin-top:.75rem;color:#1f2933c7;line-height:1.45}.christianity-rule-note ul{display:grid;gap:.45rem;margin:.8rem 0 0;padding-left:1.05rem;color:#1f2933c7;line-height:1.35}.christianity-floating-card>small,.christianity-floating-card>span{color:#1f2933a3}.christianity-floating-card>strong{font-size:clamp(1.55rem,8vw,2.35rem);line-height:1.05}.christianity-floating-card>p{margin:0;align-self:end;font-size:.95rem;line-height:1.35}.christianity-floating-card-actions{position:relative;z-index:4;display:flex;justify-content:center;padding:0 .35rem;transform:translateZ(0)}.christianity-floating-card-actions button{min-height:2.35rem;padding:0 1rem;border:0;border-radius:999px;background:#102a43;color:#fff;font:inherit;font-size:.9rem;font-weight:800;box-shadow:0 .65rem 1.3rem #102a432e}.christianity-floating-card-actions button:disabled{cursor:not-allowed;opacity:.45}@media (min-width: 52rem){.christianity-floating-card-shell{width:min(29rem,calc(100vw - 3rem))}.christianity-floating-card{min-height:min(35rem,calc(100vh - 4rem));padding:1.35rem}}.christianity-history-backdrop{z-index:40}.christianity-history-drawer{position:fixed;right:auto;bottom:max(.5rem,env(safe-area-inset-bottom));left:50%;z-index:41;display:grid;grid-template-rows:auto minmax(0,1fr);gap:.75rem;width:min(calc(100vw - 1rem),44rem);min-height:min(18rem,calc(100dvh - 1rem));max-height:min(32rem,calc(100dvh - 2rem));padding:.8rem;border:1px solid rgba(36,48,68,.16);border-radius:.75rem;background:#fffffffa;box-shadow:0 1.5rem 4rem #102a4347;transform:translate(-50%)}.christianity-history-drawer header{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-history-drawer h2,.christianity-history-drawer p{margin:0}.christianity-history-drawer header span{display:grid;place-items:center;min-width:1.85rem;height:1.85rem;border-radius:999px;background:#edf2f7;font-weight:800}.christianity-dialog-actions{display:flex;align-items:center;gap:.45rem}.christianity-dialog-close{min-height:1.85rem;padding:0 .62rem;border:1px solid rgba(36,48,68,.14);border-radius:999px;background:#fff;color:#1f2933c7;font:inherit;font-size:.76rem;font-weight:800;box-shadow:0 .35rem .8rem #102a4314}.christianity-history-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(5.4rem,1fr));gap:.55rem;min-height:0;overflow-y:scroll;scrollbar-color:rgba(36,48,68,.32) rgba(226,232,240,.72);scrollbar-gutter:stable;padding:.1rem .1rem .25rem}.christianity-history-grid::-webkit-scrollbar,.christianity-offering-list::-webkit-scrollbar{width:.65rem}.christianity-history-grid::-webkit-scrollbar-track,.christianity-offering-list::-webkit-scrollbar-track{border-radius:999px;background:#e2e8f0b8}.christianity-history-grid::-webkit-scrollbar-thumb,.christianity-offering-list::-webkit-scrollbar-thumb{border:.14rem solid rgba(226,232,240,.72);border-radius:999px;background:#24304452}.christianity-offerings-drawer{width:min(calc(100vw - 1rem),48rem);min-height:min(20rem,calc(100dvh - 1rem));max-height:min(34rem,calc(100dvh - 2rem))}.christianity-offering-list{display:grid;gap:.6rem;min-height:0;overflow-y:scroll;scrollbar-color:rgba(36,48,68,.32) rgba(226,232,240,.72);scrollbar-gutter:stable;padding:.1rem}.christianity-offering-row{display:grid;grid-template-columns:minmax(4.9rem,6.2rem) minmax(0,1fr);gap:.65rem;align-items:stretch;padding:.45rem;border:1px solid rgba(36,48,68,.12);border-radius:.65rem;background:#fff}.christianity-offering-row.is-exhausted{opacity:.68}.christianity-offering-card{min-height:7.4rem;background:linear-gradient(180deg,#fffffff5,#f8fafcf5),radial-gradient(circle at 82% 14%,#facc15 0 .48rem,transparent .5rem);box-shadow:0 .45rem 1rem #102a431a}.christianity-offering-card.christianity-card-frame{min-height:0;aspect-ratio:var(--christianity-card-aspect)}.christianity-offering-card small{color:#1f293394;font-size:.66rem;text-transform:uppercase}.christianity-offering-card p,.christianity-offering-row p{margin:0}.christianity-offering-card p{align-self:end;color:#1f2933a3;font-size:.72rem;line-height:1.2}.christianity-offering-row>div{display:grid;gap:.35rem;align-content:center;min-width:0}.christianity-offering-row>div p{color:#1f2933b8;font-size:.85rem;line-height:1.3}.christianity-offering-row>div button{justify-self:start;min-height:2.2rem;padding:0 .7rem;border:1px solid rgba(16,42,67,.16);border-radius:.5rem;background:#102a43;color:#fff;font:inherit;font-weight:800}.christianity-offering-row>div button:disabled{background:#e2e8f0;color:#1f293394}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.55}button:focus-visible{outline:.1875rem solid color-mix(in srgb,var(--christianity-theme-focus) 24%,transparent);outline-offset:.125rem}@media (max-width: 720px){.christianity-shell{padding:.55rem 0;border-right:0;border-left:0;border-radius:0}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{align-items:stretch;flex-direction:column}.christianity-match-strip{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:.35rem;padding:.35rem}.christianity-match-player{gap:.35rem}.christianity-match-player small{display:none}.christianity-scoreboard{min-width:3.65rem;padding:0 .35rem}.christianity-scoreboard strong{font-size:1.05rem}.christianity-table{gap:.35rem;padding-right:.25rem;padding-left:.25rem}.christianity-player-side{padding:.3rem .25rem}.christianity-battle-zone{--christianity-battle-card-width: min(5.2rem, calc((100vw - 4.25rem)/4) );grid-template-columns:repeat(4,var(--christianity-battle-card-width));justify-content:center;min-height:8.75rem;overflow-x:clip}.christianity-hand-fan{min-height:11.45rem;padding-bottom:2rem;overflow:visible}.christianity-hand-shelf{min-height:12.65rem;margin-top:-1rem;padding-top:1.35rem;padding-bottom:.9rem}.christianity-hand-shelf--opponent{min-height:6.65rem;margin-top:0;margin-bottom:0;padding-top:.4rem;padding-bottom:.85rem}.christianity-player-rack{grid-template-columns:minmax(4.5rem,5.7rem) minmax(4.4rem,1fr) minmax(3.5rem,4.8rem)}.christianity-shared-zone{gap:.45rem;grid-template-columns:repeat(3,minmax(0,1fr))}.christianity-zone-card,.christianity-zone-pile{min-height:6.15rem;padding:.58rem .46rem .5rem;gap:.24rem}.christianity-zone-pile i{top:2rem;right:.52rem;width:2.35rem;height:3.25rem}.christianity-offering-pile{min-height:6.85rem;padding:.88rem .46rem .55rem;gap:.24rem}.christianity-offering-pile i{top:2.25rem;left:.56rem;width:2.35rem;height:3.25rem}.christianity-card-preview-card{width:clamp(4.2rem,20vw,5.7rem);height:auto;min-height:0}.christianity-leader-card{width:clamp(4.55rem,20vw,5.7rem);min-height:0}.christianity-offering-row{grid-template-columns:minmax(4.5rem,5.5rem) minmax(0,1fr);gap:.5rem}.christianity-hand-fan--opponent{min-height:5.75rem;padding-bottom:.7rem}}\n"], dependencies: [{ kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: LightRippleDirective, selector: "[valLightRipple]" }] }); }
|
|
70062
|
+
}
|
|
70063
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChristianityGameComponent, decorators: [{
|
|
70064
|
+
type: Component,
|
|
70065
|
+
args: [{ selector: 'val-christianity-game', standalone: true, imports: [CdkDrag, CdkDropList, LightRippleDirective], template: `
|
|
70066
|
+
<main class="christianity-shell">
|
|
70067
|
+
<section class="christianity-header">
|
|
70068
|
+
<div>
|
|
70069
|
+
<p>{{ t('christianityEyebrow') }}</p>
|
|
70070
|
+
<h1>{{ t('christianityTitle') }}</h1>
|
|
70071
|
+
</div>
|
|
70072
|
+
<div class="christianity-turn" [class.is-own-turn]="isOwnTurn()">
|
|
70073
|
+
<span>{{ t('christianityTurn') }}</span>
|
|
70074
|
+
<strong>{{ currentPlayer().displayName }}</strong>
|
|
70075
|
+
</div>
|
|
70076
|
+
</section>
|
|
70077
|
+
|
|
70078
|
+
<section class="christianity-match-strip" [attr.aria-label]="t('christianityMatchScore')">
|
|
70079
|
+
<article class="christianity-match-player">
|
|
70080
|
+
<span class="christianity-avatar" [style.background]="player().avatarColor">{{ player().avatar }}</span>
|
|
70081
|
+
<div>
|
|
70082
|
+
<strong>{{ player().displayName }}</strong>
|
|
70083
|
+
<small>{{ player().leaderName }} · {{ player().leaderHp }}/{{ player().leaderMaxHp }}</small>
|
|
70084
|
+
</div>
|
|
70085
|
+
</article>
|
|
70086
|
+
<div class="christianity-scoreboard">
|
|
70087
|
+
<span>{{ t('christianityMatch') }}</span>
|
|
70088
|
+
<strong>{{ game().matchScore.P1 }}-{{ game().matchScore.P2 }}</strong>
|
|
70089
|
+
</div>
|
|
70090
|
+
<article class="christianity-match-player christianity-match-player--opponent">
|
|
70091
|
+
<span class="christianity-avatar" [style.background]="opponent().avatarColor">{{ opponent().avatar }}</span>
|
|
70092
|
+
<div>
|
|
70093
|
+
<strong>{{ opponent().displayName }}</strong>
|
|
70094
|
+
<small>{{ opponent().leaderName }} · {{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</small>
|
|
70095
|
+
</div>
|
|
70096
|
+
</article>
|
|
70097
|
+
</section>
|
|
70098
|
+
|
|
70099
|
+
<section class="christianity-hand-shelf christianity-hand-shelf--opponent">
|
|
70100
|
+
<div class="christianity-hand-meter christianity-hand-meter--opponent">
|
|
70101
|
+
<span>{{ t('christianityHand') }}</span>
|
|
70102
|
+
<strong>{{ opponentHandCount() }}</strong>
|
|
70103
|
+
</div>
|
|
70104
|
+
<section class="christianity-hand-fan christianity-hand-fan--opponent" [attr.aria-label]="t('christianityOpponentHand')">
|
|
70105
|
+
@for (_ of hiddenHandCards(opponentHandCount()); track $index) {
|
|
70106
|
+
<button
|
|
70107
|
+
type="button"
|
|
70108
|
+
class="christianity-card-preview-card christianity-card-frame christianity-card-frame--back"
|
|
70109
|
+
valLightRipple
|
|
70110
|
+
[style.transform]="fanTransform($index, opponentHandCount(), true)"
|
|
70111
|
+
[attr.aria-label]="t('christianityHiddenCard')"
|
|
70112
|
+
>
|
|
70113
|
+
<img class="christianity-card-back-symbol" src="assets/games/christianity/card-symbol.svg" alt="" />
|
|
70114
|
+
</button>
|
|
70115
|
+
}
|
|
70116
|
+
</section>
|
|
70117
|
+
</section>
|
|
70118
|
+
|
|
70119
|
+
<section class="christianity-table" [attr.aria-label]="t('christianityTable')">
|
|
70120
|
+
<section class="christianity-player-side christianity-player-side--opponent">
|
|
70121
|
+
<section class="christianity-player-rack christianity-player-rack--opponent">
|
|
70122
|
+
<div class="christianity-offerings-zone">
|
|
70123
|
+
<button type="button" class="christianity-offering-pile" valLightRipple (click)="openOfferings('P2')">
|
|
70124
|
+
<i aria-hidden="true"></i>
|
|
70125
|
+
<i aria-hidden="true"></i>
|
|
70126
|
+
<i aria-hidden="true"></i>
|
|
70127
|
+
<span>{{ t('christianityOfferings') }}</span>
|
|
70128
|
+
<strong>{{ readyOfferings(opponent()) }}/{{ totalOfferings(opponent()) }}</strong>
|
|
70129
|
+
</button>
|
|
70130
|
+
</div>
|
|
70131
|
+
<button type="button" class="christianity-leader-card christianity-card-frame christianity-card-frame--leader" valLightRipple [class.is-target]="selectedAttacker() && !hasOpponentGuards()" (click)="handleOpponentLeader()">
|
|
70132
|
+
<header class="christianity-card-frame-header">
|
|
70133
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
70134
|
+
<strong>{{ opponent().leaderName }}</strong>
|
|
70135
|
+
<span>{{ opponent().leaderHp }}</span>
|
|
70136
|
+
</header>
|
|
70137
|
+
<section class="christianity-card-frame-art">
|
|
70138
|
+
<span>{{ opponent().leaderName }}</span>
|
|
70139
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
70140
|
+
</section>
|
|
70141
|
+
<section class="christianity-card-frame-effect">
|
|
70142
|
+
<strong>{{ opponent().leaderHp }}/{{ opponent().leaderMaxHp }}</strong>
|
|
70143
|
+
</section>
|
|
70144
|
+
</button>
|
|
70145
|
+
<span class="christianity-rack-spacer" aria-hidden="true"></span>
|
|
70146
|
+
</section>
|
|
70147
|
+
|
|
70148
|
+
<section class="christianity-battle-zone christianity-battle-zone--opponent" [attr.aria-label]="t('christianityOpponentBattle')">
|
|
70149
|
+
@for (slot of battleSlots('P2'); track slot.trackId) {
|
|
70150
|
+
@if (slot.card) {
|
|
70151
|
+
<button
|
|
70152
|
+
type="button"
|
|
70153
|
+
class="christianity-card-preview-card christianity-card-preview-card--battle christianity-card-frame christianity-card-frame--battle"
|
|
70154
|
+
valLightRipple
|
|
70155
|
+
[class.is-target]="selectedAttacker()"
|
|
70156
|
+
(click)="handleOpponentCharacter(slot.card)"
|
|
70157
|
+
>
|
|
70158
|
+
<header class="christianity-card-frame-header">
|
|
70159
|
+
<small>{{ t('christianityCost') }} {{ cardDefinition(slot.card.cardId).cost }}</small>
|
|
70160
|
+
<strong>{{ slot.card.name }}</strong>
|
|
70161
|
+
<span>{{ cardDefinition(slot.card.cardId).cost }}</span>
|
|
70162
|
+
</header>
|
|
70163
|
+
<section class="christianity-card-frame-art">
|
|
70164
|
+
<span>{{ slot.card.name }}</span>
|
|
70165
|
+
<small>{{ t('christianityCharacterCard') }}</small>
|
|
70166
|
+
</section>
|
|
70167
|
+
<section class="christianity-card-frame-effect">
|
|
70168
|
+
<strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
|
|
70169
|
+
</section>
|
|
70170
|
+
</button>
|
|
70171
|
+
} @else {
|
|
70172
|
+
<span class="christianity-slot"></span>
|
|
70173
|
+
}
|
|
70174
|
+
}
|
|
70175
|
+
</section>
|
|
70176
|
+
</section>
|
|
70177
|
+
|
|
70178
|
+
<section class="christianity-shared-zone" [attr.aria-label]="t('christianitySharedZone')">
|
|
70179
|
+
<button type="button" class="christianity-zone-pile christianity-zone-pile--history" valLightRipple (click)="openHistory()">
|
|
70180
|
+
<i aria-hidden="true"></i>
|
|
70181
|
+
<i aria-hidden="true"></i>
|
|
70182
|
+
<i aria-hidden="true"></i>
|
|
70183
|
+
<span>{{ t('christianityHistory') }}</span>
|
|
70184
|
+
<strong>{{ game().historyZone.length }}</strong>
|
|
70185
|
+
</button>
|
|
70186
|
+
<button type="button" class="christianity-zone-pile christianity-zone-pile--deck" valLightRipple aria-live="polite" (click)="inspectDeck()">
|
|
70187
|
+
<i aria-hidden="true"></i>
|
|
70188
|
+
<i aria-hidden="true"></i>
|
|
70189
|
+
<i aria-hidden="true"></i>
|
|
70190
|
+
<span>{{ t('christianityDeck') }}</span>
|
|
70191
|
+
<strong>{{ game().sharedDeck.length }}</strong>
|
|
70192
|
+
</button>
|
|
70193
|
+
<div class="christianity-zone-card">
|
|
70194
|
+
<span>{{ t('christianityPlace') }}</span>
|
|
70195
|
+
<strong>{{ t('christianityEmpty') }}</strong>
|
|
70196
|
+
</div>
|
|
70197
|
+
</section>
|
|
70198
|
+
|
|
70199
|
+
<section class="christianity-player-side">
|
|
70200
|
+
<section class="christianity-battle-zone" [class.is-placing-card]="canPlaceSelectedCharacter() || isDraggingCharacter()" [attr.aria-label]="t('christianityYourBattle')">
|
|
70201
|
+
@for (slot of battleSlots('P1'); track slot.trackId) {
|
|
70202
|
+
@if (slot.card) {
|
|
70203
|
+
<button
|
|
70204
|
+
type="button"
|
|
70205
|
+
class="christianity-card-preview-card christianity-card-preview-card--battle christianity-card-frame christianity-card-frame--battle"
|
|
70206
|
+
valLightRipple
|
|
70207
|
+
[class.is-selected]="selectedAttacker()?.instanceId === slot.card.instanceId"
|
|
70208
|
+
[class.is-exhausted]="!slot.card.canAttack"
|
|
70209
|
+
(click)="selectAttacker(slot.card)"
|
|
70210
|
+
>
|
|
70211
|
+
<header class="christianity-card-frame-header">
|
|
70212
|
+
<small>{{ t('christianityCost') }} {{ cardDefinition(slot.card.cardId).cost }}</small>
|
|
70213
|
+
<strong>{{ slot.card.name }}</strong>
|
|
70214
|
+
<span>{{ cardDefinition(slot.card.cardId).cost }}</span>
|
|
70215
|
+
</header>
|
|
70216
|
+
<section class="christianity-card-frame-art">
|
|
70217
|
+
<span>{{ slot.card.name }}</span>
|
|
70218
|
+
<small>{{ t('christianityCharacterCard') }}</small>
|
|
70219
|
+
</section>
|
|
70220
|
+
<section class="christianity-card-frame-effect">
|
|
70221
|
+
<strong>{{ slot.card.attack }} / {{ slot.card.currentHp }}</strong>
|
|
70222
|
+
</section>
|
|
70223
|
+
</button>
|
|
70224
|
+
} @else {
|
|
70225
|
+
<button
|
|
70226
|
+
type="button"
|
|
70227
|
+
class="christianity-slot"
|
|
70228
|
+
cdkDropList
|
|
70229
|
+
[id]="battleSlotDropId($index)"
|
|
70230
|
+
[cdkDropListData]="$index"
|
|
70231
|
+
[cdkDropListConnectedTo]="['christianity-hand-source']"
|
|
70232
|
+
[cdkDropListEnterPredicate]="canDropOnBattleSlot"
|
|
70233
|
+
[class.christianity-slot--play-target]="canPlaceSelectedCharacter() || isDraggingCharacter()"
|
|
70234
|
+
valLightRipple
|
|
70235
|
+
(cdkDropListDropped)="dropOnBattleSlot($event, $index)"
|
|
70236
|
+
(click)="playSelectedCard($index)"
|
|
70237
|
+
>
|
|
70238
|
+
@if (canPlaceSelectedCharacter() || isDraggingCharacter()) {
|
|
70239
|
+
<span>{{ t('christianityPlayHere') }}</span>
|
|
70240
|
+
}
|
|
70241
|
+
</button>
|
|
70242
|
+
}
|
|
70243
|
+
}
|
|
70244
|
+
</section>
|
|
70245
|
+
|
|
70246
|
+
<section class="christianity-player-rack">
|
|
70247
|
+
<div class="christianity-offerings-zone">
|
|
70248
|
+
<button
|
|
70249
|
+
type="button"
|
|
70250
|
+
class="christianity-offering-pile"
|
|
70251
|
+
cdkDropList
|
|
70252
|
+
id="christianity-offerings-drop"
|
|
70253
|
+
valLightRipple
|
|
70254
|
+
[cdkDropListConnectedTo]="['christianity-hand-source']"
|
|
70255
|
+
[class.is-play-target]="canPlaceSelectedOffering() || isDraggingOffering()"
|
|
70256
|
+
[cdkDropListEnterPredicate]="canDropOnOfferings"
|
|
70257
|
+
(cdkDropListDropped)="dropOnOfferings($event)"
|
|
70258
|
+
(click)="handleOfferingPile('P1')"
|
|
70259
|
+
>
|
|
70260
|
+
<i aria-hidden="true"></i>
|
|
70261
|
+
<i aria-hidden="true"></i>
|
|
70262
|
+
<i aria-hidden="true"></i>
|
|
70263
|
+
<span>{{ t('christianityOfferings') }}</span>
|
|
70264
|
+
<strong>{{ readyOfferings(player()) }}/{{ totalOfferings(player()) }}</strong>
|
|
70265
|
+
</button>
|
|
70266
|
+
</div>
|
|
70267
|
+
<button type="button" class="christianity-leader-card christianity-card-frame christianity-card-frame--leader" valLightRipple (click)="inspectLeader('P1')">
|
|
70268
|
+
<header class="christianity-card-frame-header">
|
|
70269
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
70270
|
+
<strong>{{ player().leaderName }}</strong>
|
|
70271
|
+
<span>{{ player().leaderHp }}</span>
|
|
70272
|
+
</header>
|
|
70273
|
+
<section class="christianity-card-frame-art">
|
|
70274
|
+
<span>{{ player().leaderName }}</span>
|
|
70275
|
+
<small>{{ t('christianityLeaderCard') }}</small>
|
|
70276
|
+
</section>
|
|
70277
|
+
<section class="christianity-card-frame-effect">
|
|
70278
|
+
<strong>{{ player().leaderHp }}/{{ player().leaderMaxHp }}</strong>
|
|
70279
|
+
</section>
|
|
70280
|
+
</button>
|
|
70281
|
+
<div class="christianity-player-command">
|
|
70282
|
+
<div class="christianity-player-badge">
|
|
70283
|
+
<span class="christianity-avatar" [style.background]="player().avatarColor">{{ player().avatar }}</span>
|
|
70284
|
+
<strong>{{ player().displayName }}</strong>
|
|
70285
|
+
</div>
|
|
70286
|
+
<button
|
|
70287
|
+
type="button"
|
|
70288
|
+
class="christianity-end-turn"
|
|
70289
|
+
(click)="endTurn()"
|
|
70290
|
+
>
|
|
70291
|
+
{{ t('christianityEndTurn') }}
|
|
70292
|
+
</button>
|
|
70293
|
+
</div>
|
|
70294
|
+
</section>
|
|
70295
|
+
</section>
|
|
70296
|
+
</section>
|
|
70297
|
+
|
|
70298
|
+
<section class="christianity-hand-shelf">
|
|
70299
|
+
<div class="christianity-hand-meter">
|
|
70300
|
+
<span>{{ t('christianityHand') }}</span>
|
|
70301
|
+
<strong>{{ player().hand?.length ?? 0 }}</strong>
|
|
70302
|
+
</div>
|
|
70303
|
+
<section
|
|
70304
|
+
class="christianity-hand-fan"
|
|
70305
|
+
cdkDropList
|
|
70306
|
+
id="christianity-hand-source"
|
|
70307
|
+
[cdkDropListConnectedTo]="dropTargetIds()"
|
|
70308
|
+
[attr.aria-label]="t('christianityYourHand')"
|
|
70309
|
+
(pointerleave)="clearHoveredHandIndex()"
|
|
70310
|
+
>
|
|
70311
|
+
@for (cardId of player().hand ?? []; track cardId + $index) {
|
|
70312
|
+
@let card = cardDefinition(cardId);
|
|
70313
|
+
<div
|
|
70314
|
+
class="christianity-hand-card-wrap"
|
|
70315
|
+
[class.is-selected]="selectedHandCard() === cardId"
|
|
70316
|
+
[class.is-dragging]="draggingCardId() === cardId"
|
|
70317
|
+
[style.z-index]="handCardZIndex($index)"
|
|
70318
|
+
[style.transform]="fanTransform($index, player().hand?.length ?? 0, false)"
|
|
70319
|
+
(pointerenter)="setHoveredHandIndex($index)"
|
|
70320
|
+
(pointerdown)="setHoveredHandIndex($index)"
|
|
70321
|
+
(pointerup)="releaseHoveredHand($event)"
|
|
70322
|
+
>
|
|
70323
|
+
<button
|
|
70324
|
+
type="button"
|
|
70325
|
+
class="christianity-card-preview-card christianity-card-preview-card--hand christianity-card-frame"
|
|
70326
|
+
cdkDrag
|
|
70327
|
+
valLightRipple
|
|
70328
|
+
[cdkDragData]="cardId"
|
|
70329
|
+
[cdkDragDisabled]="!canPlay(card)"
|
|
70330
|
+
[class.is-selected]="selectedHandCard() === cardId"
|
|
70331
|
+
[class.is-disabled]="!canPlay(card)"
|
|
70332
|
+
(cdkDragStarted)="startDraggingCard(cardId)"
|
|
70333
|
+
(cdkDragEnded)="endDraggingCard()"
|
|
70334
|
+
(click)="selectHandCard(cardId)"
|
|
70335
|
+
>
|
|
70336
|
+
<header class="christianity-card-frame-header">
|
|
70337
|
+
<small>{{ card.type === 'offering' ? t('christianityOfferingCard') : t('christianityCost') + ' ' + card.cost }}</small>
|
|
70338
|
+
<strong>{{ card.name }}</strong>
|
|
70339
|
+
<span>{{ card.type === 'offering' ? '+' + card.life : card.cost }}</span>
|
|
70340
|
+
</header>
|
|
70341
|
+
<section class="christianity-card-frame-art">
|
|
70342
|
+
<span>{{ card.name }}</span>
|
|
70343
|
+
<small>{{ cardTypeLabel(card) }}</small>
|
|
70344
|
+
</section>
|
|
70345
|
+
<section class="christianity-card-frame-effect">
|
|
70346
|
+
<strong>
|
|
70347
|
+
@if (card.type === 'offering') {
|
|
70348
|
+
+{{ card.life }}
|
|
70349
|
+
} @else {
|
|
70350
|
+
{{ card.attack }} / {{ card.life }}
|
|
70351
|
+
}
|
|
70352
|
+
</strong>
|
|
70353
|
+
</section>
|
|
70354
|
+
<footer class="christianity-card-frame-footer">
|
|
70355
|
+
<span>{{ card.edition ?? 'MVP' }}</span>
|
|
70356
|
+
<span>{{ card.collectorNumber ?? card.id }}</span>
|
|
70357
|
+
</footer>
|
|
70358
|
+
</button>
|
|
70359
|
+
<button
|
|
70360
|
+
type="button"
|
|
70361
|
+
class="christianity-card-eye"
|
|
70362
|
+
[attr.aria-label]="t('christianityPreviewCard')"
|
|
70363
|
+
(click)="inspectHandCard(cardId, true); $event.stopPropagation()"
|
|
70364
|
+
></button>
|
|
70365
|
+
</div>
|
|
70366
|
+
}
|
|
70367
|
+
</section>
|
|
70368
|
+
</section>
|
|
70369
|
+
|
|
70370
|
+
@if (selectedPreview()) {
|
|
70371
|
+
<button type="button" class="christianity-preview-backdrop" [attr.aria-label]="t('christianityClosePreview')" (click)="closePreview()"></button>
|
|
70372
|
+
<aside
|
|
70373
|
+
class="christianity-floating-card-shell"
|
|
70374
|
+
aria-live="polite"
|
|
70375
|
+
>
|
|
70376
|
+
<button type="button" class="christianity-floating-card-close" (click)="closePreview()">
|
|
70377
|
+
{{ t('close') }}
|
|
70378
|
+
</button>
|
|
70379
|
+
<div
|
|
70380
|
+
class="christianity-floating-card"
|
|
70381
|
+
[style.--preview-rotate-x]="previewTilt().rotateX + 'deg'"
|
|
70382
|
+
[style.--preview-rotate-y]="previewTilt().rotateY + 'deg'"
|
|
70383
|
+
[style.--preview-shift-x]="previewTilt().shiftX + 'px'"
|
|
70384
|
+
[style.--preview-shift-y]="previewTilt().shiftY + 'px'"
|
|
70385
|
+
(pointermove)="tiltPreview($event)"
|
|
70386
|
+
(pointerleave)="resetPreviewTilt()"
|
|
70387
|
+
>
|
|
70388
|
+
@if (selectedPreviewCard(); as previewCard) {
|
|
70389
|
+
<header class="christianity-full-card-header">
|
|
70390
|
+
<span class="christianity-full-card-type-icon" aria-hidden="true"></span>
|
|
70391
|
+
<strong>{{ previewCard.name }}</strong>
|
|
70392
|
+
<span class="christianity-full-card-cost">{{ previewCard.type === 'offering' ? '+' + previewCard.life : previewCard.cost }}</span>
|
|
70393
|
+
</header>
|
|
70394
|
+
<section class="christianity-full-card-art" [class.has-image]="previewCard.imageUrl">
|
|
70395
|
+
@if (previewCard.imageUrl) {
|
|
70396
|
+
<img [src]="previewCard.imageUrl" [alt]="previewCard.name" />
|
|
70397
|
+
} @else {
|
|
70398
|
+
<span>{{ previewCard.name }}</span>
|
|
70399
|
+
}
|
|
70400
|
+
<small>{{ cardTypeLabel(previewCard) }}</small>
|
|
70401
|
+
</section>
|
|
70402
|
+
<section class="christianity-full-card-verse">
|
|
70403
|
+
<p>{{ previewCard.verseText ?? selectedPreview()?.body }}</p>
|
|
70404
|
+
@if (previewCard.scripture) {
|
|
70405
|
+
<strong>{{ previewCard.scripture }}</strong>
|
|
70406
|
+
}
|
|
70407
|
+
</section>
|
|
70408
|
+
<section class="christianity-full-card-effect">
|
|
70409
|
+
<div class="christianity-full-card-stats">
|
|
70410
|
+
@if (previewCard.type === 'character') {
|
|
70411
|
+
<strong>{{ previewCard.attack }}</strong>
|
|
70412
|
+
<strong>{{ previewCard.life }}</strong>
|
|
70413
|
+
} @else {
|
|
70414
|
+
<strong>+{{ previewCard.life }}</strong>
|
|
70415
|
+
}
|
|
70416
|
+
</div>
|
|
70417
|
+
<div>
|
|
70418
|
+
@if (previewCard.abilityName) {
|
|
70419
|
+
<strong>{{ previewCard.abilityName }}</strong>
|
|
70420
|
+
}
|
|
70421
|
+
<p>{{ previewCard.abilityText ?? selectedPreview()?.body }}</p>
|
|
70422
|
+
</div>
|
|
70423
|
+
<span
|
|
70424
|
+
class="christianity-full-card-rarity"
|
|
70425
|
+
[class.is-normal]="!previewCard.rarity || previewCard.rarity === 'normal'"
|
|
70426
|
+
[class.is-uncommon]="previewCard.rarity === 'uncommon'"
|
|
70427
|
+
[class.is-rare]="previewCard.rarity === 'rare'"
|
|
70428
|
+
[class.is-legendary]="previewCard.rarity === 'legendary'"
|
|
70429
|
+
aria-hidden="true"
|
|
70430
|
+
></span>
|
|
70431
|
+
</section>
|
|
70432
|
+
<footer class="christianity-full-card-footer">
|
|
70433
|
+
<span>{{ previewCard.edition ?? 'MVP' }}</span>
|
|
70434
|
+
<span>{{ previewCard.collectorNumber ?? previewCard.id }}</span>
|
|
70435
|
+
<span>{{ previewCard.year ?? '2026' }} CHRISTIANITY</span>
|
|
70436
|
+
<span>{{ previewCard.author ?? 'MVP' }}</span>
|
|
70437
|
+
</footer>
|
|
70438
|
+
} @else {
|
|
70439
|
+
<small>{{ selectedPreview()?.eyebrow }}</small>
|
|
70440
|
+
<strong>{{ selectedPreview()?.title }}</strong>
|
|
70441
|
+
<span>{{ selectedPreview()?.meta }}</span>
|
|
70442
|
+
<p>{{ selectedPreview()?.body }}</p>
|
|
70443
|
+
}
|
|
70444
|
+
</div>
|
|
70445
|
+
@if (selectedPreview()?.source === 'hand') {
|
|
70446
|
+
<div class="christianity-floating-card-actions">
|
|
70447
|
+
<button type="button" [disabled]="previewActionDisabled()" (click)="playPreviewCard()">
|
|
70448
|
+
{{ selectedActionLabel() }}
|
|
70449
|
+
</button>
|
|
70450
|
+
</div>
|
|
70451
|
+
}
|
|
70452
|
+
</aside>
|
|
70453
|
+
}
|
|
70454
|
+
|
|
70455
|
+
@if (selectedInfo(); as info) {
|
|
70456
|
+
<button type="button" class="christianity-info-backdrop" [attr.aria-label]="t('close')" (click)="closeInfo()"></button>
|
|
70457
|
+
<aside class="christianity-info-panel" aria-live="polite">
|
|
70458
|
+
<button type="button" class="christianity-dialog-close christianity-info-close" (click)="closeInfo()">
|
|
70459
|
+
{{ t('close') }}
|
|
70460
|
+
</button>
|
|
70461
|
+
<div class="christianity-rule-note">
|
|
70462
|
+
<span class="christianity-rule-note-icon" aria-hidden="true">i</span>
|
|
70463
|
+
<div>
|
|
70464
|
+
<small>{{ info.eyebrow }}</small>
|
|
70465
|
+
<h2>{{ info.title }}</h2>
|
|
70466
|
+
<strong>{{ info.meta }}</strong>
|
|
70467
|
+
<p>{{ info.body }}</p>
|
|
70468
|
+
<ul>
|
|
70469
|
+
@for (fact of info.facts; track fact) {
|
|
70470
|
+
<li>{{ fact }}</li>
|
|
70471
|
+
}
|
|
70472
|
+
</ul>
|
|
70473
|
+
</div>
|
|
70474
|
+
</div>
|
|
70475
|
+
</aside>
|
|
70476
|
+
}
|
|
70477
|
+
|
|
70478
|
+
<section class="christianity-actions" aria-live="polite">
|
|
70479
|
+
<p>{{ statusText() }}</p>
|
|
70480
|
+
<div>
|
|
70481
|
+
<button type="button" [disabled]="selectedActionDisabled()" (click)="playSelectedCard()">
|
|
70482
|
+
{{ selectedActionLabel() }}
|
|
70483
|
+
</button>
|
|
70484
|
+
<button type="button" (click)="resetMock()">
|
|
70485
|
+
{{ t('christianityReset') }}
|
|
70486
|
+
</button>
|
|
70487
|
+
</div>
|
|
70488
|
+
</section>
|
|
70489
|
+
|
|
70490
|
+
@if (showHistory()) {
|
|
70491
|
+
<button type="button" class="christianity-history-backdrop" [attr.aria-label]="t('christianityCloseHistory')" (click)="showHistory.set(false)"></button>
|
|
70492
|
+
<section class="christianity-history-drawer">
|
|
70493
|
+
<header>
|
|
70494
|
+
<h2>{{ t('christianityHistory') }}</h2>
|
|
70495
|
+
<div class="christianity-dialog-actions">
|
|
70496
|
+
<span>{{ game().historyZone.length }}</span>
|
|
70497
|
+
<button type="button" class="christianity-dialog-close" (click)="showHistory.set(false)">
|
|
70498
|
+
{{ t('close') }}
|
|
70499
|
+
</button>
|
|
70500
|
+
</div>
|
|
70501
|
+
</header>
|
|
70502
|
+
@if (game().historyZone.length) {
|
|
70503
|
+
<div class="christianity-history-grid">
|
|
70504
|
+
@for (cardId of game().historyZone; track cardId + $index) {
|
|
70505
|
+
@let card = cardDefinition(cardId);
|
|
70506
|
+
<button type="button" class="christianity-card-preview-card christianity-card-frame christianity-card-frame--list" valLightRipple (click)="inspectHistoryCard(cardId)">
|
|
70507
|
+
<header class="christianity-card-frame-header">
|
|
70508
|
+
<small>{{ card.type === 'offering' ? t('christianityOfferingCard') : t('christianityCost') + ' ' + card.cost }}</small>
|
|
70509
|
+
<strong>{{ card.name }}</strong>
|
|
70510
|
+
<span>{{ card.type === 'offering' ? '+' + card.life : card.cost }}</span>
|
|
70511
|
+
</header>
|
|
70512
|
+
<section class="christianity-card-frame-art">
|
|
70513
|
+
<span>{{ card.name }}</span>
|
|
70514
|
+
<small>{{ cardTypeLabel(card) }}</small>
|
|
70515
|
+
</section>
|
|
70516
|
+
<section class="christianity-card-frame-effect">
|
|
70517
|
+
<strong>
|
|
70518
|
+
@if (card.type === 'offering') {
|
|
70519
|
+
+{{ card.life }}
|
|
70520
|
+
} @else {
|
|
70521
|
+
{{ card.attack }} / {{ card.life }}
|
|
70522
|
+
}
|
|
70523
|
+
</strong>
|
|
70524
|
+
</section>
|
|
70525
|
+
</button>
|
|
70526
|
+
}
|
|
70527
|
+
</div>
|
|
70528
|
+
} @else {
|
|
70529
|
+
<p>{{ t('christianityHistoryEmpty') }}</p>
|
|
70530
|
+
}
|
|
70531
|
+
</section>
|
|
70532
|
+
}
|
|
70533
|
+
|
|
70534
|
+
@if (offeringsSeat()) {
|
|
70535
|
+
@let offeringPlayer = game().players[offeringsSeat()!];
|
|
70536
|
+
<button type="button" class="christianity-history-backdrop" [attr.aria-label]="t('christianityCloseOfferings')" (click)="closeOfferings()"></button>
|
|
70537
|
+
<section class="christianity-history-drawer christianity-offerings-drawer">
|
|
70538
|
+
<header>
|
|
70539
|
+
<h2>{{ t('christianityOfferings') }}</h2>
|
|
70540
|
+
<div class="christianity-dialog-actions">
|
|
70541
|
+
<span>{{ readyOfferings(offeringPlayer) }}/{{ totalOfferings(offeringPlayer) }}</span>
|
|
70542
|
+
<button type="button" class="christianity-dialog-close" (click)="closeOfferings()">
|
|
70543
|
+
{{ t('close') }}
|
|
70544
|
+
</button>
|
|
70545
|
+
</div>
|
|
70546
|
+
</header>
|
|
70547
|
+
<div class="christianity-offering-list">
|
|
70548
|
+
@for (offering of offeringPlayer.offerings; track offering.instanceId) {
|
|
70549
|
+
<article class="christianity-offering-row" [class.is-exhausted]="!offering.ready">
|
|
70550
|
+
<button type="button" class="christianity-offering-card christianity-card-frame christianity-card-frame--list" valLightRipple (click)="inspectOffering(offering)">
|
|
70551
|
+
<header class="christianity-card-frame-header">
|
|
70552
|
+
<small>{{ t('christianityOfferingCard') }}</small>
|
|
70553
|
+
<strong>{{ offering.name }}</strong>
|
|
70554
|
+
<span>+{{ offering.value }}</span>
|
|
70555
|
+
</header>
|
|
70556
|
+
<section class="christianity-card-frame-art">
|
|
70557
|
+
<span>{{ offering.name }}</span>
|
|
70558
|
+
<small>{{ t('christianityOfferingCard') }}</small>
|
|
70559
|
+
</section>
|
|
70560
|
+
<section class="christianity-card-frame-effect">
|
|
70561
|
+
<strong>+{{ offering.value }}</strong>
|
|
70562
|
+
@if (offering.abilityName) {
|
|
70563
|
+
<p>{{ offering.abilityName }}</p>
|
|
70564
|
+
}
|
|
70565
|
+
</section>
|
|
70566
|
+
</button>
|
|
70567
|
+
<div>
|
|
70568
|
+
<strong>{{ offering.ready ? t('christianityOfferingReady') : t('christianityOfferingExhausted') }}</strong>
|
|
70569
|
+
<p>{{ offering.abilityText || t('christianityOfferingNoAbility') }}</p>
|
|
70570
|
+
@if (offering.abilityName) {
|
|
70571
|
+
<button
|
|
70572
|
+
type="button"
|
|
70573
|
+
[disabled]="!canUseOfferingAbility(offering, offeringsSeat()!)"
|
|
70574
|
+
(click)="useOfferingAbility(offering, offeringsSeat()!)"
|
|
70575
|
+
>
|
|
70576
|
+
{{ t('christianityUseAbility') }}
|
|
70577
|
+
</button>
|
|
70578
|
+
}
|
|
70579
|
+
</div>
|
|
70580
|
+
</article>
|
|
70581
|
+
}
|
|
70582
|
+
</div>
|
|
70583
|
+
</section>
|
|
70584
|
+
}
|
|
70585
|
+
</main>
|
|
70586
|
+
`, styles: [":host{--christianity-theme-ink: var(--val-text-color, #1f2933);--christianity-theme-surface: #ffffff;--christianity-theme-parchment: #fffaf0;--christianity-theme-olive: #5f6f2a;--christianity-theme-gold: #d6a21d;--christianity-theme-gold-soft: rgba(214, 162, 29, .18);--christianity-theme-gold-ring: rgba(214, 162, 29, .48);--christianity-theme-glow: rgba(245, 199, 85, .32);--christianity-theme-focus: #2563eb;--christianity-theme-shadow: rgba(82, 64, 28, .18);--christianity-theme-shadow-strong: rgba(82, 64, 28, .3);--christianity-card-aspect: 5 / 7.45;display:block;max-width:100%;min-width:0;overflow-x:clip;color:var(--christianity-theme-ink)}.christianity-shell{box-sizing:border-box;display:grid;gap:.65rem;width:100%;max-width:100%;min-width:0;padding:.75rem .25rem;border:1px solid rgba(36,48,68,.12);border-radius:.75rem;background:#f6f8fb;overflow-x:clip;overflow-y:visible}.christianity-header,.christianity-match-strip,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-header h1,.christianity-header p,.christianity-match-player strong,.christianity-match-player small,.christianity-scoreboard span,.christianity-history h2,.christianity-actions p{margin:0}.christianity-header h1{font-size:1.35rem;line-height:1.1}.christianity-header p,.christianity-turn span,.christianity-offerings span,.christianity-hidden-hand span,.christianity-deck span,.christianity-place span,.christianity-pile span,.christianity-leader span{color:#1f2933a3;font-size:.75rem}.christianity-turn,.christianity-leader,.christianity-offerings,.christianity-hidden-hand,.christianity-pile,.christianity-deck,.christianity-place{display:grid;gap:.15rem;min-width:5.25rem;padding:.55rem .65rem;border:1px solid rgba(36,48,68,.12);border-radius:.5rem;background:#fff}.christianity-turn.is-own-turn{border-color:#12806c59;background:#ecfdf5}.christianity-match-strip{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);padding:.45rem;border:1px solid rgba(36,48,68,.1);border-radius:.75rem;background:#fff}.christianity-match-player{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.5rem;align-items:center;min-width:0}.christianity-match-player--opponent{direction:rtl}.christianity-match-player--opponent div{direction:ltr;text-align:right}.christianity-match-player div{display:grid;min-width:0}.christianity-match-player strong,.christianity-match-player small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.christianity-match-player small,.christianity-scoreboard span{color:#1f293394;font-size:.72rem}.christianity-scoreboard{display:grid;justify-items:center;min-width:4.2rem;padding:0 .55rem;border-right:1px solid rgba(36,48,68,.1);border-left:1px solid rgba(36,48,68,.1)}.christianity-scoreboard strong{font-size:1.2rem;line-height:1}.christianity-table{box-sizing:border-box;display:grid;gap:.45rem;width:100%;max-width:100%;min-width:0;padding:.45rem .35rem;border-radius:.75rem;background:#dceafb;overflow-x:clip;overflow-y:visible}.christianity-player-side{box-sizing:border-box;display:grid;gap:.35rem;width:100%;max-width:100%;min-width:0;padding:.35rem .3rem;border-radius:.7rem;background:#ffffff57;grid-template-rows:minmax(7rem,1fr) auto;min-height:13.75rem}.christianity-player-side--opponent{grid-template-rows:auto minmax(7rem,1fr)}.christianity-player{display:grid;gap:.65rem}.christianity-battle-zone{--christianity-battle-card-width: clamp(4.8rem, 15vw, 6.6rem);box-sizing:border-box;display:grid;grid-template-columns:repeat(4,var(--christianity-battle-card-width));gap:.5rem;align-items:center;justify-content:center;width:100%;max-width:100%;min-width:0;min-height:clamp(9.1rem,29vw,11rem);padding:.55rem .4rem;border-radius:.75rem;background:#ffffffc2;transition:background .16s ease,box-shadow .16s ease}.christianity-battle-zone.is-placing-card{background:linear-gradient(180deg,#fffaf0f5,#ffffffd6),#ffffffc2;box-shadow:inset 0 0 0 .14rem var(--christianity-theme-gold-soft),0 .8rem 1.7rem #5f6f2a1f}.christianity-shared-zone{padding:.55rem .4rem;border-radius:.75rem;background:#ffffffe6}.christianity-card,.christianity-end-turn,.christianity-actions button,.christianity-pile,.christianity-leader--target{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card{display:grid;align-content:space-between;min-height:5.8rem;padding:.5rem;text-align:left;box-shadow:0 .5rem 1.25rem #24304414}.christianity-card span{font-weight:700}.christianity-card strong{justify-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-card.is-selected{border-color:var(--christianity-theme-gold);box-shadow:0 0 0 .18rem var(--christianity-theme-gold-soft),0 .85rem 1.4rem var(--christianity-theme-shadow)}.christianity-card.is-disabled,.christianity-card.is-exhausted{opacity:.55}.christianity-card.is-target{border-color:#dc2626}.christianity-offering-cards{display:grid;grid-auto-flow:column;grid-auto-columns:.7rem;gap:.16rem;align-items:end;min-height:1.05rem}.christianity-offering-cards i{display:block;width:.65rem;height:.95rem;border:1px solid rgba(16,42,67,.22);border-radius:.18rem;background:#f8fafc}.christianity-offering-cards i.is-used{background:#cbd5e1;transform:rotate(90deg);transform-origin:center}.christianity-slot{display:grid;place-items:center;justify-self:center;width:var(--christianity-battle-card-width);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);border:1px dashed rgba(36,48,68,.22);border-radius:.5rem;background:#ffffff73;color:inherit;font:inherit}.christianity-slot--play-target{position:relative;border-color:var(--christianity-theme-gold-ring);background:linear-gradient(180deg,#fffaf0eb,#f8fafcd1),#ffffffb3;color:#5d4305;font-weight:800;overflow:hidden;box-shadow:inset 0 0 0 .12rem #d6a21d33,0 .7rem 1.25rem var(--christianity-theme-shadow);animation:christianity-target-pulse 1.45s ease-in-out infinite}.christianity-slot--play-target:before{content:\"\";position:absolute;inset:.35rem;border:1px solid rgba(214,162,29,.22);border-radius:.4rem;background:linear-gradient(135deg,rgba(214,162,29,.1),transparent 46%),radial-gradient(circle at 50% 42%,var(--christianity-theme-glow),transparent 58%)}.christianity-slot--play-target span{position:relative;z-index:2;padding:.16rem .44rem;border-radius:999px;background:#ffffffc7;font-size:.78rem}@keyframes christianity-target-pulse{0%,to{box-shadow:inset 0 0 0 .12rem #d6a21d33,0 .7rem 1.25rem var(--christianity-theme-shadow)}50%{box-shadow:inset 0 0 0 .16rem #d6a21d57,0 .9rem 1.65rem var(--christianity-theme-shadow-strong)}}.christianity-hand{display:grid;grid-auto-columns:minmax(6rem,8rem);grid-auto-flow:column;gap:.55rem;overflow-x:auto;padding-bottom:.25rem}.christianity-actions{align-items:flex-start;padding:.75rem;border-radius:.75rem;background:#fff}.christianity-actions div{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end}.christianity-actions button,.christianity-end-turn{min-height:2.4rem;padding:0 .75rem;font-weight:700}.christianity-actions button:not(:disabled),.christianity-end-turn{background:#102a43;color:#fff}.christianity-history{padding:.75rem;border-radius:.75rem;background:#fff}.christianity-hand-fan{position:relative;display:flex;justify-content:center;min-height:10.8rem;padding:.25rem .25rem 2.1rem;isolation:isolate;overflow:visible}.christianity-hand-shelf{position:relative;display:grid;z-index:12;min-height:12rem;margin-top:-1.15rem;padding:1.45rem .25rem 1rem;overflow:visible}.christianity-hand-shelf--opponent{z-index:8;min-height:6.85rem;margin-top:0;margin-bottom:0;padding:.45rem .25rem .85rem}.christianity-hand-fan--opponent{min-height:5.9rem;padding-bottom:.75rem;align-items:start}.christianity-card-preview-card,.christianity-card-mini,.christianity-offering-pile,.christianity-offering-card,.christianity-leader-card,.christianity-zone-card,.christianity-zone-pile,.christianity-end-turn{border:1px solid rgba(36,48,68,.16);border-radius:.5rem;background:#fff;color:inherit;font:inherit}.christianity-card-preview-card{display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;gap:.28rem;align-content:stretch;width:clamp(4.9rem,17vw,7.1rem);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);padding:.48rem;text-align:left;transform-origin:50% 115%;transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;box-shadow:0 .5rem 1.25rem #2430441a}.christianity-card-frame{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;gap:.28rem;align-content:stretch;overflow:hidden;padding:.48rem;text-align:left;background:linear-gradient(180deg,#fffffffa,#f8fafcfa),radial-gradient(circle at 15% 0%,rgba(214,162,29,.12),transparent 44%);box-shadow:0 .5rem 1.25rem #2430441a,inset 0 0 0 .18rem #ffffff9e}.christianity-card-frame-header{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.16rem;align-items:start;min-width:0}.christianity-card-frame-header small{grid-column:1;min-width:0;overflow:hidden;color:#1f2933a3;font-size:clamp(.52rem,1.5vw,.68rem);line-height:1;text-overflow:ellipsis;white-space:nowrap}.christianity-card-frame-header strong{grid-column:1;justify-self:start;align-self:start;min-width:0;padding:0;overflow:hidden;border-radius:0;background:transparent;font-size:clamp(.82rem,2.5vw,1.05rem);line-height:1.02;text-overflow:ellipsis;white-space:nowrap}.christianity-card-frame-header span{grid-column:2;grid-row:1 / span 2;display:grid;place-items:center;min-width:1.3rem;height:1.3rem;padding:0 .22rem;border-radius:999px;background:#ffd91a;color:#243044;font-size:.8rem;font-weight:900;line-height:1;box-shadow:inset 0 -.08rem #52401c2e}.christianity-card-frame-art{position:relative;display:grid;place-items:center;min-height:0;overflow:hidden;border-radius:.36rem;background:linear-gradient(135deg,#5f6f2a2e,#d6a21d24),radial-gradient(circle at 50% 18%,rgba(255,255,255,.72),transparent 48%),#dbe7ef;box-shadow:inset 0 0 0 1px #24304414}.christianity-card-frame-art>span{max-width:78%;overflow:hidden;color:#2430447a;font-size:clamp(.82rem,2.2vw,1.05rem);font-weight:900;line-height:1.02;text-align:center;text-overflow:ellipsis}.christianity-card-frame-art small{position:absolute;right:0;bottom:.28rem;max-width:78%;padding:.1rem .34rem;overflow:hidden;border-radius:999px 0 0 999px;background:#ffffffe6;color:#1f2933a8;font-size:.48rem;font-style:italic;font-weight:900;line-height:1;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.christianity-card-frame-effect{display:grid;align-content:center;gap:.1rem;min-height:1.45rem;padding:.24rem;overflow:hidden;border-radius:.34rem;background:radial-gradient(circle at 50% 70%,rgba(36,48,68,.06),transparent 44%),#ffffffdb}.christianity-card-frame-effect strong{justify-self:end;align-self:end;padding:.12rem .32rem;border-radius:999px;background:#edf2f7;font-size:clamp(.66rem,2vw,.82rem);line-height:1.05}.christianity-card-frame-effect p{margin:0;overflow:hidden;color:#1f2933b8;font-size:.58rem;line-height:1.1;text-overflow:ellipsis;white-space:nowrap}.christianity-card-frame-footer{display:flex;justify-content:space-between;gap:.22rem;color:#1f293385;font-size:.46rem;font-weight:800;line-height:1}.christianity-card-frame--battle{gap:.22rem;padding:.42rem}.christianity-card-frame--battle .christianity-card-frame-art{min-height:2.6rem}.christianity-card-frame--leader .christianity-card-frame-art{background:linear-gradient(135deg,#2563eb24,#d6a21d29),radial-gradient(circle at 50% 18%,rgba(255,255,255,.78),transparent 48%),#e7eef8}.christianity-card-frame--list{width:clamp(4.4rem,22vw,5.8rem);padding:.38rem}.christianity-card-frame--list .christianity-card-frame-art{min-height:2.5rem}.christianity-hand-card-wrap{position:relative;display:grid;justify-items:center;flex:0 0 auto;margin-inline:-.42rem;padding-bottom:2rem;transform-origin:50% 115%;transition:transform .16s ease,filter .16s ease}.christianity-hand-card-wrap:hover,.christianity-hand-card-wrap.is-selected,.christianity-hand-card-wrap.is-dragging{z-index:3}.christianity-hand-card-wrap:hover .christianity-card-preview-card--hand,.christianity-hand-card-wrap.is-selected .christianity-card-preview-card--hand,.christianity-hand-card-wrap.is-dragging .christianity-card-preview-card--hand{border-color:var(--christianity-theme-gold);box-shadow:0 0 0 .12rem var(--christianity-theme-gold-soft),0 1rem 2rem var(--christianity-theme-shadow)}.christianity-card-preview-card--hand{touch-action:none}.christianity-card-preview-card--hand.cdk-drag-disabled{cursor:not-allowed}.christianity-card-preview-card.cdk-drag-preview{width:clamp(4.9rem,17vw,7.1rem);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);border:1px solid var(--christianity-theme-gold-ring);box-shadow:0 0 0 .16rem #fff4c2ad,0 1.5rem 3rem var(--christianity-theme-shadow-strong);transform:rotate(2deg) scale(1.03)}.christianity-card-preview-card.cdk-drag-placeholder{width:clamp(4.9rem,17vw,7.1rem);height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);opacity:.22}.christianity-slot.cdk-drop-list-dragging,.christianity-offering-pile.cdk-drop-list-dragging{border-color:var(--christianity-theme-gold-ring)}.christianity-slot.cdk-drop-list-receiving,.christianity-offering-pile.cdk-drop-list-receiving{box-shadow:inset 0 0 0 .18rem #d6a21d57,0 1rem 1.9rem var(--christianity-theme-shadow-strong)}.christianity-card-eye{position:absolute;right:50%;bottom:.38rem;width:2.15rem;height:1.55rem;border:1px solid color-mix(in srgb,var(--christianity-theme-focus) 52%,transparent);border-radius:999px;background:#fffffff0;box-shadow:0 .55rem 1.1rem #102a4324;opacity:0;transform:translate(50%,-.2rem) scale(.92);transition:opacity .14s ease,transform .14s ease,border-color .14s ease}.christianity-card-eye:before{content:\"\";position:absolute;top:50%;left:50%;width:1.1rem;height:1.1rem;border:.12rem solid var(--christianity-theme-focus);border-radius:82% 0;background:#fffffff0;transform:translate(-50%,-50%) rotate(45deg)}.christianity-card-eye:after{content:\"\";position:absolute;top:50%;left:50%;width:.42rem;height:.42rem;border:.09rem solid rgba(255,255,255,.95);border-radius:999px;background:radial-gradient(circle at 35% 32%,#ffffff 0 .06rem,transparent .07rem),var(--christianity-theme-focus);transform:translate(-50%,-50%)}.christianity-hand-card-wrap:hover .christianity-card-eye,.christianity-hand-card-wrap.is-selected .christianity-card-eye,.christianity-card-eye:focus-visible{opacity:1;transform:translate(50%) scale(1)}.christianity-offering-pile.is-play-target{border-color:var(--christianity-theme-gold-ring);background:linear-gradient(180deg,#fffaf0f5,#fffffff0),radial-gradient(circle at 82% 14%,rgba(250,204,21,.28) 0 .7rem,transparent .72rem);box-shadow:inset 0 0 0 .12rem #d6a21d3d,0 .8rem 1.55rem var(--christianity-theme-shadow);animation:christianity-target-pulse 1.45s ease-in-out infinite}.christianity-card-preview-card--back{width:clamp(4rem,14vw,5.7rem);min-height:0;aspect-ratio:var(--christianity-card-aspect);place-items:center;padding:.55rem;box-shadow:0 .8rem 1.55rem #24304424;transform-origin:50% -18%;background:radial-gradient(circle at 50% 44%,rgba(143,215,242,.22),transparent 40%),linear-gradient(135deg,#102a431f,#102a4305),repeating-linear-gradient(45deg,#dbeafe 0 .34rem,#f8fafc .34rem .68rem)}.christianity-card-back-symbol{width:min(72%,3.65rem);height:auto;opacity:.92;filter:drop-shadow(0 .25rem .35rem rgba(16,42,67,.16)) saturate(.95)}.christianity-card-preview-card--battle{justify-self:center;width:var(--christianity-battle-card-width);min-width:0;height:auto;min-height:0;aspect-ratio:var(--christianity-card-aspect);margin-inline:0}.christianity-card-preview-card>span,.christianity-card-mini>span,.christianity-offering-pile>span,.christianity-offering-card>span,.christianity-leader-card>span,.christianity-zone-card>span,.christianity-zone-pile>span{position:relative;z-index:2;align-self:start;font-weight:700;line-height:1.05}.christianity-card-preview-card>strong,.christianity-card-mini>strong,.christianity-offering-pile>strong,.christianity-offering-card>strong,.christianity-leader-card>strong,.christianity-zone-card>strong,.christianity-zone-pile>strong{position:relative;z-index:3;justify-self:end;align-self:end;padding:.15rem .35rem;border-radius:999px;background:#edf2f7;font-size:.8rem}.christianity-player-rack{box-sizing:border-box;display:grid;grid-template-columns:minmax(5.9rem,7rem) minmax(5rem,1fr) minmax(4.2rem,7rem);gap:.45rem;align-items:end;justify-items:stretch;width:100%;max-width:100%;min-width:0}.christianity-player-rack--opponent{align-items:start}.christianity-hand-meter{position:absolute;top:0;right:.35rem;z-index:4;display:inline-grid;grid-auto-flow:column;gap:.25rem;align-items:center;min-height:1.7rem;padding:.18rem .46rem;border:1px solid rgba(36,48,68,.12);border-radius:999px;background:#ffffffe6;box-shadow:0 .35rem .8rem #102a4314}.christianity-hand-meter--opponent{top:.15rem}.christianity-hand-meter span{color:#1f293394;font-size:.68rem}.christianity-hand-meter strong{font-size:.86rem}.christianity-player-badge,.christianity-player-command{display:grid;gap:.35rem;justify-items:center;min-width:0}.christianity-player-badge{align-content:start;color:#1f2933c2;font-size:.74rem}.christianity-player-badge--opponent{justify-self:center;grid-auto-flow:column;align-items:center;justify-content:center}.christianity-player-badge strong{max-width:6.5rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.christianity-avatar{display:grid;place-items:center;width:1.85rem;height:1.85rem;border-radius:999px;color:#fff;font-size:.76rem;font-weight:800;box-shadow:0 .35rem .9rem #102a4329}.christianity-offerings-zone{display:flex;flex-wrap:wrap;gap:.25rem;justify-content:flex-start;justify-self:start;width:100%}.christianity-card-mini,.christianity-offering-pile,.christianity-offering-card,.christianity-leader-card,.christianity-zone-card,.christianity-zone-pile{display:grid;align-content:space-between;min-height:4.9rem;padding:.48rem;text-align:left}.christianity-card-frame{display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;align-content:stretch}.christianity-offering-pile,.christianity-zone-card,.christianity-zone-pile{grid-template-rows:auto minmax(2.6rem,1fr) auto;align-content:stretch;gap:.32rem}.christianity-card-mini{width:3.5rem}.christianity-offering-pile{position:relative;isolation:isolate;overflow:hidden;justify-self:start;width:min(100%,5.9rem);min-height:7.1rem;padding:.95rem .52rem .6rem;background:linear-gradient(180deg,#fff,#f8fafc),linear-gradient(135deg,rgba(250,204,21,.18),transparent 42%)}.christianity-offering-pile i{position:absolute;top:2.45rem;left:.72rem;z-index:-1;width:2.55rem;height:3.55rem;border:1px solid rgba(16,42,67,.18);border-radius:.35rem;background:linear-gradient(180deg,#ffffffeb,#f1f5f9eb),radial-gradient(circle at 78% 18%,#facc15 0 .38rem,transparent .4rem);box-shadow:0 .35rem .85rem #102a431a;transform:rotate(-5deg)}.christianity-offering-pile i:nth-child(2){transform:translate(.28rem,.08rem) rotate(3deg)}.christianity-offering-pile i:nth-child(3){transform:translate(.55rem,.18rem) rotate(-1deg)}.christianity-leader-card{align-self:center;justify-self:center;width:clamp(4.75rem,17vw,6rem);min-height:0;aspect-ratio:var(--christianity-card-aspect)}.christianity-rack-spacer{display:block;min-height:1px}.christianity-battle-zone{grid-template-columns:repeat(4,var(--christianity-battle-card-width))}.christianity-shared-zone{box-sizing:border-box;display:grid;grid-template-columns:repeat(3,minmax(4.3rem,1fr));align-items:stretch;width:100%;max-width:100%;min-width:0}.christianity-zone-card,.christianity-zone-pile{min-height:6.45rem;padding:.7rem .52rem .55rem}.christianity-zone-pile{position:relative;isolation:isolate;overflow:hidden;box-shadow:inset 0 0 0 999px #ffffff1f}.christianity-zone-pile i{position:absolute;top:2.2rem;right:.72rem;z-index:-1;width:2.7rem;height:3.7rem;border:1px solid rgba(16,42,67,.18);border-radius:.35rem;background:#f8fafc;box-shadow:0 .35rem .85rem #102a431c;transform:rotate(4deg)}.christianity-zone-pile i:nth-child(2){transform:translate(-.28rem,.12rem) rotate(-3deg)}.christianity-zone-pile i:nth-child(3){background:linear-gradient(135deg,#102a4329,#102a4308),repeating-linear-gradient(45deg,#dbeafe 0 .33rem,#fff .33rem .66rem);transform:translate(-.54rem,.24rem) rotate(2deg)}.christianity-floating-card-shell{position:fixed;top:50%;left:50%;z-index:80;display:grid;gap:.55rem;width:min(26rem,calc(100vw - 1.25rem));padding-top:2.35rem;transform:translate(-50%,-50%)}.christianity-floating-card{position:relative;z-index:1;display:grid;grid-template-rows:auto minmax(9rem,1.25fr) auto minmax(7rem,.9fr) auto;gap:.58rem;width:100%;min-height:min(29rem,calc(100vh - 3.5rem));padding:.72rem;border:1px solid rgba(36,48,68,.18);border-radius:.75rem;background:linear-gradient(180deg,#fffffff5,#f8fafcf5),radial-gradient(circle at 20% 0%,var(--christianity-theme-gold-soft),transparent 45%);box-shadow:0 0 0 .18rem #fff4c294,0 0 2.2rem var(--christianity-theme-glow),0 2.4rem 5rem #102a4357,inset 0 0 0 .35rem #ffffff8c;touch-action:none;transform:translate(var(--preview-shift-x, 0px),var(--preview-shift-y, 0px)) perspective(48rem) rotateX(var(--preview-rotate-x, 5deg)) rotateY(var(--preview-rotate-y, -5deg));transition:transform 90ms ease-out}.christianity-full-card-header{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:.42rem;align-items:center}.christianity-full-card-header strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:clamp(1.25rem,5vw,1.85rem);line-height:1.04}.christianity-full-card-type-icon,.christianity-full-card-cost{display:grid;place-items:center;border-radius:999px}.christianity-full-card-type-icon{width:1.6rem;height:1.6rem;background:radial-gradient(circle at 50% 50%,rgba(95,111,42,.72) 0 .22rem,transparent .24rem),#2430441a}.christianity-full-card-cost{width:2.1rem;height:2.1rem;background:#ffd91a;color:#243044;font-size:1.35rem;font-weight:900;box-shadow:inset 0 -.12rem #52401c2e}.christianity-full-card-art{position:relative;display:grid;place-items:center;min-height:9rem;overflow:hidden;border-radius:.48rem;background:linear-gradient(135deg,#5f6f2a33,#d6a21d29),radial-gradient(circle at 50% 25%,rgba(255,255,255,.76),transparent 42%),#dbe7ef;box-shadow:inset 0 0 0 1px #24304414}.christianity-full-card-art img{width:100%;height:100%;object-fit:cover}.christianity-full-card-art>span{max-width:80%;color:#24304494;font-size:clamp(1.1rem,5vw,1.8rem);font-weight:900;line-height:1.05;text-align:center}.christianity-full-card-art small{position:absolute;right:0;bottom:.55rem;min-width:5rem;padding:.16rem .48rem;border-radius:999px 0 0 999px;background:#ffffffe6;box-shadow:0 .3rem .8rem #102a431f;color:#1f2933bd;font-size:.68rem;font-style:italic;font-weight:900;text-align:center;text-transform:uppercase}.christianity-full-card-verse,.christianity-full-card-effect{display:grid;gap:.32rem}.christianity-full-card-verse p,.christianity-full-card-effect p{margin:0;line-height:1.25}.christianity-full-card-verse{color:#171923;font-family:Georgia,Times New Roman,serif;font-size:clamp(.72rem,2.7vw,.86rem)}.christianity-full-card-verse strong{font-family:inherit;font-size:.78rem;font-weight:900}.christianity-full-card-effect{position:relative;align-content:start;min-height:7rem;padding:.6rem .7rem;overflow:hidden;border-radius:.45rem;background:radial-gradient(circle at 50% 72%,rgba(36,48,68,.07),transparent 34%),#ffffffdb}.christianity-full-card-stats{display:flex;gap:1rem;min-height:1.35rem}.christianity-full-card-stats strong{font-size:1rem;line-height:1}.christianity-full-card-effect>div:last-of-type{display:grid;gap:.12rem}.christianity-full-card-effect>div:last-of-type strong{font-size:.82rem}.christianity-full-card-effect p{font-size:clamp(.78rem,2.9vw,.92rem)}.christianity-full-card-rarity{position:absolute;top:.62rem;right:.62rem;width:.46rem;height:.46rem;border-radius:.12rem;transform:rotate(45deg)}.christianity-full-card-rarity.is-normal{background:#d1d5db}.christianity-full-card-rarity.is-uncommon{background:#22c55e}.christianity-full-card-rarity.is-rare{background:#3b82f6}.christianity-full-card-rarity.is-legendary{background:#eab308}.christianity-full-card-footer{display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;gap:.34rem;align-items:center;color:#1f2933ad;font-size:.58rem;line-height:1;text-transform:uppercase}.christianity-full-card-footer span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.christianity-floating-card-close{position:absolute;top:0;right:.15rem;z-index:4;min-height:2rem;padding:0 .6rem;border:1px solid rgba(36,48,68,.14);border-radius:999px;background:#ffffffe6;color:#1f2933c7;font:inherit;font-size:.76rem;font-weight:800;box-shadow:0 .45rem 1rem #102a431a}.christianity-preview-backdrop,.christianity-history-backdrop,.christianity-info-backdrop{position:fixed;inset:0;border:0;border-radius:0;background:#0f172a75}.christianity-preview-backdrop{z-index:79}.christianity-info-backdrop{z-index:50}.christianity-info-panel{position:fixed;top:50%;left:50%;z-index:51;width:min(31rem,calc(100vw - 1.25rem));max-height:min(34rem,calc(100vh - 2rem));padding-top:2.35rem;transform:translate(-50%,-50%)}.christianity-info-close{position:absolute;top:0;right:.15rem;z-index:2}.christianity-rule-note{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.85rem;max-height:inherit;padding:1rem;overflow-y:auto;border:1px solid rgba(36,48,68,.14);border-radius:.9rem;background:linear-gradient(180deg,#fffffff7,#f8fafcf7),radial-gradient(circle at 8% 0%,rgba(37,99,235,.1),transparent 38%);box-shadow:0 1.2rem 2.6rem #102a433d,inset 0 0 0 .25rem #ffffff85}.christianity-rule-note-icon{display:grid;place-items:center;width:2.1rem;height:2.1rem;border-radius:999px;background:color-mix(in srgb,var(--christianity-theme-focus) 12%,#ffffff);color:var(--christianity-theme-focus);font-size:1rem;font-weight:900;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--christianity-theme-focus) 24%,transparent)}.christianity-rule-note small,.christianity-rule-note strong,.christianity-rule-note p,.christianity-rule-note h2{margin:0}.christianity-rule-note small{color:#1f29339e;font-size:.78rem;font-weight:800;text-transform:uppercase}.christianity-rule-note h2{margin-top:.18rem;font-size:clamp(1.5rem,7vw,2.2rem);line-height:1.05}.christianity-rule-note strong{display:inline-flex;width:fit-content;margin-top:.55rem;padding:.22rem .55rem;border-radius:999px;background:#edf2f7;font-size:.92rem}.christianity-rule-note p{margin-top:.75rem;color:#1f2933c7;line-height:1.45}.christianity-rule-note ul{display:grid;gap:.45rem;margin:.8rem 0 0;padding-left:1.05rem;color:#1f2933c7;line-height:1.35}.christianity-floating-card>small,.christianity-floating-card>span{color:#1f2933a3}.christianity-floating-card>strong{font-size:clamp(1.55rem,8vw,2.35rem);line-height:1.05}.christianity-floating-card>p{margin:0;align-self:end;font-size:.95rem;line-height:1.35}.christianity-floating-card-actions{position:relative;z-index:4;display:flex;justify-content:center;padding:0 .35rem;transform:translateZ(0)}.christianity-floating-card-actions button{min-height:2.35rem;padding:0 1rem;border:0;border-radius:999px;background:#102a43;color:#fff;font:inherit;font-size:.9rem;font-weight:800;box-shadow:0 .65rem 1.3rem #102a432e}.christianity-floating-card-actions button:disabled{cursor:not-allowed;opacity:.45}@media (min-width: 52rem){.christianity-floating-card-shell{width:min(29rem,calc(100vw - 3rem))}.christianity-floating-card{min-height:min(35rem,calc(100vh - 4rem));padding:1.35rem}}.christianity-history-backdrop{z-index:40}.christianity-history-drawer{position:fixed;right:auto;bottom:max(.5rem,env(safe-area-inset-bottom));left:50%;z-index:41;display:grid;grid-template-rows:auto minmax(0,1fr);gap:.75rem;width:min(calc(100vw - 1rem),44rem);min-height:min(18rem,calc(100dvh - 1rem));max-height:min(32rem,calc(100dvh - 2rem));padding:.8rem;border:1px solid rgba(36,48,68,.16);border-radius:.75rem;background:#fffffffa;box-shadow:0 1.5rem 4rem #102a4347;transform:translate(-50%)}.christianity-history-drawer header{display:flex;align-items:center;justify-content:space-between;gap:.75rem}.christianity-history-drawer h2,.christianity-history-drawer p{margin:0}.christianity-history-drawer header span{display:grid;place-items:center;min-width:1.85rem;height:1.85rem;border-radius:999px;background:#edf2f7;font-weight:800}.christianity-dialog-actions{display:flex;align-items:center;gap:.45rem}.christianity-dialog-close{min-height:1.85rem;padding:0 .62rem;border:1px solid rgba(36,48,68,.14);border-radius:999px;background:#fff;color:#1f2933c7;font:inherit;font-size:.76rem;font-weight:800;box-shadow:0 .35rem .8rem #102a4314}.christianity-history-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(5.4rem,1fr));gap:.55rem;min-height:0;overflow-y:scroll;scrollbar-color:rgba(36,48,68,.32) rgba(226,232,240,.72);scrollbar-gutter:stable;padding:.1rem .1rem .25rem}.christianity-history-grid::-webkit-scrollbar,.christianity-offering-list::-webkit-scrollbar{width:.65rem}.christianity-history-grid::-webkit-scrollbar-track,.christianity-offering-list::-webkit-scrollbar-track{border-radius:999px;background:#e2e8f0b8}.christianity-history-grid::-webkit-scrollbar-thumb,.christianity-offering-list::-webkit-scrollbar-thumb{border:.14rem solid rgba(226,232,240,.72);border-radius:999px;background:#24304452}.christianity-offerings-drawer{width:min(calc(100vw - 1rem),48rem);min-height:min(20rem,calc(100dvh - 1rem));max-height:min(34rem,calc(100dvh - 2rem))}.christianity-offering-list{display:grid;gap:.6rem;min-height:0;overflow-y:scroll;scrollbar-color:rgba(36,48,68,.32) rgba(226,232,240,.72);scrollbar-gutter:stable;padding:.1rem}.christianity-offering-row{display:grid;grid-template-columns:minmax(4.9rem,6.2rem) minmax(0,1fr);gap:.65rem;align-items:stretch;padding:.45rem;border:1px solid rgba(36,48,68,.12);border-radius:.65rem;background:#fff}.christianity-offering-row.is-exhausted{opacity:.68}.christianity-offering-card{min-height:7.4rem;background:linear-gradient(180deg,#fffffff5,#f8fafcf5),radial-gradient(circle at 82% 14%,#facc15 0 .48rem,transparent .5rem);box-shadow:0 .45rem 1rem #102a431a}.christianity-offering-card.christianity-card-frame{min-height:0;aspect-ratio:var(--christianity-card-aspect)}.christianity-offering-card small{color:#1f293394;font-size:.66rem;text-transform:uppercase}.christianity-offering-card p,.christianity-offering-row p{margin:0}.christianity-offering-card p{align-self:end;color:#1f2933a3;font-size:.72rem;line-height:1.2}.christianity-offering-row>div{display:grid;gap:.35rem;align-content:center;min-width:0}.christianity-offering-row>div p{color:#1f2933b8;font-size:.85rem;line-height:1.3}.christianity-offering-row>div button{justify-self:start;min-height:2.2rem;padding:0 .7rem;border:1px solid rgba(16,42,67,.16);border-radius:.5rem;background:#102a43;color:#fff;font:inherit;font-weight:800}.christianity-offering-row>div button:disabled{background:#e2e8f0;color:#1f293394}button{cursor:pointer}button:disabled{cursor:not-allowed;opacity:.55}button:focus-visible{outline:.1875rem solid color-mix(in srgb,var(--christianity-theme-focus) 24%,transparent);outline-offset:.125rem}@media (max-width: 720px){.christianity-shell{padding:.55rem 0;border-right:0;border-left:0;border-radius:0}.christianity-header,.christianity-player__summary,.christianity-shared-zone,.christianity-actions{align-items:stretch;flex-direction:column}.christianity-match-strip{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:.35rem;padding:.35rem}.christianity-match-player{gap:.35rem}.christianity-match-player small{display:none}.christianity-scoreboard{min-width:3.65rem;padding:0 .35rem}.christianity-scoreboard strong{font-size:1.05rem}.christianity-table{gap:.35rem;padding-right:.25rem;padding-left:.25rem}.christianity-player-side{padding:.3rem .25rem}.christianity-battle-zone{--christianity-battle-card-width: min(5.2rem, calc((100vw - 4.25rem)/4) );grid-template-columns:repeat(4,var(--christianity-battle-card-width));justify-content:center;min-height:8.75rem;overflow-x:clip}.christianity-hand-fan{min-height:11.45rem;padding-bottom:2rem;overflow:visible}.christianity-hand-shelf{min-height:12.65rem;margin-top:-1rem;padding-top:1.35rem;padding-bottom:.9rem}.christianity-hand-shelf--opponent{min-height:6.65rem;margin-top:0;margin-bottom:0;padding-top:.4rem;padding-bottom:.85rem}.christianity-player-rack{grid-template-columns:minmax(4.5rem,5.7rem) minmax(4.4rem,1fr) minmax(3.5rem,4.8rem)}.christianity-shared-zone{gap:.45rem;grid-template-columns:repeat(3,minmax(0,1fr))}.christianity-zone-card,.christianity-zone-pile{min-height:6.15rem;padding:.58rem .46rem .5rem;gap:.24rem}.christianity-zone-pile i{top:2rem;right:.52rem;width:2.35rem;height:3.25rem}.christianity-offering-pile{min-height:6.85rem;padding:.88rem .46rem .55rem;gap:.24rem}.christianity-offering-pile i{top:2.25rem;left:.56rem;width:2.35rem;height:3.25rem}.christianity-card-preview-card{width:clamp(4.2rem,20vw,5.7rem);height:auto;min-height:0}.christianity-leader-card{width:clamp(4.55rem,20vw,5.7rem);min-height:0}.christianity-offering-row{grid-template-columns:minmax(4.5rem,5.5rem) minmax(0,1fr);gap:.5rem}.christianity-hand-fan--opponent{min-height:5.75rem;padding-bottom:.7rem}}\n"] }]
|
|
70587
|
+
}], ctorParameters: () => [] });
|
|
70588
|
+
|
|
68567
70589
|
addIcons({ refreshOutline, sparklesOutline, trophyOutline });
|
|
68568
70590
|
const BUBBLE_COLORS = {
|
|
68569
70591
|
rose: '#ff4f9f',
|
|
@@ -68620,6 +70642,7 @@ class BubbleBlitzGameComponent {
|
|
|
68620
70642
|
this.animating = signal(false);
|
|
68621
70643
|
this.leaderboard = signal(this.readLeaderboard());
|
|
68622
70644
|
this.confirmAction = signal(undefined);
|
|
70645
|
+
this.confirmedAction = signal(undefined);
|
|
68623
70646
|
this.config = computed(() => MODE_CONFIG[this.mode()]);
|
|
68624
70647
|
this.feverReady = computed(() => this.fever() >= this.config().feverTarget);
|
|
68625
70648
|
this.feverProgress = computed(() => Math.min(100, Math.round((this.fever() / this.config().feverTarget) * 100)));
|
|
@@ -68799,13 +70822,12 @@ class BubbleBlitzGameComponent {
|
|
|
68799
70822
|
closeConfirmModal() {
|
|
68800
70823
|
this.confirmAction.set(undefined);
|
|
68801
70824
|
}
|
|
68802
|
-
|
|
68803
|
-
if (token !== 'confirm') {
|
|
68804
|
-
this.closeConfirmModal();
|
|
68805
|
-
return;
|
|
68806
|
-
}
|
|
68807
|
-
const action = this.confirmAction();
|
|
70825
|
+
handleConfirmModalDismissed() {
|
|
68808
70826
|
this.confirmAction.set(undefined);
|
|
70827
|
+
const action = this.confirmedAction();
|
|
70828
|
+
this.confirmedAction.set(undefined);
|
|
70829
|
+
if (!action)
|
|
70830
|
+
return;
|
|
68809
70831
|
if (action === 'restart') {
|
|
68810
70832
|
this.start();
|
|
68811
70833
|
return;
|
|
@@ -68818,6 +70840,15 @@ class BubbleBlitzGameComponent {
|
|
|
68818
70840
|
this.resetToGamesMenu();
|
|
68819
70841
|
}
|
|
68820
70842
|
}
|
|
70843
|
+
confirmPendingAction(token) {
|
|
70844
|
+
if (token !== 'confirm') {
|
|
70845
|
+
this.closeConfirmModal();
|
|
70846
|
+
return;
|
|
70847
|
+
}
|
|
70848
|
+
const action = this.confirmAction();
|
|
70849
|
+
this.confirmedAction.set(action);
|
|
70850
|
+
this.confirmAction.set(undefined);
|
|
70851
|
+
}
|
|
68821
70852
|
startTimer() {
|
|
68822
70853
|
this.stopTimer();
|
|
68823
70854
|
this.timer = window.setInterval(() => {
|
|
@@ -69121,7 +71152,7 @@ class BubbleBlitzGameComponent {
|
|
|
69121
71152
|
<ion-modal
|
|
69122
71153
|
[isOpen]="!!confirmAction()"
|
|
69123
71154
|
cssClass="val-modal-adaptive"
|
|
69124
|
-
(didDismiss)="
|
|
71155
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
69125
71156
|
>
|
|
69126
71157
|
<ng-template>
|
|
69127
71158
|
<val-modal-layout
|
|
@@ -69271,7 +71302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
69271
71302
|
<ion-modal
|
|
69272
71303
|
[isOpen]="!!confirmAction()"
|
|
69273
71304
|
cssClass="val-modal-adaptive"
|
|
69274
|
-
(didDismiss)="
|
|
71305
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
69275
71306
|
>
|
|
69276
71307
|
<ng-template>
|
|
69277
71308
|
<val-modal-layout
|
|
@@ -69335,6 +71366,7 @@ class MemoryGameComponent {
|
|
|
69335
71366
|
this.lockBoard = signal(false);
|
|
69336
71367
|
this.leaderboard = signal(this.readLeaderboard());
|
|
69337
71368
|
this.confirmAction = signal(undefined);
|
|
71369
|
+
this.confirmedAction = signal(undefined);
|
|
69338
71370
|
this.profileConfig = computed(() => PROFILE_CONFIG[this.profile()]);
|
|
69339
71371
|
this.pairCount = computed(() => this.profileConfig().pairs);
|
|
69340
71372
|
this.boardClass = computed(() => `memory-board ${this.profileConfig().boardClass}`);
|
|
@@ -69472,13 +71504,12 @@ class MemoryGameComponent {
|
|
|
69472
71504
|
closeConfirmModal() {
|
|
69473
71505
|
this.confirmAction.set(undefined);
|
|
69474
71506
|
}
|
|
69475
|
-
|
|
69476
|
-
if (token !== 'confirm') {
|
|
69477
|
-
this.closeConfirmModal();
|
|
69478
|
-
return;
|
|
69479
|
-
}
|
|
69480
|
-
const action = this.confirmAction();
|
|
71507
|
+
handleConfirmModalDismissed() {
|
|
69481
71508
|
this.confirmAction.set(undefined);
|
|
71509
|
+
const action = this.confirmedAction();
|
|
71510
|
+
this.confirmedAction.set(undefined);
|
|
71511
|
+
if (!action)
|
|
71512
|
+
return;
|
|
69482
71513
|
if (action === 'restart') {
|
|
69483
71514
|
this.start();
|
|
69484
71515
|
return;
|
|
@@ -69491,6 +71522,15 @@ class MemoryGameComponent {
|
|
|
69491
71522
|
this.resetToGamesMenu();
|
|
69492
71523
|
}
|
|
69493
71524
|
}
|
|
71525
|
+
confirmPendingAction(token) {
|
|
71526
|
+
if (token !== 'confirm') {
|
|
71527
|
+
this.closeConfirmModal();
|
|
71528
|
+
return;
|
|
71529
|
+
}
|
|
71530
|
+
const action = this.confirmAction();
|
|
71531
|
+
this.confirmedAction.set(action);
|
|
71532
|
+
this.confirmAction.set(undefined);
|
|
71533
|
+
}
|
|
69494
71534
|
flip(card) {
|
|
69495
71535
|
if (this.lockBoard() || card.flipped || card.matched || this.won() || this.failed())
|
|
69496
71536
|
return;
|
|
@@ -69805,7 +71845,7 @@ class MemoryGameComponent {
|
|
|
69805
71845
|
<ion-modal
|
|
69806
71846
|
[isOpen]="!!confirmAction()"
|
|
69807
71847
|
cssClass="val-modal-adaptive"
|
|
69808
|
-
(didDismiss)="
|
|
71848
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
69809
71849
|
>
|
|
69810
71850
|
<ng-template>
|
|
69811
71851
|
<val-modal-layout
|
|
@@ -69963,7 +72003,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
69963
72003
|
<ion-modal
|
|
69964
72004
|
[isOpen]="!!confirmAction()"
|
|
69965
72005
|
cssClass="val-modal-adaptive"
|
|
69966
|
-
(didDismiss)="
|
|
72006
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
69967
72007
|
>
|
|
69968
72008
|
<ng-template>
|
|
69969
72009
|
<val-modal-layout
|
|
@@ -70309,6 +72349,7 @@ class SimonGameComponent {
|
|
|
70309
72349
|
this.activePad = signal(undefined);
|
|
70310
72350
|
this.leaderboard = signal(this.readLeaderboard());
|
|
70311
72351
|
this.confirmAction = signal(undefined);
|
|
72352
|
+
this.confirmedAction = signal(undefined);
|
|
70312
72353
|
this.modeConfig = computed(() => SIMON_MODES[this.mode()]);
|
|
70313
72354
|
this.bestRound = computed(() => this.modeLeaderboard()[0]?.round ?? 0);
|
|
70314
72355
|
this.modeLeaderboard = computed(() => this.leaderboard()
|
|
@@ -70408,13 +72449,12 @@ class SimonGameComponent {
|
|
|
70408
72449
|
closeConfirmModal() {
|
|
70409
72450
|
this.confirmAction.set(undefined);
|
|
70410
72451
|
}
|
|
70411
|
-
|
|
70412
|
-
if (token !== 'confirm') {
|
|
70413
|
-
this.closeConfirmModal();
|
|
70414
|
-
return;
|
|
70415
|
-
}
|
|
70416
|
-
const action = this.confirmAction();
|
|
72452
|
+
handleConfirmModalDismissed() {
|
|
70417
72453
|
this.confirmAction.set(undefined);
|
|
72454
|
+
const action = this.confirmedAction();
|
|
72455
|
+
this.confirmedAction.set(undefined);
|
|
72456
|
+
if (!action)
|
|
72457
|
+
return;
|
|
70418
72458
|
if (action === 'restart') {
|
|
70419
72459
|
this.start();
|
|
70420
72460
|
return;
|
|
@@ -70427,6 +72467,15 @@ class SimonGameComponent {
|
|
|
70427
72467
|
this.resetToGamesMenu();
|
|
70428
72468
|
}
|
|
70429
72469
|
}
|
|
72470
|
+
confirmPendingAction(token) {
|
|
72471
|
+
if (token !== 'confirm') {
|
|
72472
|
+
this.closeConfirmModal();
|
|
72473
|
+
return;
|
|
72474
|
+
}
|
|
72475
|
+
const action = this.confirmAction();
|
|
72476
|
+
this.confirmedAction.set(action);
|
|
72477
|
+
this.confirmAction.set(undefined);
|
|
72478
|
+
}
|
|
70430
72479
|
tap(pad) {
|
|
70431
72480
|
if (this.phase() !== 'waiting' || !this.acceptingInput)
|
|
70432
72481
|
return;
|
|
@@ -70670,7 +72719,7 @@ class SimonGameComponent {
|
|
|
70670
72719
|
<ion-modal
|
|
70671
72720
|
[isOpen]="!!confirmAction()"
|
|
70672
72721
|
cssClass="val-modal-adaptive"
|
|
70673
|
-
(didDismiss)="
|
|
72722
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
70674
72723
|
>
|
|
70675
72724
|
<ng-template>
|
|
70676
72725
|
<val-modal-layout
|
|
@@ -70800,7 +72849,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
70800
72849
|
<ion-modal
|
|
70801
72850
|
[isOpen]="!!confirmAction()"
|
|
70802
72851
|
cssClass="val-modal-adaptive"
|
|
70803
|
-
(didDismiss)="
|
|
72852
|
+
(didDismiss)="handleConfirmModalDismissed()"
|
|
70804
72853
|
>
|
|
70805
72854
|
<ng-template>
|
|
70806
72855
|
<val-modal-layout
|
|
@@ -86116,5 +88165,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
86116
88165
|
* Generated bundle index. Do not edit.
|
|
86117
88166
|
*/
|
|
86118
88167
|
|
|
86119
|
-
export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, APP_VERSION_PLATFORM_PLUGIN, APP_VERSION_REMOTE_PLUGIN, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, BubbleBlitzGameComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHESSIMALS_BOT_PROFILES, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, ChatComposerComponent, ChatInputComponent, ChatWindowComponent, CheckInputComponent, CheckboxRadioInputComponent, ChessimalsGameComponent, ChessimalsOnlineService, ChipGroupComponent, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentReactionModalComponent, ContentService, ContentTransformer, ConversationListItemComponent, ConversationService, CookieBannerComponent, CookieSettingsComponent, CountdownComponent, CreateOrgModalComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_BUTTON_PRESETS, DEFAULT_CANCEL_BUTTON, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_LOGIN_LOGO, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_POST_UPDATE_GRACE_MS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DataTableComponent, DatasetPaginationService, DateInputComponent, DatePickerComponent, DateRangeInputComponent, DebugConsoleComponent, DeleteAccountModalComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EditOrgModalComponent, EmptyStateComponent, EntityCardComponent, EntityFeedService, ExpandableTextComponent, ExternalBrowserService, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FontSizeOption, FontSizeSelectorComponent, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormFieldComponent, FormSchemaBuilderService, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HapticsService, HasPermissionDirective, HeaderActionsService, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, HtmlViewerModalComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, IONIC_COLORS$5 as IONIC_COLORS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, InviteMemberModalComponent, ItemListComponent, KNOWN_ROUTES, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGGED_IN_HINT_COOKIE, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LanguageSelectorV2Component, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LiveReadFallbackService, LoadMoreComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, META_SCHEMA_VERSION, METRIC_CARD_DEFAULTS, MINI_GAME_PLAYER_AVATARS, MINI_GAME_PLAYER_COLORS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MediaViewerModalComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MemoryGameComponent, MenuComponent, MessageBubbleComponent, MessagingService, MetaService, MetricCardComponent, MfaModalComponent, MiniGamePlayerProfileService, MiniGamesMenuComponent, ModalLayoutComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OperationReferenceComponent, OptionCardsComponent, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PLATFORM_CONFIGS, POST_UPDATE_TS_KEY, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PdfService, PermissionCatalogService, PermissionSelectorComponent, PermissionsModalComponent, PermissionsViewComponent, PhoneDisplayComponent, PhoneFormatService, PhoneInputComponent, PickerV2Component, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, PricingTableComponent, ProcessLinksPipe, ProfileContentComponent, ProfileModalComponent, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, ReactionBarComponent, ReactionsService, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestFormComponent, RequestModalComponent, RequestService, RetroAudioService, RightsFooterComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SETTINGS_SECTIONS_CATALOG, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SectionHeaderComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SessionListModalComponent, SessionService, SessionTransitionOverlayComponent, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimonGameComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashComponent, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, ThreadPanelComponent, TicketCardComponent, TicketCardImageService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, TypingIndicatorComponent, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UsageMetersComponent, UsageService, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_CHAT_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_NETWORK_ERROR_KEY, VALTECH_REACTIONS_CONFIG, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VALTECH_WHATSAPP_CONFIG, VERSION, ValtechErrorService, VerifyViewComponent, WhatsappFabComponent, WhatsappService, WizardComponent, WizardFooterComponent, WorkflowService, applyChessimalsMove, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildSettingsCards, button, canSubmitRequestType, chooseChessimalsBotMove, collections, connectPageRefresh, createChessimalsGame, createChessimalsReviewState, createErrorStateProps, createFirebaseConfig, createGlowCardProps, createInitialDatasetState, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, datasetPageFromLegacyCursor, docs, errorLoggingInterceptor, extractPathParams, formatClockTime, formatDateSeparator, formatRelativeTime, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getChessimalsAllLegalMoves, getChessimalsLegalMoves, getChessimalsPieceAt, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, groupPermissionsByScope, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isKnownRoute, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, positionKey, provideLegalContent, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAppVersionHttp, provideValtechAuth, provideValtechAuthInterceptor, provideValtechChat, provideValtechContent, provideValtechDebugConsole, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationClickActions, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechReactions, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, provideValtechWhatsapp, query, rbacGuard, renderPatternSvgInner, replaceSpecialChars, requestSubmitMode, resignChessimalsGame, resolveColor, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, selectableRequestTypes, storagePaths, superAdminGuard, toArticle, validateRoutes };
|
|
88168
|
+
export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, APP_VERSION_PLATFORM_PLUGIN, APP_VERSION_REMOTE_PLUGIN, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, BubbleBlitzGameComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHESSIMALS_BOT_PROFILES, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, ChatComposerComponent, ChatInputComponent, ChatWindowComponent, CheckInputComponent, CheckboxRadioInputComponent, ChessimalsGameComponent, ChessimalsOnlineService, ChipGroupComponent, ChristianityGameComponent, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentReactionModalComponent, ContentService, ContentTransformer, ConversationListItemComponent, ConversationService, CookieBannerComponent, CookieSettingsComponent, CountdownComponent, CreateOrgModalComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_BUTTON_PRESETS, DEFAULT_CANCEL_BUTTON, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_LOGIN_LOGO, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_POST_UPDATE_GRACE_MS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DataTableComponent, DatasetPaginationService, DateInputComponent, DatePickerComponent, DateRangeInputComponent, DebugConsoleComponent, DeleteAccountModalComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EditOrgModalComponent, EmptyStateComponent, EntityCardComponent, EntityFeedService, ExpandableTextComponent, ExternalBrowserService, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FontSizeOption, FontSizeSelectorComponent, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormFieldComponent, FormSchemaBuilderService, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HapticsService, HasPermissionDirective, HeaderActionsService, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, HtmlViewerModalComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, IONIC_COLORS$5 as IONIC_COLORS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, InviteMemberModalComponent, ItemListComponent, KNOWN_ROUTES, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGGED_IN_HINT_COOKIE, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LanguageSelectorV2Component, LayeredCardComponent, LegalContentService, LegalLinkService, LightRippleDirective, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LiveReadFallbackService, LoadMoreComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, META_SCHEMA_VERSION, METRIC_CARD_DEFAULTS, MINI_GAME_PLAYER_AVATARS, MINI_GAME_PLAYER_COLORS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MediaViewerModalComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MemoryGameComponent, MenuComponent, MessageBubbleComponent, MessagingService, MetaService, MetricCardComponent, MfaModalComponent, MiniGamePlayerProfileService, MiniGamesMenuComponent, ModalLayoutComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OperationReferenceComponent, OptionCardsComponent, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PLATFORM_CONFIGS, POST_UPDATE_TS_KEY, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PdfService, PermissionCatalogService, PermissionSelectorComponent, PermissionsModalComponent, PermissionsViewComponent, PhoneDisplayComponent, PhoneFormatService, PhoneInputComponent, PickerV2Component, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, PricingTableComponent, ProcessLinksPipe, ProfileContentComponent, ProfileModalComponent, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, ReactionBarComponent, ReactionsService, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestFormComponent, RequestModalComponent, RequestService, RetroAudioService, RightsFooterComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SETTINGS_SECTIONS_CATALOG, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SectionHeaderComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SessionListModalComponent, SessionService, SessionTransitionOverlayComponent, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimonGameComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashComponent, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, ThreadPanelComponent, TicketCardComponent, TicketCardImageService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, TypingIndicatorComponent, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UsageMetersComponent, UsageService, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_CHAT_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_NETWORK_ERROR_KEY, VALTECH_REACTIONS_CONFIG, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VALTECH_WHATSAPP_CONFIG, VERSION, ValtechErrorService, VerifyViewComponent, WhatsappFabComponent, WhatsappService, WizardComponent, WizardFooterComponent, WorkflowService, applyChessimalsMove, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildSettingsCards, button, canSubmitRequestType, chooseChessimalsBotMove, collections, connectPageRefresh, createChessimalsGame, createChessimalsReviewState, createErrorStateProps, createFirebaseConfig, createGlowCardProps, createInitialDatasetState, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, datasetPageFromLegacyCursor, docs, errorLoggingInterceptor, extractPathParams, formatClockTime, formatDateSeparator, formatRelativeTime, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getChessimalsAllLegalMoves, getChessimalsLegalMoves, getChessimalsPieceAt, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, groupPermissionsByScope, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isKnownRoute, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, positionKey, provideLegalContent, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAppVersionHttp, provideValtechAuth, provideValtechAuthInterceptor, provideValtechChat, provideValtechContent, provideValtechDebugConsole, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationClickActions, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechReactions, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, provideValtechWhatsapp, query, rbacGuard, renderPatternSvgInner, replaceSpecialChars, requestSubmitMode, resignChessimalsGame, resolveColor, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, selectableRequestTypes, storagePaths, superAdminGuard, toArticle, validateRoutes };
|
|
86120
88169
|
//# sourceMappingURL=valtech-components.mjs.map
|