@bendyline/gezel-service 1.0.2 → 1.0.4

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.
Files changed (88) hide show
  1. package/dist/bin/gezeld.js +17797 -16874
  2. package/dist/handboek-content/whats-new/1.26226.md +89 -0
  3. package/dist/handboek.js +13 -2
  4. package/dist/index-store/static-index-worker.js +8 -5
  5. package/dist/index.d.ts +109 -7
  6. package/dist/index.js +17797 -16874
  7. package/dist/memory/embed-worker.js +22 -3
  8. package/dist/providers/mlx/python/gezel_mlx_server.py +154 -22
  9. package/dist/ui/assets/{TerminalCodeEditor-BpkIEKrW.js → TerminalCodeEditor-BuMcfTS4.js} +2 -2
  10. package/dist/ui/assets/{_.contribution-DESswd3T.js → _.contribution-CZO2XAKt.js} +1 -1
  11. package/dist/ui/assets/{chunk-6N2J7C2B-Du7clJkV.js → chunk-6N2J7C2B-BNHR_rFP.js} +1 -1
  12. package/dist/ui/assets/chunk-ILCJ3WFD-CUnKgI_I.js +4 -0
  13. package/dist/ui/assets/chunk-S5PCVMKU-i2wfHmvU.js +6 -0
  14. package/dist/ui/assets/{chunk-WATAOG4Y-BnCgSncI.js → chunk-WATAOG4Y-BbL-tDgQ.js} +1 -1
  15. package/dist/ui/assets/{cpp.contribution-DazoHQwn.js → cpp.contribution-BJzhk0Zj.js} +1 -1
  16. package/dist/ui/assets/{csharp.contribution-B64MdTmq.js → csharp.contribution-BR9K2qKj.js} +1 -1
  17. package/dist/ui/assets/{css.contribution-u617lXYH.js → css.contribution-CfkVmdah.js} +1 -1
  18. package/dist/ui/assets/{cssMode-Cf_QqRjJ.js → cssMode-MMeGUmV2.js} +1 -1
  19. package/dist/ui/assets/dist-8uH4DcHx.js +2 -0
  20. package/dist/ui/assets/dist-CFOmf7nD.js +222 -0
  21. package/dist/ui/assets/{dockerfile.contribution-P8T1FxHz.js → dockerfile.contribution-IZMl57B5.js} +1 -1
  22. package/dist/ui/assets/docx-BEJpkI6I.js +2 -0
  23. package/dist/ui/assets/extract-UTAOG7LV-BY3SCkzz.js +1 -0
  24. package/dist/ui/assets/{go.contribution-BqqmPpYF.js → go.contribution-BxCBwhZs.js} +1 -1
  25. package/dist/ui/assets/{handlebars-B9qcPqjD.js → handlebars-CreIkams.js} +1 -1
  26. package/dist/ui/assets/handlebars.contribution-BGlyL-dm.js +2 -0
  27. package/dist/ui/assets/{html-Fp2jEZ7j.js → html-BSrz1IKi.js} +1 -1
  28. package/dist/ui/assets/html.contribution-CucOMFQ_.js +2 -0
  29. package/dist/ui/assets/{htmlMode-B5cPhGim.js → htmlMode-DRG7XY5Z.js} +1 -1
  30. package/dist/ui/assets/{index-CQSh1NUQ.js → index-Bqu-32S3.js} +197 -191
  31. package/dist/ui/assets/index-DTicLc4o.css +1 -0
  32. package/dist/ui/assets/infer-D6e75m-s.js +2 -0
  33. package/dist/ui/assets/{ini.contribution-XkZYQphY.js → ini.contribution-CGX5OdXM.js} +1 -1
  34. package/dist/ui/assets/{java.contribution-CUQitE0a.js → java.contribution-CVhfJ_us.js} +1 -1
  35. package/dist/ui/assets/{javascript-CcBUpTjJ.js → javascript-QelFp9t5.js} +1 -1
  36. package/dist/ui/assets/javascript.contribution--no0ijCu.js +2 -0
  37. package/dist/ui/assets/{jsonMode-D9SbmDW6.js → jsonMode-T4Ss3lDu.js} +1 -1
  38. package/dist/ui/assets/{kotlin.contribution-B9AYd3Yp.js → kotlin.contribution-DxFbGDYA.js} +1 -1
  39. package/dist/ui/assets/layouts-2A7QNF6Y-CWQp8HDd.js +1 -0
  40. package/dist/ui/assets/{less.contribution-DtKQK3HF.js → less.contribution-g9R8XRZf.js} +1 -1
  41. package/dist/ui/assets/{lua.contribution-DxFFDcBW.js → lua.contribution-YqDsEy8Z.js} +1 -1
  42. package/dist/ui/assets/{markdown.contribution-B7aCxle-.js → markdown.contribution-DboXnPnx.js} +1 -1
  43. package/dist/ui/assets/{monaco-BBFILBn6.js → monaco-BdFw56DI.js} +3 -3
  44. package/dist/ui/assets/{monaco-base-CvsKN-Z-.js → monaco-base-DrP3D13F.js} +1 -1
  45. package/dist/ui/assets/{monaco-setup-BeHgXlpG.js → monaco-setup-QyF22y9h.js} +1 -1
  46. package/dist/ui/assets/{monaco.contribution-BBrbIBfd.js → monaco.contribution-BkqIxESv.js} +2 -2
  47. package/dist/ui/assets/{monaco.contribution-B-c9k_-7.js → monaco.contribution-CMzPFHtO.js} +2 -2
  48. package/dist/ui/assets/{monaco.contribution-Baa3Cv83.js → monaco.contribution-FA_ESP-W.js} +2 -2
  49. package/dist/ui/assets/{monaco.contribution-DRZnYNPl.js → monaco.contribution-XEpc63ty.js} +2 -2
  50. package/dist/ui/assets/{php.contribution-vC08ovbS.js → php.contribution-rnpik0Kk.js} +1 -1
  51. package/dist/ui/assets/pptx-DZdEoDP9.js +6 -0
  52. package/dist/ui/assets/{python-CevkXHVb.js → python-CF7X5t9Q.js} +1 -1
  53. package/dist/ui/assets/python.contribution-CyJGCfSq.js +2 -0
  54. package/dist/ui/assets/{ruby.contribution-BMZvE4z1.js → ruby.contribution-4ZyPGu2E.js} +1 -1
  55. package/dist/ui/assets/{rust.contribution-DOWKjtrn.js → rust.contribution-Cl_B3X2G.js} +1 -1
  56. package/dist/ui/assets/{scss.contribution-BXLJWEv0.js → scss.contribution-BO02gVLZ.js} +1 -1
  57. package/dist/ui/assets/{shell.contribution-gbqcscnj.js → shell.contribution-Dn9Y0uHs.js} +1 -1
  58. package/dist/ui/assets/{sql.contribution-DO39C_-u.js → sql.contribution-Bog_5Rc8.js} +1 -1
  59. package/dist/ui/assets/{swift.contribution-D4Vjb2VA.js → swift.contribution-CfiAr7AX.js} +1 -1
  60. package/dist/ui/assets/{terminal-monaco-setup-Bb4lnoOq.js → terminal-monaco-setup-B-EnkGiy.js} +1 -1
  61. package/dist/ui/assets/{tsMode-BAHQHAnm.js → tsMode-B2WuLuPL.js} +1 -1
  62. package/dist/ui/assets/{typescript-15FhCrR2.js → typescript-Bv_J1tKT.js} +1 -1
  63. package/dist/ui/assets/typescript.contribution-CM0XQCYi.js +2 -0
  64. package/dist/ui/assets/xlsx-DDBRN-IU.js +4 -0
  65. package/dist/ui/assets/{xml-BA1mrkDo.js → xml-DMV-f4tm.js} +1 -1
  66. package/dist/ui/assets/xml.contribution-QqmOB9gT.js +2 -0
  67. package/dist/ui/assets/{yaml-CIqCv-ro.js → yaml-Bb6mZXY5.js} +1 -1
  68. package/dist/ui/assets/yaml.contribution-DCDnWhHR.js +2 -0
  69. package/dist/ui/index.html +11 -11
  70. package/package.json +13 -13
  71. package/dist/ui/assets/chunk-ILCJ3WFD-fHFoZ9wm.js +0 -4
  72. package/dist/ui/assets/chunk-S5PCVMKU-DopU3Q9j.js +0 -6
  73. package/dist/ui/assets/dist-DB6xxrlD.js +0 -2
  74. package/dist/ui/assets/dist-DucbO86I.js +0 -222
  75. package/dist/ui/assets/docx-IZY6hX8A.js +0 -2
  76. package/dist/ui/assets/extract-UTAOG7LV-BZ_L7lLL.js +0 -1
  77. package/dist/ui/assets/handlebars.contribution-vZslMuRE.js +0 -2
  78. package/dist/ui/assets/html.contribution-B1GzaEV-.js +0 -2
  79. package/dist/ui/assets/index-Ch0qGtVJ.css +0 -1
  80. package/dist/ui/assets/infer-v-bCXeT9.js +0 -2
  81. package/dist/ui/assets/javascript.contribution-D6DhUpPP.js +0 -2
  82. package/dist/ui/assets/layouts-2A7QNF6Y-D94iKLLQ.js +0 -1
  83. package/dist/ui/assets/pptx-CsdVR0xn.js +0 -6
  84. package/dist/ui/assets/python.contribution-C6TUOYNZ.js +0 -2
  85. package/dist/ui/assets/typescript.contribution-D30L44Mw.js +0 -2
  86. package/dist/ui/assets/xlsx-CdLmEC42.js +0 -4
  87. package/dist/ui/assets/xml.contribution-CN9NFcUA.js +0 -2
  88. package/dist/ui/assets/yaml.contribution-BsLB8vrs.js +0 -2
