inspector-ng 0.0.11 → 0.0.12

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.
@@ -655,7 +655,7 @@ const createId = () => typeof crypto !== 'undefined' && 'randomUUID' in crypto
655
655
  ? crypto.randomUUID()
656
656
  : `${Date.now()}-${Math.random()}`;
657
657
  const formatValue = (value) => Math.round(value);
658
- /** Compact relative time for Raycast-style list subtitles. */
658
+ /** Ultra-compact relative time for dense command-palette metadata. */
659
659
  const formatRelativeTime = (iso, now = Date.now()) => {
660
660
  const then = Date.parse(iso);
661
661
  if (Number.isNaN(then)) {
@@ -663,30 +663,38 @@ const formatRelativeTime = (iso, now = Date.now()) => {
663
663
  }
664
664
  const seconds = Math.round((now - then) / 1000);
665
665
  if (seconds < 45) {
666
- return 'just now';
666
+ return 'now';
667
667
  }
668
668
  if (seconds < 90) {
669
- return '1m ago';
669
+ return '1m';
670
670
  }
671
671
  const minutes = Math.round(seconds / 60);
672
672
  if (minutes < 60) {
673
- return `${minutes}m ago`;
673
+ return `${minutes}m`;
674
674
  }
675
675
  const hours = Math.round(minutes / 60);
676
676
  if (hours < 24) {
677
- return `${hours}h ago`;
677
+ return `${hours}h`;
678
678
  }
679
679
  const days = Math.round(hours / 24);
680
680
  if (days < 30) {
681
- return `${days}d ago`;
681
+ return `${days}d`;
682
682
  }
683
683
  const months = Math.round(days / 30);
684
684
  if (months < 12) {
685
- return `${months}mo ago`;
685
+ return `${months}mo`;
686
686
  }
687
- return `${Math.round(months / 12)}y ago`;
687
+ return `${Math.round(months / 12)}y`;
688
688
  };
689
689
 
690
+ const INSPECTOR_COMMAND_ACTIONS = [
691
+ { id: 'save', label: 'Save', ariaLabel: 'Save checkpoint', keywords: 'save checkpoint capture state' },
692
+ { id: 'select', label: 'Select', ariaLabel: 'Select mode', keywords: 'select inspect pointer element' },
693
+ { id: 'type', label: 'Type', ariaLabel: 'Toggle typography overlay', keywords: 'type typography text overlay' },
694
+ { id: 'vertical', label: 'V', ariaLabel: 'Vertical guides', keywords: 'vertical v guide guides' },
695
+ { id: 'horizontal', label: 'H', ariaLabel: 'Horizontal guides', keywords: 'horizontal h guide guides' },
696
+ { id: 'off', label: 'Off', ariaLabel: 'Disable inspector', keywords: 'off disable inspector power' },
697
+ ];
690
698
  class inspectorComponent {
691
699
  constructor(platformId) {
692
700
  this.Math = Math;
@@ -704,13 +712,31 @@ class inspectorComponent {
704
712
  this.checkpointService = inject(InspectorCheckpointService, { optional: true });
705
713
  this.commandBarOpen = signal(false);
706
714
  this.checkpointQuery = signal('');
707
- this.activeCheckpointIndex = signal(0);
715
+ this.activeCommandIndex = signal(0);
708
716
  this.editingCheckpointId = signal(null);
709
717
  this.deletingCheckpointId = signal(null);
710
718
  this.renameDraft = signal('');
711
719
  this.checkpointToast = signal(null);
712
720
  this.checkpointToastIsError = signal(false);
713
721
  this.filteredCheckpoints = computed(() => fuzzyCheckpoints(this.checkpointService?.checkpoints() ?? [], this.checkpointQuery()));
722
+ this.filteredInspectorActions = computed(() => {
723
+ const terms = this.checkpointQuery().trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
724
+ if (!terms.length)
725
+ return INSPECTOR_COMMAND_ACTIONS;
726
+ return INSPECTOR_COMMAND_ACTIONS.filter((action) => {
727
+ const searchableText = `${action.label} ${action.ariaLabel} ${action.keywords}`.toLocaleLowerCase();
728
+ return terms.every((term) => searchableText.includes(term));
729
+ });
730
+ });
731
+ this.commandResultCount = computed(() => this.filteredCheckpoints().length + this.filteredInspectorActions().length);
732
+ this.activeCommandResultId = computed(() => {
733
+ const checkpoint = this.filteredCheckpoints()[this.activeCommandIndex()];
734
+ if (checkpoint)
735
+ return `inspector-checkpoint-${checkpoint.id}`;
736
+ const actionIndex = this.activeCommandIndex() - this.filteredCheckpoints().length;
737
+ const action = this.filteredInspectorActions()[actionIndex];
738
+ return action ? `inspector-action-${action.id}` : null;
739
+ });
714
740
  this.enabled = signal(true);
715
741
  this.toolMode = signal('none');
716
742
  this.guideOrientation = signal('vertical');
@@ -855,14 +881,14 @@ class inspectorComponent {
855
881
  return;
856
882
  this.commandBarOpen.set(true);
857
883
  this.checkpointQuery.set('');
858
- this.activeCheckpointIndex.set(0);
884
+ this.activeCommandIndex.set(0);
859
885
  this.editingCheckpointId.set(null);
860
886
  this.deletingCheckpointId.set(null);
861
887
  this.checkpointService.clearError();
862
888
  this.checkpointDialog()?.nativeElement.showModal();
863
889
  queueMicrotask(() => this.checkpointSearch()?.nativeElement.focus());
864
890
  await this.checkpointService.load();
865
- this.clampActiveCheckpoint();
891
+ this.clampActiveCommand();
866
892
  }
867
893
  closeCheckpointCommandBar() {
868
894
  if (this.checkpointService?.busy())
@@ -874,13 +900,55 @@ class inspectorComponent {
874
900
  }
875
901
  updateCheckpointQuery(event) {
876
902
  this.checkpointQuery.set(event.target.value);
877
- this.activeCheckpointIndex.set(0);
903
+ this.activeCommandIndex.set(0);
878
904
  this.editingCheckpointId.set(null);
879
905
  this.deletingCheckpointId.set(null);
880
906
  this.checkpointService?.clearError();
881
907
  }
882
908
  setActiveCheckpoint(index) {
883
- this.activeCheckpointIndex.set(index);
909
+ this.activeCommandIndex.set(index);
910
+ }
911
+ shouldShowCheckpointRoute(checkpoint) {
912
+ if (!checkpoint.route.trim())
913
+ return false;
914
+ return this.normalizeCheckpointLabel(checkpoint.name) !== this.normalizeCheckpointLabel(checkpoint.route);
915
+ }
916
+ setActiveInspectorAction(index) {
917
+ this.activeCommandIndex.set(this.filteredCheckpoints().length + index);
918
+ }
919
+ async executeInspectorAction(action) {
920
+ if (this.checkpointService?.busy())
921
+ return;
922
+ switch (action.id) {
923
+ case 'select':
924
+ this.setToolMode('select');
925
+ this.closeCheckpointCommandBar();
926
+ break;
927
+ case 'type':
928
+ this.toggleTypography();
929
+ this.closeCheckpointCommandBar();
930
+ break;
931
+ case 'save':
932
+ await this.saveCheckpoint();
933
+ if (this.commandBarOpen()) {
934
+ const index = this.filteredInspectorActions().findIndex(({ id }) => id === action.id);
935
+ if (index >= 0)
936
+ this.setActiveInspectorAction(index);
937
+ }
938
+ break;
939
+ case 'vertical':
940
+ this.activateGuideOrientation('vertical');
941
+ this.closeCheckpointCommandBar();
942
+ break;
943
+ case 'horizontal':
944
+ this.activateGuideOrientation('horizontal');
945
+ this.closeCheckpointCommandBar();
946
+ break;
947
+ case 'off':
948
+ this.closeCheckpointCommandBar();
949
+ this.disableInspector();
950
+ break;
951
+ }
884
952
  }
885
953
  async restoreCheckpoint(checkpoint) {
886
954
  if (!this.checkpointService || this.checkpointService.busy())
@@ -937,7 +1005,7 @@ class inspectorComponent {
937
1005
  if (!await this.checkpointService?.delete(checkpoint.id))
938
1006
  return;
939
1007
  this.deletingCheckpointId.set(null);
940
- this.clampActiveCheckpoint();
1008
+ this.clampActiveCommand();
941
1009
  this.checkpointSearch()?.nativeElement.focus();
942
1010
  }
943
1011
  handleCheckpointDialogClick(event) {
@@ -979,75 +1047,29 @@ class inspectorComponent {
979
1047
  this.handleCommandBarKeydown(event, key);
980
1048
  return;
981
1049
  }
982
- if (key === 'm') {
983
- const target = event.target;
984
- if (target?.matches('input, textarea, select') ||
985
- target?.isContentEditable) {
986
- return;
987
- }
988
- event.preventDefault();
989
- this.setInspectorEnabled(!this.enabled());
990
- return;
991
- }
992
- if (!this.enabled()) {
993
- return;
994
- }
995
- if ((event.metaKey || event.ctrlKey) && key === 'z') {
996
- event.preventDefault();
997
- event.shiftKey ? this.redo() : this.undo();
998
- return;
999
- }
1000
- if (key === 's') {
1001
- event.preventDefault();
1002
- this.setToolMode('select');
1003
- return;
1004
- }
1005
- if (key === 'g') {
1006
- event.preventDefault();
1007
- this.setToolMode('guides');
1008
- return;
1009
- }
1010
- if (key === 'h') {
1011
- event.preventDefault();
1012
- this.setGuideOrientation('horizontal');
1013
- return;
1014
- }
1015
- if (key === 'v') {
1016
- event.preventDefault();
1017
- this.setGuideOrientation('vertical');
1018
- return;
1019
- }
1020
- if (event.key === 'Alt') {
1021
- this.altPressed.set(true);
1022
- this.updateDistanceOverlay();
1023
- return;
1024
- }
1025
1050
  if (key === 'escape') {
1026
1051
  event.preventDefault();
1027
- this.selectedMeasurement.set(null);
1028
- this.selectedGuideId.set(null);
1029
- this.hoverRect.set(null);
1030
- this.distanceOverlay.set(null);
1031
- this.selectedElement = null;
1032
- this.hoverElement = null;
1033
- this.guidePreview.set(null);
1034
- this.clearGuides();
1035
- this.refreshTypographyBlocks();
1036
- return;
1037
- }
1038
- if ((key === 'backspace' || key === 'delete') && this.selectedGuideId()) {
1039
- event.preventDefault();
1040
- const nextGuides = this.guides().filter((guide) => guide.id !== this.selectedGuideId());
1041
- this.guides.set(nextGuides);
1042
- this.selectedGuideId.set(null);
1043
- this.recordHistory(nextGuides);
1052
+ this.clearInspectorCanvas();
1044
1053
  }
1045
1054
  }
1046
- handleKeyup(event) {
1047
- if (event.key === 'Alt') {
1048
- this.altPressed.set(false);
1049
- this.distanceOverlay.set(null);
1050
- }
1055
+ clearInspectorCanvas() {
1056
+ this.selectedMeasurement.set(null);
1057
+ this.selectedGuideId.set(null);
1058
+ this.hoverRect.set(null);
1059
+ this.distanceOverlay.set(null);
1060
+ this.altPressed.set(false);
1061
+ this.selectedElement = null;
1062
+ this.hoverElement = null;
1063
+ this.guidePreview.set(null);
1064
+ this.draggingGuideId = null;
1065
+ this.clearGuides();
1066
+ this.refreshTypographyBlocks();
1067
+ }
1068
+ normalizeCheckpointLabel(value) {
1069
+ return value
1070
+ .trim()
1071
+ .toLocaleLowerCase()
1072
+ .replace(/^\/+|\/+$/g, '');
1051
1073
  }
1052
1074
  handlePointerMove(event) {
1053
1075
  if (!this.enabled() || !this.isBrowser) {
@@ -1160,7 +1182,10 @@ class inspectorComponent {
1160
1182
  }
1161
1183
  handleCommandBarKeydown(event, key) {
1162
1184
  const checkpoints = this.filteredCheckpoints();
1163
- const active = checkpoints[this.activeCheckpointIndex()];
1185
+ const actions = this.filteredInspectorActions();
1186
+ const activeCheckpoint = checkpoints[this.activeCommandIndex()];
1187
+ const activeActionIndex = this.activeCommandIndex() - checkpoints.length;
1188
+ const activeAction = actions[activeActionIndex];
1164
1189
  const target = event.target;
1165
1190
  const isRenameInput = target?.classList?.contains('inspector-command-row__rename') ?? false;
1166
1191
  if (key === 'escape') {
@@ -1185,37 +1210,58 @@ class inspectorComponent {
1185
1210
  return;
1186
1211
  if (key === 'arrowdown') {
1187
1212
  event.preventDefault();
1188
- this.activeCheckpointIndex.set(Math.min(this.activeCheckpointIndex() + 1, Math.max(0, checkpoints.length - 1)));
1189
- this.scrollActiveCheckpointIntoView();
1213
+ if (activeCheckpoint) {
1214
+ const nextIndex = this.activeCommandIndex() < checkpoints.length - 1
1215
+ ? this.activeCommandIndex() + 1
1216
+ : actions.length ? checkpoints.length : this.activeCommandIndex();
1217
+ this.activeCommandIndex.set(nextIndex);
1218
+ }
1219
+ this.scrollActiveCommandIntoView();
1190
1220
  return;
1191
1221
  }
1192
1222
  if (key === 'arrowup') {
1193
1223
  event.preventDefault();
1194
- this.activeCheckpointIndex.set(Math.max(0, this.activeCheckpointIndex() - 1));
1195
- this.scrollActiveCheckpointIntoView();
1224
+ if (activeAction && checkpoints.length) {
1225
+ this.activeCommandIndex.set(checkpoints.length - 1);
1226
+ }
1227
+ else if (activeCheckpoint) {
1228
+ this.activeCommandIndex.set(Math.max(0, this.activeCommandIndex() - 1));
1229
+ }
1230
+ this.scrollActiveCommandIntoView();
1196
1231
  return;
1197
1232
  }
1198
- if (key === 'enter' && active && !this.deletingCheckpointId()) {
1233
+ if (key === 'arrowright' && (activeCheckpoint || activeAction) && actions.length) {
1199
1234
  event.preventDefault();
1200
- void this.restoreCheckpoint(active);
1235
+ const nextActionIndex = activeAction
1236
+ ? Math.min(activeActionIndex + 1, actions.length - 1)
1237
+ : 0;
1238
+ this.activeCommandIndex.set(checkpoints.length + nextActionIndex);
1239
+ this.scrollActiveCommandIntoView();
1201
1240
  return;
1202
1241
  }
1203
- if (key === 'f2' && active) {
1242
+ if (key === 'arrowleft' && activeAction) {
1204
1243
  event.preventDefault();
1205
- this.beginRename(active);
1244
+ this.activeCommandIndex.set(checkpoints.length + Math.max(0, activeActionIndex - 1));
1245
+ this.scrollActiveCommandIntoView();
1206
1246
  return;
1207
1247
  }
1208
- if (key === 'delete' && active) {
1248
+ if (key === 'enter' && activeCheckpoint && !this.deletingCheckpointId()) {
1209
1249
  event.preventDefault();
1210
- this.beginDelete(active);
1250
+ void this.restoreCheckpoint(activeCheckpoint);
1251
+ return;
1252
+ }
1253
+ if (key === 'enter' && activeAction) {
1254
+ event.preventDefault();
1255
+ void this.executeInspectorAction(activeAction);
1256
+ return;
1211
1257
  }
1212
1258
  }
1213
- clampActiveCheckpoint() {
1214
- this.activeCheckpointIndex.set(Math.min(this.activeCheckpointIndex(), Math.max(0, this.filteredCheckpoints().length - 1)));
1259
+ clampActiveCommand() {
1260
+ this.activeCommandIndex.set(Math.min(this.activeCommandIndex(), Math.max(0, this.commandResultCount() - 1)));
1215
1261
  }
1216
- scrollActiveCheckpointIntoView() {
1262
+ scrollActiveCommandIntoView() {
1217
1263
  queueMicrotask(() => {
1218
- const row = this.checkpointDialog()?.nativeElement.querySelector(`[data-checkpoint-index="${this.activeCheckpointIndex()}"]`);
1264
+ const row = this.checkpointDialog()?.nativeElement.querySelector(`[data-command-index="${this.activeCommandIndex()}"]`);
1219
1265
  row?.scrollIntoView({ block: 'nearest' });
1220
1266
  });
1221
1267
  }
@@ -1373,11 +1419,11 @@ class inspectorComponent {
1373
1419
  return null;
1374
1420
  }
1375
1421
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: inspectorComponent, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); }
1376
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: inspectorComponent, isStandalone: true, selector: "inspector-overlay", inputs: { highlightColor: "highlightColor", guideColor: "guideColor", hoverHighlightEnabled: "hoverHighlightEnabled", persistOnReload: "persistOnReload" }, host: { listeners: { "window:keydown": "handleKeydown($event)", "window:keyup": "handleKeyup($event)", "window:pointermove": "handlePointerMove($event)", "window:pointerup": "handlePointerUp()", "window:click": "handleClick($event)", "window:resize": "handleViewportChange()", "window:scroll": "handleViewportChange()" } }, viewQueries: [{ propertyName: "overlayRoot", first: true, predicate: ["overlayRoot"], descendants: true, isSignal: true }, { propertyName: "checkpointDialog", first: true, predicate: ["checkpointDialog"], descendants: true, isSignal: true }, { propertyName: "checkpointSearch", first: true, predicate: ["checkpointSearch"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"inspector-root\" #overlayRoot>\n @if (checkpointService) {\n <dialog\n #checkpointDialog\n class=\"inspector-command-dialog\"\n aria-labelledby=\"inspector-command-title\"\n (cancel)=\"$event.preventDefault(); closeCheckpointCommandBar()\"\n (click)=\"handleCheckpointDialogClick($event)\"\n >\n <section class=\"inspector-command\" (click)=\"$event.stopPropagation()\">\n <header class=\"inspector-command__search\">\n <label id=\"inspector-command-title\" class=\"inspector-visually-hidden\" for=\"inspector-checkpoint-search\">\n Search checkpoints\n </label>\n <svg class=\"inspector-command__search-icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M7 2.25a4.75 4.75 0 1 0 2.94 8.48l2.91 2.92.8-.8-2.92-2.91A4.75 4.75 0 0 0 7 2.25Zm-3.62 4.75a3.62 3.62 0 1 1 7.24 0 3.62 3.62 0 0 1-7.24 0Z\" />\n </svg>\n <input\n #checkpointSearch\n id=\"inspector-checkpoint-search\"\n type=\"search\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n placeholder=\"Search checkpoints\u2026\"\n [value]=\"checkpointQuery()\"\n [attr.aria-controls]=\"'inspector-checkpoint-results'\"\n [attr.aria-activedescendant]=\"filteredCheckpoints().length ? 'inspector-checkpoint-' + filteredCheckpoints()[activeCheckpointIndex()].id : null\"\n (input)=\"updateCheckpointQuery($event)\"\n />\n </header>\n\n @if (checkpointService.error(); as error) {\n <p class=\"inspector-command__message inspector-command__message--error\" role=\"alert\">{{ error }}</p>\n }\n\n <div id=\"inspector-checkpoint-results\" class=\"inspector-command__results\" role=\"listbox\" aria-label=\"Saved checkpoints\">\n @if (checkpointService.loading()) {\n <p class=\"inspector-command__message\" role=\"status\">Loading\u2026</p>\n } @else if (!checkpointService.checkpoints().length) {\n <p class=\"inspector-command__message\" role=\"status\">No checkpoints yet</p>\n } @else if (!filteredCheckpoints().length) {\n <p class=\"inspector-command__message\" role=\"status\">No matches</p>\n } @else {\n @for (checkpoint of filteredCheckpoints(); track checkpoint.id; let index = $index) {\n <div\n class=\"inspector-command-row\"\n role=\"option\"\n [id]=\"'inspector-checkpoint-' + checkpoint.id\"\n [attr.data-checkpoint-index]=\"index\"\n [attr.aria-selected]=\"activeCheckpointIndex() === index\"\n [class.is-active]=\"activeCheckpointIndex() === index\"\n [class.is-busy]=\"checkpointService.busy() && activeCheckpointIndex() === index\"\n (mouseenter)=\"setActiveCheckpoint(index)\"\n (click)=\"deletingCheckpointId() === checkpoint.id || editingCheckpointId() === checkpoint.id ? null : restoreCheckpoint(checkpoint)\"\n >\n @if (deletingCheckpointId() === checkpoint.id) {\n <span class=\"inspector-command-row__confirm\">Delete \u201C{{ checkpoint.name }}\u201D?</span>\n <span class=\"inspector-command-row__confirm-actions\">\n <button type=\"button\" class=\"is-danger\" (click)=\"confirmDelete(checkpoint, $event)\">Delete</button>\n <button type=\"button\" (click)=\"cancelDelete($event)\">Keep</button>\n </span>\n } @else if (editingCheckpointId() === checkpoint.id) {\n <input\n class=\"inspector-command-row__rename\"\n aria-label=\"Checkpoint name\"\n [value]=\"renameDraft()\"\n (input)=\"updateRenameDraft($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n } @else {\n <span class=\"inspector-command-row__content\">\n <span class=\"inspector-command-row__name\">\n @if (checkpointService.busy() && activeCheckpointIndex() === index) {\n Restoring\u2026\n } @else {\n {{ checkpoint.name }}\n }\n </span>\n <span class=\"inspector-command-row__meta\">\n <span class=\"inspector-command-row__route\">{{ checkpoint.route || '/' }}</span>\n <span class=\"inspector-command-row__separator\" aria-hidden=\"true\">\u00B7</span>\n <span class=\"inspector-command-row__activity\">\n {{ checkpoint.lastUsedAt ? 'Used' : 'Saved' }} {{ formatRelativeTime(checkpointActivityAt(checkpoint)) }}\n </span>\n </span>\n </span>\n <span class=\"inspector-command-row__actions\">\n <button type=\"button\" (click)=\"beginRename(checkpoint, $event)\" [attr.aria-label]=\"'Rename ' + checkpoint.name\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"m11.8 1.8 2.4 2.4-8.3 8.3-3.1.7.7-3.1zm-8 10.4 1.5-.3-1.2-1.2z\" /></svg>\n </button>\n <button type=\"button\" (click)=\"beginDelete(checkpoint, $event)\" [attr.aria-label]=\"'Delete ' + checkpoint.name\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M5.5 2h5l.5 1H14v1.25H2V3h3zm-2 3.25h9L12 14H4z\" /></svg>\n </button>\n </span>\n }\n </div>\n }\n }\n </div>\n\n <footer class=\"inspector-command__actions\" aria-label=\"Inspector actions\">\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"toolMode() === 'select'\"\n (click)=\"setToolMode('select'); closeCheckpointCommandBar()\"\n aria-label=\"Select mode\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M3 2l8 8-3 .7L6.7 13 6 10 3 2z\" /></svg>\n <span>Select</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"showTypography()\"\n (click)=\"toggleTypography(); closeCheckpointCommandBar()\"\n aria-label=\"Toggle typography overlay\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M3 4V2h10v2h-4v10H7V4z\" /></svg>\n <span>Type</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n (click)=\"saveCheckpoint()\"\n [disabled]=\"checkpointService.busy()\"\n aria-label=\"Save checkpoint\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M2.5 2h9.6l1.4 1.4V14h-11zm2 1.5v3h6v-3zm.5 6V12h6V9.5z\" /></svg>\n <span>Save</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"toolMode() === 'guides' && guideOrientation() === 'vertical'\"\n (click)=\"activateGuideOrientation('vertical'); closeCheckpointCommandBar()\"\n aria-label=\"Vertical guides\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M7.25 2h1.5v12h-1.5z\" /></svg>\n <span>V</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"toolMode() === 'guides' && guideOrientation() === 'horizontal'\"\n (click)=\"activateGuideOrientation('horizontal'); closeCheckpointCommandBar()\"\n aria-label=\"Horizontal guides\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M2 7.25h12v1.5H2z\" /></svg>\n <span>H</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action inspector-command-action--danger\"\n (click)=\"closeCheckpointCommandBar(); disableInspector()\"\n aria-label=\"Disable inspector; press M to enable\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M7.25 1.5h1.5v6h-1.5zM4.1 3.35l.96 1.15A4.25 4.25 0 1 0 10.94 4.5l.96-1.15A5.75 5.75 0 1 1 4.1 3.35z\" /></svg>\n <span>Off</span>\n </button>\n </footer>\n </section>\n </dialog>\n }\n\n @if (checkpointToast(); as toast) {\n <p\n class=\"inspector-checkpoint-toast\"\n [class.inspector-checkpoint-toast--error]=\"checkpointToastIsError()\"\n [attr.role]=\"checkpointToastIsError() ? 'alert' : 'status'\"\n >{{ toast }}</p>\n }\n\n @if (enabled() && toolMode() === \"select\") {\n @if (hoverRect() && hoverHighlightEnabled) {\n <div\n class=\"inspector-box inspector-box--hover\"\n [style.left.px]=\"hoverRect()!.left\"\n [style.top.px]=\"hoverRect()!.top\"\n [style.width.px]=\"hoverRect()!.width\"\n [style.height.px]=\"hoverRect()!.height\"\n [style.--inspector-accent]=\"highlightColor\"\n ></div>\n }\n\n @if (selectedMeasurement(); as selected) {\n @if (selected.gap.active && selected.parentRect) {\n <div\n class=\"inspector-box inspector-box--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top\"\n [style.width.px]=\"selected.parentRect.width\"\n [style.height.px]=\"selected.parentRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top - 8\"\n >\n G {{ formatGap(selected) }}\n </div>\n }\n\n <div\n class=\"inspector-box inspector-box--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top\"\n [style.width.px]=\"selected.marginRect.width\"\n [style.height.px]=\"selected.marginRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top - 8\"\n >\n M {{ formatEdges(selected.margin) }}\n </div>\n\n <div\n class=\"inspector-box inspector-box--selected\"\n [style.left.px]=\"selected.rect.left\"\n [style.top.px]=\"selected.rect.top\"\n [style.width.px]=\"selected.rect.width\"\n [style.height.px]=\"selected.rect.height\"\n [style.--inspector-accent]=\"highlightColor\"\n >\n <div class=\"inspector-label\">{{ selectedMetaLine() }}</div>\n </div>\n\n <div\n class=\"inspector-box inspector-box--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"selected.paddingRect.top\"\n [style.width.px]=\"selected.paddingRect.width\"\n [style.height.px]=\"selected.paddingRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"\n selected.paddingRect.top + selected.paddingRect.height + 8\n \"\n >\n P {{ formatEdges(selected.padding) }}\n </div>\n }\n }\n\n @if (enabled() && showTypography()) {\n @for (block of textBlocks(); track block.id) {\n <div\n class=\"inspector-text-chip\"\n [style.left.px]=\"block.rect.left\"\n [style.top.px]=\"block.rect.top - 8\"\n >\n <span\n class=\"inspector-text-chip__swatch\"\n [style.background]=\"block.styles.color\"\n ></span>\n <span>{{ block.styles.fontSize }}</span>\n <span>{{ block.styles.lineHeight }}</span>\n <span>{{ block.styles.color }}</span>\n </div>\n }\n }\n\n @if (enabled() && altPressed() && distanceOverlay(); as distance) {\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectA.left\"\n [style.top.px]=\"distance.rectA.top\"\n [style.width.px]=\"distance.rectA.width\"\n [style.height.px]=\"distance.rectA.height\"\n ></div>\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectB.left\"\n [style.top.px]=\"distance.rectB.top\"\n [style.width.px]=\"distance.rectB.width\"\n [style.height.px]=\"distance.rectB.height\"\n ></div>\n\n @for (\n connector of distance.connectors;\n track trackConnector($index, connector)\n ) {\n <div\n class=\"inspector-connector\"\n [class.inspector-connector--vertical]=\"connector.x1 === connector.x2\"\n [class.inspector-connector--horizontal]=\"connector.y1 === connector.y2\"\n [style.left.px]=\"Math.min(connector.x1, connector.x2)\"\n [style.top.px]=\"Math.min(connector.y1, connector.y2)\"\n [style.width.px]=\"Math.max(1, Math.abs(connector.x2 - connector.x1))\"\n [style.height.px]=\"Math.max(1, Math.abs(connector.y2 - connector.y1))\"\n ></div>\n }\n\n @if (distance.horizontal && distance.horizontal.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--horizontal\"\n [style.left.px]=\"\n Math.min(distance.horizontal.x1!, distance.horizontal.x2!)\n \"\n [style.top.px]=\"distance.horizontal.y!\"\n [style.width.px]=\"\n Math.abs(distance.horizontal.x2! - distance.horizontal.x1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag\"\n [style.left.px]=\"\n (distance.horizontal.x1! + distance.horizontal.x2!) / 2\n \"\n [style.top.px]=\"distance.horizontal.y! + 10\"\n >\n {{ formatValue(distance.horizontal.value) }}\n </div>\n }\n\n @if (distance.vertical && distance.vertical.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--vertical\"\n [style.left.px]=\"distance.vertical.x!\"\n [style.top.px]=\"Math.min(distance.vertical.y1!, distance.vertical.y2!)\"\n [style.height.px]=\"\n Math.abs(distance.vertical.y2! - distance.vertical.y1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag inspector-distance-tag--vertical\"\n [style.left.px]=\"distance.vertical.x! + 10\"\n [style.top.px]=\"(distance.vertical.y1! + distance.vertical.y2!) / 2\"\n >\n {{ formatValue(distance.vertical.value) }}\n </div>\n }\n }\n\n @if (enabled()) {\n @if (toolMode() === \"guides\") {\n @if (guidePreview(); as preview) {\n <div\n class=\"inspector-guide inspector-guide--preview\"\n [class.inspector-guide--vertical]=\"preview.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"\n preview.orientation === 'horizontal'\n \"\n [style.left.px]=\"\n preview.orientation === 'vertical' ? preview.position : null\n \"\n [style.top.px]=\"\n preview.orientation === 'horizontal' ? preview.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n >\n <span class=\"inspector-guide-line\"></span>\n </div>\n }\n }\n\n @for (guide of guides(); track guide.id) {\n <button\n type=\"button\"\n class=\"inspector-guide\"\n [class.inspector-guide--vertical]=\"guide.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"guide.orientation === 'horizontal'\"\n [class.inspector-guide--selected]=\"selectedGuideId() === guide.id\"\n [style.left.px]=\"\n guide.orientation === 'vertical' ? guide.position : null\n \"\n [style.top.px]=\"\n guide.orientation === 'horizontal' ? guide.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n (pointerdown)=\"startGuideDrag($event, guide)\"\n >\n <span class=\"inspector-guide-line\"></span>\n </button>\n }\n }\n</div>\n", styles: [":host{--inspector-panel: oklch(20% .012 280 / .92);--inspector-panel-edge: oklch(100% 0 0 / .08);--inspector-text: oklch(96% .005 280);--inspector-muted: oklch(70% .014 280);--inspector-faint: oklch(56% .012 280);--inspector-blue: oklch(68% .15 255);--inspector-blue-soft: oklch(68% .15 255 / .14);--inspector-orange: oklch(78% .14 70);--inspector-green: oklch(74% .15 150);--inspector-violet: oklch(72% .15 305);--inspector-radius: 8px;--inspector-shadow: 0 12px 32px oklch(6% .02 280 / .5);--inspector-font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--inspector-ease: cubic-bezier(.16, 1, .3, 1);position:fixed;inset:0;z-index:2147;pointer-events:none;font-family:var(--inspector-font);color:var(--inspector-text);-webkit-font-smoothing:antialiased}.inspector-root{position:fixed;inset:0;pointer-events:none}.inspector-command-dialog{--command-surface: oklch(17.5% .012 280);--command-surface-active: oklch(26% .02 265);--command-edge: oklch(100% 0 0 / .08);--command-text: oklch(96% .005 280);--command-muted: oklch(68% .014 280);--command-faint: oklch(52% .012 280);--command-accent: oklch(72% .13 255);--command-danger: oklch(68% .17 25);box-sizing:border-box;inset-block-start:max(10vh,48px);width:min(420px,calc(100vw - 24px));max-width:none;max-height:min(360px,calc(100vh - 64px));margin:0 auto;padding:0;overflow:hidden;border:1px solid var(--command-edge);border-radius:var(--inspector-radius);background:var(--command-surface);color:var(--command-text);box-shadow:var(--inspector-shadow);opacity:0;pointer-events:auto;transform:translateY(-4px);transition:opacity .1s ease,transform .1s ease,overlay .1s allow-discrete,display .1s allow-discrete;font-family:var(--inspector-font);-webkit-font-smoothing:antialiased}.inspector-command-dialog[open]{opacity:1;transform:none;transition-duration:.14s;transition-timing-function:var(--inspector-ease)}@starting-style{.inspector-command-dialog[open]{opacity:0;transform:translateY(-4px)}}.inspector-command-dialog::backdrop{background:#01010266}.inspector-command{display:grid;grid-template-rows:auto auto 1fr auto;min-width:0;min-height:0;max-height:min(360px,calc(100vh - 64px))}.inspector-command__search{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 11px;border-bottom:1px solid var(--command-edge)}.inspector-command__search-icon{width:14px;height:14px;flex:0 0 auto;fill:var(--command-faint)}.inspector-command__search input,.inspector-command-row__rename{min-width:0;border:0;outline:0;background:transparent;color:var(--command-text);font:inherit}.inspector-command__search input{flex:1 1 auto;width:100%;height:39px;padding:0;font-size:13px;font-weight:450;line-height:1.3}.inspector-command__search input::placeholder{color:var(--command-faint);opacity:1}.inspector-command__search input::-webkit-search-cancel-button{display:none}.inspector-command__results{min-height:0;max-height:260px;overflow:auto;padding:5px;scrollbar-width:thin;scrollbar-color:oklch(100% 0 0 / .1) transparent}.inspector-command-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:6px;min-height:34px;padding:0 7px 0 9px;border-radius:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.inspector-command-row.is-active{background:var(--command-surface-active)}.inspector-command-row.is-busy{cursor:wait;pointer-events:none;opacity:.7}.inspector-command-row__content{display:flex;align-items:baseline;gap:8px;min-width:0;overflow:hidden}.inspector-command-row__name{flex:0 1 auto;min-width:3ch;overflow:hidden;color:var(--command-text);font-size:12px;font-weight:500;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__meta{display:inline-flex;flex:0 1 auto;align-items:baseline;gap:4px;min-width:0;overflow:hidden;color:var(--command-faint);font-size:11px;font-weight:400;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__route{min-width:0;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__separator,.inspector-command-row__activity{flex:0 0 auto}.inspector-command-row.is-active .inspector-command-row__activity{color:var(--command-muted)}.inspector-command-row__actions,.inspector-command-row__confirm-actions{display:flex;align-items:center;gap:1px}.inspector-command-row__actions{opacity:0;pointer-events:none}.inspector-command-row:hover .inspector-command-row__actions,.inspector-command-row:focus-within .inspector-command-row__actions{opacity:1;pointer-events:auto}.inspector-command-row button{display:inline-grid;width:22px;min-height:22px;padding:0;place-items:center;border:0;border-radius:4px;background:transparent;color:var(--command-muted);cursor:pointer;font-family:inherit;font-size:10px;font-weight:550;line-height:1.2}.inspector-command-row button svg{width:11px;height:11px;fill:currentColor}.inspector-command-row button:hover{background:#ffffff12;color:var(--command-text)}.inspector-command-row button.is-danger{width:auto;padding:0 7px;color:var(--command-danger);font-size:11px}.inspector-command-row button.is-danger:hover{background:#ef66611f}.inspector-command-row__confirm-actions button:not(.is-danger){width:auto;padding:0 7px;font-size:11px}.inspector-command-row button:focus-visible,.inspector-command-row__rename:focus-visible{outline:1px solid var(--command-accent);outline-offset:1px}.inspector-command-row__confirm{grid-column:1;color:var(--command-text);font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__rename{grid-column:1 / -1;min-height:26px;padding-inline:6px;border:1px solid oklch(72% .13 255 / .4);border-radius:4px;background:#191a21;font-size:12px;font-weight:500}.inspector-command__message{margin:0;padding:16px 10px;color:var(--command-faint);font-size:12px;line-height:1.4;text-align:center}.inspector-command__message--error{padding:6px 10px;border-bottom:1px solid oklch(55% .08 25 / .3);background:#39191780;color:#f7cbc7;text-align:left;font-size:11px}.inspector-command__actions{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:2px;padding:4px;border-top:1px solid var(--command-edge)}.inspector-command-action{display:flex;min-width:0;min-height:28px;align-items:center;justify-content:center;gap:4px;padding:0 4px;overflow:hidden;border:0;border-radius:5px;background:transparent;color:var(--command-muted);cursor:pointer;font:inherit;font-size:10px;font-weight:500;line-height:1;text-align:left}.inspector-command-action svg{width:11px;height:11px;flex:0 0 auto;fill:currentColor}.inspector-command-action span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inspector-command-action:hover:not(:disabled){background:#ffffff0f;color:var(--command-text)}.inspector-command-action.is-active{background:#6aa7f421;color:#c2daf9}.inspector-command-action--danger:hover:not(:disabled){background:#ef66611a;color:#f5b9b4}.inspector-command-action:disabled{cursor:wait;opacity:.45}.inspector-command-action:focus-visible{outline:1px solid var(--command-accent);outline-offset:-1px}.inspector-visually-hidden{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.inspector-checkpoint-toast{position:fixed;top:10px;left:50%;z-index:500;margin:0;padding:5px 10px;border:1px solid oklch(74% .12 150 / .25);border-radius:999px;background:#0e1f12f0;color:#cce6d0;box-shadow:var(--inspector-shadow);font-size:11px;font-weight:520;line-height:1.25;pointer-events:none;transform:translate(-50%)}.inspector-checkpoint-toast--error{border-color:#e2726b4d;background:#351311f0;color:#fed2cd}@media (prefers-reduced-motion: reduce){.inspector-command-dialog{transition-duration:.01ms!important}.inspector-command-dialog,.inspector-command-dialog[open]{transform:none}}.inspector-box{position:fixed;box-sizing:border-box;pointer-events:none;border:1px solid var(--inspector-accent, var(--inspector-blue));background:color-mix(in srgb,var(--inspector-accent, var(--inspector-blue)) 8%,transparent)}.inspector-box--hover{opacity:.55}.inspector-box--selected{border-width:1.5px}.inspector-box--margin{border-color:#f0a646d1;background:#f0a64614}.inspector-box--padding{border-color:#5ac576d1;background:#5ac57614}.inspector-box--gap{border-color:#bb8aefb8;background:#bb8aef0d}.inspector-box--distance{border-style:dashed;border-color:#539af2b3;background:transparent}.inspector-label,.inspector-box-tag,.inspector-text-chip,.inspector-distance-tag{font-variant-numeric:tabular-nums}.inspector-label{position:absolute;left:0;top:0;transform:translateY(calc(-100% - 6px));max-width:min(380px,calc(100vw - 20px));padding:4px 7px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:var(--inspector-panel);color:var(--inspector-text);box-shadow:var(--inspector-shadow);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);font-size:10px;font-weight:500;line-height:1.2;white-space:nowrap}.inspector-box-tag{position:fixed;transform:translateY(-100%);padding:3px 5px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-box-tag--margin{color:#f5c076}.inspector-box-tag--padding{color:#95dfa4;transform:translateY(0)}.inspector-box-tag--gap{color:oklch(86% .09 305)}.inspector-text-chip{position:fixed;transform:translateY(-100%);display:inline-flex;gap:5px;align-items:center;padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:#e4e4e9;font-size:9px;font-weight:500;line-height:1;white-space:nowrap;pointer-events:none}.inspector-text-chip__swatch{width:7px;height:7px;border-radius:999px;border:1px solid oklch(100% 0 0 / .16);flex:0 0 auto}.inspector-connector{position:fixed;border-color:#539af2b8;border-style:dashed;pointer-events:none}.inspector-connector--vertical{border-left-width:1px;width:0}.inspector-connector--horizontal{border-top-width:1px;height:0}.inspector-distance-line{position:fixed;background:var(--inspector-blue);pointer-events:none}.inspector-distance-line--horizontal{height:1px}.inspector-distance-line--vertical{width:1px}.inspector-distance-tag{position:fixed;transform:translate(-50%);padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f2;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-distance-tag--vertical{transform:translateY(-50%)}.inspector-guide{position:fixed;margin:0;padding:0;border:0;background:transparent;pointer-events:auto;cursor:grab}.inspector-guide--vertical{top:0;width:14px;height:100vh;transform:translate(-50%)}.inspector-guide--horizontal{left:0;width:100vw;height:14px;transform:translateY(-50%)}.inspector-guide--preview{opacity:.55;pointer-events:none;cursor:default}.inspector-guide--preview .inspector-guide-line{background:color-mix(in srgb,var(--inspector-guide, #ff7a00) 72%,transparent)}.inspector-guide-line{position:absolute;inset:0;pointer-events:none}.inspector-guide--vertical .inspector-guide-line{left:calc(50% - .5px);width:1px;height:100%;background:var(--inspector-guide, #ff7a00)}.inspector-guide--horizontal .inspector-guide-line{top:calc(50% - .5px);width:100%;height:1px;background:var(--inspector-guide, #ff7a00)}.inspector-guide--selected .inspector-guide-line{box-shadow:0 0 0 1px #ffffff80}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1422
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: inspectorComponent, isStandalone: true, selector: "inspector-overlay", inputs: { highlightColor: "highlightColor", guideColor: "guideColor", hoverHighlightEnabled: "hoverHighlightEnabled", persistOnReload: "persistOnReload" }, host: { listeners: { "window:keydown": "handleKeydown($event)", "window:pointermove": "handlePointerMove($event)", "window:pointerup": "handlePointerUp()", "window:click": "handleClick($event)", "window:resize": "handleViewportChange()", "window:scroll": "handleViewportChange()" } }, viewQueries: [{ propertyName: "overlayRoot", first: true, predicate: ["overlayRoot"], descendants: true, isSignal: true }, { propertyName: "checkpointDialog", first: true, predicate: ["checkpointDialog"], descendants: true, isSignal: true }, { propertyName: "checkpointSearch", first: true, predicate: ["checkpointSearch"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"inspector-root\" #overlayRoot>\n @if (checkpointService) {\n <dialog\n #checkpointDialog\n class=\"inspector-command-dialog\"\n aria-labelledby=\"inspector-command-title\"\n (cancel)=\"$event.preventDefault(); closeCheckpointCommandBar()\"\n (click)=\"handleCheckpointDialogClick($event)\"\n >\n <section class=\"inspector-command\" (click)=\"$event.stopPropagation()\">\n <header class=\"inspector-command__search\">\n <label\n id=\"inspector-command-title\"\n class=\"inspector-visually-hidden\"\n for=\"inspector-checkpoint-search\"\n >\n inspector-ng command palette\n </label>\n <svg\n class=\"inspector-command__search-icon inspector-command__search-icon--cat\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <g class=\"inspector-command__cat-face\">\n <path\n d=\"M3.2 6.1 2.7 2.6l3 1.5A5.7 5.7 0 0 1 8 3.6c.8 0 1.6.2 2.3.5l3-1.5-.5 3.5c.5.8.7 1.7.7 2.7 0 2.8-2.4 4.5-5.5 4.5s-5.5-1.7-5.5-4.5c0-1 .2-1.9.7-2.7Z\"\n />\n <g class=\"inspector-command__cat-eyes\">\n <circle cx=\"5.7\" cy=\"8.3\" r=\".65\" />\n <circle cx=\"10.3\" cy=\"8.3\" r=\".65\" />\n </g>\n <path d=\"m6.8 10.3 1.2.7 1.2-.7M8 11v.7\" />\n </g>\n </svg>\n <input\n #checkpointSearch\n id=\"inspector-checkpoint-search\"\n type=\"search\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n placeholder=\"inspector-ng\u2026\"\n [value]=\"checkpointQuery()\"\n [attr.aria-controls]=\"'inspector-checkpoint-results inspector-command-actions'\"\n [attr.aria-activedescendant]=\"activeCommandResultId()\"\n (input)=\"updateCheckpointQuery($event)\"\n />\n </header>\n\n @if (checkpointService.error(); as error) {\n <p\n class=\"inspector-command__message inspector-command__message--error\"\n role=\"alert\"\n >\n {{ error }}\n </p>\n }\n\n <div\n id=\"inspector-checkpoint-results\"\n class=\"inspector-command__results\"\n role=\"listbox\"\n aria-label=\"Saved checkpoints\"\n >\n @if (checkpointService.loading()) {\n <p class=\"inspector-command__message\" role=\"status\">Loading\u2026</p>\n } @else if (\n !checkpointService.checkpoints().length && !checkpointQuery().trim()\n ) {\n <p class=\"inspector-command__message\" role=\"status\">\n No checkpoints yet\n </p>\n } @else if (\n !filteredCheckpoints().length && !filteredInspectorActions().length\n ) {\n <p class=\"inspector-command__message\" role=\"status\">No matches</p>\n } @else {\n @for (\n checkpoint of filteredCheckpoints();\n track checkpoint.id;\n let index = $index\n ) {\n <div\n class=\"inspector-command-row\"\n role=\"option\"\n [id]=\"'inspector-checkpoint-' + checkpoint.id\"\n [attr.data-command-index]=\"index\"\n [attr.aria-selected]=\"activeCommandIndex() === index\"\n [class.is-active]=\"activeCommandIndex() === index\"\n [class.is-busy]=\"\n checkpointService.busy() && activeCommandIndex() === index\n \"\n (mouseenter)=\"setActiveCheckpoint(index)\"\n (click)=\"\n deletingCheckpointId() === checkpoint.id ||\n editingCheckpointId() === checkpoint.id\n ? null\n : restoreCheckpoint(checkpoint)\n \"\n >\n @if (deletingCheckpointId() === checkpoint.id) {\n <span class=\"inspector-command-row__confirm\"\n >Delete \u201C{{ checkpoint.name }}\u201D?</span\n >\n <span class=\"inspector-command-row__confirm-actions\">\n <button\n type=\"button\"\n class=\"is-danger\"\n (click)=\"confirmDelete(checkpoint, $event)\"\n >\n Delete\n </button>\n <button type=\"button\" (click)=\"cancelDelete($event)\">\n Keep\n </button>\n </span>\n } @else if (editingCheckpointId() === checkpoint.id) {\n <input\n class=\"inspector-command-row__rename\"\n aria-label=\"Checkpoint name\"\n [value]=\"renameDraft()\"\n (input)=\"updateRenameDraft($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n } @else {\n <span class=\"inspector-command-row__content\">\n <span class=\"inspector-command-row__name\">\n @if (\n checkpointService.busy() &&\n activeCommandIndex() === index\n ) {\n Restoring\u2026\n } @else {\n {{ checkpoint.name }}\n }\n </span>\n <span class=\"inspector-command-row__meta\">\n @if (shouldShowCheckpointRoute(checkpoint)) {\n <span class=\"inspector-command-row__route\">{{\n checkpoint.route\n }}</span>\n <span\n class=\"inspector-command-row__separator\"\n aria-hidden=\"true\"\n >\u00B7</span\n >\n }\n <span class=\"inspector-command-row__activity\">\n {{ checkpoint.lastUsedAt ? \"Used\" : \"Saved\" }}\n {{\n formatRelativeTime(checkpointActivityAt(checkpoint))\n }}\n </span>\n </span>\n </span>\n <span class=\"inspector-command-row__actions\">\n <button\n type=\"button\"\n (click)=\"beginRename(checkpoint, $event)\"\n [attr.aria-label]=\"'Rename ' + checkpoint.name\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"m11.8 1.8 2.4 2.4-8.3 8.3-3.1.7.7-3.1zm-8 10.4 1.5-.3-1.2-1.2z\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n (click)=\"beginDelete(checkpoint, $event)\"\n [attr.aria-label]=\"'Delete ' + checkpoint.name\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M5.5 2h5l.5 1H14v1.25H2V3h3zm-2 3.25h9L12 14H4z\"\n />\n </svg>\n </button>\n </span>\n }\n </div>\n }\n }\n </div>\n\n @if (filteredInspectorActions().length) {\n <footer\n id=\"inspector-command-actions\"\n class=\"inspector-command__actions\"\n role=\"listbox\"\n aria-label=\"Inspector actions\"\n aria-orientation=\"horizontal\"\n >\n @for (\n action of filteredInspectorActions();\n track action.id;\n let index = $index\n ) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"inspector-command-action\"\n [id]=\"'inspector-action-' + action.id\"\n [attr.data-command-index]=\"filteredCheckpoints().length + index\"\n [attr.aria-label]=\"action.ariaLabel\"\n [attr.aria-selected]=\"\n activeCommandIndex() === filteredCheckpoints().length + index\n \"\n [attr.aria-disabled]=\"checkpointService.busy()\"\n [class.is-selected]=\"\n activeCommandIndex() === filteredCheckpoints().length + index\n \"\n [class.is-active]=\"\n (action.id === 'select' && toolMode() === 'select') ||\n (action.id === 'type' && showTypography()) ||\n (action.id === 'vertical' &&\n toolMode() === 'guides' &&\n guideOrientation() === 'vertical') ||\n (action.id === 'horizontal' &&\n toolMode() === 'guides' &&\n guideOrientation() === 'horizontal')\n \"\n [class.inspector-command-action--danger]=\"action.id === 'off'\"\n [disabled]=\"checkpointService.busy()\"\n (mouseenter)=\"setActiveInspectorAction(index)\"\n (click)=\"executeInspectorAction(action)\"\n >\n @switch (action.id) {\n @case (\"select\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M3 2l8 8-3 .7L6.7 13 6 10 3 2z\" />\n </svg>\n }\n @case (\"type\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M3 4V2h10v2h-4v10H7V4z\" />\n </svg>\n }\n @case (\"save\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M2.5 2h9.6l1.4 1.4V14h-11zm2 1.5v3h6v-3zm.5 6V12h6V9.5z\"\n />\n </svg>\n }\n @case (\"vertical\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M7.25 2h1.5v12h-1.5z\" />\n </svg>\n }\n @case (\"horizontal\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M2 7.25h12v1.5H2z\" />\n </svg>\n }\n @case (\"off\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M7.25 1.5h1.5v6h-1.5zM4.1 3.35l.96 1.15A4.25 4.25 0 1 0 10.94 4.5l.96-1.15A5.75 5.75 0 1 1 4.1 3.35z\"\n />\n </svg>\n }\n }\n <span>{{ action.label }}</span>\n </button>\n }\n </footer>\n }\n </section>\n </dialog>\n }\n\n @if (checkpointToast(); as toast) {\n <p\n class=\"inspector-checkpoint-toast\"\n [class.inspector-checkpoint-toast--error]=\"checkpointToastIsError()\"\n [attr.role]=\"checkpointToastIsError() ? 'alert' : 'status'\"\n >\n {{ toast }}\n </p>\n }\n\n @if (enabled() && toolMode() === \"select\") {\n @if (hoverRect() && hoverHighlightEnabled) {\n <div\n class=\"inspector-box inspector-box--hover\"\n [style.left.px]=\"hoverRect()!.left\"\n [style.top.px]=\"hoverRect()!.top\"\n [style.width.px]=\"hoverRect()!.width\"\n [style.height.px]=\"hoverRect()!.height\"\n [style.--inspector-accent]=\"highlightColor\"\n ></div>\n }\n\n @if (selectedMeasurement(); as selected) {\n @if (selected.gap.active && selected.parentRect) {\n <div\n class=\"inspector-box inspector-box--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top\"\n [style.width.px]=\"selected.parentRect.width\"\n [style.height.px]=\"selected.parentRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top - 8\"\n >\n G {{ formatGap(selected) }}\n </div>\n }\n\n <div\n class=\"inspector-box inspector-box--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top\"\n [style.width.px]=\"selected.marginRect.width\"\n [style.height.px]=\"selected.marginRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top - 8\"\n >\n M {{ formatEdges(selected.margin) }}\n </div>\n\n <div\n class=\"inspector-box inspector-box--selected\"\n [style.left.px]=\"selected.rect.left\"\n [style.top.px]=\"selected.rect.top\"\n [style.width.px]=\"selected.rect.width\"\n [style.height.px]=\"selected.rect.height\"\n [style.--inspector-accent]=\"highlightColor\"\n >\n <div class=\"inspector-label\">{{ selectedMetaLine() }}</div>\n </div>\n\n <div\n class=\"inspector-box inspector-box--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"selected.paddingRect.top\"\n [style.width.px]=\"selected.paddingRect.width\"\n [style.height.px]=\"selected.paddingRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"\n selected.paddingRect.top + selected.paddingRect.height + 8\n \"\n >\n P {{ formatEdges(selected.padding) }}\n </div>\n }\n }\n\n @if (enabled() && showTypography()) {\n @for (block of textBlocks(); track block.id) {\n <div\n class=\"inspector-text-chip\"\n [style.left.px]=\"block.rect.left\"\n [style.top.px]=\"block.rect.top - 8\"\n >\n <span\n class=\"inspector-text-chip__swatch\"\n [style.background]=\"block.styles.color\"\n ></span>\n <span>{{ block.styles.fontSize }}</span>\n <span>{{ block.styles.lineHeight }}</span>\n <span>{{ block.styles.color }}</span>\n </div>\n }\n }\n\n @if (enabled() && altPressed() && distanceOverlay(); as distance) {\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectA.left\"\n [style.top.px]=\"distance.rectA.top\"\n [style.width.px]=\"distance.rectA.width\"\n [style.height.px]=\"distance.rectA.height\"\n ></div>\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectB.left\"\n [style.top.px]=\"distance.rectB.top\"\n [style.width.px]=\"distance.rectB.width\"\n [style.height.px]=\"distance.rectB.height\"\n ></div>\n\n @for (\n connector of distance.connectors;\n track trackConnector($index, connector)\n ) {\n <div\n class=\"inspector-connector\"\n [class.inspector-connector--vertical]=\"connector.x1 === connector.x2\"\n [class.inspector-connector--horizontal]=\"connector.y1 === connector.y2\"\n [style.left.px]=\"Math.min(connector.x1, connector.x2)\"\n [style.top.px]=\"Math.min(connector.y1, connector.y2)\"\n [style.width.px]=\"Math.max(1, Math.abs(connector.x2 - connector.x1))\"\n [style.height.px]=\"Math.max(1, Math.abs(connector.y2 - connector.y1))\"\n ></div>\n }\n\n @if (distance.horizontal && distance.horizontal.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--horizontal\"\n [style.left.px]=\"\n Math.min(distance.horizontal.x1!, distance.horizontal.x2!)\n \"\n [style.top.px]=\"distance.horizontal.y!\"\n [style.width.px]=\"\n Math.abs(distance.horizontal.x2! - distance.horizontal.x1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag\"\n [style.left.px]=\"\n (distance.horizontal.x1! + distance.horizontal.x2!) / 2\n \"\n [style.top.px]=\"distance.horizontal.y! + 10\"\n >\n {{ formatValue(distance.horizontal.value) }}\n </div>\n }\n\n @if (distance.vertical && distance.vertical.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--vertical\"\n [style.left.px]=\"distance.vertical.x!\"\n [style.top.px]=\"Math.min(distance.vertical.y1!, distance.vertical.y2!)\"\n [style.height.px]=\"\n Math.abs(distance.vertical.y2! - distance.vertical.y1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag inspector-distance-tag--vertical\"\n [style.left.px]=\"distance.vertical.x! + 10\"\n [style.top.px]=\"(distance.vertical.y1! + distance.vertical.y2!) / 2\"\n >\n {{ formatValue(distance.vertical.value) }}\n </div>\n }\n }\n\n @if (enabled()) {\n @if (toolMode() === \"guides\") {\n @if (guidePreview(); as preview) {\n <div\n class=\"inspector-guide inspector-guide--preview\"\n [class.inspector-guide--vertical]=\"preview.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"\n preview.orientation === 'horizontal'\n \"\n [style.left.px]=\"\n preview.orientation === 'vertical' ? preview.position : null\n \"\n [style.top.px]=\"\n preview.orientation === 'horizontal' ? preview.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n >\n <span class=\"inspector-guide-line\"></span>\n </div>\n }\n }\n\n @for (guide of guides(); track guide.id) {\n <button\n type=\"button\"\n class=\"inspector-guide\"\n [class.inspector-guide--vertical]=\"guide.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"guide.orientation === 'horizontal'\"\n [class.inspector-guide--selected]=\"selectedGuideId() === guide.id\"\n [style.left.px]=\"\n guide.orientation === 'vertical' ? guide.position : null\n \"\n [style.top.px]=\"\n guide.orientation === 'horizontal' ? guide.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n (pointerdown)=\"startGuideDrag($event, guide)\"\n >\n <span class=\"inspector-guide-line\"></span>\n </button>\n }\n }\n</div>\n", styles: [":host{--inspector-panel: oklch(20% .012 280 / .92);--inspector-panel-edge: oklch(100% 0 0 / .08);--inspector-text: oklch(96% .005 280);--inspector-muted: oklch(70% .014 280);--inspector-faint: oklch(56% .012 280);--inspector-blue: oklch(68% .15 255);--inspector-blue-soft: oklch(68% .15 255 / .14);--inspector-orange: oklch(78% .14 70);--inspector-green: oklch(74% .15 150);--inspector-violet: oklch(72% .15 305);--inspector-radius: 8px;--inspector-shadow: 0 12px 32px oklch(6% .02 280 / .5);--inspector-font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--inspector-ease: cubic-bezier(.16, 1, .3, 1);position:fixed;inset:0;z-index:2147;pointer-events:none;font-family:var(--inspector-font);color:var(--inspector-text);-webkit-font-smoothing:antialiased}.inspector-root{position:fixed;inset:0;pointer-events:none}.inspector-command-dialog{--command-surface: oklch(17.5% .012 280);--command-surface-active: oklch(26% .02 265);--command-edge: oklch(100% 0 0 / .08);--command-text: oklch(96% .005 280);--command-muted: oklch(68% .014 280);--command-faint: oklch(52% .012 280);--command-accent: oklch(72% .13 255);--command-danger: oklch(68% .17 25);box-sizing:border-box;inset-block-start:max(10vh,48px);width:min(420px,calc(100vw - 24px));max-width:none;max-height:min(360px,calc(100vh - 64px));margin:0 auto;padding:0;overflow:hidden;border:1px solid var(--command-edge);border-radius:var(--inspector-radius);background:var(--command-surface);color:var(--command-text);box-shadow:var(--inspector-shadow);opacity:0;pointer-events:auto;transform:translateY(-4px);transition:opacity .1s ease,transform .1s ease,overlay .1s allow-discrete,display .1s allow-discrete;font-family:var(--inspector-font);-webkit-font-smoothing:antialiased}.inspector-command-dialog[open]{opacity:1;transform:none;transition-duration:.14s;transition-timing-function:var(--inspector-ease)}@starting-style{.inspector-command-dialog[open]{opacity:0;transform:translateY(-4px)}}.inspector-command-dialog::backdrop{background:#01010266}.inspector-command{display:grid;grid-template-rows:auto auto 1fr auto;min-width:0;min-height:0;max-height:min(360px,calc(100vh - 64px))}.inspector-command__search{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 11px;border-bottom:1px solid var(--command-edge)}.inspector-command__search-icon{width:15px;height:15px;flex:0 0 auto;overflow:visible;fill:none;stroke:var(--command-faint);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}.inspector-command__search-icon circle{fill:var(--command-faint);stroke:none}.inspector-command__search-icon--cat{transition:stroke .14s var(--inspector-ease)}.inspector-command__cat-face{transform-box:fill-box;transform-origin:center;animation:inspector-cat-listen 5.4s var(--inspector-ease) infinite}.inspector-command__cat-eyes{transform-box:fill-box;transform-origin:center;animation:inspector-cat-blink 4.2s ease-out infinite}.inspector-command__search:focus-within .inspector-command__search-icon--cat{stroke:var(--command-accent);animation:inspector-cat-arrive .42s var(--inspector-ease) both}.inspector-command__search:focus-within .inspector-command__search-icon circle{fill:var(--command-accent)}@keyframes inspector-cat-arrive{0%{transform:translateY(1px) rotate(-7deg)}65%{transform:translateY(0) rotate(3deg)}to{transform:none}}@keyframes inspector-cat-listen{0%,88%,to{transform:rotate(0)}92%{transform:rotate(-5deg)}96%{transform:rotate(3deg)}}@keyframes inspector-cat-blink{0%,90%,94%,to{transform:scaleY(1)}92%{transform:scaleY(.08)}}.inspector-command__search input,.inspector-command-row__rename{min-width:0;border:0;outline:0;background:transparent;color:var(--command-text);font:inherit}.inspector-command__search input{flex:1 1 auto;width:100%;height:39px;padding:0;font-size:13px;font-weight:450;line-height:1.3}.inspector-command__search input::placeholder{color:var(--command-faint);opacity:1}.inspector-command__search input::-webkit-search-cancel-button{display:none}.inspector-command__results{min-height:0;max-height:260px;overflow:auto;padding:5px;scrollbar-width:thin;scrollbar-color:oklch(100% 0 0 / .1) transparent}.inspector-command-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:6px;min-height:34px;padding:0 7px 0 9px;border-radius:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.inspector-command-row.is-active{background:var(--command-surface-active)}.inspector-command-row.is-busy{cursor:wait;pointer-events:none;opacity:.7}.inspector-command-row__content{display:flex;align-items:baseline;gap:8px;min-width:0;overflow:hidden}.inspector-command-row__name{flex:0 1 auto;min-width:3ch;overflow:hidden;color:var(--command-text);font-size:12px;font-weight:500;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__meta{display:inline-flex;flex:0 1 auto;align-items:baseline;gap:4px;min-width:0;overflow:hidden;color:var(--command-faint);font-size:11px;font-weight:400;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__route{min-width:0;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__separator,.inspector-command-row__activity{flex:0 0 auto}.inspector-command-row.is-active .inspector-command-row__activity{color:var(--command-muted)}.inspector-command-row__actions,.inspector-command-row__confirm-actions{display:flex;align-items:center;gap:1px}.inspector-command-row__actions{opacity:0;pointer-events:none}.inspector-command-row:hover .inspector-command-row__actions,.inspector-command-row:focus-within .inspector-command-row__actions{opacity:1;pointer-events:auto}.inspector-command-row button{display:inline-grid;width:22px;min-height:22px;padding:0;place-items:center;border:0;border-radius:4px;background:transparent;color:var(--command-muted);cursor:pointer;font-family:inherit;font-size:10px;font-weight:550;line-height:1.2}.inspector-command-row button svg{width:11px;height:11px;fill:currentColor}.inspector-command-row button:hover{background:#ffffff12;color:var(--command-text)}.inspector-command-row button.is-danger{width:auto;padding:0 7px;color:var(--command-danger);font-size:11px}.inspector-command-row button.is-danger:hover{background:#ef66611f}.inspector-command-row__confirm-actions button:not(.is-danger){width:auto;padding:0 7px;font-size:11px}.inspector-command-row button:focus-visible,.inspector-command-row__rename:focus-visible{outline:1px solid var(--command-accent);outline-offset:1px}.inspector-command-row__confirm{grid-column:1;color:var(--command-text);font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__rename{grid-column:1 / -1;min-height:26px;padding-inline:6px;border:1px solid oklch(72% .13 255 / .4);border-radius:4px;background:#191a21;font-size:12px;font-weight:500}.inspector-command__message{margin:0;padding:16px 10px;color:var(--command-faint);font-size:12px;line-height:1.4;text-align:center}.inspector-command__message--error{padding:6px 10px;border-bottom:1px solid oklch(55% .08 25 / .3);background:#39191780;color:#f7cbc7;text-align:left;font-size:11px}.inspector-command__actions{display:flex;gap:2px;padding:4px;border-top:1px solid var(--command-edge)}.inspector-command-action{display:flex;flex:1 1 0;min-width:0;min-height:28px;align-items:center;justify-content:center;gap:4px;padding:0 4px;overflow:hidden;border:0;border-radius:5px;background:transparent;color:var(--command-muted);cursor:pointer;font:inherit;font-size:10px;font-weight:500;line-height:1;text-align:left}.inspector-command-action svg{width:11px;height:11px;flex:0 0 auto;fill:currentColor}.inspector-command-action span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inspector-command-action:hover:not(:disabled){background:#ffffff0f;color:var(--command-text)}.inspector-command-action.is-active{background:#6aa7f421;color:#c2daf9}.inspector-command-action.is-selected{background:var(--command-surface-active);color:var(--command-text)}.inspector-command-action--danger:hover:not(:disabled){background:#ef66611a;color:#f5b9b4}.inspector-command-action:disabled{cursor:wait;opacity:.45}.inspector-command-action:focus-visible{outline:1px solid var(--command-accent);outline-offset:-1px}.inspector-visually-hidden{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.inspector-checkpoint-toast{position:fixed;top:10px;left:50%;z-index:500;margin:0;padding:5px 10px;border:1px solid oklch(74% .12 150 / .25);border-radius:999px;background:#0e1f12f0;color:#cce6d0;box-shadow:var(--inspector-shadow);font-size:11px;font-weight:520;line-height:1.25;pointer-events:none;transform:translate(-50%)}.inspector-checkpoint-toast--error{border-color:#e2726b4d;background:#351311f0;color:#fed2cd}@media (prefers-reduced-motion: reduce){.inspector-command-dialog{transition-duration:.01ms!important}.inspector-command-dialog,.inspector-command-dialog[open]{transform:none}.inspector-command__search-icon--cat,.inspector-command__cat-face,.inspector-command__cat-eyes{animation:none;transition:none}}.inspector-box{position:fixed;box-sizing:border-box;pointer-events:none;border:1px solid var(--inspector-accent, var(--inspector-blue));background:color-mix(in srgb,var(--inspector-accent, var(--inspector-blue)) 8%,transparent)}.inspector-box--hover{opacity:.55}.inspector-box--selected{border-width:1.5px}.inspector-box--margin{border-color:#f0a646d1;background:#f0a64614}.inspector-box--padding{border-color:#5ac576d1;background:#5ac57614}.inspector-box--gap{border-color:#bb8aefb8;background:#bb8aef0d}.inspector-box--distance{border-style:dashed;border-color:#539af2b3;background:transparent}.inspector-label,.inspector-box-tag,.inspector-text-chip,.inspector-distance-tag{font-variant-numeric:tabular-nums}.inspector-label{position:absolute;left:0;top:0;transform:translateY(calc(-100% - 6px));max-width:min(380px,calc(100vw - 20px));padding:4px 7px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:var(--inspector-panel);color:var(--inspector-text);box-shadow:var(--inspector-shadow);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);font-size:10px;font-weight:500;line-height:1.2;white-space:nowrap}.inspector-box-tag{position:fixed;transform:translateY(-100%);padding:3px 5px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-box-tag--margin{color:#f5c076}.inspector-box-tag--padding{color:#95dfa4;transform:translateY(0)}.inspector-box-tag--gap{color:oklch(86% .09 305)}.inspector-text-chip{position:fixed;transform:translateY(-100%);display:inline-flex;gap:5px;align-items:center;padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:#e4e4e9;font-size:9px;font-weight:500;line-height:1;white-space:nowrap;pointer-events:none}.inspector-text-chip__swatch{width:7px;height:7px;border-radius:999px;border:1px solid oklch(100% 0 0 / .16);flex:0 0 auto}.inspector-connector{position:fixed;border-color:#539af2b8;border-style:dashed;pointer-events:none}.inspector-connector--vertical{border-left-width:1px;width:0}.inspector-connector--horizontal{border-top-width:1px;height:0}.inspector-distance-line{position:fixed;background:var(--inspector-blue);pointer-events:none}.inspector-distance-line--horizontal{height:1px}.inspector-distance-line--vertical{width:1px}.inspector-distance-tag{position:fixed;transform:translate(-50%);padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f2;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-distance-tag--vertical{transform:translateY(-50%)}.inspector-guide{position:fixed;margin:0;padding:0;border:0;background:transparent;pointer-events:auto;cursor:grab}.inspector-guide--vertical{top:0;width:14px;height:100vh;transform:translate(-50%)}.inspector-guide--horizontal{left:0;width:100vw;height:14px;transform:translateY(-50%)}.inspector-guide--preview{opacity:.55;pointer-events:none;cursor:default}.inspector-guide--preview .inspector-guide-line{background:color-mix(in srgb,var(--inspector-guide, #ff7a00) 72%,transparent)}.inspector-guide-line{position:absolute;inset:0;pointer-events:none}.inspector-guide--vertical .inspector-guide-line{left:calc(50% - .5px);width:1px;height:100%;background:var(--inspector-guide, #ff7a00)}.inspector-guide--horizontal .inspector-guide-line{top:calc(50% - .5px);width:100%;height:1px;background:var(--inspector-guide, #ff7a00)}.inspector-guide--selected .inspector-guide-line{box-shadow:0 0 0 1px #ffffff80}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1377
1423
  }
1378
1424
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: inspectorComponent, decorators: [{
1379
1425
  type: Component,
1380
- args: [{ selector: 'inspector-overlay', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"inspector-root\" #overlayRoot>\n @if (checkpointService) {\n <dialog\n #checkpointDialog\n class=\"inspector-command-dialog\"\n aria-labelledby=\"inspector-command-title\"\n (cancel)=\"$event.preventDefault(); closeCheckpointCommandBar()\"\n (click)=\"handleCheckpointDialogClick($event)\"\n >\n <section class=\"inspector-command\" (click)=\"$event.stopPropagation()\">\n <header class=\"inspector-command__search\">\n <label id=\"inspector-command-title\" class=\"inspector-visually-hidden\" for=\"inspector-checkpoint-search\">\n Search checkpoints\n </label>\n <svg class=\"inspector-command__search-icon\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M7 2.25a4.75 4.75 0 1 0 2.94 8.48l2.91 2.92.8-.8-2.92-2.91A4.75 4.75 0 0 0 7 2.25Zm-3.62 4.75a3.62 3.62 0 1 1 7.24 0 3.62 3.62 0 0 1-7.24 0Z\" />\n </svg>\n <input\n #checkpointSearch\n id=\"inspector-checkpoint-search\"\n type=\"search\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n placeholder=\"Search checkpoints\u2026\"\n [value]=\"checkpointQuery()\"\n [attr.aria-controls]=\"'inspector-checkpoint-results'\"\n [attr.aria-activedescendant]=\"filteredCheckpoints().length ? 'inspector-checkpoint-' + filteredCheckpoints()[activeCheckpointIndex()].id : null\"\n (input)=\"updateCheckpointQuery($event)\"\n />\n </header>\n\n @if (checkpointService.error(); as error) {\n <p class=\"inspector-command__message inspector-command__message--error\" role=\"alert\">{{ error }}</p>\n }\n\n <div id=\"inspector-checkpoint-results\" class=\"inspector-command__results\" role=\"listbox\" aria-label=\"Saved checkpoints\">\n @if (checkpointService.loading()) {\n <p class=\"inspector-command__message\" role=\"status\">Loading\u2026</p>\n } @else if (!checkpointService.checkpoints().length) {\n <p class=\"inspector-command__message\" role=\"status\">No checkpoints yet</p>\n } @else if (!filteredCheckpoints().length) {\n <p class=\"inspector-command__message\" role=\"status\">No matches</p>\n } @else {\n @for (checkpoint of filteredCheckpoints(); track checkpoint.id; let index = $index) {\n <div\n class=\"inspector-command-row\"\n role=\"option\"\n [id]=\"'inspector-checkpoint-' + checkpoint.id\"\n [attr.data-checkpoint-index]=\"index\"\n [attr.aria-selected]=\"activeCheckpointIndex() === index\"\n [class.is-active]=\"activeCheckpointIndex() === index\"\n [class.is-busy]=\"checkpointService.busy() && activeCheckpointIndex() === index\"\n (mouseenter)=\"setActiveCheckpoint(index)\"\n (click)=\"deletingCheckpointId() === checkpoint.id || editingCheckpointId() === checkpoint.id ? null : restoreCheckpoint(checkpoint)\"\n >\n @if (deletingCheckpointId() === checkpoint.id) {\n <span class=\"inspector-command-row__confirm\">Delete \u201C{{ checkpoint.name }}\u201D?</span>\n <span class=\"inspector-command-row__confirm-actions\">\n <button type=\"button\" class=\"is-danger\" (click)=\"confirmDelete(checkpoint, $event)\">Delete</button>\n <button type=\"button\" (click)=\"cancelDelete($event)\">Keep</button>\n </span>\n } @else if (editingCheckpointId() === checkpoint.id) {\n <input\n class=\"inspector-command-row__rename\"\n aria-label=\"Checkpoint name\"\n [value]=\"renameDraft()\"\n (input)=\"updateRenameDraft($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n } @else {\n <span class=\"inspector-command-row__content\">\n <span class=\"inspector-command-row__name\">\n @if (checkpointService.busy() && activeCheckpointIndex() === index) {\n Restoring\u2026\n } @else {\n {{ checkpoint.name }}\n }\n </span>\n <span class=\"inspector-command-row__meta\">\n <span class=\"inspector-command-row__route\">{{ checkpoint.route || '/' }}</span>\n <span class=\"inspector-command-row__separator\" aria-hidden=\"true\">\u00B7</span>\n <span class=\"inspector-command-row__activity\">\n {{ checkpoint.lastUsedAt ? 'Used' : 'Saved' }} {{ formatRelativeTime(checkpointActivityAt(checkpoint)) }}\n </span>\n </span>\n </span>\n <span class=\"inspector-command-row__actions\">\n <button type=\"button\" (click)=\"beginRename(checkpoint, $event)\" [attr.aria-label]=\"'Rename ' + checkpoint.name\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"m11.8 1.8 2.4 2.4-8.3 8.3-3.1.7.7-3.1zm-8 10.4 1.5-.3-1.2-1.2z\" /></svg>\n </button>\n <button type=\"button\" (click)=\"beginDelete(checkpoint, $event)\" [attr.aria-label]=\"'Delete ' + checkpoint.name\">\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M5.5 2h5l.5 1H14v1.25H2V3h3zm-2 3.25h9L12 14H4z\" /></svg>\n </button>\n </span>\n }\n </div>\n }\n }\n </div>\n\n <footer class=\"inspector-command__actions\" aria-label=\"Inspector actions\">\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"toolMode() === 'select'\"\n (click)=\"setToolMode('select'); closeCheckpointCommandBar()\"\n aria-label=\"Select mode\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M3 2l8 8-3 .7L6.7 13 6 10 3 2z\" /></svg>\n <span>Select</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"showTypography()\"\n (click)=\"toggleTypography(); closeCheckpointCommandBar()\"\n aria-label=\"Toggle typography overlay\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M3 4V2h10v2h-4v10H7V4z\" /></svg>\n <span>Type</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n (click)=\"saveCheckpoint()\"\n [disabled]=\"checkpointService.busy()\"\n aria-label=\"Save checkpoint\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M2.5 2h9.6l1.4 1.4V14h-11zm2 1.5v3h6v-3zm.5 6V12h6V9.5z\" /></svg>\n <span>Save</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"toolMode() === 'guides' && guideOrientation() === 'vertical'\"\n (click)=\"activateGuideOrientation('vertical'); closeCheckpointCommandBar()\"\n aria-label=\"Vertical guides\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M7.25 2h1.5v12h-1.5z\" /></svg>\n <span>V</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action\"\n [class.is-active]=\"toolMode() === 'guides' && guideOrientation() === 'horizontal'\"\n (click)=\"activateGuideOrientation('horizontal'); closeCheckpointCommandBar()\"\n aria-label=\"Horizontal guides\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M2 7.25h12v1.5H2z\" /></svg>\n <span>H</span>\n </button>\n <button\n type=\"button\"\n class=\"inspector-command-action inspector-command-action--danger\"\n (click)=\"closeCheckpointCommandBar(); disableInspector()\"\n aria-label=\"Disable inspector; press M to enable\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M7.25 1.5h1.5v6h-1.5zM4.1 3.35l.96 1.15A4.25 4.25 0 1 0 10.94 4.5l.96-1.15A5.75 5.75 0 1 1 4.1 3.35z\" /></svg>\n <span>Off</span>\n </button>\n </footer>\n </section>\n </dialog>\n }\n\n @if (checkpointToast(); as toast) {\n <p\n class=\"inspector-checkpoint-toast\"\n [class.inspector-checkpoint-toast--error]=\"checkpointToastIsError()\"\n [attr.role]=\"checkpointToastIsError() ? 'alert' : 'status'\"\n >{{ toast }}</p>\n }\n\n @if (enabled() && toolMode() === \"select\") {\n @if (hoverRect() && hoverHighlightEnabled) {\n <div\n class=\"inspector-box inspector-box--hover\"\n [style.left.px]=\"hoverRect()!.left\"\n [style.top.px]=\"hoverRect()!.top\"\n [style.width.px]=\"hoverRect()!.width\"\n [style.height.px]=\"hoverRect()!.height\"\n [style.--inspector-accent]=\"highlightColor\"\n ></div>\n }\n\n @if (selectedMeasurement(); as selected) {\n @if (selected.gap.active && selected.parentRect) {\n <div\n class=\"inspector-box inspector-box--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top\"\n [style.width.px]=\"selected.parentRect.width\"\n [style.height.px]=\"selected.parentRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top - 8\"\n >\n G {{ formatGap(selected) }}\n </div>\n }\n\n <div\n class=\"inspector-box inspector-box--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top\"\n [style.width.px]=\"selected.marginRect.width\"\n [style.height.px]=\"selected.marginRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top - 8\"\n >\n M {{ formatEdges(selected.margin) }}\n </div>\n\n <div\n class=\"inspector-box inspector-box--selected\"\n [style.left.px]=\"selected.rect.left\"\n [style.top.px]=\"selected.rect.top\"\n [style.width.px]=\"selected.rect.width\"\n [style.height.px]=\"selected.rect.height\"\n [style.--inspector-accent]=\"highlightColor\"\n >\n <div class=\"inspector-label\">{{ selectedMetaLine() }}</div>\n </div>\n\n <div\n class=\"inspector-box inspector-box--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"selected.paddingRect.top\"\n [style.width.px]=\"selected.paddingRect.width\"\n [style.height.px]=\"selected.paddingRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"\n selected.paddingRect.top + selected.paddingRect.height + 8\n \"\n >\n P {{ formatEdges(selected.padding) }}\n </div>\n }\n }\n\n @if (enabled() && showTypography()) {\n @for (block of textBlocks(); track block.id) {\n <div\n class=\"inspector-text-chip\"\n [style.left.px]=\"block.rect.left\"\n [style.top.px]=\"block.rect.top - 8\"\n >\n <span\n class=\"inspector-text-chip__swatch\"\n [style.background]=\"block.styles.color\"\n ></span>\n <span>{{ block.styles.fontSize }}</span>\n <span>{{ block.styles.lineHeight }}</span>\n <span>{{ block.styles.color }}</span>\n </div>\n }\n }\n\n @if (enabled() && altPressed() && distanceOverlay(); as distance) {\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectA.left\"\n [style.top.px]=\"distance.rectA.top\"\n [style.width.px]=\"distance.rectA.width\"\n [style.height.px]=\"distance.rectA.height\"\n ></div>\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectB.left\"\n [style.top.px]=\"distance.rectB.top\"\n [style.width.px]=\"distance.rectB.width\"\n [style.height.px]=\"distance.rectB.height\"\n ></div>\n\n @for (\n connector of distance.connectors;\n track trackConnector($index, connector)\n ) {\n <div\n class=\"inspector-connector\"\n [class.inspector-connector--vertical]=\"connector.x1 === connector.x2\"\n [class.inspector-connector--horizontal]=\"connector.y1 === connector.y2\"\n [style.left.px]=\"Math.min(connector.x1, connector.x2)\"\n [style.top.px]=\"Math.min(connector.y1, connector.y2)\"\n [style.width.px]=\"Math.max(1, Math.abs(connector.x2 - connector.x1))\"\n [style.height.px]=\"Math.max(1, Math.abs(connector.y2 - connector.y1))\"\n ></div>\n }\n\n @if (distance.horizontal && distance.horizontal.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--horizontal\"\n [style.left.px]=\"\n Math.min(distance.horizontal.x1!, distance.horizontal.x2!)\n \"\n [style.top.px]=\"distance.horizontal.y!\"\n [style.width.px]=\"\n Math.abs(distance.horizontal.x2! - distance.horizontal.x1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag\"\n [style.left.px]=\"\n (distance.horizontal.x1! + distance.horizontal.x2!) / 2\n \"\n [style.top.px]=\"distance.horizontal.y! + 10\"\n >\n {{ formatValue(distance.horizontal.value) }}\n </div>\n }\n\n @if (distance.vertical && distance.vertical.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--vertical\"\n [style.left.px]=\"distance.vertical.x!\"\n [style.top.px]=\"Math.min(distance.vertical.y1!, distance.vertical.y2!)\"\n [style.height.px]=\"\n Math.abs(distance.vertical.y2! - distance.vertical.y1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag inspector-distance-tag--vertical\"\n [style.left.px]=\"distance.vertical.x! + 10\"\n [style.top.px]=\"(distance.vertical.y1! + distance.vertical.y2!) / 2\"\n >\n {{ formatValue(distance.vertical.value) }}\n </div>\n }\n }\n\n @if (enabled()) {\n @if (toolMode() === \"guides\") {\n @if (guidePreview(); as preview) {\n <div\n class=\"inspector-guide inspector-guide--preview\"\n [class.inspector-guide--vertical]=\"preview.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"\n preview.orientation === 'horizontal'\n \"\n [style.left.px]=\"\n preview.orientation === 'vertical' ? preview.position : null\n \"\n [style.top.px]=\"\n preview.orientation === 'horizontal' ? preview.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n >\n <span class=\"inspector-guide-line\"></span>\n </div>\n }\n }\n\n @for (guide of guides(); track guide.id) {\n <button\n type=\"button\"\n class=\"inspector-guide\"\n [class.inspector-guide--vertical]=\"guide.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"guide.orientation === 'horizontal'\"\n [class.inspector-guide--selected]=\"selectedGuideId() === guide.id\"\n [style.left.px]=\"\n guide.orientation === 'vertical' ? guide.position : null\n \"\n [style.top.px]=\"\n guide.orientation === 'horizontal' ? guide.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n (pointerdown)=\"startGuideDrag($event, guide)\"\n >\n <span class=\"inspector-guide-line\"></span>\n </button>\n }\n }\n</div>\n", styles: [":host{--inspector-panel: oklch(20% .012 280 / .92);--inspector-panel-edge: oklch(100% 0 0 / .08);--inspector-text: oklch(96% .005 280);--inspector-muted: oklch(70% .014 280);--inspector-faint: oklch(56% .012 280);--inspector-blue: oklch(68% .15 255);--inspector-blue-soft: oklch(68% .15 255 / .14);--inspector-orange: oklch(78% .14 70);--inspector-green: oklch(74% .15 150);--inspector-violet: oklch(72% .15 305);--inspector-radius: 8px;--inspector-shadow: 0 12px 32px oklch(6% .02 280 / .5);--inspector-font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--inspector-ease: cubic-bezier(.16, 1, .3, 1);position:fixed;inset:0;z-index:2147;pointer-events:none;font-family:var(--inspector-font);color:var(--inspector-text);-webkit-font-smoothing:antialiased}.inspector-root{position:fixed;inset:0;pointer-events:none}.inspector-command-dialog{--command-surface: oklch(17.5% .012 280);--command-surface-active: oklch(26% .02 265);--command-edge: oklch(100% 0 0 / .08);--command-text: oklch(96% .005 280);--command-muted: oklch(68% .014 280);--command-faint: oklch(52% .012 280);--command-accent: oklch(72% .13 255);--command-danger: oklch(68% .17 25);box-sizing:border-box;inset-block-start:max(10vh,48px);width:min(420px,calc(100vw - 24px));max-width:none;max-height:min(360px,calc(100vh - 64px));margin:0 auto;padding:0;overflow:hidden;border:1px solid var(--command-edge);border-radius:var(--inspector-radius);background:var(--command-surface);color:var(--command-text);box-shadow:var(--inspector-shadow);opacity:0;pointer-events:auto;transform:translateY(-4px);transition:opacity .1s ease,transform .1s ease,overlay .1s allow-discrete,display .1s allow-discrete;font-family:var(--inspector-font);-webkit-font-smoothing:antialiased}.inspector-command-dialog[open]{opacity:1;transform:none;transition-duration:.14s;transition-timing-function:var(--inspector-ease)}@starting-style{.inspector-command-dialog[open]{opacity:0;transform:translateY(-4px)}}.inspector-command-dialog::backdrop{background:#01010266}.inspector-command{display:grid;grid-template-rows:auto auto 1fr auto;min-width:0;min-height:0;max-height:min(360px,calc(100vh - 64px))}.inspector-command__search{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 11px;border-bottom:1px solid var(--command-edge)}.inspector-command__search-icon{width:14px;height:14px;flex:0 0 auto;fill:var(--command-faint)}.inspector-command__search input,.inspector-command-row__rename{min-width:0;border:0;outline:0;background:transparent;color:var(--command-text);font:inherit}.inspector-command__search input{flex:1 1 auto;width:100%;height:39px;padding:0;font-size:13px;font-weight:450;line-height:1.3}.inspector-command__search input::placeholder{color:var(--command-faint);opacity:1}.inspector-command__search input::-webkit-search-cancel-button{display:none}.inspector-command__results{min-height:0;max-height:260px;overflow:auto;padding:5px;scrollbar-width:thin;scrollbar-color:oklch(100% 0 0 / .1) transparent}.inspector-command-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:6px;min-height:34px;padding:0 7px 0 9px;border-radius:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.inspector-command-row.is-active{background:var(--command-surface-active)}.inspector-command-row.is-busy{cursor:wait;pointer-events:none;opacity:.7}.inspector-command-row__content{display:flex;align-items:baseline;gap:8px;min-width:0;overflow:hidden}.inspector-command-row__name{flex:0 1 auto;min-width:3ch;overflow:hidden;color:var(--command-text);font-size:12px;font-weight:500;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__meta{display:inline-flex;flex:0 1 auto;align-items:baseline;gap:4px;min-width:0;overflow:hidden;color:var(--command-faint);font-size:11px;font-weight:400;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__route{min-width:0;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__separator,.inspector-command-row__activity{flex:0 0 auto}.inspector-command-row.is-active .inspector-command-row__activity{color:var(--command-muted)}.inspector-command-row__actions,.inspector-command-row__confirm-actions{display:flex;align-items:center;gap:1px}.inspector-command-row__actions{opacity:0;pointer-events:none}.inspector-command-row:hover .inspector-command-row__actions,.inspector-command-row:focus-within .inspector-command-row__actions{opacity:1;pointer-events:auto}.inspector-command-row button{display:inline-grid;width:22px;min-height:22px;padding:0;place-items:center;border:0;border-radius:4px;background:transparent;color:var(--command-muted);cursor:pointer;font-family:inherit;font-size:10px;font-weight:550;line-height:1.2}.inspector-command-row button svg{width:11px;height:11px;fill:currentColor}.inspector-command-row button:hover{background:#ffffff12;color:var(--command-text)}.inspector-command-row button.is-danger{width:auto;padding:0 7px;color:var(--command-danger);font-size:11px}.inspector-command-row button.is-danger:hover{background:#ef66611f}.inspector-command-row__confirm-actions button:not(.is-danger){width:auto;padding:0 7px;font-size:11px}.inspector-command-row button:focus-visible,.inspector-command-row__rename:focus-visible{outline:1px solid var(--command-accent);outline-offset:1px}.inspector-command-row__confirm{grid-column:1;color:var(--command-text);font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__rename{grid-column:1 / -1;min-height:26px;padding-inline:6px;border:1px solid oklch(72% .13 255 / .4);border-radius:4px;background:#191a21;font-size:12px;font-weight:500}.inspector-command__message{margin:0;padding:16px 10px;color:var(--command-faint);font-size:12px;line-height:1.4;text-align:center}.inspector-command__message--error{padding:6px 10px;border-bottom:1px solid oklch(55% .08 25 / .3);background:#39191780;color:#f7cbc7;text-align:left;font-size:11px}.inspector-command__actions{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:2px;padding:4px;border-top:1px solid var(--command-edge)}.inspector-command-action{display:flex;min-width:0;min-height:28px;align-items:center;justify-content:center;gap:4px;padding:0 4px;overflow:hidden;border:0;border-radius:5px;background:transparent;color:var(--command-muted);cursor:pointer;font:inherit;font-size:10px;font-weight:500;line-height:1;text-align:left}.inspector-command-action svg{width:11px;height:11px;flex:0 0 auto;fill:currentColor}.inspector-command-action span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inspector-command-action:hover:not(:disabled){background:#ffffff0f;color:var(--command-text)}.inspector-command-action.is-active{background:#6aa7f421;color:#c2daf9}.inspector-command-action--danger:hover:not(:disabled){background:#ef66611a;color:#f5b9b4}.inspector-command-action:disabled{cursor:wait;opacity:.45}.inspector-command-action:focus-visible{outline:1px solid var(--command-accent);outline-offset:-1px}.inspector-visually-hidden{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.inspector-checkpoint-toast{position:fixed;top:10px;left:50%;z-index:500;margin:0;padding:5px 10px;border:1px solid oklch(74% .12 150 / .25);border-radius:999px;background:#0e1f12f0;color:#cce6d0;box-shadow:var(--inspector-shadow);font-size:11px;font-weight:520;line-height:1.25;pointer-events:none;transform:translate(-50%)}.inspector-checkpoint-toast--error{border-color:#e2726b4d;background:#351311f0;color:#fed2cd}@media (prefers-reduced-motion: reduce){.inspector-command-dialog{transition-duration:.01ms!important}.inspector-command-dialog,.inspector-command-dialog[open]{transform:none}}.inspector-box{position:fixed;box-sizing:border-box;pointer-events:none;border:1px solid var(--inspector-accent, var(--inspector-blue));background:color-mix(in srgb,var(--inspector-accent, var(--inspector-blue)) 8%,transparent)}.inspector-box--hover{opacity:.55}.inspector-box--selected{border-width:1.5px}.inspector-box--margin{border-color:#f0a646d1;background:#f0a64614}.inspector-box--padding{border-color:#5ac576d1;background:#5ac57614}.inspector-box--gap{border-color:#bb8aefb8;background:#bb8aef0d}.inspector-box--distance{border-style:dashed;border-color:#539af2b3;background:transparent}.inspector-label,.inspector-box-tag,.inspector-text-chip,.inspector-distance-tag{font-variant-numeric:tabular-nums}.inspector-label{position:absolute;left:0;top:0;transform:translateY(calc(-100% - 6px));max-width:min(380px,calc(100vw - 20px));padding:4px 7px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:var(--inspector-panel);color:var(--inspector-text);box-shadow:var(--inspector-shadow);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);font-size:10px;font-weight:500;line-height:1.2;white-space:nowrap}.inspector-box-tag{position:fixed;transform:translateY(-100%);padding:3px 5px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-box-tag--margin{color:#f5c076}.inspector-box-tag--padding{color:#95dfa4;transform:translateY(0)}.inspector-box-tag--gap{color:oklch(86% .09 305)}.inspector-text-chip{position:fixed;transform:translateY(-100%);display:inline-flex;gap:5px;align-items:center;padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:#e4e4e9;font-size:9px;font-weight:500;line-height:1;white-space:nowrap;pointer-events:none}.inspector-text-chip__swatch{width:7px;height:7px;border-radius:999px;border:1px solid oklch(100% 0 0 / .16);flex:0 0 auto}.inspector-connector{position:fixed;border-color:#539af2b8;border-style:dashed;pointer-events:none}.inspector-connector--vertical{border-left-width:1px;width:0}.inspector-connector--horizontal{border-top-width:1px;height:0}.inspector-distance-line{position:fixed;background:var(--inspector-blue);pointer-events:none}.inspector-distance-line--horizontal{height:1px}.inspector-distance-line--vertical{width:1px}.inspector-distance-tag{position:fixed;transform:translate(-50%);padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f2;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-distance-tag--vertical{transform:translateY(-50%)}.inspector-guide{position:fixed;margin:0;padding:0;border:0;background:transparent;pointer-events:auto;cursor:grab}.inspector-guide--vertical{top:0;width:14px;height:100vh;transform:translate(-50%)}.inspector-guide--horizontal{left:0;width:100vw;height:14px;transform:translateY(-50%)}.inspector-guide--preview{opacity:.55;pointer-events:none;cursor:default}.inspector-guide--preview .inspector-guide-line{background:color-mix(in srgb,var(--inspector-guide, #ff7a00) 72%,transparent)}.inspector-guide-line{position:absolute;inset:0;pointer-events:none}.inspector-guide--vertical .inspector-guide-line{left:calc(50% - .5px);width:1px;height:100%;background:var(--inspector-guide, #ff7a00)}.inspector-guide--horizontal .inspector-guide-line{top:calc(50% - .5px);width:100%;height:1px;background:var(--inspector-guide, #ff7a00)}.inspector-guide--selected .inspector-guide-line{box-shadow:0 0 0 1px #ffffff80}\n"] }]
1426
+ args: [{ selector: 'inspector-overlay', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"inspector-root\" #overlayRoot>\n @if (checkpointService) {\n <dialog\n #checkpointDialog\n class=\"inspector-command-dialog\"\n aria-labelledby=\"inspector-command-title\"\n (cancel)=\"$event.preventDefault(); closeCheckpointCommandBar()\"\n (click)=\"handleCheckpointDialogClick($event)\"\n >\n <section class=\"inspector-command\" (click)=\"$event.stopPropagation()\">\n <header class=\"inspector-command__search\">\n <label\n id=\"inspector-command-title\"\n class=\"inspector-visually-hidden\"\n for=\"inspector-checkpoint-search\"\n >\n inspector-ng command palette\n </label>\n <svg\n class=\"inspector-command__search-icon inspector-command__search-icon--cat\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <g class=\"inspector-command__cat-face\">\n <path\n d=\"M3.2 6.1 2.7 2.6l3 1.5A5.7 5.7 0 0 1 8 3.6c.8 0 1.6.2 2.3.5l3-1.5-.5 3.5c.5.8.7 1.7.7 2.7 0 2.8-2.4 4.5-5.5 4.5s-5.5-1.7-5.5-4.5c0-1 .2-1.9.7-2.7Z\"\n />\n <g class=\"inspector-command__cat-eyes\">\n <circle cx=\"5.7\" cy=\"8.3\" r=\".65\" />\n <circle cx=\"10.3\" cy=\"8.3\" r=\".65\" />\n </g>\n <path d=\"m6.8 10.3 1.2.7 1.2-.7M8 11v.7\" />\n </g>\n </svg>\n <input\n #checkpointSearch\n id=\"inspector-checkpoint-search\"\n type=\"search\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n placeholder=\"inspector-ng\u2026\"\n [value]=\"checkpointQuery()\"\n [attr.aria-controls]=\"'inspector-checkpoint-results inspector-command-actions'\"\n [attr.aria-activedescendant]=\"activeCommandResultId()\"\n (input)=\"updateCheckpointQuery($event)\"\n />\n </header>\n\n @if (checkpointService.error(); as error) {\n <p\n class=\"inspector-command__message inspector-command__message--error\"\n role=\"alert\"\n >\n {{ error }}\n </p>\n }\n\n <div\n id=\"inspector-checkpoint-results\"\n class=\"inspector-command__results\"\n role=\"listbox\"\n aria-label=\"Saved checkpoints\"\n >\n @if (checkpointService.loading()) {\n <p class=\"inspector-command__message\" role=\"status\">Loading\u2026</p>\n } @else if (\n !checkpointService.checkpoints().length && !checkpointQuery().trim()\n ) {\n <p class=\"inspector-command__message\" role=\"status\">\n No checkpoints yet\n </p>\n } @else if (\n !filteredCheckpoints().length && !filteredInspectorActions().length\n ) {\n <p class=\"inspector-command__message\" role=\"status\">No matches</p>\n } @else {\n @for (\n checkpoint of filteredCheckpoints();\n track checkpoint.id;\n let index = $index\n ) {\n <div\n class=\"inspector-command-row\"\n role=\"option\"\n [id]=\"'inspector-checkpoint-' + checkpoint.id\"\n [attr.data-command-index]=\"index\"\n [attr.aria-selected]=\"activeCommandIndex() === index\"\n [class.is-active]=\"activeCommandIndex() === index\"\n [class.is-busy]=\"\n checkpointService.busy() && activeCommandIndex() === index\n \"\n (mouseenter)=\"setActiveCheckpoint(index)\"\n (click)=\"\n deletingCheckpointId() === checkpoint.id ||\n editingCheckpointId() === checkpoint.id\n ? null\n : restoreCheckpoint(checkpoint)\n \"\n >\n @if (deletingCheckpointId() === checkpoint.id) {\n <span class=\"inspector-command-row__confirm\"\n >Delete \u201C{{ checkpoint.name }}\u201D?</span\n >\n <span class=\"inspector-command-row__confirm-actions\">\n <button\n type=\"button\"\n class=\"is-danger\"\n (click)=\"confirmDelete(checkpoint, $event)\"\n >\n Delete\n </button>\n <button type=\"button\" (click)=\"cancelDelete($event)\">\n Keep\n </button>\n </span>\n } @else if (editingCheckpointId() === checkpoint.id) {\n <input\n class=\"inspector-command-row__rename\"\n aria-label=\"Checkpoint name\"\n [value]=\"renameDraft()\"\n (input)=\"updateRenameDraft($event)\"\n (click)=\"$event.stopPropagation()\"\n />\n } @else {\n <span class=\"inspector-command-row__content\">\n <span class=\"inspector-command-row__name\">\n @if (\n checkpointService.busy() &&\n activeCommandIndex() === index\n ) {\n Restoring\u2026\n } @else {\n {{ checkpoint.name }}\n }\n </span>\n <span class=\"inspector-command-row__meta\">\n @if (shouldShowCheckpointRoute(checkpoint)) {\n <span class=\"inspector-command-row__route\">{{\n checkpoint.route\n }}</span>\n <span\n class=\"inspector-command-row__separator\"\n aria-hidden=\"true\"\n >\u00B7</span\n >\n }\n <span class=\"inspector-command-row__activity\">\n {{ checkpoint.lastUsedAt ? \"Used\" : \"Saved\" }}\n {{\n formatRelativeTime(checkpointActivityAt(checkpoint))\n }}\n </span>\n </span>\n </span>\n <span class=\"inspector-command-row__actions\">\n <button\n type=\"button\"\n (click)=\"beginRename(checkpoint, $event)\"\n [attr.aria-label]=\"'Rename ' + checkpoint.name\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"m11.8 1.8 2.4 2.4-8.3 8.3-3.1.7.7-3.1zm-8 10.4 1.5-.3-1.2-1.2z\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n (click)=\"beginDelete(checkpoint, $event)\"\n [attr.aria-label]=\"'Delete ' + checkpoint.name\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M5.5 2h5l.5 1H14v1.25H2V3h3zm-2 3.25h9L12 14H4z\"\n />\n </svg>\n </button>\n </span>\n }\n </div>\n }\n }\n </div>\n\n @if (filteredInspectorActions().length) {\n <footer\n id=\"inspector-command-actions\"\n class=\"inspector-command__actions\"\n role=\"listbox\"\n aria-label=\"Inspector actions\"\n aria-orientation=\"horizontal\"\n >\n @for (\n action of filteredInspectorActions();\n track action.id;\n let index = $index\n ) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"inspector-command-action\"\n [id]=\"'inspector-action-' + action.id\"\n [attr.data-command-index]=\"filteredCheckpoints().length + index\"\n [attr.aria-label]=\"action.ariaLabel\"\n [attr.aria-selected]=\"\n activeCommandIndex() === filteredCheckpoints().length + index\n \"\n [attr.aria-disabled]=\"checkpointService.busy()\"\n [class.is-selected]=\"\n activeCommandIndex() === filteredCheckpoints().length + index\n \"\n [class.is-active]=\"\n (action.id === 'select' && toolMode() === 'select') ||\n (action.id === 'type' && showTypography()) ||\n (action.id === 'vertical' &&\n toolMode() === 'guides' &&\n guideOrientation() === 'vertical') ||\n (action.id === 'horizontal' &&\n toolMode() === 'guides' &&\n guideOrientation() === 'horizontal')\n \"\n [class.inspector-command-action--danger]=\"action.id === 'off'\"\n [disabled]=\"checkpointService.busy()\"\n (mouseenter)=\"setActiveInspectorAction(index)\"\n (click)=\"executeInspectorAction(action)\"\n >\n @switch (action.id) {\n @case (\"select\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M3 2l8 8-3 .7L6.7 13 6 10 3 2z\" />\n </svg>\n }\n @case (\"type\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M3 4V2h10v2h-4v10H7V4z\" />\n </svg>\n }\n @case (\"save\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M2.5 2h9.6l1.4 1.4V14h-11zm2 1.5v3h6v-3zm.5 6V12h6V9.5z\"\n />\n </svg>\n }\n @case (\"vertical\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M7.25 2h1.5v12h-1.5z\" />\n </svg>\n }\n @case (\"horizontal\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M2 7.25h12v1.5H2z\" />\n </svg>\n }\n @case (\"off\") {\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M7.25 1.5h1.5v6h-1.5zM4.1 3.35l.96 1.15A4.25 4.25 0 1 0 10.94 4.5l.96-1.15A5.75 5.75 0 1 1 4.1 3.35z\"\n />\n </svg>\n }\n }\n <span>{{ action.label }}</span>\n </button>\n }\n </footer>\n }\n </section>\n </dialog>\n }\n\n @if (checkpointToast(); as toast) {\n <p\n class=\"inspector-checkpoint-toast\"\n [class.inspector-checkpoint-toast--error]=\"checkpointToastIsError()\"\n [attr.role]=\"checkpointToastIsError() ? 'alert' : 'status'\"\n >\n {{ toast }}\n </p>\n }\n\n @if (enabled() && toolMode() === \"select\") {\n @if (hoverRect() && hoverHighlightEnabled) {\n <div\n class=\"inspector-box inspector-box--hover\"\n [style.left.px]=\"hoverRect()!.left\"\n [style.top.px]=\"hoverRect()!.top\"\n [style.width.px]=\"hoverRect()!.width\"\n [style.height.px]=\"hoverRect()!.height\"\n [style.--inspector-accent]=\"highlightColor\"\n ></div>\n }\n\n @if (selectedMeasurement(); as selected) {\n @if (selected.gap.active && selected.parentRect) {\n <div\n class=\"inspector-box inspector-box--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top\"\n [style.width.px]=\"selected.parentRect.width\"\n [style.height.px]=\"selected.parentRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--gap\"\n [style.left.px]=\"selected.parentRect.left\"\n [style.top.px]=\"selected.parentRect.top - 8\"\n >\n G {{ formatGap(selected) }}\n </div>\n }\n\n <div\n class=\"inspector-box inspector-box--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top\"\n [style.width.px]=\"selected.marginRect.width\"\n [style.height.px]=\"selected.marginRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--margin\"\n [style.left.px]=\"selected.marginRect.left\"\n [style.top.px]=\"selected.marginRect.top - 8\"\n >\n M {{ formatEdges(selected.margin) }}\n </div>\n\n <div\n class=\"inspector-box inspector-box--selected\"\n [style.left.px]=\"selected.rect.left\"\n [style.top.px]=\"selected.rect.top\"\n [style.width.px]=\"selected.rect.width\"\n [style.height.px]=\"selected.rect.height\"\n [style.--inspector-accent]=\"highlightColor\"\n >\n <div class=\"inspector-label\">{{ selectedMetaLine() }}</div>\n </div>\n\n <div\n class=\"inspector-box inspector-box--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"selected.paddingRect.top\"\n [style.width.px]=\"selected.paddingRect.width\"\n [style.height.px]=\"selected.paddingRect.height\"\n ></div>\n <div\n class=\"inspector-box-tag inspector-box-tag--padding\"\n [style.left.px]=\"selected.paddingRect.left\"\n [style.top.px]=\"\n selected.paddingRect.top + selected.paddingRect.height + 8\n \"\n >\n P {{ formatEdges(selected.padding) }}\n </div>\n }\n }\n\n @if (enabled() && showTypography()) {\n @for (block of textBlocks(); track block.id) {\n <div\n class=\"inspector-text-chip\"\n [style.left.px]=\"block.rect.left\"\n [style.top.px]=\"block.rect.top - 8\"\n >\n <span\n class=\"inspector-text-chip__swatch\"\n [style.background]=\"block.styles.color\"\n ></span>\n <span>{{ block.styles.fontSize }}</span>\n <span>{{ block.styles.lineHeight }}</span>\n <span>{{ block.styles.color }}</span>\n </div>\n }\n }\n\n @if (enabled() && altPressed() && distanceOverlay(); as distance) {\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectA.left\"\n [style.top.px]=\"distance.rectA.top\"\n [style.width.px]=\"distance.rectA.width\"\n [style.height.px]=\"distance.rectA.height\"\n ></div>\n <div\n class=\"inspector-box inspector-box--distance\"\n [style.left.px]=\"distance.rectB.left\"\n [style.top.px]=\"distance.rectB.top\"\n [style.width.px]=\"distance.rectB.width\"\n [style.height.px]=\"distance.rectB.height\"\n ></div>\n\n @for (\n connector of distance.connectors;\n track trackConnector($index, connector)\n ) {\n <div\n class=\"inspector-connector\"\n [class.inspector-connector--vertical]=\"connector.x1 === connector.x2\"\n [class.inspector-connector--horizontal]=\"connector.y1 === connector.y2\"\n [style.left.px]=\"Math.min(connector.x1, connector.x2)\"\n [style.top.px]=\"Math.min(connector.y1, connector.y2)\"\n [style.width.px]=\"Math.max(1, Math.abs(connector.x2 - connector.x1))\"\n [style.height.px]=\"Math.max(1, Math.abs(connector.y2 - connector.y1))\"\n ></div>\n }\n\n @if (distance.horizontal && distance.horizontal.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--horizontal\"\n [style.left.px]=\"\n Math.min(distance.horizontal.x1!, distance.horizontal.x2!)\n \"\n [style.top.px]=\"distance.horizontal.y!\"\n [style.width.px]=\"\n Math.abs(distance.horizontal.x2! - distance.horizontal.x1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag\"\n [style.left.px]=\"\n (distance.horizontal.x1! + distance.horizontal.x2!) / 2\n \"\n [style.top.px]=\"distance.horizontal.y! + 10\"\n >\n {{ formatValue(distance.horizontal.value) }}\n </div>\n }\n\n @if (distance.vertical && distance.vertical.value > 0) {\n <div\n class=\"inspector-distance-line inspector-distance-line--vertical\"\n [style.left.px]=\"distance.vertical.x!\"\n [style.top.px]=\"Math.min(distance.vertical.y1!, distance.vertical.y2!)\"\n [style.height.px]=\"\n Math.abs(distance.vertical.y2! - distance.vertical.y1!)\n \"\n ></div>\n <div\n class=\"inspector-distance-tag inspector-distance-tag--vertical\"\n [style.left.px]=\"distance.vertical.x! + 10\"\n [style.top.px]=\"(distance.vertical.y1! + distance.vertical.y2!) / 2\"\n >\n {{ formatValue(distance.vertical.value) }}\n </div>\n }\n }\n\n @if (enabled()) {\n @if (toolMode() === \"guides\") {\n @if (guidePreview(); as preview) {\n <div\n class=\"inspector-guide inspector-guide--preview\"\n [class.inspector-guide--vertical]=\"preview.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"\n preview.orientation === 'horizontal'\n \"\n [style.left.px]=\"\n preview.orientation === 'vertical' ? preview.position : null\n \"\n [style.top.px]=\"\n preview.orientation === 'horizontal' ? preview.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n >\n <span class=\"inspector-guide-line\"></span>\n </div>\n }\n }\n\n @for (guide of guides(); track guide.id) {\n <button\n type=\"button\"\n class=\"inspector-guide\"\n [class.inspector-guide--vertical]=\"guide.orientation === 'vertical'\"\n [class.inspector-guide--horizontal]=\"guide.orientation === 'horizontal'\"\n [class.inspector-guide--selected]=\"selectedGuideId() === guide.id\"\n [style.left.px]=\"\n guide.orientation === 'vertical' ? guide.position : null\n \"\n [style.top.px]=\"\n guide.orientation === 'horizontal' ? guide.position : null\n \"\n [style.--inspector-guide]=\"guideColor\"\n (pointerdown)=\"startGuideDrag($event, guide)\"\n >\n <span class=\"inspector-guide-line\"></span>\n </button>\n }\n }\n</div>\n", styles: [":host{--inspector-panel: oklch(20% .012 280 / .92);--inspector-panel-edge: oklch(100% 0 0 / .08);--inspector-text: oklch(96% .005 280);--inspector-muted: oklch(70% .014 280);--inspector-faint: oklch(56% .012 280);--inspector-blue: oklch(68% .15 255);--inspector-blue-soft: oklch(68% .15 255 / .14);--inspector-orange: oklch(78% .14 70);--inspector-green: oklch(74% .15 150);--inspector-violet: oklch(72% .15 305);--inspector-radius: 8px;--inspector-shadow: 0 12px 32px oklch(6% .02 280 / .5);--inspector-font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--inspector-ease: cubic-bezier(.16, 1, .3, 1);position:fixed;inset:0;z-index:2147;pointer-events:none;font-family:var(--inspector-font);color:var(--inspector-text);-webkit-font-smoothing:antialiased}.inspector-root{position:fixed;inset:0;pointer-events:none}.inspector-command-dialog{--command-surface: oklch(17.5% .012 280);--command-surface-active: oklch(26% .02 265);--command-edge: oklch(100% 0 0 / .08);--command-text: oklch(96% .005 280);--command-muted: oklch(68% .014 280);--command-faint: oklch(52% .012 280);--command-accent: oklch(72% .13 255);--command-danger: oklch(68% .17 25);box-sizing:border-box;inset-block-start:max(10vh,48px);width:min(420px,calc(100vw - 24px));max-width:none;max-height:min(360px,calc(100vh - 64px));margin:0 auto;padding:0;overflow:hidden;border:1px solid var(--command-edge);border-radius:var(--inspector-radius);background:var(--command-surface);color:var(--command-text);box-shadow:var(--inspector-shadow);opacity:0;pointer-events:auto;transform:translateY(-4px);transition:opacity .1s ease,transform .1s ease,overlay .1s allow-discrete,display .1s allow-discrete;font-family:var(--inspector-font);-webkit-font-smoothing:antialiased}.inspector-command-dialog[open]{opacity:1;transform:none;transition-duration:.14s;transition-timing-function:var(--inspector-ease)}@starting-style{.inspector-command-dialog[open]{opacity:0;transform:translateY(-4px)}}.inspector-command-dialog::backdrop{background:#01010266}.inspector-command{display:grid;grid-template-rows:auto auto 1fr auto;min-width:0;min-height:0;max-height:min(360px,calc(100vh - 64px))}.inspector-command__search{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 11px;border-bottom:1px solid var(--command-edge)}.inspector-command__search-icon{width:15px;height:15px;flex:0 0 auto;overflow:visible;fill:none;stroke:var(--command-faint);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}.inspector-command__search-icon circle{fill:var(--command-faint);stroke:none}.inspector-command__search-icon--cat{transition:stroke .14s var(--inspector-ease)}.inspector-command__cat-face{transform-box:fill-box;transform-origin:center;animation:inspector-cat-listen 5.4s var(--inspector-ease) infinite}.inspector-command__cat-eyes{transform-box:fill-box;transform-origin:center;animation:inspector-cat-blink 4.2s ease-out infinite}.inspector-command__search:focus-within .inspector-command__search-icon--cat{stroke:var(--command-accent);animation:inspector-cat-arrive .42s var(--inspector-ease) both}.inspector-command__search:focus-within .inspector-command__search-icon circle{fill:var(--command-accent)}@keyframes inspector-cat-arrive{0%{transform:translateY(1px) rotate(-7deg)}65%{transform:translateY(0) rotate(3deg)}to{transform:none}}@keyframes inspector-cat-listen{0%,88%,to{transform:rotate(0)}92%{transform:rotate(-5deg)}96%{transform:rotate(3deg)}}@keyframes inspector-cat-blink{0%,90%,94%,to{transform:scaleY(1)}92%{transform:scaleY(.08)}}.inspector-command__search input,.inspector-command-row__rename{min-width:0;border:0;outline:0;background:transparent;color:var(--command-text);font:inherit}.inspector-command__search input{flex:1 1 auto;width:100%;height:39px;padding:0;font-size:13px;font-weight:450;line-height:1.3}.inspector-command__search input::placeholder{color:var(--command-faint);opacity:1}.inspector-command__search input::-webkit-search-cancel-button{display:none}.inspector-command__results{min-height:0;max-height:260px;overflow:auto;padding:5px;scrollbar-width:thin;scrollbar-color:oklch(100% 0 0 / .1) transparent}.inspector-command-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:6px;min-height:34px;padding:0 7px 0 9px;border-radius:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.inspector-command-row.is-active{background:var(--command-surface-active)}.inspector-command-row.is-busy{cursor:wait;pointer-events:none;opacity:.7}.inspector-command-row__content{display:flex;align-items:baseline;gap:8px;min-width:0;overflow:hidden}.inspector-command-row__name{flex:0 1 auto;min-width:3ch;overflow:hidden;color:var(--command-text);font-size:12px;font-weight:500;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__meta{display:inline-flex;flex:0 1 auto;align-items:baseline;gap:4px;min-width:0;overflow:hidden;color:var(--command-faint);font-size:11px;font-weight:400;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.inspector-command-row__route{min-width:0;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__separator,.inspector-command-row__activity{flex:0 0 auto}.inspector-command-row.is-active .inspector-command-row__activity{color:var(--command-muted)}.inspector-command-row__actions,.inspector-command-row__confirm-actions{display:flex;align-items:center;gap:1px}.inspector-command-row__actions{opacity:0;pointer-events:none}.inspector-command-row:hover .inspector-command-row__actions,.inspector-command-row:focus-within .inspector-command-row__actions{opacity:1;pointer-events:auto}.inspector-command-row button{display:inline-grid;width:22px;min-height:22px;padding:0;place-items:center;border:0;border-radius:4px;background:transparent;color:var(--command-muted);cursor:pointer;font-family:inherit;font-size:10px;font-weight:550;line-height:1.2}.inspector-command-row button svg{width:11px;height:11px;fill:currentColor}.inspector-command-row button:hover{background:#ffffff12;color:var(--command-text)}.inspector-command-row button.is-danger{width:auto;padding:0 7px;color:var(--command-danger);font-size:11px}.inspector-command-row button.is-danger:hover{background:#ef66611f}.inspector-command-row__confirm-actions button:not(.is-danger){width:auto;padding:0 7px;font-size:11px}.inspector-command-row button:focus-visible,.inspector-command-row__rename:focus-visible{outline:1px solid var(--command-accent);outline-offset:1px}.inspector-command-row__confirm{grid-column:1;color:var(--command-text);font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.inspector-command-row__rename{grid-column:1 / -1;min-height:26px;padding-inline:6px;border:1px solid oklch(72% .13 255 / .4);border-radius:4px;background:#191a21;font-size:12px;font-weight:500}.inspector-command__message{margin:0;padding:16px 10px;color:var(--command-faint);font-size:12px;line-height:1.4;text-align:center}.inspector-command__message--error{padding:6px 10px;border-bottom:1px solid oklch(55% .08 25 / .3);background:#39191780;color:#f7cbc7;text-align:left;font-size:11px}.inspector-command__actions{display:flex;gap:2px;padding:4px;border-top:1px solid var(--command-edge)}.inspector-command-action{display:flex;flex:1 1 0;min-width:0;min-height:28px;align-items:center;justify-content:center;gap:4px;padding:0 4px;overflow:hidden;border:0;border-radius:5px;background:transparent;color:var(--command-muted);cursor:pointer;font:inherit;font-size:10px;font-weight:500;line-height:1;text-align:left}.inspector-command-action svg{width:11px;height:11px;flex:0 0 auto;fill:currentColor}.inspector-command-action span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inspector-command-action:hover:not(:disabled){background:#ffffff0f;color:var(--command-text)}.inspector-command-action.is-active{background:#6aa7f421;color:#c2daf9}.inspector-command-action.is-selected{background:var(--command-surface-active);color:var(--command-text)}.inspector-command-action--danger:hover:not(:disabled){background:#ef66611a;color:#f5b9b4}.inspector-command-action:disabled{cursor:wait;opacity:.45}.inspector-command-action:focus-visible{outline:1px solid var(--command-accent);outline-offset:-1px}.inspector-visually-hidden{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.inspector-checkpoint-toast{position:fixed;top:10px;left:50%;z-index:500;margin:0;padding:5px 10px;border:1px solid oklch(74% .12 150 / .25);border-radius:999px;background:#0e1f12f0;color:#cce6d0;box-shadow:var(--inspector-shadow);font-size:11px;font-weight:520;line-height:1.25;pointer-events:none;transform:translate(-50%)}.inspector-checkpoint-toast--error{border-color:#e2726b4d;background:#351311f0;color:#fed2cd}@media (prefers-reduced-motion: reduce){.inspector-command-dialog{transition-duration:.01ms!important}.inspector-command-dialog,.inspector-command-dialog[open]{transform:none}.inspector-command__search-icon--cat,.inspector-command__cat-face,.inspector-command__cat-eyes{animation:none;transition:none}}.inspector-box{position:fixed;box-sizing:border-box;pointer-events:none;border:1px solid var(--inspector-accent, var(--inspector-blue));background:color-mix(in srgb,var(--inspector-accent, var(--inspector-blue)) 8%,transparent)}.inspector-box--hover{opacity:.55}.inspector-box--selected{border-width:1.5px}.inspector-box--margin{border-color:#f0a646d1;background:#f0a64614}.inspector-box--padding{border-color:#5ac576d1;background:#5ac57614}.inspector-box--gap{border-color:#bb8aefb8;background:#bb8aef0d}.inspector-box--distance{border-style:dashed;border-color:#539af2b3;background:transparent}.inspector-label,.inspector-box-tag,.inspector-text-chip,.inspector-distance-tag{font-variant-numeric:tabular-nums}.inspector-label{position:absolute;left:0;top:0;transform:translateY(calc(-100% - 6px));max-width:min(380px,calc(100vw - 20px));padding:4px 7px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:var(--inspector-panel);color:var(--inspector-text);box-shadow:var(--inspector-shadow);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);font-size:10px;font-weight:500;line-height:1.2;white-space:nowrap}.inspector-box-tag{position:fixed;transform:translateY(-100%);padding:3px 5px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-box-tag--margin{color:#f5c076}.inspector-box-tag--padding{color:#95dfa4;transform:translateY(0)}.inspector-box-tag--gap{color:oklch(86% .09 305)}.inspector-text-chip{position:fixed;transform:translateY(-100%);display:inline-flex;gap:5px;align-items:center;padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f0;color:#e4e4e9;font-size:9px;font-weight:500;line-height:1;white-space:nowrap;pointer-events:none}.inspector-text-chip__swatch{width:7px;height:7px;border-radius:999px;border:1px solid oklch(100% 0 0 / .16);flex:0 0 auto}.inspector-connector{position:fixed;border-color:#539af2b8;border-style:dashed;pointer-events:none}.inspector-connector--vertical{border-left-width:1px;width:0}.inspector-connector--horizontal{border-top-width:1px;height:0}.inspector-distance-line{position:fixed;background:var(--inspector-blue);pointer-events:none}.inspector-distance-line--horizontal{height:1px}.inspector-distance-line--vertical{width:1px}.inspector-distance-tag{position:fixed;transform:translate(-50%);padding:3px 6px;border-radius:999px;border:1px solid var(--inspector-panel-edge);background:#0e0f15f2;color:var(--inspector-text);font-size:9px;font-weight:520;line-height:1;pointer-events:none}.inspector-distance-tag--vertical{transform:translateY(-50%)}.inspector-guide{position:fixed;margin:0;padding:0;border:0;background:transparent;pointer-events:auto;cursor:grab}.inspector-guide--vertical{top:0;width:14px;height:100vh;transform:translate(-50%)}.inspector-guide--horizontal{left:0;width:100vw;height:14px;transform:translateY(-50%)}.inspector-guide--preview{opacity:.55;pointer-events:none;cursor:default}.inspector-guide--preview .inspector-guide-line{background:color-mix(in srgb,var(--inspector-guide, #ff7a00) 72%,transparent)}.inspector-guide-line{position:absolute;inset:0;pointer-events:none}.inspector-guide--vertical .inspector-guide-line{left:calc(50% - .5px);width:1px;height:100%;background:var(--inspector-guide, #ff7a00)}.inspector-guide--horizontal .inspector-guide-line{top:calc(50% - .5px);width:100%;height:1px;background:var(--inspector-guide, #ff7a00)}.inspector-guide--selected .inspector-guide-line{box-shadow:0 0 0 1px #ffffff80}\n"] }]
1381
1427
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1382
1428
  type: Inject,
1383
1429
  args: [PLATFORM_ID]
@@ -1392,9 +1438,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1392
1438
  }], handleKeydown: [{
1393
1439
  type: HostListener,
1394
1440
  args: ['window:keydown', ['$event']]
1395
- }], handleKeyup: [{
1396
- type: HostListener,
1397
- args: ['window:keyup', ['$event']]
1398
1441
  }], handlePointerMove: [{
1399
1442
  type: HostListener,
1400
1443
  args: ['window:pointermove', ['$event']]