@selimssevgi/cube-design-angular 0.1.0 → 0.2.1

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.
@@ -1,5 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
- import { ChangeDetectionStrategy, Component, computed, input } from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, InjectionToken, TemplateRef, afterNextRender, computed, contentChild, effect, inject, input, output, signal, untracked, viewChild } from "@angular/core";
3
+ import { NgTemplateOutlet } from "@angular/common";
3
4
  function sizeFor(count) {
4
5
  let s = 1;
5
6
  while (s * s * s < count && s < 7) s++;
@@ -255,6 +256,1861 @@ i0.ɵɵngDeclareClassMetadata({
255
256
  }]
256
257
  }
257
258
  });
258
- export { CubePicture, drawCube, sizeFor };
259
+ const CUBE_HOLD_MS = 520;
260
+ const CUBE_HOLD_SLOP = 10;
261
+ var CubeHold = class CubeHold {
262
+ cubeHoldDisabled = input(false, ...ngDevMode ? [{ debugName: "cubeHoldDisabled" }] : /* istanbul ignore next */ []);
263
+ cubeHoldMs = input(520, ...ngDevMode ? [{ debugName: "cubeHoldMs" }] : /* istanbul ignore next */ []);
264
+ cubeHoldSlop = input(10, ...ngDevMode ? [{ debugName: "cubeHoldSlop" }] : /* istanbul ignore next */ []);
265
+ cubeHoldBuzz = input(true, ...ngDevMode ? [{ debugName: "cubeHoldBuzz" }] : /* istanbul ignore next */ []);
266
+ cubeHeld = output();
267
+ element = inject(ElementRef).nativeElement;
268
+ timer;
269
+ start = null;
270
+ pointers = /* @__PURE__ */ new Set();
271
+ pressFired = false;
272
+ swallow = false;
273
+ constructor() {
274
+ const swallow = (e) => {
275
+ if (!this.swallow) return;
276
+ this.swallow = false;
277
+ e.preventDefault();
278
+ e.stopImmediatePropagation();
279
+ };
280
+ this.element.addEventListener("click", swallow, true);
281
+ inject(DestroyRef).onDestroy(() => {
282
+ clearTimeout(this.timer);
283
+ this.element.removeEventListener("click", swallow, true);
284
+ });
285
+ }
286
+ press(e) {
287
+ this.pointers.add(e.pointerId);
288
+ this.cancel();
289
+ this.pressFired = false;
290
+ this.swallow = false;
291
+ if (this.cubeHoldDisabled() || this.pointers.size > 1 || e.button > 0) return;
292
+ this.start = {
293
+ x: e.clientX,
294
+ y: e.clientY
295
+ };
296
+ this.timer = setTimeout(() => this.fire("press", e), this.cubeHoldMs());
297
+ }
298
+ moved(e) {
299
+ if (!this.start) return;
300
+ if (Math.hypot(e.clientX - this.start.x, e.clientY - this.start.y) > this.cubeHoldSlop()) this.cancel();
301
+ }
302
+ lift(e) {
303
+ this.pointers.delete(e.pointerId);
304
+ this.cancel();
305
+ }
306
+ menu(e) {
307
+ if (this.cubeHoldDisabled()) return;
308
+ e.preventDefault();
309
+ if (this.pressFired) return;
310
+ this.fire("menu", e);
311
+ }
312
+ fire(via, event) {
313
+ this.cancel();
314
+ if (this.cubeHoldDisabled()) return;
315
+ this.pressFired = via === "press";
316
+ this.swallow = true;
317
+ if (this.cubeHoldBuzz()) globalThis.navigator?.vibrate?.(12);
318
+ this.cubeHeld.emit({
319
+ via,
320
+ element: this.element,
321
+ event
322
+ });
323
+ }
324
+ cancel() {
325
+ clearTimeout(this.timer);
326
+ this.timer = void 0;
327
+ this.start = null;
328
+ }
329
+ static ɵfac = i0.ɵɵngDeclareFactory({
330
+ minVersion: "12.0.0",
331
+ version: "22.2.4",
332
+ ngImport: i0,
333
+ type: CubeHold,
334
+ deps: [],
335
+ target: i0.ɵɵFactoryTarget.Directive
336
+ });
337
+ static ɵdir = i0.ɵɵngDeclareDirective({
338
+ minVersion: "17.1.0",
339
+ version: "22.2.4",
340
+ type: CubeHold,
341
+ isStandalone: true,
342
+ selector: "[cubeHold]",
343
+ inputs: {
344
+ cubeHoldDisabled: {
345
+ classPropertyName: "cubeHoldDisabled",
346
+ publicName: "cubeHoldDisabled",
347
+ isSignal: true,
348
+ isRequired: false,
349
+ transformFunction: null
350
+ },
351
+ cubeHoldMs: {
352
+ classPropertyName: "cubeHoldMs",
353
+ publicName: "cubeHoldMs",
354
+ isSignal: true,
355
+ isRequired: false,
356
+ transformFunction: null
357
+ },
358
+ cubeHoldSlop: {
359
+ classPropertyName: "cubeHoldSlop",
360
+ publicName: "cubeHoldSlop",
361
+ isSignal: true,
362
+ isRequired: false,
363
+ transformFunction: null
364
+ },
365
+ cubeHoldBuzz: {
366
+ classPropertyName: "cubeHoldBuzz",
367
+ publicName: "cubeHoldBuzz",
368
+ isSignal: true,
369
+ isRequired: false,
370
+ transformFunction: null
371
+ }
372
+ },
373
+ outputs: { cubeHeld: "cubeHeld" },
374
+ host: {
375
+ listeners: {
376
+ "pointerdown": "press($event)",
377
+ "pointermove": "moved($event)",
378
+ "pointerup": "lift($event)",
379
+ "pointercancel": "lift($event)",
380
+ "pointerleave": "lift($event)",
381
+ "contextmenu": "menu($event)",
382
+ "keydown": "pressFired = false; swallow = false"
383
+ },
384
+ properties: {
385
+ "style.user-select": "cubeHoldDisabled() ? null : \"none\"",
386
+ "style.-webkit-user-select": "cubeHoldDisabled() ? null : \"none\"",
387
+ "style.-webkit-touch-callout": "cubeHoldDisabled() ? null : \"none\""
388
+ }
389
+ },
390
+ ngImport: i0
391
+ });
392
+ };
393
+ i0.ɵɵngDeclareClassMetadata({
394
+ minVersion: "12.0.0",
395
+ version: "22.2.4",
396
+ ngImport: i0,
397
+ type: CubeHold,
398
+ decorators: [{
399
+ type: Directive,
400
+ args: [{
401
+ selector: "[cubeHold]",
402
+ host: {
403
+ "[style.user-select]": "cubeHoldDisabled() ? null : \"none\"",
404
+ "[style.-webkit-user-select]": "cubeHoldDisabled() ? null : \"none\"",
405
+ "[style.-webkit-touch-callout]": "cubeHoldDisabled() ? null : \"none\"",
406
+ "(pointerdown)": "press($event)",
407
+ "(pointermove)": "moved($event)",
408
+ "(pointerup)": "lift($event)",
409
+ "(pointercancel)": "lift($event)",
410
+ "(pointerleave)": "lift($event)",
411
+ "(contextmenu)": "menu($event)",
412
+ "(keydown)": "pressFired = false; swallow = false"
413
+ }
414
+ }]
415
+ }],
416
+ ctorParameters: () => [],
417
+ propDecorators: {
418
+ cubeHoldDisabled: [{
419
+ type: i0.Input,
420
+ args: [{
421
+ isSignal: true,
422
+ alias: "cubeHoldDisabled",
423
+ required: false
424
+ }]
425
+ }],
426
+ cubeHoldMs: [{
427
+ type: i0.Input,
428
+ args: [{
429
+ isSignal: true,
430
+ alias: "cubeHoldMs",
431
+ required: false
432
+ }]
433
+ }],
434
+ cubeHoldSlop: [{
435
+ type: i0.Input,
436
+ args: [{
437
+ isSignal: true,
438
+ alias: "cubeHoldSlop",
439
+ required: false
440
+ }]
441
+ }],
442
+ cubeHoldBuzz: [{
443
+ type: i0.Input,
444
+ args: [{
445
+ isSignal: true,
446
+ alias: "cubeHoldBuzz",
447
+ required: false
448
+ }]
449
+ }],
450
+ cubeHeld: [{
451
+ type: i0.Output,
452
+ args: ["cubeHeld"]
453
+ }]
454
+ }
455
+ });
456
+ const CUBE_ICON_NAMES = [
457
+ "names",
458
+ "name",
459
+ "change",
460
+ "move",
461
+ "place",
462
+ "whose",
463
+ "library",
464
+ "mine",
465
+ "shown",
466
+ "hidden",
467
+ "view",
468
+ "sort",
469
+ "kept",
470
+ "face",
471
+ "added",
472
+ "up",
473
+ "down",
474
+ "plus",
475
+ "square",
476
+ "one",
477
+ "two",
478
+ "three",
479
+ "four",
480
+ "grid-4x5",
481
+ "grid-3x6"
482
+ ];
483
+ const SHAPES = {
484
+ square: {
485
+ cols: 3,
486
+ rows: 3
487
+ },
488
+ one: {
489
+ cols: 1,
490
+ rows: 3
491
+ },
492
+ two: {
493
+ cols: 2,
494
+ rows: 3
495
+ },
496
+ three: {
497
+ cols: 3,
498
+ rows: 3
499
+ },
500
+ four: {
501
+ cols: 4,
502
+ rows: 3
503
+ },
504
+ "grid-4x5": {
505
+ cols: 4,
506
+ rows: 5
507
+ },
508
+ "grid-3x6": {
509
+ cols: 3,
510
+ rows: 6
511
+ }
512
+ };
513
+ function cubeIconCells(icon) {
514
+ const shape = SHAPES[icon];
515
+ if (!shape) return null;
516
+ const { cols, rows } = shape;
517
+ const gap = 1.6;
518
+ const size = Math.min((17 - gap * (cols - 1)) / cols, (17 - gap * (rows - 1)) / rows);
519
+ const w = cols * size + gap * (cols - 1);
520
+ const h = rows * size + gap * (rows - 1);
521
+ const out = [];
522
+ for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) out.push({
523
+ x: cols === 1 ? 3.5 : 12 - w / 2 + c * (size + gap),
524
+ y: 12 - h / 2 + r * (size + gap),
525
+ w: cols === 1 ? 17 : size,
526
+ h: size
527
+ });
528
+ return out;
529
+ }
530
+ var CubeIcon = class CubeIcon {
531
+ icon = input.required(...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
532
+ inUse = input(false, ...ngDevMode ? [{ debugName: "inUse" }] : /* istanbul ignore next */ []);
533
+ cells = computed(() => cubeIconCells(this.icon()), ...ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []);
534
+ static ɵfac = i0.ɵɵngDeclareFactory({
535
+ minVersion: "12.0.0",
536
+ version: "22.2.4",
537
+ ngImport: i0,
538
+ type: CubeIcon,
539
+ deps: [],
540
+ target: i0.ɵɵFactoryTarget.Component
541
+ });
542
+ static ɵcmp = i0.ɵɵngDeclareComponent({
543
+ minVersion: "17.0.0",
544
+ version: "22.2.4",
545
+ type: CubeIcon,
546
+ isStandalone: true,
547
+ selector: "cube-icon",
548
+ inputs: {
549
+ icon: {
550
+ classPropertyName: "icon",
551
+ publicName: "icon",
552
+ isSignal: true,
553
+ isRequired: true,
554
+ transformFunction: null
555
+ },
556
+ inUse: {
557
+ classPropertyName: "inUse",
558
+ publicName: "inUse",
559
+ isSignal: true,
560
+ isRequired: false,
561
+ transformFunction: null
562
+ }
563
+ },
564
+ host: { properties: { "class.in-use": "inUse()" } },
565
+ ngImport: i0,
566
+ template: `
567
+ <svg viewBox="0 0 24 24" aria-hidden="true">
568
+ @if (cells(); as cs) {
569
+ @for (c of cs; track $index) {
570
+ <rect
571
+ class="cell"
572
+ [attr.x]="c.x"
573
+ [attr.y]="c.y"
574
+ [attr.width]="c.w"
575
+ [attr.height]="c.h"
576
+ rx="0.8"
577
+ />
578
+ }
579
+ }
580
+ @switch (icon()) {
581
+ @case ('view') {
582
+ <rect x="4" y="4" width="7" height="7" rx="1.5" />
583
+ <rect x="13" y="4" width="7" height="7" rx="1.5" />
584
+ <rect x="4" y="13" width="7" height="7" rx="1.5" />
585
+ <rect x="13" y="13" width="7" height="7" rx="1.5" />
586
+ }
587
+ @case ('sort') {
588
+ <path d="M8 19V5M4.5 8.5 8 5l3.5 3.5M16 5v14M12.5 15.5 16 19l3.5-3.5" />
589
+ }
590
+ @case ('kept') {
591
+ <path d="M5 7h14M5 12h14M5 17h9" />
592
+ }
593
+ @case ('face') {
594
+ <path d="M12 3.5 20 8v8l-8 4.5L4 16V8Z" />
595
+ <path d="M4 8l8 4.5L20 8M12 12.5v8" />
596
+ }
597
+ @case ('added') {
598
+ <circle cx="12" cy="12" r="8" />
599
+ <path d="M12 7.5V12l3 2" />
600
+ }
601
+ @case ('up') {
602
+ <path d="M12 19V5M6.5 10.5 12 5l5.5 5.5" />
603
+ }
604
+ @case ('plus') {
605
+ <path d="M12 5v14M5 12h14" />
606
+ }
607
+ @case ('down') {
608
+ <path d="M12 5v14M6.5 13.5 12 19l5.5-5.5" />
609
+ }
610
+ @case ('names') {
611
+ <path d="M3.5 12.5 11 5h8v8l-7.5 7.5a1.5 1.5 0 0 1-2.1 0L3.5 14.6a1.5 1.5 0 0 1 0-2.1Z" />
612
+ <circle cx="15.2" cy="8.8" r="1.4" />
613
+ }
614
+ @case ('name') {
615
+ <path d="M5 18 9.5 6h1L15 18M6.6 14h6.8" />
616
+ <path
617
+ d="M17 11.5c1.6-1.2 3.5-.5 3.5 1.4V18M20.5 14.6c-2.6-.3-4 .4-4 1.8 0 1.9 2.7 2 4 .3"
618
+ />
619
+ }
620
+ @case ('change') {
621
+ <path d="M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z" />
622
+ <path d="M13.5 6.5l4 4" />
623
+ }
624
+ @case ('move') {
625
+ <path
626
+ d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1"
627
+ />
628
+ <path d="M2.5 13H12M9 10l3 3-3 3" />
629
+ }
630
+ @case ('place') {
631
+ <path
632
+ d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Z"
633
+ />
634
+ }
635
+ @case ('whose') {
636
+ <circle cx="9" cy="8" r="3.2" />
637
+ <path d="M3 19c.6-3.4 3-5.2 6-5.2s5.4 1.8 6 5.2" />
638
+ <path d="M16 5.5a3 3 0 0 1 0 5.6M18.5 14.4c1.4.8 2.3 2.4 2.5 4.6" />
639
+ }
640
+ @case ('library') {
641
+ <path d="M4 5h4v15H4zM10 5h4v15h-4z" />
642
+ <path d="m16 6 3.6-1 3 14.4-3.6 1z" />
643
+ }
644
+ @case ('mine') {
645
+ <circle cx="12" cy="8" r="3.4" />
646
+ <path d="M5 20c.7-4 3.5-6 7-6s6.3 2 7 6" />
647
+ }
648
+ @case ('shown') {
649
+ <path d="M3 12s3.2-6 9-6 9 6 9 6-3.2 6-9 6-9-6-9-6Z" />
650
+ <circle cx="12" cy="12" r="2.6" />
651
+ }
652
+ @case ('hidden') {
653
+ <path d="M3 12s3.2-6 9-6c1.6 0 3 .45 4.2 1.1M21 12s-3.2 6-9 6c-1.6 0-3-.45-4.2-1.1" />
654
+ <path d="M4.5 19.5 19.5 4.5" />
655
+ }
656
+ }
657
+ </svg>
658
+ `,
659
+ isInline: true,
660
+ styles: [":host{display:inline-block;width:var(--cube-icon-size, 34px);height:var(--cube-icon-size, 34px);line-height:0}svg{width:100%;height:100%;fill:none;stroke:var(--cube-icon-stroke, #1f2a26);stroke-width:var(--cube-icon-stroke-width, 1.7);stroke-linecap:round;stroke-linejoin:round}.cell{fill:var(--cube-icon-stroke, #1f2a26);stroke:none;opacity:var(--cube-icon-cell-opacity, .8)}:host(.in-use) svg{stroke:var(--cube-icon-in-use, #3b5a4c)}:host(.in-use) .cell{fill:var(--cube-icon-in-use, #3b5a4c)}\n"],
661
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
662
+ });
663
+ };
664
+ i0.ɵɵngDeclareClassMetadata({
665
+ minVersion: "12.0.0",
666
+ version: "22.2.4",
667
+ ngImport: i0,
668
+ type: CubeIcon,
669
+ decorators: [{
670
+ type: Component,
671
+ args: [{
672
+ selector: "cube-icon",
673
+ template: `
674
+ <svg viewBox="0 0 24 24" aria-hidden="true">
675
+ @if (cells(); as cs) {
676
+ @for (c of cs; track $index) {
677
+ <rect
678
+ class="cell"
679
+ [attr.x]="c.x"
680
+ [attr.y]="c.y"
681
+ [attr.width]="c.w"
682
+ [attr.height]="c.h"
683
+ rx="0.8"
684
+ />
685
+ }
686
+ }
687
+ @switch (icon()) {
688
+ @case ('view') {
689
+ <rect x="4" y="4" width="7" height="7" rx="1.5" />
690
+ <rect x="13" y="4" width="7" height="7" rx="1.5" />
691
+ <rect x="4" y="13" width="7" height="7" rx="1.5" />
692
+ <rect x="13" y="13" width="7" height="7" rx="1.5" />
693
+ }
694
+ @case ('sort') {
695
+ <path d="M8 19V5M4.5 8.5 8 5l3.5 3.5M16 5v14M12.5 15.5 16 19l3.5-3.5" />
696
+ }
697
+ @case ('kept') {
698
+ <path d="M5 7h14M5 12h14M5 17h9" />
699
+ }
700
+ @case ('face') {
701
+ <path d="M12 3.5 20 8v8l-8 4.5L4 16V8Z" />
702
+ <path d="M4 8l8 4.5L20 8M12 12.5v8" />
703
+ }
704
+ @case ('added') {
705
+ <circle cx="12" cy="12" r="8" />
706
+ <path d="M12 7.5V12l3 2" />
707
+ }
708
+ @case ('up') {
709
+ <path d="M12 19V5M6.5 10.5 12 5l5.5 5.5" />
710
+ }
711
+ @case ('plus') {
712
+ <path d="M12 5v14M5 12h14" />
713
+ }
714
+ @case ('down') {
715
+ <path d="M12 5v14M6.5 13.5 12 19l5.5-5.5" />
716
+ }
717
+ @case ('names') {
718
+ <path d="M3.5 12.5 11 5h8v8l-7.5 7.5a1.5 1.5 0 0 1-2.1 0L3.5 14.6a1.5 1.5 0 0 1 0-2.1Z" />
719
+ <circle cx="15.2" cy="8.8" r="1.4" />
720
+ }
721
+ @case ('name') {
722
+ <path d="M5 18 9.5 6h1L15 18M6.6 14h6.8" />
723
+ <path
724
+ d="M17 11.5c1.6-1.2 3.5-.5 3.5 1.4V18M20.5 14.6c-2.6-.3-4 .4-4 1.8 0 1.9 2.7 2 4 .3"
725
+ />
726
+ }
727
+ @case ('change') {
728
+ <path d="M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z" />
729
+ <path d="M13.5 6.5l4 4" />
730
+ }
731
+ @case ('move') {
732
+ <path
733
+ d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1"
734
+ />
735
+ <path d="M2.5 13H12M9 10l3 3-3 3" />
736
+ }
737
+ @case ('place') {
738
+ <path
739
+ d="M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Z"
740
+ />
741
+ }
742
+ @case ('whose') {
743
+ <circle cx="9" cy="8" r="3.2" />
744
+ <path d="M3 19c.6-3.4 3-5.2 6-5.2s5.4 1.8 6 5.2" />
745
+ <path d="M16 5.5a3 3 0 0 1 0 5.6M18.5 14.4c1.4.8 2.3 2.4 2.5 4.6" />
746
+ }
747
+ @case ('library') {
748
+ <path d="M4 5h4v15H4zM10 5h4v15h-4z" />
749
+ <path d="m16 6 3.6-1 3 14.4-3.6 1z" />
750
+ }
751
+ @case ('mine') {
752
+ <circle cx="12" cy="8" r="3.4" />
753
+ <path d="M5 20c.7-4 3.5-6 7-6s6.3 2 7 6" />
754
+ }
755
+ @case ('shown') {
756
+ <path d="M3 12s3.2-6 9-6 9 6 9 6-3.2 6-9 6-9-6-9-6Z" />
757
+ <circle cx="12" cy="12" r="2.6" />
758
+ }
759
+ @case ('hidden') {
760
+ <path d="M3 12s3.2-6 9-6c1.6 0 3 .45 4.2 1.1M21 12s-3.2 6-9 6c-1.6 0-3-.45-4.2-1.1" />
761
+ <path d="M4.5 19.5 19.5 4.5" />
762
+ }
763
+ }
764
+ </svg>
765
+ `,
766
+ host: { "[class.in-use]": "inUse()" },
767
+ changeDetection: ChangeDetectionStrategy.OnPush,
768
+ styles: [":host{display:inline-block;width:var(--cube-icon-size, 34px);height:var(--cube-icon-size, 34px);line-height:0}svg{width:100%;height:100%;fill:none;stroke:var(--cube-icon-stroke, #1f2a26);stroke-width:var(--cube-icon-stroke-width, 1.7);stroke-linecap:round;stroke-linejoin:round}.cell{fill:var(--cube-icon-stroke, #1f2a26);stroke:none;opacity:var(--cube-icon-cell-opacity, .8)}:host(.in-use) svg{stroke:var(--cube-icon-in-use, #3b5a4c)}:host(.in-use) .cell{fill:var(--cube-icon-in-use, #3b5a4c)}\n"]
769
+ }]
770
+ }],
771
+ propDecorators: {
772
+ icon: [{
773
+ type: i0.Input,
774
+ args: [{
775
+ isSignal: true,
776
+ alias: "icon",
777
+ required: true
778
+ }]
779
+ }],
780
+ inUse: [{
781
+ type: i0.Input,
782
+ args: [{
783
+ isSignal: true,
784
+ alias: "inUse",
785
+ required: false
786
+ }]
787
+ }]
788
+ }
789
+ });
790
+ const CONTEXT_PART_ORDER = [
791
+ "names",
792
+ "change",
793
+ "view",
794
+ "sort",
795
+ "move",
796
+ "whose",
797
+ "hide"
798
+ ];
799
+ function orderParts(parts) {
800
+ const unique = [...new Set(parts)];
801
+ return [...CONTEXT_PART_ORDER.filter((p) => unique.includes(p)), ...unique.filter((p) => !CONTEXT_PART_ORDER.includes(p))];
802
+ }
803
+ const CONTEXT_CUBE_SOURCE = new InjectionToken("CONTEXT_CUBE_SOURCE");
804
+ const CONTEXT_CUBE_WORDS = new InjectionToken("CONTEXT_CUBE_WORDS");
805
+ const PART_ICONS = { hide: "shown" };
806
+ function partsLevel(parts, words, now = {}) {
807
+ return orderParts(parts).map((p) => ({
808
+ key: p,
809
+ title: words.parts[p]?.title ?? "",
810
+ line: now[p]?.line !== void 0 ? now[p]?.line : words.parts[p]?.line ?? null,
811
+ icon: now[p]?.icon ?? PART_ICONS[p] ?? p,
812
+ data: p
813
+ }));
814
+ }
815
+ const VIEW_KEYS = [
816
+ "square",
817
+ "one",
818
+ "two",
819
+ "three",
820
+ "four",
821
+ "grid-4x5",
822
+ "grid-3x6"
823
+ ];
824
+ const isView = (v) => VIEW_KEYS.includes(v);
825
+ function gridFor(view, count) {
826
+ const n = Math.max(1, count);
827
+ switch (view) {
828
+ case "square": {
829
+ const side = Math.max(1, Math.ceil(Math.sqrt(n)));
830
+ return {
831
+ cols: side,
832
+ rows: side
833
+ };
834
+ }
835
+ case "one":
836
+ case "two":
837
+ case "three":
838
+ case "four": {
839
+ const cols = {
840
+ one: 1,
841
+ two: 2,
842
+ three: 3,
843
+ four: 4
844
+ }[view];
845
+ return {
846
+ cols,
847
+ rows: Math.ceil(n / cols)
848
+ };
849
+ }
850
+ case "grid-4x5":
851
+ case "grid-3x6": {
852
+ const [cols, rows] = view === "grid-4x5" ? [4, 5] : [3, 6];
853
+ return {
854
+ cols,
855
+ rows: rows * Math.ceil(n / (cols * rows))
856
+ };
857
+ }
858
+ }
859
+ }
860
+ function sortItems(items, by, dir) {
861
+ const sign = dir === "down" ? -1 : 1;
862
+ const known = (v) => v !== null && v !== void 0 && v !== "";
863
+ return items.map((item, at) => ({
864
+ item,
865
+ at,
866
+ value: by(item)
867
+ })).sort((a, b) => {
868
+ const ka = known(a.value);
869
+ const kb = known(b.value);
870
+ if (!ka || !kb) return Number(!ka) - Number(!kb) || a.at - b.at;
871
+ return sign * compare(a.value, b.value) || a.at - b.at;
872
+ }).map((x) => x.item);
873
+ }
874
+ function compare(a, b) {
875
+ if (typeof a === "number" && typeof b === "number") return a - b;
876
+ return String(a).localeCompare(String(b));
877
+ }
878
+ function namesLevel(names, words, opts = {}) {
879
+ const tiles = [...names.filter((n) => n.current), ...names.filter((n) => !n.current).reverse()].map((n, i) => ({
880
+ key: `name:${i}:${n.name}`,
881
+ title: n.name,
882
+ line: words.names.line?.(n) ?? null,
883
+ icon: "name",
884
+ inUse: n.current,
885
+ data: { name: n }
886
+ }));
887
+ if (opts.canAdd) tiles.push({
888
+ key: "name:+",
889
+ title: words.names.another.title,
890
+ line: words.names.another.line ?? null,
891
+ icon: "plus",
892
+ adds: true,
893
+ data: { another: true }
894
+ });
895
+ return tiles;
896
+ }
897
+ function hideLevel(hidden, words) {
898
+ return [{
899
+ key: "hide:shown",
900
+ title: words.hide.shown.title,
901
+ line: words.hide.shown.line ?? null,
902
+ icon: "shown",
903
+ inUse: !hidden,
904
+ data: false
905
+ }, {
906
+ key: "hide:hidden",
907
+ title: words.hide.hidden.title,
908
+ line: words.hide.hidden.line ?? null,
909
+ icon: "hidden",
910
+ inUse: hidden,
911
+ data: true
912
+ }];
913
+ }
914
+ function viewLevel(now, words, views = VIEW_KEYS) {
915
+ return views.map((v) => ({
916
+ key: "view:" + v,
917
+ title: words.views[v]?.title ?? "",
918
+ line: v === now ? null : words.views[v]?.line ?? null,
919
+ icon: v,
920
+ inUse: v === now,
921
+ data: v
922
+ }));
923
+ }
924
+ function directionWords(option, words) {
925
+ return {
926
+ up: option.up ?? words.directions.up,
927
+ down: option.down ?? words.directions.down
928
+ };
929
+ }
930
+ function sortLevel(options, now, words) {
931
+ return options.map((o) => {
932
+ const inUse = now.by === o.by;
933
+ const directed = o.directed !== false;
934
+ return {
935
+ key: "sort:" + o.by,
936
+ title: o.title,
937
+ line: inUse && directed ? directionWords(o, words)[now.dir].title : o.line ?? null,
938
+ icon: o.icon,
939
+ inUse,
940
+ data: o
941
+ };
942
+ });
943
+ }
944
+ function sortDirectionsLevel(option, now, words) {
945
+ const w = directionWords(option, words);
946
+ return ["up", "down"].map((dir) => ({
947
+ key: "dir:" + dir,
948
+ title: w[dir].title,
949
+ line: w[dir].line ?? null,
950
+ icon: dir,
951
+ inUse: now.by === option.by && now.dir === dir,
952
+ data: dir
953
+ }));
954
+ }
955
+ const TURNING_SIDES = 4;
956
+ function turningRows(pieces, own, cols = 3, rows = cols) {
957
+ const across = Math.max(1, Math.floor(cols));
958
+ const down = Math.max(1, Math.floor(rows));
959
+ const count = pieces.length + (own !== null ? 1 : 0);
960
+ const perRow = across * 4;
961
+ const rowCount = Math.max(down, Math.ceil(count / perRow));
962
+ const grid = Array.from({ length: rowCount }, () => Array.from({ length: 4 }, () => Array.from({ length: across }).fill(null)));
963
+ const front = [];
964
+ for (let r = 0; r < rowCount; r++) for (let c = 0; c < across; c++) front.push([r, c]);
965
+ const frontForPieces = own !== null ? front.slice(0, -1) : front;
966
+ if (own !== null) grid[rowCount - 1][0][across - 1] = own;
967
+ let next = 0;
968
+ for (const [r, c] of frontForPieces) {
969
+ if (next >= pieces.length) break;
970
+ grid[r][0][c] = pieces[next++];
971
+ }
972
+ for (let r = 0; r < rowCount && next < pieces.length; r++) for (let s = 1; s < 4 && next < pieces.length; s++) for (let c = 0; c < across && next < pieces.length; c++) grid[r][s][c] = pieces[next++];
973
+ return {
974
+ rows: grid,
975
+ sides: grid.map((row) => 1 + row.slice(1).filter((side) => side.some((t) => t !== null)).length)
976
+ };
977
+ }
978
+ function squareLevelFor(cell) {
979
+ return cell >= 280 ? 0 : cell >= 150 ? 1 : cell >= 100 ? 2 : cell >= 70 ? 3 : 4;
980
+ }
981
+ function squareGap(n) {
982
+ return n <= 2 ? 12 : n === 3 ? 10 : n === 4 ? 8 : 5;
983
+ }
984
+ const SQUARE_MAX_SIDE = 880;
985
+ const SQUARE_LIST_ROW = 76;
986
+ function squareLayout(view, count, room, opts = {}) {
987
+ const n = Math.max(0, count);
988
+ const grid = gridFor(view, n);
989
+ const cols = grid.cols;
990
+ const rows = view === "square" ? grid.rows : Math.max(1, Math.ceil(n / cols));
991
+ const width = Math.max(0, Math.min(view === "square" ? Math.min(room.width, room.tall) : room.width, opts.maxSide ?? 880));
992
+ const list = view === "one";
993
+ const gap = list ? 8 : squareGap(Math.max(cols, Math.min(rows, 5)));
994
+ const cell = Math.max(0, (width - gap * (cols - 1)) / cols);
995
+ const rowHeight = list ? opts.listRow ?? 76 : cell;
996
+ return {
997
+ cols,
998
+ rows,
999
+ width,
1000
+ height: rows * rowHeight + gap * (rows - 1),
1001
+ gap,
1002
+ cell,
1003
+ rowHeight,
1004
+ level: list ? 1 : squareLevelFor(cell),
1005
+ list,
1006
+ open: cols * rows - n
1007
+ };
1008
+ }
1009
+ var CubeSquareTile = class CubeSquareTile {
1010
+ template = inject(TemplateRef);
1011
+ cubeSquareTile = input(...ngDevMode ? [void 0, { debugName: "cubeSquareTile" }] : /* istanbul ignore next */ []);
1012
+ static ngTemplateContextGuard(_dir, ctx) {
1013
+ return true;
1014
+ }
1015
+ static ɵfac = i0.ɵɵngDeclareFactory({
1016
+ minVersion: "12.0.0",
1017
+ version: "22.2.4",
1018
+ ngImport: i0,
1019
+ type: CubeSquareTile,
1020
+ deps: [],
1021
+ target: i0.ɵɵFactoryTarget.Directive
1022
+ });
1023
+ static ɵdir = i0.ɵɵngDeclareDirective({
1024
+ minVersion: "17.1.0",
1025
+ version: "22.2.4",
1026
+ type: CubeSquareTile,
1027
+ isStandalone: true,
1028
+ selector: "ng-template[cubeSquareTile]",
1029
+ inputs: { cubeSquareTile: {
1030
+ classPropertyName: "cubeSquareTile",
1031
+ publicName: "cubeSquareTile",
1032
+ isSignal: true,
1033
+ isRequired: false,
1034
+ transformFunction: null
1035
+ } },
1036
+ ngImport: i0
1037
+ });
1038
+ };
1039
+ i0.ɵɵngDeclareClassMetadata({
1040
+ minVersion: "12.0.0",
1041
+ version: "22.2.4",
1042
+ ngImport: i0,
1043
+ type: CubeSquareTile,
1044
+ decorators: [{
1045
+ type: Directive,
1046
+ args: [{ selector: "ng-template[cubeSquareTile]" }]
1047
+ }],
1048
+ propDecorators: { cubeSquareTile: [{
1049
+ type: i0.Input,
1050
+ args: [{
1051
+ isSignal: true,
1052
+ alias: "cubeSquareTile",
1053
+ required: false
1054
+ }]
1055
+ }] }
1056
+ });
1057
+ function turningFront(view, across = 3) {
1058
+ if (view === "square") return {
1059
+ cols: across,
1060
+ rows: across
1061
+ };
1062
+ if (view === "grid-4x5") return {
1063
+ cols: 4,
1064
+ rows: 5
1065
+ };
1066
+ if (view === "grid-3x6") return {
1067
+ cols: 3,
1068
+ rows: 6
1069
+ };
1070
+ return null;
1071
+ }
1072
+ const TURNING_BELOW = 640;
1073
+ const TURNING_NUDGE_UNTIL = 3;
1074
+ let turnedHere = 0;
1075
+ const readTurned = (key) => {
1076
+ if (!key) return turnedHere;
1077
+ try {
1078
+ return Number(localStorage.getItem(key)) || 0;
1079
+ } catch {
1080
+ return turnedHere;
1081
+ }
1082
+ };
1083
+ const noteTurned = (key) => {
1084
+ turnedHere++;
1085
+ if (!key) return;
1086
+ try {
1087
+ localStorage.setItem(key, String(readTurned(key) + 1));
1088
+ } catch {}
1089
+ };
1090
+ const reducedMotion = () => typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
1091
+ var CubeSquare = class CubeSquare {
1092
+ tiles = input.required(...ngDevMode ? [{ debugName: "tiles" }] : /* istanbul ignore next */ []);
1093
+ view = input("square", ...ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []);
1094
+ maxSide = input(880, ...ngDevMode ? [{ debugName: "maxSide" }] : /* istanbul ignore next */ []);
1095
+ listRow = input(76, ...ngDevMode ? [{ debugName: "listRow" }] : /* istanbul ignore next */ []);
1096
+ dashed = input(false, ...ngDevMode ? [{ debugName: "dashed" }] : /* istanbul ignore next */ []);
1097
+ keyOf = input((_, i) => i, ...ngDevMode ? [{ debugName: "keyOf" }] : /* istanbul ignore next */ []);
1098
+ turning = input(false, ...ngDevMode ? [{ debugName: "turning" }] : /* istanbul ignore next */ []);
1099
+ turnBelow = input(640, ...ngDevMode ? [{ debugName: "turnBelow" }] : /* istanbul ignore next */ []);
1100
+ across = input(3, ...ngDevMode ? [{ debugName: "across" }] : /* istanbul ignore next */ []);
1101
+ isOwn = input(null, ...ngDevMode ? [{ debugName: "isOwn" }] : /* istanbul ignore next */ []);
1102
+ nudgeKey = input(null, ...ngDevMode ? [{ debugName: "nudgeKey" }] : /* istanbul ignore next */ []);
1103
+ tile = contentChild(CubeSquareTile, ...ngDevMode ? [{ debugName: "tile" }] : /* istanbul ignore next */ []);
1104
+ grid = viewChild("grid", ...ngDevMode ? [{ debugName: "grid" }] : /* istanbul ignore next */ []);
1105
+ room = signal({
1106
+ width: 0,
1107
+ tall: 0
1108
+ }, ...ngDevMode ? [{ debugName: "room" }] : /* istanbul ignore next */ []);
1109
+ front = computed(() => {
1110
+ if (!this.turning()) return null;
1111
+ if ((this.room().width || 354) >= this.turnBelow()) return null;
1112
+ const front = turningFront(this.view(), Math.max(1, Math.floor(this.across())));
1113
+ return front && this.tiles().length > front.cols * front.rows ? front : null;
1114
+ }, ...ngDevMode ? [{ debugName: "front" }] : /* istanbul ignore next */ []);
1115
+ layout = computed(() => {
1116
+ const r = this.room();
1117
+ const width = r.width || 354;
1118
+ const room = {
1119
+ width,
1120
+ tall: r.tall || width
1121
+ };
1122
+ const opts = {
1123
+ maxSide: this.maxSide(),
1124
+ listRow: this.listRow()
1125
+ };
1126
+ const front = this.front();
1127
+ if (!front) return squareLayout(this.view(), this.tiles().length, room, opts);
1128
+ const full = squareLayout(this.view(), front.cols * front.rows, room, opts);
1129
+ const rows = this.rings()?.rows.length ?? front.rows;
1130
+ return {
1131
+ ...full,
1132
+ rows,
1133
+ height: rows * full.rowHeight + full.gap * (rows - 1),
1134
+ open: 0
1135
+ };
1136
+ }, ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
1137
+ rings = computed(() => {
1138
+ const front = this.front();
1139
+ if (!front) return null;
1140
+ const isOwn = this.isOwn();
1141
+ const tiles = this.tiles();
1142
+ const own = isOwn ? tiles.find((t) => isOwn(t)) ?? null : null;
1143
+ return turningRows(own === null ? tiles : tiles.filter((t) => t !== own), own, front.cols, front.rows);
1144
+ }, ...ngDevMode ? [{ debugName: "rings" }] : /* istanbul ignore next */ []);
1145
+ indexes = computed(() => new Map(this.tiles().map((t, i) => [t, i])), ...ngDevMode ? [{ debugName: "indexes" }] : /* istanbul ignore next */ []);
1146
+ indexOf(t) {
1147
+ return this.indexes().get(t) ?? 0;
1148
+ }
1149
+ openPlaces = computed(() => Array.from({ length: this.layout().open }, (_, i) => i), ...ngDevMode ? [{ debugName: "openPlaces" }] : /* istanbul ignore next */ []);
1150
+ angles = signal({}, ...ngDevMode ? [{ debugName: "angles" }] : /* istanbul ignore next */ []);
1151
+ dragging = signal(null, ...ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []);
1152
+ still = signal(reducedMotion(), ...ngDevMode ? [{ debugName: "still" }] : /* istanbul ignore next */ []);
1153
+ nudging = signal(false, ...ngDevMode ? [{ debugName: "nudging" }] : /* istanbul ignore next */ []);
1154
+ drag = null;
1155
+ fingers = /* @__PURE__ */ new Set();
1156
+ suppressClick = false;
1157
+ nudged = false;
1158
+ timers = [];
1159
+ host = inject(ElementRef).nativeElement;
1160
+ angle(row) {
1161
+ return this.angles()[row] ?? 0;
1162
+ }
1163
+ sideOf(row) {
1164
+ const sides = 4;
1165
+ return (Math.round(-this.angle(row) / 90) % sides + sides) % sides;
1166
+ }
1167
+ filled(row) {
1168
+ return this.rings()?.sides[row] ?? 1;
1169
+ }
1170
+ down(row, e) {
1171
+ this.fingers.add(e.pointerId);
1172
+ if (this.fingers.size > 1) {
1173
+ this.cancelDrag();
1174
+ return;
1175
+ }
1176
+ if (this.filled(row) <= 1) return;
1177
+ this.drag = {
1178
+ row,
1179
+ id: e.pointerId,
1180
+ x: e.clientX,
1181
+ y: e.clientY,
1182
+ base: this.angle(row),
1183
+ moved: false
1184
+ };
1185
+ }
1186
+ move(row, e) {
1187
+ const drag = this.drag;
1188
+ if (!drag || drag.row !== row || drag.id !== e.pointerId) return;
1189
+ const dx = e.clientX - drag.x;
1190
+ const dy = e.clientY - drag.y;
1191
+ if (!drag.moved) {
1192
+ if (Math.abs(dx) < 8 || Math.abs(dx) < Math.abs(dy)) return;
1193
+ drag.moved = true;
1194
+ this.dragging.set(row);
1195
+ e.currentTarget?.setPointerCapture?.(e.pointerId);
1196
+ }
1197
+ const width = this.layout().width || 354;
1198
+ this.angles.update((a) => ({
1199
+ ...a,
1200
+ [row]: drag.base + dx / width * 90
1201
+ }));
1202
+ }
1203
+ up(row, e) {
1204
+ this.fingers.delete(e.pointerId);
1205
+ const drag = this.drag;
1206
+ if (!drag || drag.row !== row || drag.id !== e.pointerId) return;
1207
+ this.drag = null;
1208
+ if (!drag.moved) return;
1209
+ this.dragging.set(null);
1210
+ this.suppressClick = true;
1211
+ setTimeout(() => this.suppressClick = false);
1212
+ const moved = this.angle(row) - drag.base;
1213
+ const steps = Math.abs(moved) > 12 ? Math.sign(moved) * Math.max(1, Math.round(Math.abs(moved) / 90)) : 0;
1214
+ this.settle(row, drag.base, steps);
1215
+ }
1216
+ cancelDrag() {
1217
+ const drag = this.drag;
1218
+ this.drag = null;
1219
+ if (!drag?.moved) return;
1220
+ this.dragging.set(null);
1221
+ this.angles.update((a) => ({
1222
+ ...a,
1223
+ [drag.row]: drag.base
1224
+ }));
1225
+ }
1226
+ settle(row, base, steps) {
1227
+ const filled = this.filled(row);
1228
+ const sideAt = (s) => (Math.round(-(base + s * 90) / 90) % 4 + 4) % 4;
1229
+ let n = steps;
1230
+ while (n !== 0 && sideAt(n) >= filled) n += Math.sign(n);
1231
+ this.angles.update((a) => ({
1232
+ ...a,
1233
+ [row]: base + n * 90
1234
+ }));
1235
+ if (n !== 0) noteTurned(this.nudgeKey());
1236
+ }
1237
+ key(row, e) {
1238
+ if (e.key !== "ArrowRight" && e.key !== "ArrowLeft") return;
1239
+ if (this.filled(row) <= 1) return;
1240
+ e.preventDefault();
1241
+ const col = this.focusedColumn(e.target);
1242
+ this.settle(row, this.angle(row), e.key === "ArrowRight" ? -1 : 1);
1243
+ setTimeout(() => this.focusSide(row, col));
1244
+ }
1245
+ focusedColumn(target) {
1246
+ const cell = target?.closest(".cs-cell, .cs-place");
1247
+ const side = cell?.parentElement;
1248
+ return cell && side ? Array.from(side.children).indexOf(cell) : 0;
1249
+ }
1250
+ focusSide(row, col) {
1251
+ const side = this.host.querySelector(`.cs-row[data-row="${row}"] .cs-side[data-side="${this.sideOf(row)}"]`);
1252
+ if (!side) return;
1253
+ const cells = Array.from(side.children);
1254
+ const order = [cells[col], ...cells].filter(Boolean);
1255
+ const focusable = "button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])";
1256
+ for (const cell of order) {
1257
+ const el = cell.matches(focusable) ? cell : cell.querySelector(focusable);
1258
+ if (el) {
1259
+ el.focus();
1260
+ return;
1261
+ }
1262
+ }
1263
+ side.closest(".cs-row")?.focus();
1264
+ }
1265
+ nudge() {
1266
+ const rings = this.rings();
1267
+ if (this.nudged || !rings || reducedMotion()) return;
1268
+ if (readTurned(this.nudgeKey()) >= 3) return;
1269
+ const rows = rings.sides.flatMap((s, i) => s > 1 ? [i] : []);
1270
+ if (!rows.length) return;
1271
+ this.nudged = true;
1272
+ this.nudging.set(true);
1273
+ const set = (row, angle) => {
1274
+ if (this.drag || this.dragging() !== null) return;
1275
+ this.angles.update((a) => ({
1276
+ ...a,
1277
+ [row]: angle
1278
+ }));
1279
+ };
1280
+ rows.forEach((row, i) => {
1281
+ this.timers.push(setTimeout(() => set(row, -22), 500 + i * 180), setTimeout(() => set(row, 0), 1020 + i * 180));
1282
+ });
1283
+ this.timers.push(setTimeout(() => this.nudging.set(false), 1600 + rows.length * 180));
1284
+ }
1285
+ constructor() {
1286
+ const host = this.host;
1287
+ const destroy = inject(DestroyRef);
1288
+ const swallow = (e) => {
1289
+ if (!this.suppressClick) return;
1290
+ e.stopPropagation();
1291
+ e.preventDefault();
1292
+ };
1293
+ host.addEventListener("click", swallow, true);
1294
+ destroy.onDestroy(() => {
1295
+ host.removeEventListener("click", swallow, true);
1296
+ this.timers.forEach(clearTimeout);
1297
+ });
1298
+ effect(() => {
1299
+ if (this.rings()) untracked(() => this.timers.push(setTimeout(() => this.nudge())));
1300
+ });
1301
+ afterNextRender(() => {
1302
+ const measure = () => this.room.set({
1303
+ width: host.clientWidth,
1304
+ tall: Math.max(320, window.innerHeight - 48)
1305
+ });
1306
+ measure();
1307
+ const watch = typeof ResizeObserver === "function" ? new ResizeObserver(measure) : null;
1308
+ watch?.observe(host);
1309
+ window.addEventListener("resize", measure);
1310
+ destroy.onDestroy(() => {
1311
+ watch?.disconnect();
1312
+ window.removeEventListener("resize", measure);
1313
+ });
1314
+ });
1315
+ let before = 0;
1316
+ let beforeView = null;
1317
+ effect(() => {
1318
+ const { cols, list } = this.layout();
1319
+ const view = this.view();
1320
+ const el = this.grid()?.nativeElement;
1321
+ if (el && before && cols !== before && view === beforeView && !list && !reducedMotion() && typeof el.animate === "function") el.animate([{ transform: `scale(${cols / before})` }, { transform: "none" }], {
1322
+ duration: 420,
1323
+ easing: "cubic-bezier(.2,.7,.2,1)"
1324
+ });
1325
+ before = cols;
1326
+ beforeView = view;
1327
+ });
1328
+ }
1329
+ static ɵfac = i0.ɵɵngDeclareFactory({
1330
+ minVersion: "12.0.0",
1331
+ version: "22.2.4",
1332
+ ngImport: i0,
1333
+ type: CubeSquare,
1334
+ deps: [],
1335
+ target: i0.ɵɵFactoryTarget.Component
1336
+ });
1337
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1338
+ minVersion: "17.0.0",
1339
+ version: "22.2.4",
1340
+ type: CubeSquare,
1341
+ isStandalone: true,
1342
+ selector: "cube-square",
1343
+ inputs: {
1344
+ tiles: {
1345
+ classPropertyName: "tiles",
1346
+ publicName: "tiles",
1347
+ isSignal: true,
1348
+ isRequired: true,
1349
+ transformFunction: null
1350
+ },
1351
+ view: {
1352
+ classPropertyName: "view",
1353
+ publicName: "view",
1354
+ isSignal: true,
1355
+ isRequired: false,
1356
+ transformFunction: null
1357
+ },
1358
+ maxSide: {
1359
+ classPropertyName: "maxSide",
1360
+ publicName: "maxSide",
1361
+ isSignal: true,
1362
+ isRequired: false,
1363
+ transformFunction: null
1364
+ },
1365
+ listRow: {
1366
+ classPropertyName: "listRow",
1367
+ publicName: "listRow",
1368
+ isSignal: true,
1369
+ isRequired: false,
1370
+ transformFunction: null
1371
+ },
1372
+ dashed: {
1373
+ classPropertyName: "dashed",
1374
+ publicName: "dashed",
1375
+ isSignal: true,
1376
+ isRequired: false,
1377
+ transformFunction: null
1378
+ },
1379
+ keyOf: {
1380
+ classPropertyName: "keyOf",
1381
+ publicName: "keyOf",
1382
+ isSignal: true,
1383
+ isRequired: false,
1384
+ transformFunction: null
1385
+ },
1386
+ turning: {
1387
+ classPropertyName: "turning",
1388
+ publicName: "turning",
1389
+ isSignal: true,
1390
+ isRequired: false,
1391
+ transformFunction: null
1392
+ },
1393
+ turnBelow: {
1394
+ classPropertyName: "turnBelow",
1395
+ publicName: "turnBelow",
1396
+ isSignal: true,
1397
+ isRequired: false,
1398
+ transformFunction: null
1399
+ },
1400
+ across: {
1401
+ classPropertyName: "across",
1402
+ publicName: "across",
1403
+ isSignal: true,
1404
+ isRequired: false,
1405
+ transformFunction: null
1406
+ },
1407
+ isOwn: {
1408
+ classPropertyName: "isOwn",
1409
+ publicName: "isOwn",
1410
+ isSignal: true,
1411
+ isRequired: false,
1412
+ transformFunction: null
1413
+ },
1414
+ nudgeKey: {
1415
+ classPropertyName: "nudgeKey",
1416
+ publicName: "nudgeKey",
1417
+ isSignal: true,
1418
+ isRequired: false,
1419
+ transformFunction: null
1420
+ }
1421
+ },
1422
+ queries: [{
1423
+ propertyName: "tile",
1424
+ first: true,
1425
+ predicate: CubeSquareTile,
1426
+ descendants: true,
1427
+ isSignal: true
1428
+ }],
1429
+ viewQueries: [{
1430
+ propertyName: "grid",
1431
+ first: true,
1432
+ predicate: ["grid"],
1433
+ descendants: true,
1434
+ isSignal: true
1435
+ }],
1436
+ ngImport: i0,
1437
+ template: `
1438
+ @let sq = layout();
1439
+ @if (rings(); as r) {
1440
+ <div
1441
+ class="cs-turning"
1442
+ [class]="'cs-turning cs-l' + sq.level"
1443
+ [class.cs-dashed]="dashed()"
1444
+ [attr.data-level]="sq.level"
1445
+ [style.width.px]="sq.width"
1446
+ [style.--cs-gap.px]="sq.gap"
1447
+ >
1448
+ @for (row of r.rows; track ri; let ri = $index) {
1449
+ <div
1450
+ class="cs-row"
1451
+ [class.cs-turns]="r.sides[ri] > 1"
1452
+ [attr.data-row]="ri"
1453
+ [style.height.px]="sq.rowHeight"
1454
+ (pointerdown)="down(ri, $event)"
1455
+ (pointermove)="move(ri, $event)"
1456
+ (pointerup)="up(ri, $event)"
1457
+ (pointercancel)="up(ri, $event)"
1458
+ (keydown)="key(ri, $event)"
1459
+ >
1460
+ @if (r.sides[ri] > 1) {
1461
+ <span class="cs-edge" aria-hidden="true"></span>
1462
+ }
1463
+ <div
1464
+ class="cs-band"
1465
+ [class.cs-still]="dragging() === ri || still()"
1466
+ [class.cs-nudging]="nudging()"
1467
+ [style.transform]="
1468
+ 'translateZ(' + -sq.width / 2 + 'px) rotateY(' + angle(ri) + 'deg)'
1469
+ "
1470
+ >
1471
+ @for (side of row; track si; let si = $index) {
1472
+ <div
1473
+ class="cs-side"
1474
+ [attr.data-side]="si"
1475
+ [style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
1476
+ [style.transform]="
1477
+ 'rotateY(' + si * 90 + 'deg) translateZ(' + sq.width / 2 + 'px)'
1478
+ "
1479
+ [attr.aria-hidden]="sideOf(ri) === si ? null : 'true'"
1480
+ [attr.inert]="sideOf(ri) === si ? null : ''"
1481
+ >
1482
+ @for (t of side; track ci; let ci = $index) {
1483
+ @if (t !== null) {
1484
+ <div class="cs-cell">
1485
+ @if (tile(); as tpl) {
1486
+ <ng-container
1487
+ [ngTemplateOutlet]="tpl.template"
1488
+ [ngTemplateOutletContext]="{
1489
+ $implicit: t,
1490
+ index: indexOf(t),
1491
+ level: sq.level,
1492
+ cell: sq.cell,
1493
+ rowHeight: sq.rowHeight,
1494
+ list: false,
1495
+ }"
1496
+ />
1497
+ }
1498
+ </div>
1499
+ } @else if (si < r.sides[ri]) {
1500
+ <div class="cs-place" aria-hidden="true"></div>
1501
+ }
1502
+ }
1503
+ </div>
1504
+ }
1505
+ </div>
1506
+ </div>
1507
+ }
1508
+ </div>
1509
+ } @else {
1510
+ <div
1511
+ #grid
1512
+ [class]="'cs-square cs-l' + sq.level"
1513
+ [class.cs-list]="sq.list"
1514
+ [class.cs-dashed]="dashed()"
1515
+ [attr.data-level]="sq.level"
1516
+ [style.width.px]="sq.width"
1517
+ [style.height.px]="sq.height"
1518
+ [style.--cs-gap.px]="sq.gap"
1519
+ [style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
1520
+ [style.grid-template-rows]="'repeat(' + sq.rows + ', minmax(0, 1fr))'"
1521
+ >
1522
+ @for (t of tiles(); track keyOf()(t, $index); let i = $index) {
1523
+ <div class="cs-cell">
1524
+ @if (tile(); as tpl) {
1525
+ <ng-container
1526
+ [ngTemplateOutlet]="tpl.template"
1527
+ [ngTemplateOutletContext]="{
1528
+ $implicit: t,
1529
+ index: i,
1530
+ level: sq.level,
1531
+ cell: sq.cell,
1532
+ rowHeight: sq.rowHeight,
1533
+ list: sq.list,
1534
+ }"
1535
+ />
1536
+ }
1537
+ </div>
1538
+ }
1539
+ @for (i of openPlaces(); track i) {
1540
+ <div class="cs-place" aria-hidden="true"></div>
1541
+ }
1542
+ </div>
1543
+ }
1544
+ `,
1545
+ isInline: true,
1546
+ styles: [":host{display:block}.cs-square{display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-cell{display:grid;min-width:0;min-height:0}.cs-place{box-sizing:border-box;border:var(--cube-square-place-width, 1.5px) solid var(--cube-square-place, color-mix(in srgb, #dae0d9 55%, transparent));border-radius:var(--cs-radius)}.cs-dashed .cs-place{border-style:dashed;border-color:var(--cube-square-place-dashed, #dae0d9)}.cs-l0{--cs-radius: 28px}.cs-l2{--cs-radius: 16px}.cs-l3{--cs-radius: 12px}.cs-l4{--cs-radius: 9px}.cs-l4 .cs-place{border-width:1px}.cs-turning{display:flex;flex-direction:column;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-row{position:relative;perspective:1400px;touch-action:pan-y;user-select:none;-webkit-user-select:none;outline:none}.cs-row:focus-visible{outline:2px solid var(--cube-square-focus, #5f9a80);outline-offset:3px;border-radius:var(--cs-radius)}.cs-band{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .38s cubic-bezier(.2,.8,.2,1)}.cs-band.cs-nudging{transition:transform .52s cubic-bezier(.4,0,.2,1)}.cs-band.cs-still{transition:none}.cs-side{position:absolute;inset:0;display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));backface-visibility:hidden}.cs-edge{pointer-events:none;position:absolute;top:18%;bottom:18%;right:calc(-1*max(4px,var(--cs-gap) - 2px));z-index:1;width:3px;border-radius:999px;background:var(--cube-square-edge, color-mix(in srgb, #5f9a80 45%, transparent))}\n"],
1547
+ dependencies: [{
1548
+ kind: "directive",
1549
+ type: NgTemplateOutlet,
1550
+ selector: "[ngTemplateOutlet]",
1551
+ inputs: [
1552
+ "ngTemplateOutletContext",
1553
+ "ngTemplateOutlet",
1554
+ "ngTemplateOutletInjector"
1555
+ ]
1556
+ }],
1557
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
1558
+ });
1559
+ };
1560
+ i0.ɵɵngDeclareClassMetadata({
1561
+ minVersion: "12.0.0",
1562
+ version: "22.2.4",
1563
+ ngImport: i0,
1564
+ type: CubeSquare,
1565
+ decorators: [{
1566
+ type: Component,
1567
+ args: [{
1568
+ selector: "cube-square",
1569
+ imports: [NgTemplateOutlet],
1570
+ template: `
1571
+ @let sq = layout();
1572
+ @if (rings(); as r) {
1573
+ <div
1574
+ class="cs-turning"
1575
+ [class]="'cs-turning cs-l' + sq.level"
1576
+ [class.cs-dashed]="dashed()"
1577
+ [attr.data-level]="sq.level"
1578
+ [style.width.px]="sq.width"
1579
+ [style.--cs-gap.px]="sq.gap"
1580
+ >
1581
+ @for (row of r.rows; track ri; let ri = $index) {
1582
+ <div
1583
+ class="cs-row"
1584
+ [class.cs-turns]="r.sides[ri] > 1"
1585
+ [attr.data-row]="ri"
1586
+ [style.height.px]="sq.rowHeight"
1587
+ (pointerdown)="down(ri, $event)"
1588
+ (pointermove)="move(ri, $event)"
1589
+ (pointerup)="up(ri, $event)"
1590
+ (pointercancel)="up(ri, $event)"
1591
+ (keydown)="key(ri, $event)"
1592
+ >
1593
+ @if (r.sides[ri] > 1) {
1594
+ <span class="cs-edge" aria-hidden="true"></span>
1595
+ }
1596
+ <div
1597
+ class="cs-band"
1598
+ [class.cs-still]="dragging() === ri || still()"
1599
+ [class.cs-nudging]="nudging()"
1600
+ [style.transform]="
1601
+ 'translateZ(' + -sq.width / 2 + 'px) rotateY(' + angle(ri) + 'deg)'
1602
+ "
1603
+ >
1604
+ @for (side of row; track si; let si = $index) {
1605
+ <div
1606
+ class="cs-side"
1607
+ [attr.data-side]="si"
1608
+ [style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
1609
+ [style.transform]="
1610
+ 'rotateY(' + si * 90 + 'deg) translateZ(' + sq.width / 2 + 'px)'
1611
+ "
1612
+ [attr.aria-hidden]="sideOf(ri) === si ? null : 'true'"
1613
+ [attr.inert]="sideOf(ri) === si ? null : ''"
1614
+ >
1615
+ @for (t of side; track ci; let ci = $index) {
1616
+ @if (t !== null) {
1617
+ <div class="cs-cell">
1618
+ @if (tile(); as tpl) {
1619
+ <ng-container
1620
+ [ngTemplateOutlet]="tpl.template"
1621
+ [ngTemplateOutletContext]="{
1622
+ $implicit: t,
1623
+ index: indexOf(t),
1624
+ level: sq.level,
1625
+ cell: sq.cell,
1626
+ rowHeight: sq.rowHeight,
1627
+ list: false,
1628
+ }"
1629
+ />
1630
+ }
1631
+ </div>
1632
+ } @else if (si < r.sides[ri]) {
1633
+ <div class="cs-place" aria-hidden="true"></div>
1634
+ }
1635
+ }
1636
+ </div>
1637
+ }
1638
+ </div>
1639
+ </div>
1640
+ }
1641
+ </div>
1642
+ } @else {
1643
+ <div
1644
+ #grid
1645
+ [class]="'cs-square cs-l' + sq.level"
1646
+ [class.cs-list]="sq.list"
1647
+ [class.cs-dashed]="dashed()"
1648
+ [attr.data-level]="sq.level"
1649
+ [style.width.px]="sq.width"
1650
+ [style.height.px]="sq.height"
1651
+ [style.--cs-gap.px]="sq.gap"
1652
+ [style.grid-template-columns]="'repeat(' + sq.cols + ', minmax(0, 1fr))'"
1653
+ [style.grid-template-rows]="'repeat(' + sq.rows + ', minmax(0, 1fr))'"
1654
+ >
1655
+ @for (t of tiles(); track keyOf()(t, $index); let i = $index) {
1656
+ <div class="cs-cell">
1657
+ @if (tile(); as tpl) {
1658
+ <ng-container
1659
+ [ngTemplateOutlet]="tpl.template"
1660
+ [ngTemplateOutletContext]="{
1661
+ $implicit: t,
1662
+ index: i,
1663
+ level: sq.level,
1664
+ cell: sq.cell,
1665
+ rowHeight: sq.rowHeight,
1666
+ list: sq.list,
1667
+ }"
1668
+ />
1669
+ }
1670
+ </div>
1671
+ }
1672
+ @for (i of openPlaces(); track i) {
1673
+ <div class="cs-place" aria-hidden="true"></div>
1674
+ }
1675
+ </div>
1676
+ }
1677
+ `,
1678
+ changeDetection: ChangeDetectionStrategy.OnPush,
1679
+ styles: [":host{display:block}.cs-square{display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-cell{display:grid;min-width:0;min-height:0}.cs-place{box-sizing:border-box;border:var(--cube-square-place-width, 1.5px) solid var(--cube-square-place, color-mix(in srgb, #dae0d9 55%, transparent));border-radius:var(--cs-radius)}.cs-dashed .cs-place{border-style:dashed;border-color:var(--cube-square-place-dashed, #dae0d9)}.cs-l0{--cs-radius: 28px}.cs-l2{--cs-radius: 16px}.cs-l3{--cs-radius: 12px}.cs-l4{--cs-radius: 9px}.cs-l4 .cs-place{border-width:1px}.cs-turning{display:flex;flex-direction:column;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));--cs-radius: var(--cube-square-radius, 20px)}.cs-row{position:relative;perspective:1400px;touch-action:pan-y;user-select:none;-webkit-user-select:none;outline:none}.cs-row:focus-visible{outline:2px solid var(--cube-square-focus, #5f9a80);outline-offset:3px;border-radius:var(--cs-radius)}.cs-band{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .38s cubic-bezier(.2,.8,.2,1)}.cs-band.cs-nudging{transition:transform .52s cubic-bezier(.4,0,.2,1)}.cs-band.cs-still{transition:none}.cs-side{position:absolute;inset:0;display:grid;gap:calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));backface-visibility:hidden}.cs-edge{pointer-events:none;position:absolute;top:18%;bottom:18%;right:calc(-1*max(4px,var(--cs-gap) - 2px));z-index:1;width:3px;border-radius:999px;background:var(--cube-square-edge, color-mix(in srgb, #5f9a80 45%, transparent))}\n"]
1680
+ }]
1681
+ }],
1682
+ ctorParameters: () => [],
1683
+ propDecorators: {
1684
+ tiles: [{
1685
+ type: i0.Input,
1686
+ args: [{
1687
+ isSignal: true,
1688
+ alias: "tiles",
1689
+ required: true
1690
+ }]
1691
+ }],
1692
+ view: [{
1693
+ type: i0.Input,
1694
+ args: [{
1695
+ isSignal: true,
1696
+ alias: "view",
1697
+ required: false
1698
+ }]
1699
+ }],
1700
+ maxSide: [{
1701
+ type: i0.Input,
1702
+ args: [{
1703
+ isSignal: true,
1704
+ alias: "maxSide",
1705
+ required: false
1706
+ }]
1707
+ }],
1708
+ listRow: [{
1709
+ type: i0.Input,
1710
+ args: [{
1711
+ isSignal: true,
1712
+ alias: "listRow",
1713
+ required: false
1714
+ }]
1715
+ }],
1716
+ dashed: [{
1717
+ type: i0.Input,
1718
+ args: [{
1719
+ isSignal: true,
1720
+ alias: "dashed",
1721
+ required: false
1722
+ }]
1723
+ }],
1724
+ keyOf: [{
1725
+ type: i0.Input,
1726
+ args: [{
1727
+ isSignal: true,
1728
+ alias: "keyOf",
1729
+ required: false
1730
+ }]
1731
+ }],
1732
+ turning: [{
1733
+ type: i0.Input,
1734
+ args: [{
1735
+ isSignal: true,
1736
+ alias: "turning",
1737
+ required: false
1738
+ }]
1739
+ }],
1740
+ turnBelow: [{
1741
+ type: i0.Input,
1742
+ args: [{
1743
+ isSignal: true,
1744
+ alias: "turnBelow",
1745
+ required: false
1746
+ }]
1747
+ }],
1748
+ across: [{
1749
+ type: i0.Input,
1750
+ args: [{
1751
+ isSignal: true,
1752
+ alias: "across",
1753
+ required: false
1754
+ }]
1755
+ }],
1756
+ isOwn: [{
1757
+ type: i0.Input,
1758
+ args: [{
1759
+ isSignal: true,
1760
+ alias: "isOwn",
1761
+ required: false
1762
+ }]
1763
+ }],
1764
+ nudgeKey: [{
1765
+ type: i0.Input,
1766
+ args: [{
1767
+ isSignal: true,
1768
+ alias: "nudgeKey",
1769
+ required: false
1770
+ }]
1771
+ }],
1772
+ tile: [{
1773
+ type: i0.ContentChild,
1774
+ args: [i0.forwardRef(() => CubeSquareTile), { isSignal: true }]
1775
+ }],
1776
+ grid: [{
1777
+ type: i0.ViewChild,
1778
+ args: ["grid", { isSignal: true }]
1779
+ }]
1780
+ }
1781
+ });
1782
+ const contextLevelFor = squareLevelFor;
1783
+ function contextSquare(count, room, maxSide = 880) {
1784
+ const { cols: n, rows } = gridFor("square", count);
1785
+ const side = Math.max(0, Math.min(room, maxSide));
1786
+ const gap = squareGap(n);
1787
+ const cell = (side - gap * (n - 1)) / n;
1788
+ return {
1789
+ n,
1790
+ side,
1791
+ gap,
1792
+ level: contextLevelFor(cell),
1793
+ open: n * rows - Math.max(0, count)
1794
+ };
1795
+ }
1796
+ function contextIcon(tile) {
1797
+ if (CUBE_ICON_NAMES.includes(tile.icon)) return tile.icon;
1798
+ if (tile.adds) return "plus";
1799
+ if (tile.icon === "hide") return "shown";
1800
+ return "face";
1801
+ }
1802
+ var CubeContext = class CubeContext {
1803
+ held = input.required(...ngDevMode ? [{ debugName: "held" }] : /* istanbul ignore next */ []);
1804
+ path = input([], ...ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []);
1805
+ source = input(null, ...ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []);
1806
+ words = input(null, ...ngDevMode ? [{ debugName: "words" }] : /* istanbul ignore next */ []);
1807
+ maxSide = input(880, ...ngDevMode ? [{ debugName: "maxSide" }] : /* istanbul ignore next */ []);
1808
+ enter = output();
1809
+ out = output();
1810
+ done = output();
1811
+ tapped = output();
1812
+ given = inject(CONTEXT_CUBE_SOURCE, { optional: true });
1813
+ givenWords = inject(CONTEXT_CUBE_WORDS, { optional: true });
1814
+ busy = signal(null, ...ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []);
1815
+ again = signal(0, ...ngDevMode ? [{ debugName: "again" }] : /* istanbul ignore next */ []);
1816
+ from = computed(() => {
1817
+ const s = this.source() ?? this.given;
1818
+ if (!s) throw new Error("cube-context: provide CONTEXT_CUBE_SOURCE or pass [source]");
1819
+ return s;
1820
+ }, ...ngDevMode ? [{ debugName: "from" }] : /* istanbul ignore next */ []);
1821
+ where = computed(() => this.path().join("\0"), ...ngDevMode ? [{ debugName: "where" }] : /* istanbul ignore next */ []);
1822
+ level = computed(() => {
1823
+ this.again();
1824
+ return this.from().level(this.held(), this.path());
1825
+ }, ...ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ []);
1826
+ tiles = computed(() => this.level() ?? [], ...ngDevMode ? [{ debugName: "tiles" }] : /* istanbul ignore next */ []);
1827
+ adds = computed(() => this.tiles().some((t) => !!t.adds), ...ngDevMode ? [{ debugName: "adds" }] : /* istanbul ignore next */ []);
1828
+ keyOf = (t) => t.key;
1829
+ inUseWord = computed(() => (this.words() ?? this.givenWords)?.inUse ?? null, ...ngDevMode ? [{ debugName: "inUseWord" }] : /* istanbul ignore next */ []);
1830
+ iconOf = contextIcon;
1831
+ constructor() {
1832
+ effect(() => {
1833
+ if (this.level() === null) untracked(() => this.out.emit());
1834
+ });
1835
+ effect(() => {
1836
+ this.where();
1837
+ this.held();
1838
+ untracked(() => this.busy.set(null));
1839
+ });
1840
+ }
1841
+ async tap(tile, element) {
1842
+ if (this.busy() !== null) return;
1843
+ if (element) this.tapped.emit({
1844
+ tile,
1845
+ element
1846
+ });
1847
+ const held = this.held();
1848
+ const path = this.path();
1849
+ const where = this.where();
1850
+ const here = () => this.held() === held && this.where() === where;
1851
+ this.busy.set(tile.key);
1852
+ try {
1853
+ const picked = await this.from().pick(held, path, tile);
1854
+ if (!here()) return;
1855
+ switch (picked.kind) {
1856
+ case "enter":
1857
+ this.enter.emit(picked.path);
1858
+ break;
1859
+ case "done":
1860
+ this.done.emit(tile);
1861
+ break;
1862
+ case "out": this.out.emit();
1863
+ }
1864
+ } finally {
1865
+ if (here()) this.busy.set(null);
1866
+ this.again.update((n) => n + 1);
1867
+ }
1868
+ }
1869
+ static ɵfac = i0.ɵɵngDeclareFactory({
1870
+ minVersion: "12.0.0",
1871
+ version: "22.2.4",
1872
+ ngImport: i0,
1873
+ type: CubeContext,
1874
+ deps: [],
1875
+ target: i0.ɵɵFactoryTarget.Component
1876
+ });
1877
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1878
+ minVersion: "17.0.0",
1879
+ version: "22.2.4",
1880
+ type: CubeContext,
1881
+ isStandalone: true,
1882
+ selector: "cube-context",
1883
+ inputs: {
1884
+ held: {
1885
+ classPropertyName: "held",
1886
+ publicName: "held",
1887
+ isSignal: true,
1888
+ isRequired: true,
1889
+ transformFunction: null
1890
+ },
1891
+ path: {
1892
+ classPropertyName: "path",
1893
+ publicName: "path",
1894
+ isSignal: true,
1895
+ isRequired: false,
1896
+ transformFunction: null
1897
+ },
1898
+ source: {
1899
+ classPropertyName: "source",
1900
+ publicName: "source",
1901
+ isSignal: true,
1902
+ isRequired: false,
1903
+ transformFunction: null
1904
+ },
1905
+ words: {
1906
+ classPropertyName: "words",
1907
+ publicName: "words",
1908
+ isSignal: true,
1909
+ isRequired: false,
1910
+ transformFunction: null
1911
+ },
1912
+ maxSide: {
1913
+ classPropertyName: "maxSide",
1914
+ publicName: "maxSide",
1915
+ isSignal: true,
1916
+ isRequired: false,
1917
+ transformFunction: null
1918
+ }
1919
+ },
1920
+ outputs: {
1921
+ enter: "enter",
1922
+ out: "out",
1923
+ done: "done",
1924
+ tapped: "tapped"
1925
+ },
1926
+ ngImport: i0,
1927
+ template: `
1928
+ <cube-square
1929
+ [tiles]="tiles()"
1930
+ [dashed]="adds()"
1931
+ [maxSide]="maxSide()"
1932
+ [keyOf]="keyOf"
1933
+ [class.cc-adds]="adds()"
1934
+ >
1935
+ <ng-template [cubeSquareTile]="tiles()" let-t let-level="level">
1936
+ <button
1937
+ type="button"
1938
+ [class]="'cc-tile cc-l' + level"
1939
+ [class.cc-in-use]="!!t.inUse"
1940
+ [class.cc-pale]="!!t.pale"
1941
+ [class.cc-adds]="!!t.adds"
1942
+ [class.cc-busy]="busy() === t.key"
1943
+ [disabled]="busy() !== null"
1944
+ [attr.aria-label]="level >= 4 ? t.title : null"
1945
+ [attr.aria-current]="t.inUse ? 'true' : null"
1946
+ [attr.title]="level >= 3 ? t.title : null"
1947
+ (click)="tap(t, $any($event.currentTarget))"
1948
+ >
1949
+ <span class="cc-icon"><cube-icon [icon]="iconOf(t)" [inUse]="!!t.inUse" /></span>
1950
+ @if (level < 4) {
1951
+ <span class="cc-t">{{ t.title }}</span>
1952
+ }
1953
+ @if (t.line && level < 3) {
1954
+ <span class="cc-m">{{ t.line }}</span>
1955
+ }
1956
+ @if (t.inUse && inUseWord() && level < 3) {
1957
+ <span class="cc-tick">{{ inUseWord() }}</span>
1958
+ }
1959
+ </button>
1960
+ </ng-template>
1961
+ </cube-square>
1962
+ `,
1963
+ isInline: true,
1964
+ styles: [":host{display:block;font:inherit;color:var(--cube-context-ink, #1f2a26);--cube-square-place: color-mix(in srgb, var(--cube-context-line, #dae0d9) 55%, transparent);--cube-square-place-dashed: var(--cube-context-line, #dae0d9);--cube-square-radius: var(--cube-context-radius, 20px)}.cc-tile{all:unset;cursor:pointer;box-sizing:border-box;min-width:0;min-height:0;height:100%;overflow:hidden;display:grid;justify-items:center;align-content:center;gap:6px;padding:14px 10px 12px;text-align:center;background:var(--cube-context-tile, #ffffff);border:1px solid var(--cube-context-line, #dae0d9);border-radius:var(--cube-context-radius, 20px);user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:transform .16s}.cc-tile:active:not(:disabled){transform:scale(.97)}.cc-tile:focus-visible{outline:3px solid var(--cube-context-focus, #5f9a80);outline-offset:2px}.cc-tile.cc-in-use{border:2px solid var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-pale{background:transparent;border:2px dashed var(--cube-context-line, #dae0d9);color:var(--cube-context-quiet, #5d6a64)}.cc-tile.cc-adds{border:2px solid var(--cube-context-adds, #c8693f)}.cc-tile.cc-busy{opacity:.6;cursor:progress}.cc-tile:disabled:not(.cc-busy){cursor:default}.cc-icon{display:grid;place-items:center;line-height:0}.cc-tile.cc-adds .cc-icon{width:52px;height:52px;border-radius:50%;background:var(--cube-context-adds-bg, #f3e3d6);--cube-icon-stroke: var(--cube-context-adds-ink, #7a4a2b);--cube-icon-size: 26px}.cc-t,.cc-m{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}.cc-t{-webkit-line-clamp:var(--cube-context-title-lines, 2);line-clamp:var(--cube-context-title-lines, 2)}.cc-m{-webkit-line-clamp:var(--cube-context-line-lines, 2);line-clamp:var(--cube-context-line-lines, 2)}.cc-t{font-size:var(--cube-context-title-size, 17px);font-weight:700;line-height:1.2}.cc-m{font-size:var(--cube-context-line-size, 13px);line-height:1.3;color:var(--cube-context-quiet, #5d6a64)}.cc-tick{font-size:var(--cube-context-line-size, 13px);font-weight:800;color:var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-l0{border-radius:28px;padding:24px;gap:10px}.cc-l0 .cc-t{font-size:calc(var(--cube-context-title-size, 17px) * 26 / 17)}.cc-l0 .cc-m{font-size:calc(var(--cube-context-line-size, 13px) * 16 / 13)}.cc-l0 .cc-icon{--cube-icon-size: 64px}.cc-tile.cc-l0.cc-adds .cc-icon{width:96px;height:96px;--cube-icon-size: 40px}.cc-tile.cc-l2{border-radius:16px;padding:10px 6px;gap:5px}.cc-l2 .cc-t{font-size:calc(var(--cube-context-title-size, 17px) * 14 / 17)}.cc-l2 .cc-m{font-size:calc(var(--cube-context-line-size, 13px) * 12 / 13)}.cc-tile.cc-l3{border-radius:12px;padding:6px 4px;gap:3px}.cc-l3 .cc-t{font-size:calc(var(--cube-context-title-size, 17px) * 12 / 17)}.cc-tile.cc-l4{border-radius:9px;padding:2px;gap:0}.cc-l3 .cc-icon,.cc-l4 .cc-icon{--cube-icon-size: 24px}.cc-tile.cc-l3.cc-adds .cc-icon,.cc-tile.cc-l4.cc-adds .cc-icon{width:30px;height:30px;--cube-icon-size: 18px}\n"],
1965
+ dependencies: [
1966
+ {
1967
+ kind: "component",
1968
+ type: CubeIcon,
1969
+ selector: "cube-icon",
1970
+ inputs: ["icon", "inUse"]
1971
+ },
1972
+ {
1973
+ kind: "component",
1974
+ type: CubeSquare,
1975
+ selector: "cube-square",
1976
+ inputs: [
1977
+ "tiles",
1978
+ "view",
1979
+ "maxSide",
1980
+ "listRow",
1981
+ "dashed",
1982
+ "keyOf",
1983
+ "turning",
1984
+ "turnBelow",
1985
+ "across",
1986
+ "isOwn",
1987
+ "nudgeKey"
1988
+ ]
1989
+ },
1990
+ {
1991
+ kind: "directive",
1992
+ type: CubeSquareTile,
1993
+ selector: "ng-template[cubeSquareTile]",
1994
+ inputs: ["cubeSquareTile"]
1995
+ }
1996
+ ],
1997
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
1998
+ });
1999
+ };
2000
+ i0.ɵɵngDeclareClassMetadata({
2001
+ minVersion: "12.0.0",
2002
+ version: "22.2.4",
2003
+ ngImport: i0,
2004
+ type: CubeContext,
2005
+ decorators: [{
2006
+ type: Component,
2007
+ args: [{
2008
+ selector: "cube-context",
2009
+ imports: [
2010
+ CubeIcon,
2011
+ CubeSquare,
2012
+ CubeSquareTile
2013
+ ],
2014
+ template: `
2015
+ <cube-square
2016
+ [tiles]="tiles()"
2017
+ [dashed]="adds()"
2018
+ [maxSide]="maxSide()"
2019
+ [keyOf]="keyOf"
2020
+ [class.cc-adds]="adds()"
2021
+ >
2022
+ <ng-template [cubeSquareTile]="tiles()" let-t let-level="level">
2023
+ <button
2024
+ type="button"
2025
+ [class]="'cc-tile cc-l' + level"
2026
+ [class.cc-in-use]="!!t.inUse"
2027
+ [class.cc-pale]="!!t.pale"
2028
+ [class.cc-adds]="!!t.adds"
2029
+ [class.cc-busy]="busy() === t.key"
2030
+ [disabled]="busy() !== null"
2031
+ [attr.aria-label]="level >= 4 ? t.title : null"
2032
+ [attr.aria-current]="t.inUse ? 'true' : null"
2033
+ [attr.title]="level >= 3 ? t.title : null"
2034
+ (click)="tap(t, $any($event.currentTarget))"
2035
+ >
2036
+ <span class="cc-icon"><cube-icon [icon]="iconOf(t)" [inUse]="!!t.inUse" /></span>
2037
+ @if (level < 4) {
2038
+ <span class="cc-t">{{ t.title }}</span>
2039
+ }
2040
+ @if (t.line && level < 3) {
2041
+ <span class="cc-m">{{ t.line }}</span>
2042
+ }
2043
+ @if (t.inUse && inUseWord() && level < 3) {
2044
+ <span class="cc-tick">{{ inUseWord() }}</span>
2045
+ }
2046
+ </button>
2047
+ </ng-template>
2048
+ </cube-square>
2049
+ `,
2050
+ changeDetection: ChangeDetectionStrategy.OnPush,
2051
+ styles: [":host{display:block;font:inherit;color:var(--cube-context-ink, #1f2a26);--cube-square-place: color-mix(in srgb, var(--cube-context-line, #dae0d9) 55%, transparent);--cube-square-place-dashed: var(--cube-context-line, #dae0d9);--cube-square-radius: var(--cube-context-radius, 20px)}.cc-tile{all:unset;cursor:pointer;box-sizing:border-box;min-width:0;min-height:0;height:100%;overflow:hidden;display:grid;justify-items:center;align-content:center;gap:6px;padding:14px 10px 12px;text-align:center;background:var(--cube-context-tile, #ffffff);border:1px solid var(--cube-context-line, #dae0d9);border-radius:var(--cube-context-radius, 20px);user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transition:transform .16s}.cc-tile:active:not(:disabled){transform:scale(.97)}.cc-tile:focus-visible{outline:3px solid var(--cube-context-focus, #5f9a80);outline-offset:2px}.cc-tile.cc-in-use{border:2px solid var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-pale{background:transparent;border:2px dashed var(--cube-context-line, #dae0d9);color:var(--cube-context-quiet, #5d6a64)}.cc-tile.cc-adds{border:2px solid var(--cube-context-adds, #c8693f)}.cc-tile.cc-busy{opacity:.6;cursor:progress}.cc-tile:disabled:not(.cc-busy){cursor:default}.cc-icon{display:grid;place-items:center;line-height:0}.cc-tile.cc-adds .cc-icon{width:52px;height:52px;border-radius:50%;background:var(--cube-context-adds-bg, #f3e3d6);--cube-icon-stroke: var(--cube-context-adds-ink, #7a4a2b);--cube-icon-size: 26px}.cc-t,.cc-m{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}.cc-t{-webkit-line-clamp:var(--cube-context-title-lines, 2);line-clamp:var(--cube-context-title-lines, 2)}.cc-m{-webkit-line-clamp:var(--cube-context-line-lines, 2);line-clamp:var(--cube-context-line-lines, 2)}.cc-t{font-size:var(--cube-context-title-size, 17px);font-weight:700;line-height:1.2}.cc-m{font-size:var(--cube-context-line-size, 13px);line-height:1.3;color:var(--cube-context-quiet, #5d6a64)}.cc-tick{font-size:var(--cube-context-line-size, 13px);font-weight:800;color:var(--cube-context-in-use, #3b5a4c)}.cc-tile.cc-l0{border-radius:28px;padding:24px;gap:10px}.cc-l0 .cc-t{font-size:calc(var(--cube-context-title-size, 17px) * 26 / 17)}.cc-l0 .cc-m{font-size:calc(var(--cube-context-line-size, 13px) * 16 / 13)}.cc-l0 .cc-icon{--cube-icon-size: 64px}.cc-tile.cc-l0.cc-adds .cc-icon{width:96px;height:96px;--cube-icon-size: 40px}.cc-tile.cc-l2{border-radius:16px;padding:10px 6px;gap:5px}.cc-l2 .cc-t{font-size:calc(var(--cube-context-title-size, 17px) * 14 / 17)}.cc-l2 .cc-m{font-size:calc(var(--cube-context-line-size, 13px) * 12 / 13)}.cc-tile.cc-l3{border-radius:12px;padding:6px 4px;gap:3px}.cc-l3 .cc-t{font-size:calc(var(--cube-context-title-size, 17px) * 12 / 17)}.cc-tile.cc-l4{border-radius:9px;padding:2px;gap:0}.cc-l3 .cc-icon,.cc-l4 .cc-icon{--cube-icon-size: 24px}.cc-tile.cc-l3.cc-adds .cc-icon,.cc-tile.cc-l4.cc-adds .cc-icon{width:30px;height:30px;--cube-icon-size: 18px}\n"]
2052
+ }]
2053
+ }],
2054
+ ctorParameters: () => [],
2055
+ propDecorators: {
2056
+ held: [{
2057
+ type: i0.Input,
2058
+ args: [{
2059
+ isSignal: true,
2060
+ alias: "held",
2061
+ required: true
2062
+ }]
2063
+ }],
2064
+ path: [{
2065
+ type: i0.Input,
2066
+ args: [{
2067
+ isSignal: true,
2068
+ alias: "path",
2069
+ required: false
2070
+ }]
2071
+ }],
2072
+ source: [{
2073
+ type: i0.Input,
2074
+ args: [{
2075
+ isSignal: true,
2076
+ alias: "source",
2077
+ required: false
2078
+ }]
2079
+ }],
2080
+ words: [{
2081
+ type: i0.Input,
2082
+ args: [{
2083
+ isSignal: true,
2084
+ alias: "words",
2085
+ required: false
2086
+ }]
2087
+ }],
2088
+ maxSide: [{
2089
+ type: i0.Input,
2090
+ args: [{
2091
+ isSignal: true,
2092
+ alias: "maxSide",
2093
+ required: false
2094
+ }]
2095
+ }],
2096
+ enter: [{
2097
+ type: i0.Output,
2098
+ args: ["enter"]
2099
+ }],
2100
+ out: [{
2101
+ type: i0.Output,
2102
+ args: ["out"]
2103
+ }],
2104
+ done: [{
2105
+ type: i0.Output,
2106
+ args: ["done"]
2107
+ }],
2108
+ tapped: [{
2109
+ type: i0.Output,
2110
+ args: ["tapped"]
2111
+ }]
2112
+ }
2113
+ });
2114
+ export { CONTEXT_CUBE_SOURCE, CONTEXT_CUBE_WORDS, CONTEXT_PART_ORDER, CUBE_HOLD_MS, CUBE_HOLD_SLOP, CUBE_ICON_NAMES, CubeContext, CubeHold, CubeIcon, CubePicture, CubeSquare, CubeSquareTile, PART_ICONS, SQUARE_LIST_ROW, SQUARE_MAX_SIDE, TURNING_BELOW, TURNING_NUDGE_UNTIL, TURNING_SIDES, VIEW_KEYS, contextIcon, contextLevelFor, contextSquare, cubeIconCells, directionWords, drawCube, gridFor, hideLevel, isView, namesLevel, orderParts, partsLevel, sizeFor, sortDirectionsLevel, sortItems, sortLevel, squareGap, squareLayout, squareLevelFor, turningFront, turningRows, viewLevel };
259
2115
 
260
2116
  //# sourceMappingURL=selimssevgi-cube-design-angular.mjs.map