@@ -76,12 +76,26 @@ var PipelineLoadError = class extends Error {
76
76
  * damaged runtime.
77
77
  */
78
78
  optionalPeerMissing;
79
- constructor(message, optionalPeerMissing = false) {
79
+ /**
80
+ * Network/model-registry failures can clear without a process restart. The
81
+ * host uses this bit to apply a short retry cooldown instead of permanently
82
+ * disabling embeddings after one failed first-use download.
83
+ */
84
+ retryable;
85
+ constructor(message, optionalPeerMissing = false, retryable = false) {
80
86
  super(message);
81
87
  this.name = "PipelineLoadError";
82
88
  this.optionalPeerMissing = optionalPeerMissing;
89
+ this.retryable = retryable;
83
90
  }
84
91
  };
92
+ function isRetryablePipelineLoadFailure(error) {
93
+ const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
94
+ const code = error?.code ?? "";
95
+ return /(?:ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|UND_ERR_|fetch failed|network(?: request)? failed|socket hang up|timed?\s*out|HTTP\s+(?:408|425|429|5\d\d)|TLS|SSL|certificate)/i.test(
96
+ `${code} ${message}`
97
+ );
98
+ }
85
99
  var pipelinePromise = null;
86
100
  async function loadPipeline() {
87
101
  if (!pipelinePromise) {
@@ -96,7 +110,11 @@ async function loadPipeline() {
96
110
  } catch (err) {
97
111
  const missing = isMissingModule(err, TRANSFORMERS_MODULE);
98
112
  const message = missing ? "Local memory embeddings are an optional npm feature. Install @huggingface/transformers@^3.8.1 alongside @bendyline/gezel-service (see the service README)." : err instanceof Error ? err.message : String(err);
99
- throw new PipelineLoadError(message, missing);
113
+ throw new PipelineLoadError(
114
+ message,
115
+ missing,
116
+ !missing && isRetryablePipelineLoadFailure(err)
117
+ );
100
118
  }
101
119
  })();
102
120
  pipelinePromise.catch(() => {
@@ -135,7 +153,8 @@ port.on("message", (msg) => {
135
153
  port.postMessage({
136
154
  id: msg.id,
137
155
  error: err instanceof Error ? err.message : String(err),
138
- fatal: err instanceof PipelineLoadError,
156
+ fatal: err instanceof PipelineLoadError && !err.retryable,
157
+ retryable: err instanceof PipelineLoadError && err.retryable,
139
158
  optionalPeerMissing: err instanceof PipelineLoadError && err.optionalPeerMissing
140
159
  });
141
160
  }
@@ -368,6 +368,16 @@ print("Model and processor loaded successfully.", flush=True)
368
368
  # never piles KV past the point where a Metal command-buffer allocation aborts
369
369
  # the whole python process. 0 = unset (no ceiling → admit on width alone).
370
370
  _MEM_LIMIT_BYTES = 0
371
+ # The resident-set target supplied by the TS capacity broker. Keep this
372
+ # separately from the allocation ceiling: mlx_lm's BatchGenerator currently
373
+ # overwrites the process wired limit with Metal's full recommended working set
374
+ # during construction, so the Gezel policy must be reapplied afterwards.
375
+ _WIRED_LIMIT_BYTES = 0
376
+ # MLX keeps freed Metal buffers for reuse in a process-global cache. That is
377
+ # useful, but an unbounded pool made a ~62 GB working set retain another
378
+ # ~45 GB until mlx_lm's coarse 512-step clear, producing a 65 -> 120 GB
379
+ # sawtooth. This cap is intentionally distinct from the prompt/KV cache budget.
380
+ _MLX_BUFFER_CACHE_LIMIT_BYTES = 0
371
381
  # Throttle a multi-sub wave down to serial once live allocation reaches this
372
382
  # fraction of the ceiling. Leaves headroom for the wave's own prefill/compute
373
383
  # activation buffers, which land on top of already-resident weights + KV.
@@ -407,7 +417,15 @@ def _safe_cache_memory() -> int:
407
417
  return 0
408
418
 
409
419
 
410
- def _log_memory(phase: str) -> None:
420
+ def _safe_peak_memory() -> int:
421
+ """Peak MLX allocation in bytes, or 0 if unavailable."""
422
+ try:
423
+ return int(mx.get_peak_memory())
424
+ except Exception: # noqa: BLE001 — introspection is best-effort
425
+ return 0
426
+
427
+
428
+ def _log_memory(phase: str, cache_before: Optional[int] = None) -> None:
411
429
  """One line of memory truth per turn.
412
430
 
413
431
  Nothing observed this engine between startup and the next restart, so a
@@ -418,17 +436,91 @@ def _log_memory(phase: str) -> None:
418
436
  """
419
437
  active = _safe_active_memory()
420
438
  cached = _safe_cache_memory()
439
+ peak = _safe_peak_memory()
421
440
  if active <= 0 and cached <= 0:
422
441
  return
423
442
  mb = 1024 * 1024
424
443
  ceiling = f", ceiling={_MEM_LIMIT_BYTES // mb}MB" if _MEM_LIMIT_BYTES > 0 else ""
444
+ wired = f", wired_limit={_WIRED_LIMIT_BYTES // mb}MB" if _WIRED_LIMIT_BYTES > 0 else ""
445
+ cache_limit = (
446
+ f", cache_limit={_MLX_BUFFER_CACHE_LIMIT_BYTES // mb}MB"
447
+ if _MLX_BUFFER_CACHE_LIMIT_BYTES > 0
448
+ else ""
449
+ )
450
+ peak_text = f" peak={peak // mb}MB" if peak > 0 else ""
451
+ reclaimed_text = (
452
+ f" cache_before={cache_before // mb}MB"
453
+ if cache_before is not None and cache_before > cached
454
+ else ""
455
+ )
425
456
  print(
426
457
  f"[mem] {phase}: active={active // mb}MB cache={cached // mb}MB "
427
- f"total={(active + cached) // mb}MB{ceiling}",
458
+ f"total={(active + cached) // mb}MB{peak_text}{reclaimed_text}"
459
+ f"{ceiling}{wired}{cache_limit}",
428
460
  flush=True,
429
461
  )
430
462
 
431
463
 
464
+ def _apply_mlx_memory_policy(phase: str) -> None:
465
+ """Apply Gezel's process-wide MLX memory policy.
466
+
467
+ This is deliberately idempotent. In particular it is called immediately
468
+ after BatchGenerator construction because mlx_lm resets the wired limit in
469
+ its constructor. Every MLX call is guarded for older sidecar runtimes.
470
+ """
471
+ if _WIRED_LIMIT_BYTES > 0:
472
+ set_wired = getattr(mx, "set_wired_limit", None)
473
+ if set_wired is not None:
474
+ try:
475
+ set_wired(_WIRED_LIMIT_BYTES)
476
+ except Exception as exc: # noqa: BLE001
477
+ print(f"[mem] {phase} set_wired_limit skipped: {exc}", flush=True)
478
+ if _MLX_BUFFER_CACHE_LIMIT_BYTES > 0:
479
+ set_cache = getattr(mx, "set_cache_limit", None)
480
+ if set_cache is not None:
481
+ try:
482
+ set_cache(_MLX_BUFFER_CACHE_LIMIT_BYTES)
483
+ except Exception as exc: # noqa: BLE001
484
+ print(f"[mem] {phase} set_cache_limit skipped: {exc}", flush=True)
485
+
486
+
487
+ def _reclaim_mlx_buffer_cache(
488
+ phase: str, force: bool = False, log: bool = False
489
+ ) -> bool:
490
+ """Release MLX's free-buffer pool at a safe boundary or under pressure.
491
+
492
+ Active allocations (model weights and live KV state) are untouched.
493
+ `force` is used once a batch turn is fully drained; during generation we
494
+ clear only when total MLX memory crosses the admission threshold or the
495
+ runtime has temporarily exceeded the configured free-buffer cap.
496
+ """
497
+ active = _safe_active_memory()
498
+ cached = _safe_cache_memory()
499
+ under_pressure = (
500
+ _MEM_LIMIT_BYTES > 0
501
+ and active + cached >= _MEM_LIMIT_BYTES * _MEM_ADMIT_FRACTION
502
+ )
503
+ over_cache_limit = (
504
+ _MLX_BUFFER_CACHE_LIMIT_BYTES > 0
505
+ and cached > _MLX_BUFFER_CACHE_LIMIT_BYTES
506
+ )
507
+ reclaimed = False
508
+ if force or under_pressure or over_cache_limit:
509
+ clear_cache = getattr(mx, "clear_cache", None)
510
+ if clear_cache is not None:
511
+ try:
512
+ clear_cache()
513
+ reclaimed = True
514
+ except Exception as exc: # noqa: BLE001
515
+ print(f"[mem] {phase} clear_cache skipped: {exc}", flush=True)
516
+ # Turn boundaries and actual pressure events are useful telemetry. A
517
+ # healthy periodic probe should stay silent instead of writing one line
518
+ # every 32 decode steps.
519
+ if log or force or under_pressure or over_cache_limit:
520
+ _log_memory(phase, cache_before=cached if reclaimed else None)
521
+ return reclaimed
522
+
523
+
432
524
  def _setup_gpu_memory_ceiling() -> None:
433
525
  """Resolve the effective memory ceiling and the wired limit.
434
526
 
@@ -445,31 +537,42 @@ def _setup_gpu_memory_ceiling() -> None:
445
537
  resident, not what the engine is allowed to allocate. Falls back to the
446
538
  ceiling only when the supervisor passed no plan (unreadable geometry).
447
539
  """
448
- global _MEM_LIMIT_BYTES
540
+ global _MEM_LIMIT_BYTES, _WIRED_LIMIT_BYTES, _MLX_BUFFER_CACHE_LIMIT_BYTES
449
541
  recommended = _metal_recommended_working_set()
450
542
  arg_limit = max(0, int(getattr(ARGS, "gpu_memory_limit_mb", 0) or 0)) * 1024 * 1024
451
543
  candidates = [b for b in (recommended, arg_limit) if b > 0]
452
544
  _MEM_LIMIT_BYTES = min(candidates) if candidates else 0
453
545
  planned = max(0, int(getattr(ARGS, "wired_limit_mb", 0) or 0)) * 1024 * 1024
454
- wired_target = min(planned, _MEM_LIMIT_BYTES) if planned > 0 else _MEM_LIMIT_BYTES
455
- # Wire the resident set so it isn't paged out under pressure — Apple's
456
- # recommended setting for steady-state inference. Guarded: harmless to
457
- # skip if the call is missing or rejects the value.
458
- if wired_target > 0:
459
- set_wired = getattr(mx, "set_wired_limit", None)
460
- if set_wired is not None:
461
- try:
462
- set_wired(wired_target)
463
- except Exception as exc: # noqa: BLE001
464
- print(f"[mem] set_wired_limit skipped: {exc}", flush=True)
546
+ _WIRED_LIMIT_BYTES = (
547
+ min(planned, _MEM_LIMIT_BYTES)
548
+ if planned > 0 and _MEM_LIMIT_BYTES > 0
549
+ else planned or _MEM_LIMIT_BYTES
550
+ )
551
+ # Retain a small amount of free Metal storage for fast reuse, scaled to
552
+ # the planned working set but never allowed to become a second model-sized
553
+ # pool. Current 27B geometry resolves to just under 4 GB.
554
+ cache_scale = _WIRED_LIMIT_BYTES or _MEM_LIMIT_BYTES
555
+ if cache_scale > 0:
556
+ _MLX_BUFFER_CACHE_LIMIT_BYTES = max(
557
+ 256 * 1024 * 1024,
558
+ min(4 * 1024 * 1024 * 1024, cache_scale // 16),
559
+ )
560
+ else:
561
+ _MLX_BUFFER_CACHE_LIMIT_BYTES = 1024 * 1024 * 1024
562
+ _apply_mlx_memory_policy("startup")
465
563
  print(
466
564
  f"[mem] gpu ceiling={_MEM_LIMIT_BYTES // (1024 * 1024)}MB "
467
565
  f"(budget={arg_limit // (1024 * 1024)}MB, "
468
566
  f"metal_recommended={recommended // (1024 * 1024)}MB, "
469
- f"wired={wired_target // (1024 * 1024)}MB, "
567
+ f"wired={_WIRED_LIMIT_BYTES // (1024 * 1024)}MB, "
568
+ f"buffer_cache_limit={_MLX_BUFFER_CACHE_LIMIT_BYTES // (1024 * 1024)}MB, "
470
569
  f"active={_safe_active_memory() // (1024 * 1024)}MB)",
471
570
  flush=True,
472
571
  )
572
+ # Model loading happened before this policy was known. Drop any free
573
+ # compilation/loading buffers it left behind so the first turn starts from
574
+ # the same bounded baseline as every later turn.
575
+ _reclaim_mlx_buffer_cache("startup-ready", force=True)
473
576
 
474
577
 
475
578
  _setup_gpu_memory_ceiling()
@@ -981,6 +1084,10 @@ class BatchEngine:
981
1084
  prefill_batch_size=self._max,
982
1085
  prefill_step_size=ARGS.prefill_step_size,
983
1086
  )
1087
+ # mlx_lm BatchGenerator sets the wired limit to Metal's entire
1088
+ # recommended working set in its constructor. Restore the smaller
1089
+ # resident-set plan and free-buffer cap selected by Gezel.
1090
+ _apply_mlx_memory_policy("batch-init")
984
1091
  self._subs = {} # uid -> _Sub
985
1092
  self._pending = [] # _Sub awaiting insert
986
1093
  self._wake = asyncio.Event()
@@ -1004,6 +1111,7 @@ class BatchEngine:
1004
1111
  self._prefill_total = 0 # new tokens the active wave is prefilling
1005
1112
  self._prefill_done = {} # uid → tokens prefilled so far (this wave)
1006
1113
  self._last_prefill_emit = 0.0
1114
+ self._memory_check_steps = 0
1007
1115
  print(
1008
1116
  f"[batch] engine ready max_concurrency={self._max} "
1009
1117
  f"stop_tokens={len(stop_tokens)} (+{len(eos_from_cfg)} from generation_config"
@@ -1018,6 +1126,10 @@ class BatchEngine:
1018
1126
  self._pending.append(sub)
1019
1127
  self._wake.set()
1020
1128
 
1129
+ def is_idle(self):
1130
+ """True once no live or queued batch sub can still use scratch buffers."""
1131
+ return not self._subs and not self._pending
1132
+
1021
1133
  def _sampler_for(self, request):
1022
1134
  from mlx_lm.sample_utils import make_sampler
1023
1135
 
@@ -1138,10 +1250,7 @@ class BatchEngine:
1138
1250
  if active >= threshold:
1139
1251
  # Already tight before this wave even starts — reclaim any freed
1140
1252
  # buffer cache and re-check once before forcing serial.
1141
- try:
1142
- mx.clear_cache()
1143
- except Exception: # noqa: BLE001
1144
- pass
1253
+ _reclaim_mlx_buffer_cache("batch-admission", force=True)
1145
1254
  active = _safe_active_memory()
1146
1255
  return 1 if active >= threshold else pending
1147
1256
 
@@ -1244,6 +1353,14 @@ class BatchEngine:
1244
1353
  sub.queue.put_nowait(("err", str(exc)))
1245
1354
  self._subs.clear()
1246
1355
  continue
1356
+ # set_cache_limit bounds future reuse, while this periodic
1357
+ # pressure check also catches temporary overshoot during a
1358
+ # long prefill/decode. It replaces reliance on mlx_lm's much
1359
+ # coarser 512-generation-step cache clear.
1360
+ self._memory_check_steps += 1
1361
+ if self._memory_check_steps >= 32:
1362
+ self._memory_check_steps = 0
1363
+ _reclaim_mlx_buffer_cache("batch-pressure")
1247
1364
  for pr in prompt_responses:
1248
1365
  progress = getattr(pr, "progress", None)
1249
1366
  has_progress = isinstance(progress, tuple) and len(progress) == 2
@@ -1499,6 +1616,12 @@ async def _batched_stream_iter(sub: "_Sub"):
1499
1616
  # Release the eviction pins taken for this turn's cache + prefix.
1500
1617
  _unmark_inflight(sub.pinned_cache_ids)
1501
1618
  sub.pinned_cache_ids = []
1619
+ engine = _BATCH_ENGINE
1620
+ _reclaim_mlx_buffer_cache(
1621
+ "batch-turn-end",
1622
+ force=engine is None or engine.is_idle(),
1623
+ log=True,
1624
+ )
1502
1625
 
1503
1626
 
1504
1627
  async def _await_batched_completion(sub: "_Sub") -> None:
@@ -1520,6 +1643,12 @@ async def _await_batched_completion(sub: "_Sub") -> None:
1520
1643
  sub.cancelled = True
1521
1644
  _unmark_inflight(sub.pinned_cache_ids)
1522
1645
  sub.pinned_cache_ids = []
1646
+ engine = _BATCH_ENGINE
1647
+ _reclaim_mlx_buffer_cache(
1648
+ "batch-warm-end",
1649
+ force=engine is None or engine.is_idle(),
1650
+ log=True,
1651
+ )
1523
1652
 
1524
1653
 
1525
1654
  _BATCH_ENGINE: "Optional[BatchEngine]" = None
@@ -2440,13 +2569,16 @@ async def chat_completions(request: ChatRequest, http_request: Request):
2440
2569
  flush=True,
2441
2570
  )
2442
2571
  else:
2443
- mx.clear_cache()
2444
- print("Stream finished, cleared cache.", flush=True)
2572
+ print("Stream finished without a prompt-cache save.", flush=True)
2445
2573
  # Release the eviction pins taken for this turn — AFTER the save
2446
2574
  # above, so this turn's own _save_cache → _enforce_budget can't
2447
2575
  # evict the entry it just wrote.
2448
2576
  _unmark_inflight(pinned_cache_ids)
2449
- _log_memory("turn-end")
2577
+ # Agentic tool loops issue multiple HTTP sub-turns inside one user
2578
+ # turn. Reclaim scratch buffers at every one of those boundaries,
2579
+ # including the cache-preserving path above; prompt KV remains an
2580
+ # active allocation and is not touched by clear_cache().
2581
+ _reclaim_mlx_buffer_cache("turn-end", force=True, log=True)
2450
2582
 
2451
2583
  return StreamingResponse(
2452
2584
  stream_iter(),
@@ -1,3 +1,3 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/terminal-monaco-setup-Bb4lnoOq.js","assets/index-CQSh1NUQ.js","assets/rolldown-runtime-aKtaBQYM.js","assets/dist-DucbO86I.js","assets/dist-DB6xxrlD.js","assets/chunk-S5PCVMKU-DopU3Q9j.js","assets/chunk-7AWFHP5U-MiVVPFTx.js","assets/jszip.min-DhiFe-R7.js","assets/doc-B7NXSLxH.js","assets/chunk-O7JILDEF-CqcO1qaI.js","assets/chunk-BAOV476U-yPHu-ECL.js","assets/chunk-4VOD55SX-BFSSw0c8.js","assets/chunk-GAZKTT4R-BUf32614.js","assets/chunk-6MVWWZHL-BtFOxGE8.js","assets/chunk-XRW6P7IF-BeQQgMVK.js","assets/markdown-ekej7NJt.js","assets/schemas-Drh23Boe.js","assets/preload-helper-Czpn1I53.js","assets/pptx-CsdVR0xn.js","assets/chunk-USU6HTKB-B-ElCUQS.js","assets/chunk-JU2RHXUB-CMFDhTux.js","assets/chunk-DWNNYO5H-C9-5Gy65.js","assets/chunk-ILCJ3WFD-fHFoZ9wm.js","assets/chunk-IIQYS2YH-CPXng8SW.js","assets/storage-DUIC1aL6.js","assets/chunk-AONELFLA-Cv2nS9ga.js","assets/chunk-6RQOV3B3-CwvKotJw.js","assets/chunk-6N2J7C2B-Du7clJkV.js","assets/transform-MBfVXq54.js","assets/container-CKiqsJHV.js","assets/docx-IZY6hX8A.js","assets/html-Cgejr9YM.js","assets/pdf-66KslaXf.js","assets/chunk-KXOZMWBS-BwD4KMLI.js","assets/index-Ch0qGtVJ.css","assets/monaco-BBFILBn6.js","assets/iconLabel-uMn49Ame.js","assets/iconLabel-Bdh_-Hrb.css","assets/codiconStyles-104B1IQ5.js","assets/codiconStyles-Bp1tMeMk.css","assets/monaco-BBUd89IN.css","assets/monaco-base-CvsKN-Z-.js"])))=>i.map(i=>d[i]);
2
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{t}from"./preload-helper-Czpn1I53.js";import{c as n,l as r,o as i}from"./index-CQSh1NUQ.js";var a=e(r(),1),o=n();function s(e,t){let n=t.getLineCount(),r={lineNumber:n,column:t.getLineMaxColumn(n)};e.setPosition(r),e.revealPosition(r)}var c=(0,a.forwardRef)(function({projectId:e,initialValue:n,placeholder:r,className:c,onChange:l,onSubmit:u,onHistoryPrev:d,onHistoryNext:f,onChatEscape:p,onReady:m},h){let g=(0,a.useRef)(null),_=(0,a.useRef)(null),v=(0,a.useRef)(null),y=(0,a.useRef)(null),[,b]=(0,a.useState)(!1),x=i(),S=(0,a.useRef)(l),C=(0,a.useRef)(u),w=(0,a.useRef)(d),T=(0,a.useRef)(f),E=(0,a.useRef)(p),D=(0,a.useRef)(m);(0,a.useEffect)(()=>{S.current=l,C.current=u,w.current=d,T.current=f,E.current=p,D.current=m});let O=(0,a.useRef)(n),k=(0,a.useRef)(r),A=(0,a.useRef)(n.length),j=(0,a.useRef)(x);return j.current=x,(0,a.useEffect)(()=>{let n=!1,r=[];return(async()=>{let i;try{i=await t(()=>import(`./terminal-monaco-setup-Bb4lnoOq.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41])),await i.ensureTerminalMonaco()}catch{return}if(n||!g.current)return;let a=i.monaco;_.current=a;let o=i.terminalModelUri(e);a.editor.getModel(o)?.dispose();let c=a.editor.createModel(O.current,`gezel-terminal`,o);y.current=c;let l=a.editor.create(g.current,{model:c,automaticLayout:!0,lineNumbers:`off`,glyphMargin:!1,folding:!1,minimap:{enabled:!1},lineDecorationsWidth:0,lineNumbersMinChars:0,renderLineHighlight:`none`,scrollBeyondLastLine:!1,overviewRulerLanes:0,hideCursorInOverviewRuler:!0,scrollbar:{vertical:`auto`,horizontal:`hidden`,verticalScrollbarSize:6,useShadows:!1},wordWrap:`on`,fontSize:13.6,fontFamily:`var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)`,lineHeight:21,padding:{top:6,bottom:6},fixedOverflowWidgets:!0,quickSuggestions:{other:!0,comments:!1,strings:!0},suggestOnTriggerCharacters:!0,acceptSuggestionOnEnter:`off`,tabCompletion:`on`,contextmenu:!1,roundedSelection:!1,guides:{indentation:!1},renderWhitespace:`none`,occurrencesHighlight:`off`,matchBrackets:`never`});v.current=l,a.editor.setTheme(j.current===`dark`?`gezel-terminal-dark`:`gezel-terminal-light`),l.addCommand(a.KeyCode.Enter,()=>C.current(c.getValue())),l.addCommand(a.KeyMod.Shift|a.KeyCode.Enter,()=>l.trigger(`keyboard`,`type`,{text:`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/terminal-monaco-setup-B-EnkGiy.js","assets/index-Bqu-32S3.js","assets/rolldown-runtime-aKtaBQYM.js","assets/dist-CFOmf7nD.js","assets/dist-8uH4DcHx.js","assets/doc-B7NXSLxH.js","assets/chunk-O7JILDEF-CqcO1qaI.js","assets/chunk-BAOV476U-yPHu-ECL.js","assets/chunk-4VOD55SX-BFSSw0c8.js","assets/chunk-GAZKTT4R-BUf32614.js","assets/chunk-6MVWWZHL-BtFOxGE8.js","assets/chunk-XRW6P7IF-BeQQgMVK.js","assets/markdown-ekej7NJt.js","assets/schemas-Drh23Boe.js","assets/preload-helper-Czpn1I53.js","assets/pptx-DZdEoDP9.js","assets/chunk-USU6HTKB-B-ElCUQS.js","assets/chunk-7AWFHP5U-MiVVPFTx.js","assets/jszip.min-DhiFe-R7.js","assets/chunk-JU2RHXUB-CMFDhTux.js","assets/chunk-DWNNYO5H-C9-5Gy65.js","assets/chunk-S5PCVMKU-i2wfHmvU.js","assets/chunk-ILCJ3WFD-CUnKgI_I.js","assets/chunk-IIQYS2YH-CPXng8SW.js","assets/storage-DUIC1aL6.js","assets/chunk-AONELFLA-Cv2nS9ga.js","assets/chunk-6RQOV3B3-CwvKotJw.js","assets/chunk-6N2J7C2B-BNHR_rFP.js","assets/transform-MBfVXq54.js","assets/container-CKiqsJHV.js","assets/docx-BEJpkI6I.js","assets/html-Cgejr9YM.js","assets/pdf-66KslaXf.js","assets/chunk-KXOZMWBS-BwD4KMLI.js","assets/index-DTicLc4o.css","assets/monaco-BdFw56DI.js","assets/iconLabel-uMn49Ame.js","assets/iconLabel-Bdh_-Hrb.css","assets/codiconStyles-104B1IQ5.js","assets/codiconStyles-Bp1tMeMk.css","assets/monaco-BBUd89IN.css","assets/monaco-base-DrP3D13F.js"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{t}from"./preload-helper-Czpn1I53.js";import{c as n,l as r,o as i}from"./index-Bqu-32S3.js";var a=e(r(),1),o=n();function s(e,t){let n=t.getLineCount(),r={lineNumber:n,column:t.getLineMaxColumn(n)};e.setPosition(r),e.revealPosition(r)}var c=(0,a.forwardRef)(function({projectId:e,initialValue:n,placeholder:r,className:c,onChange:l,onSubmit:u,onHistoryPrev:d,onHistoryNext:f,onChatEscape:p,onReady:m},h){let g=(0,a.useRef)(null),_=(0,a.useRef)(null),v=(0,a.useRef)(null),y=(0,a.useRef)(null),[,b]=(0,a.useState)(!1),x=i(),S=(0,a.useRef)(l),C=(0,a.useRef)(u),w=(0,a.useRef)(d),T=(0,a.useRef)(f),E=(0,a.useRef)(p),D=(0,a.useRef)(m);(0,a.useEffect)(()=>{S.current=l,C.current=u,w.current=d,T.current=f,E.current=p,D.current=m});let O=(0,a.useRef)(n),k=(0,a.useRef)(r),A=(0,a.useRef)(n.length),j=(0,a.useRef)(x);return j.current=x,(0,a.useEffect)(()=>{let n=!1,r=[];return(async()=>{let i;try{i=await t(()=>import(`./terminal-monaco-setup-B-EnkGiy.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41])),await i.ensureTerminalMonaco()}catch{return}if(n||!g.current)return;let a=i.monaco;_.current=a;let o=i.terminalModelUri(e);a.editor.getModel(o)?.dispose();let c=a.editor.createModel(O.current,`gezel-terminal`,o);y.current=c;let l=a.editor.create(g.current,{model:c,automaticLayout:!0,lineNumbers:`off`,glyphMargin:!1,folding:!1,minimap:{enabled:!1},lineDecorationsWidth:0,lineNumbersMinChars:0,renderLineHighlight:`none`,scrollBeyondLastLine:!1,overviewRulerLanes:0,hideCursorInOverviewRuler:!0,scrollbar:{vertical:`auto`,horizontal:`hidden`,verticalScrollbarSize:6,useShadows:!1},wordWrap:`on`,fontSize:13.6,fontFamily:`var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)`,lineHeight:21,padding:{top:6,bottom:6},fixedOverflowWidgets:!0,quickSuggestions:{other:!0,comments:!1,strings:!0},suggestOnTriggerCharacters:!0,acceptSuggestionOnEnter:`off`,tabCompletion:`on`,contextmenu:!1,roundedSelection:!1,guides:{indentation:!1},renderWhitespace:`none`,occurrencesHighlight:`off`,matchBrackets:`never`});v.current=l,a.editor.setTheme(j.current===`dark`?`gezel-terminal-dark`:`gezel-terminal-light`),l.addCommand(a.KeyCode.Enter,()=>C.current(c.getValue())),l.addCommand(a.KeyMod.Shift|a.KeyCode.Enter,()=>l.trigger(`keyboard`,`type`,{text:`
3
3
  `}));let u=l.createContextKey(`terminalAtFirstLine`,!0),d=l.createContextKey(`terminalAtLastLine`,!0),f=()=>{let e=l.getPosition();u.set(!e||e.lineNumber===1),d.set(!e||e.lineNumber===c.getLineCount())};f(),r.push(l.onDidChangeCursorPosition(f)),r.push(c.onDidChangeContent(f)),l.addCommand(a.KeyCode.UpArrow,()=>w.current(),`terminalAtFirstLine && !suggestWidgetVisible`),l.addCommand(a.KeyCode.DownArrow,()=>T.current(),`terminalAtLastLine && !suggestWidgetVisible`),r.push(c.onDidChangeContent(()=>{let e=c.getValue(),t=A.current;if(A.current=e.length,E.current&&t<=1&&e.startsWith(`@`)){E.current();return}S.current?.(e)}));let p=k.current;if(p){let e=document.createElement(`div`);e.className=`terminal-editor-placeholder`,e.textContent=p;let t={getId:()=>`gezel.terminal.placeholder`,getDomNode:()=>e,getPosition:()=>({position:{lineNumber:1,column:1},preference:[a.editor.ContentWidgetPositionPreference.EXACT]})},n=!1,i=()=>{let e=c.getValue()===``;e&&!n?(l.addContentWidget(t),n=!0):!e&&n&&(l.removeContentWidget(t),n=!1)};i(),r.push(c.onDidChangeContent(i)),r.push({dispose:()=>{n&&l.removeContentWidget(t)}})}l.focus(),s(l,c),b(!0),D.current?.()})(),()=>{n=!0;for(let e of r)e.dispose();v.current?.dispose(),v.current=null,y.current?.dispose(),y.current=null}},[e]),(0,a.useEffect)(()=>{_.current?.editor.setTheme(x===`dark`?`gezel-terminal-dark`:`gezel-terminal-light`)},[x]),(0,a.useImperativeHandle)(h,()=>({getValue:()=>y.current?.getValue()??``,setValue:e=>{let t=y.current,n=v.current;t&&(t.setValue(e),A.current=e.length,n&&s(n,t))},focus:()=>v.current?.focus()}),[]),(0,o.jsx)(`div`,{ref:g,className:c??`terminal-editor-host`,"data-testid":`terminal-editor`})});export{c as default};
@@ -1 +1 @@
1
- import{s as e}from"./monaco-BBFILBn6.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={},l={},u=class e{static getOrCreate(t){return l[t]||(l[t]=new e(t)),l[t]}constructor(e){this._languageId=e,this._loadingTriggered=!1,this._lazyLoadPromise=new Promise((e,t)=>{this._lazyLoadPromiseResolve=e,this._lazyLoadPromiseReject=t})}load(){return this._loadingTriggered||(this._loadingTriggered=!0,c[this._languageId].loader().then(e=>this._lazyLoadPromiseResolve(e),e=>this._lazyLoadPromiseReject(e))),this._lazyLoadPromise}};function d(e){let t=e.id;c[t]=e,s.languages.register(e);let n=u.getOrCreate(t);s.languages.registerTokensProviderFactory(t,{create:async()=>(await n.load()).language}),s.languages.onLanguageEncountered(t,async()=>{let e=await n.load();s.languages.setLanguageConfiguration(t,e.conf)})}export{d as t};
1
+ import{s as e}from"./monaco-BdFw56DI.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={},l={},u=class e{static getOrCreate(t){return l[t]||(l[t]=new e(t)),l[t]}constructor(e){this._languageId=e,this._loadingTriggered=!1,this._lazyLoadPromise=new Promise((e,t)=>{this._lazyLoadPromiseResolve=e,this._lazyLoadPromiseReject=t})}load(){return this._loadingTriggered||(this._loadingTriggered=!0,c[this._languageId].loader().then(e=>this._lazyLoadPromiseResolve(e),e=>this._lazyLoadPromiseReject(e))),this._lazyLoadPromise}};function d(e){let t=e.id;c[t]=e,s.languages.register(e);let n=u.getOrCreate(t);s.languages.registerTokensProviderFactory(t,{create:async()=>(await n.load()).language}),s.languages.onLanguageEncountered(t,async()=>{let e=await n.load();s.languages.setLanguageConfiguration(t,e.conf)})}export{d as t};
@@ -1 +1 @@
1
- import{$ as e,D as t,K as n,Q as r,T as i,Z as a,at as o,k as s,nt as c,ot as l,q as u,tt as d}from"./chunk-S5PCVMKU-DopU3Q9j.js";var f={cx:12192e3,cy:6858e3},p=new Set([`dt`,`ftr`,`sldNum`,`hdr`]),m=12,h=4,g=128,_=2,v={x:5,y:4,w:90,h:16.7},y={x:5,y:23.3,w:90,h:66},b=44,x=24,S=22;async function C(e,t){l(t),e>0&&e%g===0&&(await new Promise(e=>setTimeout(e,0)),l(t))}function w(e,n){let r=e.getElementsByTagNameNS(t,n);return r.length>0?r[0]:null}function T(e,t){let n=e.getElementsByTagNameNS(i,t);return n.length>0?n[0]:null}function E(e,t){let n=e?.getAttribute(t);if(!n)return;let r=parseInt(n,10);return Number.isFinite(r)?r:void 0}function D(e,t){let n=e/t*100;return Math.round(Math.max(-10,Math.min(110,n))*100)/100}function O(e,t){return{x:D(e.x,t.cx),y:D(e.y,t.cy),w:D(e.cx,t.cx),h:D(e.cy,t.cy)}}function k(e){let t=w(e,`spPr`);if(!t)return null;let n=T(t,`xfrm`);if(!n)return null;let r=T(n,`off`),i=T(n,`ext`),a=E(r,`x`),o=E(r,`y`),s=E(i,`cx`),c=E(i,`cy`);return a===void 0||o===void 0||s===void 0||c===void 0||s<=0||c<=0?null:{x:a,y:o,cx:s,cy:c}}function A(e){switch(e){case`title`:case`ctrTitle`:return`title`;case`subTitle`:return`subtitle`;case``:case`body`:case`obj`:return`text`;case`pic`:case`clipArt`:case`media`:return`picture`;case`tbl`:return`table`;case`chart`:case`dgm`:return`chart`;default:return`other`}}function j(e){switch(e){case`ctrTitle`:return`title`;case``:case`subTitle`:case`obj`:case`pic`:case`clipArt`:case`media`:case`tbl`:case`chart`:case`dgm`:return`body`;default:return e}}function M(e){let t=T(e,`lvl1pPr`);if(!t)return;let n={},r=t.getAttribute(`algn`);r===`ctr`?n.align=`center`:r===`r`?n.align=`right`:r===`l`&&(n.align=`left`);let i=T(t,`defRPr`),a=E(i,`sz`);a!==void 0&&a>0&&(n.fontSizePt=a/100);let o=i?.getAttribute(`b`);return o===`1`||o===`true`?n.bold=!0:(o===`0`||o===`false`)&&(n.bold=!1),Object.keys(n).length>0?n:void 0}function N(e,t){return e?t?{fontSizePt:e.fontSizePt??t.fontSizePt,bold:e.bold??t.bold,align:e.align??t.align,anchor:e.anchor??t.anchor}:e:t}async function P(e,n,r){l(r);let i={name:``,exact:new Map,baseIdx:new Map,base:new Map},a=await c(e,n);if(!a)return i;i.name=w(a,`cSld`)?.getAttribute(`name`)?.trim()??``;let o=w(a,`txStyles`);if(o){let e=w(o,`titleStyle`),t=w(o,`bodyStyle`);e&&(i.titleStyle=M(e)),t&&(i.bodyStyle=M(t))}let s=a.getElementsByTagNameNS(t,`sp`);for(let e=0;e<s.length;e++){await C(e,r);let t=s[e],n=w(t,`ph`);if(!n)continue;let a=n.getAttribute(`type`)??``,o=E(n,`idx`)??0,c={rect:k(t)},l=w(t,`txBody`),u=l?T(l,`lstStyle`):null;u&&(c.style=M(u));let d=`${a||`body`}:${o}`;i.exact.has(d)||i.exact.set(d,c);let f=j(a),p=`${f}:${o}`;i.baseIdx.has(p)||i.baseIdx.set(p,c),i.base.has(f)||i.base.set(f,c)}return i}function F(e,t){let n=T(e,`srgbClr`)?.getAttribute(`val`);if(n&&/^[0-9a-fA-F]{6}$/.test(n))return`#${n.toLowerCase()}`;let r=T(e,`schemeClr`)?.getAttribute(`val`);if(r&&t.schemeColors?.[r])return t.schemeColors[r]}function I(e,t){for(let n=0;n<e.childNodes.length;n++){let r=e.childNodes[n];if(r&&r.nodeType===1&&r.localName===t){let e=r;if(e.namespaceURI===`http://schemas.openxmlformats.org/drawingml/2006/main`)return e}}return null}function ee(e,t,n,r){let i=k(e);if(!i)return null;let a=w(e,`spPr`);if(!a)return null;let o=T(a,`prstGeom`)?.getAttribute(`prst`);if(o===`line`||o===`straightConnector1`){let e=I(a,`ln`),o=e?I(e,`solidFill`):null,s=o?F(o,r):void 0;if(!s)return null;let c=E(e,`w`),l=c?Math.max(1,Math.min(40,Math.round(c/12700*n))):2;return{shape:`line`,rect:O(i,t),stroke:s,strokeWidthPx:l}}if(o===`rect`||o===`roundRect`){let e=I(a,`solidFill`),n=e?F(e,r):void 0;return!n||i.cx*i.cy/(t.cx*t.cy)*100<_?null:{shape:`rect`,rect:O(i,t),fill:n,...o===`roundRect`?{borderRadius:8}:{}}}return null}async function L(n,i,a,s,f,m,g){l(g);let _=await c(n,i);if(!_)return null;let b=w(_,`cSld`)?.getAttribute(`name`)?.trim()??``,x=_.documentElement?.getAttribute(`type`)??void 0,S,D,F=e(await d(n,i),u);if(F){S=o(r(i),F.target);let e=m.get(S);e||(e=P(n,S,g),m.set(S,e)),D=await e}let I=[],L=[],R=_.getElementsByTagNameNS(t,`sp`);for(let e=0;e<R.length;e++){await C(e,g);let t=R[e],n=w(t,`ph`);if(!n){if(L.length<h){let e=ee(t,a,s,f);e&&L.push(e)}continue}let r=n.getAttribute(`type`)??``;if(p.has(r))continue;let i=E(n,`idx`)??0,o=A(r),c=k(t),l=!1;if(!c&&D){let e=j(r),t=D.exact.get(`${r||`body`}:${i}`)??D.baseIdx.get(`${e}:${i}`)??D.base.get(e);t?.rect&&(c=t.rect,l=!0)}let u=c?O(c,a):o===`title`?{...v}:{...y},d=w(t,`txBody`),m=d?T(d,`lstStyle`):null,_=m?M(m):void 0;if(D){let e=j(r),t=D.exact.get(`${r||`body`}:${i}`)??D.baseIdx.get(`${e}:${i}`);_=N(_,t?.style),_=N(_,o===`title`||o===`subtitle`?D.titleStyle:D.bodyStyle)}let b=d?T(d,`bodyPr`):null,x=b?.getAttribute(`anchor`);(x===`t`||x===`ctr`||x===`b`)&&(_={..._??{},anchor:x===`t`?`top`:x===`ctr`?`middle`:`bottom`});let S=n.getAttribute(`orient`),P=b?.getAttribute(`vert`),F=S===`vert`||!!P&&P!==`horz`;I.push({kind:o,rawType:r,idx:i,rect:u,inheritedFromMaster:l,vertical:F,..._?{textStyle:_}:{}})}return{partPath:i,name:b,...x?{typeAttr:x}:{},...S?{masterPath:S}:{},...D?.name?{masterName:D.name}:{},placeholders:I,decorations:L,slideCount:0}}function R(e,t,n,r){return Math.max(0,Math.min(e+t,n+r)-Math.max(e,n))}function z(e,t){let n=R(e.x,e.w,t.x,t.w),r=R(e.y,e.h,t.y,t.h);return n<=.15*Math.min(e.w,t.w)&&r>=.5*Math.min(e.h,t.h)&&e.w>=25&&t.w>=25}function B(e,t){let n=R(e.x,e.w,t.x,t.w);return R(e.y,e.h,t.y,t.h)<=.15*Math.min(e.h,t.h)&&n>=.5*Math.min(e.w,t.w)&&e.y<t.y}function V(e){return e.w>=85&&e.h>=80}function te(e,t){return Math.abs(e.w-t.w)<=.15*Math.max(e.w,t.w)}function ne(e,t){return R(e.x,e.w,t.x,t.w)>2&&R(e.y,e.h,t.y,t.h)>2}function H(e){return e.x+e.w/2}var re=new Set([`titleOnly`,`tx`,`obj`,`objOnly`,`objTx`,`txOverObj`,`objOverTx`,`tbl`,`chart`,`dgm`,`txAndChart`,`chartAndTx`,`vertTitleAndTxOverChart`,`txAndTwoObj`,`twoObjAndTx`,`twoObjOverTx`,`objAndTwoObj`,`twoObjAndObj`,`fourObj`,`vertTx`,`vertTitleAndTx`,`clipArtAndVertTx`]);function ie(e){return!e||e===`cust`?null:e===`title`?{kind:`builtin`,template:`title`,paramSpec:`titleSubtitle`}:e===`secHead`?{kind:`builtin`,template:`sectionHeader`}:e===`blank`?{kind:`skip`}:re.has(e)?{kind:`plain`}:e===`picTx`?{kind:`feature-by-geometry`}:e===`clipArtAndTx`||e===`mediaAndTx`?{kind:`builtin`,template:`leftFeature`,paramSpec:`featureImage`}:e===`txAndClipArt`||e===`txAndMedia`?{kind:`builtin`,template:`rightFeature`,paramSpec:`featureImage`}:e===`twoColTx`||e===`twoObj`||e===`txAndObj`||e===`objAndTx`?{kind:`custom-two-column`}:e===`twoTxTwoObj`?{kind:`comparison`}:null}var ae={"title slide":{kind:`builtin`,template:`title`,paramSpec:`titleSubtitle`},"section header":{kind:`builtin`,template:`sectionHeader`},"two content":{kind:`custom-two-column`},comparison:{kind:`comparison`},"content with caption":{kind:`custom-caption`},"picture with caption":{kind:`feature-by-geometry`},"title and content":{kind:`plain`},"title only":{kind:`plain`},blank:{kind:`skip`},"vertical title and text":{kind:`plain`},"title and vertical text":{kind:`plain`}};function U(e){return ae[e.trim().toLowerCase()]??null}function W(e){return e.placeholders.filter(e=>e.kind!==`title`&&e.kind!==`subtitle`)}function G(e){if(e.placeholders.some(e=>e.vertical))return{kind:`plain`};let t=e.placeholders.some(e=>e.kind===`title`),n=W(e);if(n.length===0)return t?{kind:`plain`}:{kind:`skip`};let r=n.filter(e=>e.kind===`text`),i=n.filter(e=>e.kind===`picture`),a=n.filter(e=>e.kind!==`text`&&e.kind!==`picture`);return i.length===0&&a.length===0?r.length===1?{kind:`plain`}:r.length===2&&z(r[0].rect,r[1].rect)?te(r[0].rect,r[1].rect)?{kind:`custom-two-column`}:{kind:`custom-caption`}:r.length===4&&K(r)?{kind:`comparison`}:{kind:`plain`}:i.length===1&&a.length===0?r.length===0?V(i[0].rect)?{kind:`builtin`,template:`imageWithCaption`,paramSpec:`featureImage`}:{kind:`custom-generic`}:{kind:`feature-by-geometry`}:i.length>=2&&i.length<=4&&r.length===0&&a.length===0&&i.every((e,t)=>i.every((n,r)=>t===r||!ne(e.rect,n.rect)))?{kind:`builtin`,template:`photoGrid`,paramSpec:`photoGridGate`}:{kind:`plain`}}function K(e){if(e.length!==4)return null;let t=[...e].sort((e,t)=>H(e.rect)-H(t.rect)),n=[t[0],t[1]],r=[t[2],t[3]],i=e=>Math.abs(H(e[0].rect)-H(e[1].rect));if(i(n)>10||i(r)>10||H(r[0].rect)-H(n[1].rect)<=10)return null;let a=e=>{let t=[...e].sort((e,t)=>e.rect.y-t.rect.y),n=t[0],r=t[1];return n.rect.h>20||n.rect.y+n.rect.h>r.rect.y+2?null:[n.idx,r.idx]},o=a(n),s=a(r);return o&&s?{left:o,right:s}:null}function q(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}function J(e){return{x:`${e.x}%`,y:`${e.y}%`,width:`${e.w}%`,height:`${e.h}%`}}function oe(e,t,n){return Math.max(16,Math.min(140,Math.round((e&&e>0?e:t)*n)))}function Y(e,t,n,r,i){let a=r===`title`?b:r===`subtitle`?x:S,o={fontSize:oe(t.textStyle?.fontSizePt,a,i.pxPerPt),color:i.hints.text??`#1a1a1a`,lineHeight:r===`title`?1.15:1.4,...r===`title`?{fontWeight:t.textStyle?.bold===!1?`normal`:`bold`}:t.textStyle?.bold?{fontWeight:`bold`}:{},...t.textStyle?.align?{textAlign:t.textStyle.align}:{},...t.textStyle?.anchor?{verticalAlign:t.textStyle.anchor}:{}};return{id:e,type:`text`,position:J(t.rect),content:{text:n,style:o}}}function se(e,t,n){return{id:e,type:`image`,position:J(t.rect),content:{src:`{image:${n}}`,alt:`{image:${n}}`,fit:`cover`}}}function X(e){return e.decorations.map((e,t)=>({id:`decor-${t+1}`,type:`shape`,position:J(e.rect),content:e.shape===`line`?{shape:`line`,stroke:e.stroke,strokeWidth:e.strokeWidthPx??2}:{shape:`rect`,fill:e.fill,...e.borderRadius?{borderRadius:e.borderRadius}:{}}}))}function Z(e){return e.placeholders.find(e=>e.kind===`title`)}function Q(){return{kind:`title`,rawType:`title`,idx:0,rect:{...v},inheritedFromMaster:!1,vertical:!1}}function ce(e,t){let n=W(e).filter(e=>e.kind===`text`),r,i,a=[...n].sort((e,t)=>e.rect.x-t.rect.x);a.length>=2&&z(a[0].rect,a[a.length-1].rect)?(r=a[0],i=a[a.length-1]):(r={...Q(),kind:`text`,rawType:`body`,rect:{x:5,y:23.3,w:43,h:66}},i={...r,rect:{x:52,y:23.3,w:43,h:66}});let o=Math.max(0,Math.round((i.rect.x-(r.rect.x+r.rect.w))*100)/100),s=[...X(e)],c=Z(e)??Q();s.push(Y(`title`,c,`{title}`,`title`,t));let l={...Y(`column`,r,`{item}`,`body`,t),repeat:{source:`listItems`,direction:`row`,gap:o,max:2}};return s.push(l),s}function le(e,t){let n=[...W(e).filter(e=>e.kind===`text`)].sort((e,t)=>t.rect.w-e.rect.w),r=n[0],i=n[1],a=[...X(e)],o=Z(e)??Q();return a.push(Y(`title`,o,`{title}`,`title`,t)),r&&a.push(Y(`body`,r,`{content}`,`body`,t)),i&&a.push(Y(`caption`,i,`{attr:caption|}`,`body`,t)),a}function $(e,t){let n=[...X(e)],r=Z(e);r&&n.push(Y(`title`,r,`{title}`,`title`,t));let i=W(e);i.filter(e=>e.kind===`picture`).sort((e,t)=>e.idx-t.idx||e.rect.y-t.rect.y).forEach((e,t)=>n.push(se(`image-${t}`,e,t)));let a=i.filter(e=>e.kind===`text`);a.length>0&&n.push(Y(`body`,a[0],`{content}`,`body`,t)),a.length>1&&t.notes.push(`${a.length-1} additional text region(s) could not be bound \u2014 the token grammar has no per-region address; full text stays in the markdown body.`);let o=i.filter(e=>e.kind===`table`||e.kind===`chart`||e.kind===`other`);return o.length>0&&t.notes.push(`${o.length} table/chart placeholder(s) dropped (content flows as markdown).`),n}function ue(e){return e.some(e=>e.type===`text`||e.type===`image`)}function de(e){let t=W(e),n=t.find(e=>e.kind===`picture`);if(!n)return{kind:`plain`};let r=t.filter(e=>e.kind===`text`),i=r.find(e=>z(n.rect,e.rect));return i?{kind:`builtin`,template:H(n.rect)<H(i.rect)?`leftFeature`:`rightFeature`,paramSpec:`featureImage`}:r.some(e=>B(n.rect,e.rect))||V(n.rect)?{kind:`builtin`,template:`imageWithCaption`,paramSpec:`featureImage`}:{kind:`builtin`,template:`leftFeature`,paramSpec:`featureImage`}}function fe(e){return ie(e.typeAttr)??U(e.name)??G(e)}function pe(e,t,n,r){switch(t.kind){case`plain`:case`skip`:return{kind:t.kind};case`builtin`:return t;case`feature-by-geometry`:return de(e);case`comparison`:{let t=K(W(e).filter(e=>e.kind===`text`));return t?{kind:`builtin`,template:`twoColumn`,paramSpec:`comparisonPairs`,columns:t}:{kind:`plain`}}case`custom-two-column`:case`custom-caption`:case`custom-generic`:case`by-geometry`:{let i=t.kind===`custom-two-column`?ce(e,n):t.kind===`custom-caption`?le(e,n):$(e,n);return ue(i)?{kind:`custom`,def:{name:r,label:e.name||`Imported layout`,description:`Imported from PowerPoint layout "${e.name||r}"${e.masterName?` (master "${e.masterName}")`:``}`,viewport:n.viewport,layers:i}}:{kind:`plain`}}}}async function me(e,t){l(t);let n=await c(e,`ppt/presentation.xml`),r=n?w(n,`sldSz`):null,i=E(r,`cx`),a=E(r,`cy`);return i&&a&&i>0&&a>0?{cx:i,cy:a}:{...f}}async function he(e,n){l(n);let r=await c(e,`ppt/presentation.xml`);if(!r)return[];let i=await d(e,`ppt/presentation.xml`),u=new Map(i.map(e=>[e.id,e.target])),f=[],p=r.getElementsByTagNameNS(t,`sldId`);for(let e=0;e<p.length;e++){await C(e,n);let t=a(p[e],s,`id`,`r:id`),r=t?u.get(t):void 0;r&&f.push(o(`ppt`,r))}return f}function ge(e){return e.cy>e.cx?{width:1080,height:Math.round(1080*e.cy/e.cx)}:{width:Math.round(1080*e.cx/e.cy),height:1080}}async function _e(t,i={}){l(i.signal);let a=[],s=i.colors??{},c=i.maxTemplates??m,u=await me(t,i.signal),f=ge(u),p=f.height/(u.cy/12700),h=await he(t,i.signal),g=new Map,_=new Map,v=[];for(let a=0;a<h.length;a++){await C(a,i.signal);let s=h[a],c=e(await d(t,s),n);if(!c)continue;let l=o(r(s),c.target);g.set(s,l),_.has(l)||v.push(l),_.set(l,(_.get(l)??0)+1)}if(i.includeUnused){let e=[],n=0;for(let[r,a]of t.contentTypes.overrides)await C(n++,i.signal),a===`application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml`&&!_.has(r)&&e.push(r);e.sort(),v.push(...e)}let y=new Map,b=[],x=new Set;for(let e=0;e<v.length;e++){await C(e,i.signal);let n=v[e],r=await L(t,n,u,p,s,y,i.signal);if(!r){a.push(`layout ${n} could not be read; its slides import plain`);continue}r.slideCount=_.get(n)??0;let o=q(r.name)||`layout-${e+1}`,c=`pptx-${o}`;for(let e=2;x.has(c);e++)c=`pptx-${o}-${e}`;let l=[],d={hints:s,pxPerPt:p,viewport:f,notes:l},m=pe(r,fe(r),d,c);m.kind===`custom`&&x.add(c),b.push({extracted:r,verdict:m,notes:l})}let S=b.filter(e=>e.verdict.kind===`custom`);if(S.length>c){let e=[...S].sort((e,t)=>t.extracted.slideCount-e.extracted.slideCount).slice(c);for(let t=0;t<e.length;t++){await C(t,i.signal);let n=e[t];n.verdict={kind:`plain`},n.notes.push(`dropped: more inferred layouts than the template cap`)}a.push(`deck defines ${S.length} distinctive layouts; kept the ${c} most used as custom templates`)}let w=new Map(b.map(e=>[e.extracted.partPath,e]));return l(i.signal),{slideSize:u,layouts:b,byLayoutPath:w,layoutPathBySlide:g,warnings:a}}export{_e as t};
1
+ import{$ as e,D as t,K as n,Q as r,T as i,Z as a,at as o,k as s,nt as c,ot as l,q as u,tt as d}from"./chunk-S5PCVMKU-i2wfHmvU.js";var f={cx:12192e3,cy:6858e3},p=new Set([`dt`,`ftr`,`sldNum`,`hdr`]),m=12,h=4,g=128,_=2,v={x:5,y:4,w:90,h:16.7},y={x:5,y:23.3,w:90,h:66},b=44,x=24,S=22;async function C(e,t){l(t),e>0&&e%g===0&&(await new Promise(e=>setTimeout(e,0)),l(t))}function w(e,n){let r=e.getElementsByTagNameNS(t,n);return r.length>0?r[0]:null}function T(e,t){let n=e.getElementsByTagNameNS(i,t);return n.length>0?n[0]:null}function E(e,t){let n=e?.getAttribute(t);if(!n)return;let r=parseInt(n,10);return Number.isFinite(r)?r:void 0}function D(e,t){let n=e/t*100;return Math.round(Math.max(-10,Math.min(110,n))*100)/100}function O(e,t){return{x:D(e.x,t.cx),y:D(e.y,t.cy),w:D(e.cx,t.cx),h:D(e.cy,t.cy)}}function k(e){let t=w(e,`spPr`);if(!t)return null;let n=T(t,`xfrm`);if(!n)return null;let r=T(n,`off`),i=T(n,`ext`),a=E(r,`x`),o=E(r,`y`),s=E(i,`cx`),c=E(i,`cy`);return a===void 0||o===void 0||s===void 0||c===void 0||s<=0||c<=0?null:{x:a,y:o,cx:s,cy:c}}function A(e){switch(e){case`title`:case`ctrTitle`:return`title`;case`subTitle`:return`subtitle`;case``:case`body`:case`obj`:return`text`;case`pic`:case`clipArt`:case`media`:return`picture`;case`tbl`:return`table`;case`chart`:case`dgm`:return`chart`;default:return`other`}}function j(e){switch(e){case`ctrTitle`:return`title`;case``:case`subTitle`:case`obj`:case`pic`:case`clipArt`:case`media`:case`tbl`:case`chart`:case`dgm`:return`body`;default:return e}}function M(e){let t=T(e,`lvl1pPr`);if(!t)return;let n={},r=t.getAttribute(`algn`);r===`ctr`?n.align=`center`:r===`r`?n.align=`right`:r===`l`&&(n.align=`left`);let i=T(t,`defRPr`),a=E(i,`sz`);a!==void 0&&a>0&&(n.fontSizePt=a/100);let o=i?.getAttribute(`b`);return o===`1`||o===`true`?n.bold=!0:(o===`0`||o===`false`)&&(n.bold=!1),Object.keys(n).length>0?n:void 0}function N(e,t){return e?t?{fontSizePt:e.fontSizePt??t.fontSizePt,bold:e.bold??t.bold,align:e.align??t.align,anchor:e.anchor??t.anchor}:e:t}async function P(e,n,r){l(r);let i={name:``,exact:new Map,baseIdx:new Map,base:new Map},a=await c(e,n);if(!a)return i;i.name=w(a,`cSld`)?.getAttribute(`name`)?.trim()??``;let o=w(a,`txStyles`);if(o){let e=w(o,`titleStyle`),t=w(o,`bodyStyle`);e&&(i.titleStyle=M(e)),t&&(i.bodyStyle=M(t))}let s=a.getElementsByTagNameNS(t,`sp`);for(let e=0;e<s.length;e++){await C(e,r);let t=s[e],n=w(t,`ph`);if(!n)continue;let a=n.getAttribute(`type`)??``,o=E(n,`idx`)??0,c={rect:k(t)},l=w(t,`txBody`),u=l?T(l,`lstStyle`):null;u&&(c.style=M(u));let d=`${a||`body`}:${o}`;i.exact.has(d)||i.exact.set(d,c);let f=j(a),p=`${f}:${o}`;i.baseIdx.has(p)||i.baseIdx.set(p,c),i.base.has(f)||i.base.set(f,c)}return i}function F(e,t){let n=T(e,`srgbClr`)?.getAttribute(`val`);if(n&&/^[0-9a-fA-F]{6}$/.test(n))return`#${n.toLowerCase()}`;let r=T(e,`schemeClr`)?.getAttribute(`val`);if(r&&t.schemeColors?.[r])return t.schemeColors[r]}function I(e,t){for(let n=0;n<e.childNodes.length;n++){let r=e.childNodes[n];if(r&&r.nodeType===1&&r.localName===t){let e=r;if(e.namespaceURI===`http://schemas.openxmlformats.org/drawingml/2006/main`)return e}}return null}function ee(e,t,n,r){let i=k(e);if(!i)return null;let a=w(e,`spPr`);if(!a)return null;let o=T(a,`prstGeom`)?.getAttribute(`prst`);if(o===`line`||o===`straightConnector1`){let e=I(a,`ln`),o=e?I(e,`solidFill`):null,s=o?F(o,r):void 0;if(!s)return null;let c=E(e,`w`),l=c?Math.max(1,Math.min(40,Math.round(c/12700*n))):2;return{shape:`line`,rect:O(i,t),stroke:s,strokeWidthPx:l}}if(o===`rect`||o===`roundRect`){let e=I(a,`solidFill`),n=e?F(e,r):void 0;return!n||i.cx*i.cy/(t.cx*t.cy)*100<_?null:{shape:`rect`,rect:O(i,t),fill:n,...o===`roundRect`?{borderRadius:8}:{}}}return null}async function L(n,i,a,s,f,m,g){l(g);let _=await c(n,i);if(!_)return null;let b=w(_,`cSld`)?.getAttribute(`name`)?.trim()??``,x=_.documentElement?.getAttribute(`type`)??void 0,S,D,F=e(await d(n,i),u);if(F){S=o(r(i),F.target);let e=m.get(S);e||(e=P(n,S,g),m.set(S,e)),D=await e}let I=[],L=[],R=_.getElementsByTagNameNS(t,`sp`);for(let e=0;e<R.length;e++){await C(e,g);let t=R[e],n=w(t,`ph`);if(!n){if(L.length<h){let e=ee(t,a,s,f);e&&L.push(e)}continue}let r=n.getAttribute(`type`)??``;if(p.has(r))continue;let i=E(n,`idx`)??0,o=A(r),c=k(t),l=!1;if(!c&&D){let e=j(r),t=D.exact.get(`${r||`body`}:${i}`)??D.baseIdx.get(`${e}:${i}`)??D.base.get(e);t?.rect&&(c=t.rect,l=!0)}let u=c?O(c,a):o===`title`?{...v}:{...y},d=w(t,`txBody`),m=d?T(d,`lstStyle`):null,_=m?M(m):void 0;if(D){let e=j(r),t=D.exact.get(`${r||`body`}:${i}`)??D.baseIdx.get(`${e}:${i}`);_=N(_,t?.style),_=N(_,o===`title`||o===`subtitle`?D.titleStyle:D.bodyStyle)}let b=d?T(d,`bodyPr`):null,x=b?.getAttribute(`anchor`);(x===`t`||x===`ctr`||x===`b`)&&(_={..._??{},anchor:x===`t`?`top`:x===`ctr`?`middle`:`bottom`});let S=n.getAttribute(`orient`),P=b?.getAttribute(`vert`),F=S===`vert`||!!P&&P!==`horz`;I.push({kind:o,rawType:r,idx:i,rect:u,inheritedFromMaster:l,vertical:F,..._?{textStyle:_}:{}})}return{partPath:i,name:b,...x?{typeAttr:x}:{},...S?{masterPath:S}:{},...D?.name?{masterName:D.name}:{},placeholders:I,decorations:L,slideCount:0}}function R(e,t,n,r){return Math.max(0,Math.min(e+t,n+r)-Math.max(e,n))}function z(e,t){let n=R(e.x,e.w,t.x,t.w),r=R(e.y,e.h,t.y,t.h);return n<=.15*Math.min(e.w,t.w)&&r>=.5*Math.min(e.h,t.h)&&e.w>=25&&t.w>=25}function B(e,t){let n=R(e.x,e.w,t.x,t.w);return R(e.y,e.h,t.y,t.h)<=.15*Math.min(e.h,t.h)&&n>=.5*Math.min(e.w,t.w)&&e.y<t.y}function V(e){return e.w>=85&&e.h>=80}function te(e,t){return Math.abs(e.w-t.w)<=.15*Math.max(e.w,t.w)}function ne(e,t){return R(e.x,e.w,t.x,t.w)>2&&R(e.y,e.h,t.y,t.h)>2}function H(e){return e.x+e.w/2}var re=new Set([`titleOnly`,`tx`,`obj`,`objOnly`,`objTx`,`txOverObj`,`objOverTx`,`tbl`,`chart`,`dgm`,`txAndChart`,`chartAndTx`,`vertTitleAndTxOverChart`,`txAndTwoObj`,`twoObjAndTx`,`twoObjOverTx`,`objAndTwoObj`,`twoObjAndObj`,`fourObj`,`vertTx`,`vertTitleAndTx`,`clipArtAndVertTx`]);function ie(e){return!e||e===`cust`?null:e===`title`?{kind:`builtin`,template:`title`,paramSpec:`titleSubtitle`}:e===`secHead`?{kind:`builtin`,template:`sectionHeader`}:e===`blank`?{kind:`skip`}:re.has(e)?{kind:`plain`}:e===`picTx`?{kind:`feature-by-geometry`}:e===`clipArtAndTx`||e===`mediaAndTx`?{kind:`builtin`,template:`leftFeature`,paramSpec:`featureImage`}:e===`txAndClipArt`||e===`txAndMedia`?{kind:`builtin`,template:`rightFeature`,paramSpec:`featureImage`}:e===`twoColTx`||e===`twoObj`||e===`txAndObj`||e===`objAndTx`?{kind:`custom-two-column`}:e===`twoTxTwoObj`?{kind:`comparison`}:null}var ae={"title slide":{kind:`builtin`,template:`title`,paramSpec:`titleSubtitle`},"section header":{kind:`builtin`,template:`sectionHeader`},"two content":{kind:`custom-two-column`},comparison:{kind:`comparison`},"content with caption":{kind:`custom-caption`},"picture with caption":{kind:`feature-by-geometry`},"title and content":{kind:`plain`},"title only":{kind:`plain`},blank:{kind:`skip`},"vertical title and text":{kind:`plain`},"title and vertical text":{kind:`plain`}};function U(e){return ae[e.trim().toLowerCase()]??null}function W(e){return e.placeholders.filter(e=>e.kind!==`title`&&e.kind!==`subtitle`)}function G(e){if(e.placeholders.some(e=>e.vertical))return{kind:`plain`};let t=e.placeholders.some(e=>e.kind===`title`),n=W(e);if(n.length===0)return t?{kind:`plain`}:{kind:`skip`};let r=n.filter(e=>e.kind===`text`),i=n.filter(e=>e.kind===`picture`),a=n.filter(e=>e.kind!==`text`&&e.kind!==`picture`);return i.length===0&&a.length===0?r.length===1?{kind:`plain`}:r.length===2&&z(r[0].rect,r[1].rect)?te(r[0].rect,r[1].rect)?{kind:`custom-two-column`}:{kind:`custom-caption`}:r.length===4&&K(r)?{kind:`comparison`}:{kind:`plain`}:i.length===1&&a.length===0?r.length===0?V(i[0].rect)?{kind:`builtin`,template:`imageWithCaption`,paramSpec:`featureImage`}:{kind:`custom-generic`}:{kind:`feature-by-geometry`}:i.length>=2&&i.length<=4&&r.length===0&&a.length===0&&i.every((e,t)=>i.every((n,r)=>t===r||!ne(e.rect,n.rect)))?{kind:`builtin`,template:`photoGrid`,paramSpec:`photoGridGate`}:{kind:`plain`}}function K(e){if(e.length!==4)return null;let t=[...e].sort((e,t)=>H(e.rect)-H(t.rect)),n=[t[0],t[1]],r=[t[2],t[3]],i=e=>Math.abs(H(e[0].rect)-H(e[1].rect));if(i(n)>10||i(r)>10||H(r[0].rect)-H(n[1].rect)<=10)return null;let a=e=>{let t=[...e].sort((e,t)=>e.rect.y-t.rect.y),n=t[0],r=t[1];return n.rect.h>20||n.rect.y+n.rect.h>r.rect.y+2?null:[n.idx,r.idx]},o=a(n),s=a(r);return o&&s?{left:o,right:s}:null}function q(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}function J(e){return{x:`${e.x}%`,y:`${e.y}%`,width:`${e.w}%`,height:`${e.h}%`}}function oe(e,t,n){return Math.max(16,Math.min(140,Math.round((e&&e>0?e:t)*n)))}function Y(e,t,n,r,i){let a=r===`title`?b:r===`subtitle`?x:S,o={fontSize:oe(t.textStyle?.fontSizePt,a,i.pxPerPt),color:i.hints.text??`#1a1a1a`,lineHeight:r===`title`?1.15:1.4,...r===`title`?{fontWeight:t.textStyle?.bold===!1?`normal`:`bold`}:t.textStyle?.bold?{fontWeight:`bold`}:{},...t.textStyle?.align?{textAlign:t.textStyle.align}:{},...t.textStyle?.anchor?{verticalAlign:t.textStyle.anchor}:{}};return{id:e,type:`text`,position:J(t.rect),content:{text:n,style:o}}}function se(e,t,n){return{id:e,type:`image`,position:J(t.rect),content:{src:`{image:${n}}`,alt:`{image:${n}}`,fit:`cover`}}}function X(e){return e.decorations.map((e,t)=>({id:`decor-${t+1}`,type:`shape`,position:J(e.rect),content:e.shape===`line`?{shape:`line`,stroke:e.stroke,strokeWidth:e.strokeWidthPx??2}:{shape:`rect`,fill:e.fill,...e.borderRadius?{borderRadius:e.borderRadius}:{}}}))}function Z(e){return e.placeholders.find(e=>e.kind===`title`)}function Q(){return{kind:`title`,rawType:`title`,idx:0,rect:{...v},inheritedFromMaster:!1,vertical:!1}}function ce(e,t){let n=W(e).filter(e=>e.kind===`text`),r,i,a=[...n].sort((e,t)=>e.rect.x-t.rect.x);a.length>=2&&z(a[0].rect,a[a.length-1].rect)?(r=a[0],i=a[a.length-1]):(r={...Q(),kind:`text`,rawType:`body`,rect:{x:5,y:23.3,w:43,h:66}},i={...r,rect:{x:52,y:23.3,w:43,h:66}});let o=Math.max(0,Math.round((i.rect.x-(r.rect.x+r.rect.w))*100)/100),s=[...X(e)],c=Z(e)??Q();s.push(Y(`title`,c,`{title}`,`title`,t));let l={...Y(`column`,r,`{item}`,`body`,t),repeat:{source:`listItems`,direction:`row`,gap:o,max:2}};return s.push(l),s}function le(e,t){let n=[...W(e).filter(e=>e.kind===`text`)].sort((e,t)=>t.rect.w-e.rect.w),r=n[0],i=n[1],a=[...X(e)],o=Z(e)??Q();return a.push(Y(`title`,o,`{title}`,`title`,t)),r&&a.push(Y(`body`,r,`{content}`,`body`,t)),i&&a.push(Y(`caption`,i,`{attr:caption|}`,`body`,t)),a}function $(e,t){let n=[...X(e)],r=Z(e);r&&n.push(Y(`title`,r,`{title}`,`title`,t));let i=W(e);i.filter(e=>e.kind===`picture`).sort((e,t)=>e.idx-t.idx||e.rect.y-t.rect.y).forEach((e,t)=>n.push(se(`image-${t}`,e,t)));let a=i.filter(e=>e.kind===`text`);a.length>0&&n.push(Y(`body`,a[0],`{content}`,`body`,t)),a.length>1&&t.notes.push(`${a.length-1} additional text region(s) could not be bound \u2014 the token grammar has no per-region address; full text stays in the markdown body.`);let o=i.filter(e=>e.kind===`table`||e.kind===`chart`||e.kind===`other`);return o.length>0&&t.notes.push(`${o.length} table/chart placeholder(s) dropped (content flows as markdown).`),n}function ue(e){return e.some(e=>e.type===`text`||e.type===`image`)}function de(e){let t=W(e),n=t.find(e=>e.kind===`picture`);if(!n)return{kind:`plain`};let r=t.filter(e=>e.kind===`text`),i=r.find(e=>z(n.rect,e.rect));return i?{kind:`builtin`,template:H(n.rect)<H(i.rect)?`leftFeature`:`rightFeature`,paramSpec:`featureImage`}:r.some(e=>B(n.rect,e.rect))||V(n.rect)?{kind:`builtin`,template:`imageWithCaption`,paramSpec:`featureImage`}:{kind:`builtin`,template:`leftFeature`,paramSpec:`featureImage`}}function fe(e){return ie(e.typeAttr)??U(e.name)??G(e)}function pe(e,t,n,r){switch(t.kind){case`plain`:case`skip`:return{kind:t.kind};case`builtin`:return t;case`feature-by-geometry`:return de(e);case`comparison`:{let t=K(W(e).filter(e=>e.kind===`text`));return t?{kind:`builtin`,template:`twoColumn`,paramSpec:`comparisonPairs`,columns:t}:{kind:`plain`}}case`custom-two-column`:case`custom-caption`:case`custom-generic`:case`by-geometry`:{let i=t.kind===`custom-two-column`?ce(e,n):t.kind===`custom-caption`?le(e,n):$(e,n);return ue(i)?{kind:`custom`,def:{name:r,label:e.name||`Imported layout`,description:`Imported from PowerPoint layout "${e.name||r}"${e.masterName?` (master "${e.masterName}")`:``}`,viewport:n.viewport,layers:i}}:{kind:`plain`}}}}async function me(e,t){l(t);let n=await c(e,`ppt/presentation.xml`),r=n?w(n,`sldSz`):null,i=E(r,`cx`),a=E(r,`cy`);return i&&a&&i>0&&a>0?{cx:i,cy:a}:{...f}}async function he(e,n){l(n);let r=await c(e,`ppt/presentation.xml`);if(!r)return[];let i=await d(e,`ppt/presentation.xml`),u=new Map(i.map(e=>[e.id,e.target])),f=[],p=r.getElementsByTagNameNS(t,`sldId`);for(let e=0;e<p.length;e++){await C(e,n);let t=a(p[e],s,`id`,`r:id`),r=t?u.get(t):void 0;r&&f.push(o(`ppt`,r))}return f}function ge(e){return e.cy>e.cx?{width:1080,height:Math.round(1080*e.cy/e.cx)}:{width:Math.round(1080*e.cx/e.cy),height:1080}}async function _e(t,i={}){l(i.signal);let a=[],s=i.colors??{},c=i.maxTemplates??m,u=await me(t,i.signal),f=ge(u),p=f.height/(u.cy/12700),h=await he(t,i.signal),g=new Map,_=new Map,v=[];for(let a=0;a<h.length;a++){await C(a,i.signal);let s=h[a],c=e(await d(t,s),n);if(!c)continue;let l=o(r(s),c.target);g.set(s,l),_.has(l)||v.push(l),_.set(l,(_.get(l)??0)+1)}if(i.includeUnused){let e=[],n=0;for(let[r,a]of t.contentTypes.overrides)await C(n++,i.signal),a===`application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml`&&!_.has(r)&&e.push(r);e.sort(),v.push(...e)}let y=new Map,b=[],x=new Set;for(let e=0;e<v.length;e++){await C(e,i.signal);let n=v[e],r=await L(t,n,u,p,s,y,i.signal);if(!r){a.push(`layout ${n} could not be read; its slides import plain`);continue}r.slideCount=_.get(n)??0;let o=q(r.name)||`layout-${e+1}`,c=`pptx-${o}`;for(let e=2;x.has(c);e++)c=`pptx-${o}-${e}`;let l=[],d={hints:s,pxPerPt:p,viewport:f,notes:l},m=pe(r,fe(r),d,c);m.kind===`custom`&&x.add(c),b.push({extracted:r,verdict:m,notes:l})}let S=b.filter(e=>e.verdict.kind===`custom`);if(S.length>c){let e=[...S].sort((e,t)=>t.extracted.slideCount-e.extracted.slideCount).slice(c);for(let t=0;t<e.length;t++){await C(t,i.signal);let n=e[t];n.verdict={kind:`plain`},n.notes.push(`dropped: more inferred layouts than the template cap`)}a.push(`deck defines ${S.length} distinctive layouts; kept the ${c} most used as custom templates`)}let w=new Map(b.map(e=>[e.extracted.partPath,e]));return l(i.signal),{slideSize:u,layouts:b,byLayoutPath:w,layoutPathBySlide:g,warnings:a}}export{_e as t};
@@ -0,0 +1,4 @@
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{t}from"./jszip.min-DhiFe-R7.js";import{n}from"./chunk-7AWFHP5U-MiVVPFTx.js";import{n as r,t as i}from"./chunk-JU2RHXUB-CMFDhTux.js";import{A as a,C as o,N as s,P as c,S as l,_ as u,t as d,w as f,x as p}from"./chunk-S5PCVMKU-i2wfHmvU.js";var m=e(t(),1);function h(){let e=[],t=[],r;return{addPart(t,r,i){n(t),e.push({path:t,content:r,contentType:i})},addBinaryPart(t,r,i){n(t),e.push({path:t,binaryContent:r,contentType:i})},addRelationship(e,r){e&&n(e),t.push({sourcePart:e,relationship:r})},setCoreProperties(e){r=e},async toBlob(){return g(e,t,r).generateAsync({type:`blob`})},async toArrayBuffer(){return g(e,t,r).generateAsync({type:`arraybuffer`})}}}function g(e,t,n){let r=new m.default,i=t.slice();for(let t of e)t.content===void 0?t.binaryContent!==void 0&&r.file(t.path,t.binaryContent):r.file(t.path,t.content);if(n){let e=y(n);if(r.file(`docProps/core.xml`,e),!i.some(({sourcePart:e,relationship:t})=>e===``&&t.type===`http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties`)){let e=new Set(i.map(({relationship:e})=>e.id)),t=100;for(;e.has(`rId${t}`);)t++;i.push({sourcePart:``,relationship:{id:`rId${t}`,type:c,target:`docProps/core.xml`}})}}r.file(`[Content_Types].xml`,_(e,n));let a=S(i);for(let[e,t]of a){let n=e===``?`_rels/.rels`:x(e);r.file(n,v(t))}return r}function _(e,t){let n=[r()];n.push(`<Types xmlns="${p}">`);let a=new Map;a.set(`rels`,u),a.set(`xml`,`application/xml`);for(let t of e)if(t.binaryContent!==void 0){let e=b(t.path);e&&!a.has(e)&&a.set(e,t.contentType)}for(let[e,t]of a)n.push(` <Default Extension="${i(e)}" ContentType="${i(t)}"/>`);for(let t of e)t.content!==void 0&&n.push(` <Override PartName="/${i(t.path)}" ContentType="${i(t.contentType)}"/>`);return t&&n.push(` <Override PartName="/docProps/core.xml" ContentType="${d}"/>`),n.push(`</Types>`),n.join(`
2
+ `)}function v(e){let t=[r()];t.push(`<Relationships xmlns="${a}">`);for(let n of e){let e=[`Id="${i(n.id)}"`,`Type="${i(n.type)}"`,`Target="${i(n.target)}"`];n.targetMode&&e.push(`TargetMode="${i(n.targetMode)}"`),t.push(` <Relationship ${e.join(` `)}/>`)}return t.push(`</Relationships>`),t.join(`
3
+ `)}function y(e){let t=[r()];return t.push(`<cp:coreProperties xmlns:cp="${l}" xmlns:dc="${o}" xmlns:dcterms="${f}" xmlns:xsi="${s}">`),e.title&&t.push(` <dc:title>${i(e.title)}</dc:title>`),e.subject&&t.push(` <dc:subject>${i(e.subject)}</dc:subject>`),e.creator&&t.push(` <dc:creator>${i(e.creator)}</dc:creator>`),e.description&&t.push(` <dc:description>${i(e.description)}</dc:description>`),e.keywords&&t.push(` <cp:keywords>${i(e.keywords)}</cp:keywords>`),e.lastModifiedBy&&t.push(` <cp:lastModifiedBy>${i(e.lastModifiedBy)}</cp:lastModifiedBy>`),e.revision&&t.push(` <cp:revision>${i(e.revision)}</cp:revision>`),e.created&&t.push(` <dcterms:created xsi:type="dcterms:W3CDTF">${i(e.created)}</dcterms:created>`),e.modified&&t.push(` <dcterms:modified xsi:type="dcterms:W3CDTF">${i(e.modified)}</dcterms:modified>`),t.push(`</cp:coreProperties>`),t.join(`
4
+ `)}function b(e){let t=e.lastIndexOf(`.`);if(t!==-1)return e.substring(t+1).toLowerCase()}function x(e){let t=e.lastIndexOf(`/`);return t===-1?`_rels/${e}.rels`:`${e.substring(0,t)}/_rels/${e.substring(t+1)}.rels`}function S(e){let t=new Map;for(let{sourcePart:n,relationship:r}of e){let e=t.get(n);e||(e=[],t.set(n,e)),e.push(r)}return t}export{h as t};