@lucidkiln/core 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as withCaller, $t as suggest, A as consume, At as passesAhead, B as indentText, Bt as RenderState, C as getAttr, Ct as BLOCKED_NAMES, D as after, Dt as contentSets, E as addSlotFlags, Et as atFront, F as endPlace, Ft as additionsIn, G as locating, Gt as fillScope, H as isPromise, Ht as blockScope, I as fail, It as checkLate, J as renderTemplate, Jt as lookup$1, K as markCaller, Kt as startCapture, L as hold, Lt as closeOutlets, M as embed, Mt as runAhead, N as embedKeyed, Nt as runSequence, O as all, Ot as isRoot, P as embedScope, Pt as OUTLET_INDENT, Q as unhold, Qt as variableNames, R as holdData, Rt as recordAddition, S as toTime, St as valueLabel, T as readableNames, Tt as lookup, U as loadTemplate, Ut as emptyOut, V as indentedText, Vt as Run, W as locate, Wt as endCapture, X as startPlace, Xt as sectionCopy, Y as silence, Yt as ownerOf, Z as step, Zt as sectionScope, _ as markupText, _t as toStr, a as operatorFunction, an as escapeWith, at as describeValue, b as toPieces, bt as typeName, c as checkDepth, cn as KilnIssue, ct as isEmpty, d as functionArgument, dn as createDiagnostic, dt as literalOptions, en as Markup, et as write, f as insertedPiece, fn as issue, ft as mapKeys, g as mapContents, gt as toNumber, h as listOf$1, ht as templateFunctions, i as contains, in as escapeUrl, it as describeType, j as consumeAt, jt as passesFrom, k as checkLength, kt as mayRunAhead, l as entriesOf, ln as KilnRenderError, lt as isHashLike, m as isHtmlStrategy, mt as setOwn, n as builtinFunctions, nn as safe, nt as MISSING, o as rangeOperator, on as TEMPLATE_EXTENSION, ot as equals, p as integerArgument, pt as matchesType, q as passData, qt as childScope, r as builtinTests, rn as escapeHtml, rt as compare, s as Kept, sn as resolveTemplateName, st as hashKeys, t as Source, tn as isSafe, tt as FORMATTERS, u as fromPieces, un as KilnSyntaxError, ut as isPlainObject, v as readProperty, vt as toStringArgument, w as getMethod, wt as expose, x as toPlainData, xt as unwrap, y as scanHtml, yt as truthy, z as importsFor, zt as takeOutput } from "./source-BHcxowQp.js";
2
- import { a as ESCAPE_STRATEGIES, i as DEFAULT_SLOT, r as scanParts, t as parse } from "./parser-BU5dThuk.js";
1
+ import { $ as compare, $t as escapeUrl, A as consume, At as additionsIn, B as loadTemplate, Bt as fillScope, C as getAttr, Ct as contentSets, D as after, Dt as passesFrom, E as addSlotFlags, Et as passesAhead, F as fail, Ft as RenderState, G as renderTemplate, Gt as sectionCopy, H as locating, Ht as childScope, I as hold, It as Run, J as unhold, Jt as suggest, K as silence, Kt as sectionScope, L as holdData, Lt as blockScope, M as embed, Mt as closeOutlets, N as embedKeyed, Nt as recordAddition, O as all, Ot as runAhead, P as embedScope, Pt as takeOutput, Q as MISSING, Qt as escapeHtml, R as importsFor, Rt as emptyOut, S as toTime, St as atFront, T as readableNames, Tt as mayRunAhead, U as markCaller, Ut as lookup$1, V as locate, Vt as startCapture, W as passData, Wt as ownerOf, X as write, Xt as isSafe, Y as withCaller, Yt as Markup, Z as FORMATTERS, Zt as safe, _ as markupText, _t as unwrap, a as operatorFunction, an as KilnSyntaxError, at as isHashLike, b as toPieces, bt as expose, c as checkDepth, ct as mapKeys, d as functionArgument, dt as templateFunctions, en as escapeWith, et as describeType, f as insertedPiece, ft as toNumber, g as mapContents, gt as typeName, h as listOf$1, ht as truthy, i as contains, in as KilnRenderError, it as isEmpty, j as consumeAt, jt as checkLate, k as checkLength, kt as runSequence, l as entriesOf, lt as matchesType, m as isHtmlStrategy, mt as toStringArgument, n as builtinFunctions, nn as resolveTemplateName, nt as equals, o as rangeOperator, on as createDiagnostic, ot as isPlainObject, p as integerArgument, pt as toStr, q as step, qt as variableNames, r as builtinTests, rn as KilnIssue, rt as hashKeys, s as Kept, sn as issue, st as literalOptions, t as Source, tn as TEMPLATE_EXTENSION, tt as describeValue, u as fromPieces, ut as setOwn, v as readProperty, vt as valueLabel, w as getMethod, wt as isRoot, x as toPlainData, xt as lookup, y as scanHtml, yt as BLOCKED_NAMES, z as isPromise, zt as endCapture } from "./source-BbikGqIb.js";
2
+ import { a as ESCAPE_STRATEGIES, i as DEFAULT_SLOT, r as scanParts, t as parse } from "./parser-isboTef0.js";
3
3
  //#region src/analyzer.ts
4
4
  const MAX_DEPTH$1 = 1e3;
5
5
  /** The statement lists nested inside a statement. */
@@ -2097,18 +2097,14 @@ const printParts = (list) => {
2097
2097
  const parts = [];
2098
2098
  for (const part of list) {
2099
2099
  const last = parts.at(-1);
2100
- if (part.text !== null && last && last.text !== null) {
2101
- const offset = last.text.length;
2102
- const lines = part.lines ? [...last.lines ?? [], ...part.lines.map((start) => start + offset)] : last.lines;
2103
- parts[parts.length - 1] = {
2104
- text: last.text + part.text,
2105
- lines,
2106
- span: {
2107
- start: last.span.start,
2108
- end: part.span.end
2109
- }
2110
- };
2111
- } else parts.push(part);
2100
+ if (part.text !== null && last && last.text !== null) parts[parts.length - 1] = {
2101
+ text: last.text + part.text,
2102
+ span: {
2103
+ start: last.span.start,
2104
+ end: part.span.end
2105
+ }
2106
+ };
2107
+ else parts.push(part);
2112
2108
  }
2113
2109
  const first = parts[0];
2114
2110
  const span = {
@@ -2117,18 +2113,12 @@ const printParts = (list) => {
2117
2113
  };
2118
2114
  if (parts.length === 1 && first.text !== null) {
2119
2115
  const text = first.text;
2120
- if (!first.lines) return (run, _scope, out) => {
2121
- write(run, out, text, span);
2122
- };
2123
- const entry = indentedText(text, first.lines);
2124
2116
  return (run, _scope, out) => {
2125
- const indent = out.indent;
2126
- write(run, out, indent === "" ? text : indentText(entry, indent, out.inline), span);
2117
+ write(run, out, text, span);
2127
2118
  };
2128
2119
  }
2129
2120
  const count = parts.length;
2130
2121
  const texts = [];
2131
- const indented = [];
2132
2122
  const reads = [];
2133
2123
  const evs = [];
2134
2124
  const emits = [];
@@ -2146,7 +2136,6 @@ const printParts = (list) => {
2146
2136
  const root = compiled?.variable ?? path?.root.variable ?? null;
2147
2137
  const choice = compiled?.choice ? emitChoice(compiled.choice, emit) : null;
2148
2138
  texts.push(part.text);
2149
- indented.push(part.text !== null && part.lines ? indentedText(part.text, part.lines) : null);
2150
2139
  reads.push(root !== null ? "path" : choice ? "choice" : "other");
2151
2140
  evs.push(compiled?.ev ?? null);
2152
2141
  emits.push(emit);
@@ -2158,13 +2147,11 @@ const printParts = (list) => {
2158
2147
  spans.push(part.span);
2159
2148
  }
2160
2149
  return (run, scope, out) => {
2161
- const indent = out.indent;
2162
2150
  let text = "";
2163
2151
  for (let i = 0; i < count; i++) {
2164
2152
  const part = texts[i];
2165
2153
  if (part !== null) {
2166
- const entry = indented[i];
2167
- text += indent === "" || !entry ? part : entry.indent === indent && !out.inline ? entry.indented : indentText(entry, indent, text === "" && out.inline);
2154
+ text += part;
2168
2155
  continue;
2169
2156
  }
2170
2157
  const at = spans[i];
@@ -2648,7 +2635,6 @@ var Compiler = class {
2648
2635
  if (parts.length === 0) partsStart = i;
2649
2636
  parts.push({
2650
2637
  text: statement.value,
2651
- lines: statement.lines,
2652
2638
  span: statement.span
2653
2639
  });
2654
2640
  continue;
@@ -2780,15 +2766,13 @@ var Compiler = class {
2780
2766
  const env = this.#env;
2781
2767
  /**
2782
2768
  * Runs passes `index` to `end`. When a pass waits, the passes after it run as `passesFrom` runs them: ahead of
2783
- * it when they may. `ahead` is whether they may, found the first time a pass waits, and `indent` is the
2784
- * output's indentation when the loop started.
2769
+ * it when they may. `ahead` is whether they may, found the first time a pass waits.
2785
2770
  */
2786
- const iterate = (run, scope, out, values, keys, index, end, reused, indent, ahead) => {
2771
+ const iterate = (run, scope, out, values, keys, index, end, reused, ahead) => {
2787
2772
  const length = values.length;
2788
2773
  for (let i = index; i < end; i++) {
2789
2774
  step(run, span);
2790
2775
  const inner = reused ?? childScope(scope);
2791
- const inline = out.inline;
2792
2776
  inner[valueName] = values[i] ?? null;
2793
2777
  if (keyName !== null) inner[keyName] = keys ? keys[i] ?? null : i;
2794
2778
  if (usesLoop) inner.loop = {
@@ -2811,14 +2795,14 @@ var Compiler = class {
2811
2795
  };
2812
2796
  }
2813
2797
  const may = ahead ??= passesAhead(run, scope, effects.sets, effects.elsewhere);
2814
- return passesFrom(run, out, result, inline, i + 1, end, indent, (aheadRun, aheadOut, at) => iterate(aheadRun, scope, aheadOut, values, keys, at, at + 1, shared ? childScope(scope) : null, indent, may), span, may);
2798
+ return passesFrom(run, out, result, i + 1, end, (aheadRun, aheadOut, at) => iterate(aheadRun, scope, aheadOut, values, keys, at, at + 1, shared ? childScope(scope) : null, may), span, may);
2815
2799
  }
2816
2800
  };
2817
2801
  const start = (run, scope, out, value) => {
2818
2802
  const { values, keys } = loopItems(run, span, value, keyName !== null);
2819
2803
  if (values.length === 0) return alternate?.(run, scope, out);
2820
2804
  const reused = shared ? childScope(scope) : null;
2821
- return iterate(run, scope, out, values, keys, 0, values.length, reused, out.indent, null);
2805
+ return iterate(run, scope, out, values, keys, 0, values.length, reused, null);
2822
2806
  };
2823
2807
  const ev = iterable.ev;
2824
2808
  if (!iterable.async) return (run, scope, out) => {
@@ -2945,31 +2929,20 @@ var Compiler = class {
2945
2929
  }
2946
2930
  #blockStatement(node) {
2947
2931
  this.#defineBlock(node);
2948
- const { name, span, indent } = node;
2932
+ const { name, span } = node;
2949
2933
  return (run, scope, out) => {
2950
2934
  const entry = run.blocks.get(name)?.[0];
2951
2935
  if (!entry) return;
2952
2936
  const render = () => entry.def.body(entry.run.within(run.capture, run.blockDepth), blockScope(entry.def, scope), out);
2953
- const own = entry.run.template === run.template;
2954
- if (indent === "") return own ? render() : withCaller(run, span, render);
2955
- const saved = out.indent;
2956
- const inline = out.inline;
2957
- startPlace(out, indent);
2958
- return endPlace(out, saved, inline, own ? render() : withCaller(run, span, render));
2937
+ return entry.run.template === run.template ? render() : withCaller(run, span, render);
2959
2938
  };
2960
2939
  }
2961
2940
  #include(node) {
2962
- const { ignoreMissing, span, indent } = node;
2963
- return this.#embedding(node.template, node.with, span, (run, out, name, variables) => {
2964
- if (indent === "") return embed(run, out, span, name, variables, null, ignoreMissing);
2965
- const saved = out.indent;
2966
- const inline = out.inline;
2967
- startPlace(out, indent);
2968
- return endPlace(out, saved, inline, embed(run, out, span, name, variables, null, ignoreMissing));
2969
- });
2941
+ const { ignoreMissing, span } = node;
2942
+ return this.#embedding(node.template, node.with, span, (run, out, name, variables) => embed(run, out, span, name, variables, null, ignoreMissing));
2970
2943
  }
2971
2944
  #component(node) {
2972
- const { span, indent } = node;
2945
+ const { span } = node;
2973
2946
  const fills = node.fills.map((fill) => ({
2974
2947
  name: fill.name,
2975
2948
  body: this.#body(fill.body),
@@ -2991,11 +2964,7 @@ var Compiler = class {
2991
2964
  scope: callerScope,
2992
2965
  sets: fill.sets
2993
2966
  });
2994
- if (indent === "") return embed(run, out, span, name, variables, slots, false);
2995
- const saved = out.indent;
2996
- const inline = out.inline;
2997
- startPlace(out, indent);
2998
- return endPlace(out, saved, inline, embed(run, out, span, name, variables, slots, false));
2967
+ return embed(run, out, span, name, variables, slots, false);
2999
2968
  });
3000
2969
  }
3001
2970
  /**
@@ -3013,11 +2982,10 @@ var Compiler = class {
3013
2982
  opening = ISLAND_SCRIPT + opening;
3014
2983
  if (isRoot(state, out)) state.islandScript = true;
3015
2984
  }
3016
- const lead = (at) => (out.inline ? "" : out.indent) + at;
3017
- write(run, out, indent === void 0 ? opening : `${lead(indent)}${opening}${closing?.indent === null ? "" : "\n"}`, span);
2985
+ write(run, out, indent === void 0 ? opening : `${indent}${opening}${closing?.indent === null ? "" : "\n"}`, span);
3018
2986
  return after(fallback(run, childScope(scope), out), () => {
3019
2987
  if (!closing) return write(run, out, ISLAND_CLOSING, span);
3020
- const start = closing.indent === null ? "" : lead(closing.indent);
2988
+ const start = closing.indent ?? "";
3021
2989
  const end = closing.newline ? "\n" : "";
3022
2990
  return write(run, out, `${start}${ISLAND_CLOSING}${end}`, span);
3023
2991
  });
@@ -3040,11 +3008,7 @@ var Compiler = class {
3040
3008
  const state = run.state;
3041
3009
  const islands = state.islands;
3042
3010
  if (islands !== null && (islands.mode === "defer" || state.stream !== null && isRoot(state, out) && !run.capture?.section)) return after(loadTemplate(run, name, span), (template) => template ? render(run, out, scope, islands, template, props) : void 0);
3043
- if (indent === "") return embed(run, out, span, name, props, null, false);
3044
- const saved = out.indent;
3045
- const inline = out.inline;
3046
- startPlace(out, indent);
3047
- return endPlace(out, saved, inline, embed(run, out, span, name, props, null, false));
3011
+ return embed(run, out, span, name, props, null, false);
3048
3012
  };
3049
3013
  return this.#embedding(node.template, node.with, span, (run, out, name, variables, scope) => run.state.islands === null ? place(run, out, name, variables, scope) : atFront(run, () => place(run, out, name, variables, scope)));
3050
3014
  }
@@ -3071,8 +3035,8 @@ var Compiler = class {
3071
3035
  }
3072
3036
  #slot(node) {
3073
3037
  const fallback = this.#body(node.body);
3074
- const { name, span, indent } = node;
3075
- const render = (run, scope, out) => {
3038
+ const { name, span } = node;
3039
+ return (run, scope, out) => {
3076
3040
  const fill = run.slots?.get(name);
3077
3041
  if (!fill) return fallback(run, childScope(scope), out);
3078
3042
  try {
@@ -3085,13 +3049,6 @@ var Compiler = class {
3085
3049
  throw markCaller(run, span, error);
3086
3050
  }
3087
3051
  };
3088
- if (indent === "") return render;
3089
- return (run, scope, out) => {
3090
- const saved = out.indent;
3091
- const inline = out.inline;
3092
- startPlace(out, indent);
3093
- return endPlace(out, saved, inline, render(run, scope, out));
3094
- };
3095
3052
  }
3096
3053
  #with(node) {
3097
3054
  const value = this.#expr(node.value);
@@ -3134,11 +3091,10 @@ var Compiler = class {
3134
3091
  if (value instanceof Markup) return value.value;
3135
3092
  throw fail(run, span, "type-error", `"cache" keys are made of strings, numbers, booleans, dates and null, but got a ${typeName(value)}`);
3136
3093
  };
3137
- const fullKey = (run, out, value) => {
3094
+ const fullKey = (run, value) => {
3138
3095
  const parts = Array.isArray(value) ? value.map((item) => part(run, item)) : [part(run, value)];
3139
3096
  const { locale, timeZone, islands } = run.state;
3140
- let key = `${JSON.stringify(run.state.env.cacheNamespace)}|${templateName}|${locale}|${timeZone}|${JSON.stringify(parts)}`;
3141
- if (out.indent !== "") key += `|indent|${JSON.stringify([out.indent, out.inline])}`;
3097
+ const key = `${JSON.stringify(run.state.env.cacheNamespace)}|${templateName}|${locale}|${timeZone}|${JSON.stringify(parts)}`;
3142
3098
  return islands?.mode === "defer" ? `${key}|islands|${JSON.stringify([islands.url, islands.script])}` : key;
3143
3099
  };
3144
3100
  const lifetime = (run, value) => {
@@ -3147,7 +3103,7 @@ var Compiler = class {
3147
3103
  return value;
3148
3104
  };
3149
3105
  const save = (run, scope, out, keyValue, secondsValue) => {
3150
- const name = fullKey(run, out, keyValue);
3106
+ const name = fullKey(run, keyValue);
3151
3107
  const time = lifetime(run, secondsValue);
3152
3108
  const state = run.state;
3153
3109
  const store = state.env.cache;
@@ -3229,7 +3185,7 @@ var Compiler = class {
3229
3185
  * so the outlet must write to that output, not to a capture or a cached section.
3230
3186
  */
3231
3187
  #outlet(node) {
3232
- const { name, span, indent } = node;
3188
+ const { name, span } = node;
3233
3189
  const mark = (run, out) => {
3234
3190
  const state = run.state;
3235
3191
  if (!isRoot(state, out) || run.capture?.section) throw fail(run, span, "misplaced-outlet", `Outlet "${name}" can't be inside "cache", "set", "apply" or a macro`);
@@ -3238,8 +3194,6 @@ var Compiler = class {
3238
3194
  state.outlets.set(name, {
3239
3195
  out,
3240
3196
  offset: out.s.length,
3241
- indent: indent === void 0 ? out.indent : out.indent + indent,
3242
- inline: indent === void 0,
3243
3197
  content: null
3244
3198
  });
3245
3199
  };
@@ -3267,9 +3221,8 @@ var Compiler = class {
3267
3221
  };
3268
3222
  }
3269
3223
  /**
3270
- * `add to`: renders its content and records it for the outlet. The content takes the outlet's indentation when the
3271
- * outlet has been reached. A `once` tag that already added doesn't render again, but is still recorded, so a cached
3272
- * section saves it.
3224
+ * `add to`: renders its content and records it for the outlet. A `once` tag that already added doesn't render again,
3225
+ * but is still recorded, so a cached section saves it.
3273
3226
  */
3274
3227
  #add(node) {
3275
3228
  const body = this.#body(node.body);
@@ -3285,12 +3238,7 @@ var Compiler = class {
3285
3238
  }, front);
3286
3239
  return;
3287
3240
  }
3288
- const capture = {
3289
- s: "",
3290
- indent: OUTLET_INDENT,
3291
- inline: false,
3292
- ahead: null
3293
- };
3241
+ const capture = emptyOut();
3294
3242
  return after(body(run, childScope(scope), capture), () => recordAddition(run, span, {
3295
3243
  outlet,
3296
3244
  html: capture.s,
@@ -4208,7 +4156,7 @@ const isPrecompiled = (value) => typeof value === "object" && value !== null &&
4208
4156
  const mismatch = (name, detail) => new KilnRenderError("precompiled-mismatch", `Precompiled template "${name}" ${detail}. Precompile it again`, name);
4209
4157
  /** Compiles a precompiled template: its source, with the generated statements in place of the ones they cover. */
4210
4158
  const compilePrecompiled = (env, name, template) => {
4211
- if (template.kiln !== 4) throw mismatch(name, "was made by another version of Kiln");
4159
+ if (template.kiln !== 5) throw mismatch(name, "was made by another version of Kiln");
4212
4160
  if (template.autoescape !== env.autoescape) throw mismatch(name, "was compiled with another \"autoescape\" option");
4213
4161
  const runs = /* @__PURE__ */ new Map();
4214
4162
  const create = template.create;
@@ -4288,30 +4236,29 @@ const runtime = {
4288
4236
  unhold,
4289
4237
  /**
4290
4238
  * Continues a generated run after a statement that returned a promise, `pending`: the rest of the run starts at
4291
- * once, ahead of it, when it may, or else once the statement is done. `inline` is `out.inline` from where the
4292
- * function started. See `runAhead`.
4239
+ * once, ahead of it, when it may, or else once the statement is done. See `runAhead`.
4293
4240
  */
4294
- restAhead: (run, out, pending, inline, indent, rest, span) => mayRunAhead(run.state, inline) ? runAhead(run, out, pending, indent, rest, span) : pending.then(() => rest(run, out)),
4241
+ restAhead: (run, out, pending, rest, span) => mayRunAhead(run.state) ? runAhead(run, out, pending, rest, span) : pending.then(() => rest(run, out)),
4295
4242
  contentSets,
4296
4243
  /**
4297
4244
  * Continues a generated loop after a pass that returned a promise, `pending`: passes `from` to `to` run one at a
4298
4245
  * time with `pass`, ahead of it when they may, see `passesAhead`. `sets` are the variables the loop's body sets,
4299
4246
  * and `elsewhere` whether it places content from elsewhere.
4300
4247
  */
4301
- passAhead: (run, scope, out, pending, inline, indent, sets, elsewhere, from, to, pass, span) => passesFrom(run, out, pending, inline, from, to, indent, pass, span, passesAhead(run, scope, sets, elsewhere)),
4248
+ passAhead: (run, scope, out, pending, sets, elsewhere, from, to, pass, span) => passesFrom(run, out, pending, from, to, pass, span, passesAhead(run, scope, sets, elsewhere)),
4302
4249
  /**
4303
4250
  * For a generated loop that pauses inside a pass: starts passes `from` to `to` ahead of it when they may, and returns
4304
4251
  * what the loop calls once the pass is done. Returns null when they may not, and the loop carries on as usual.
4305
4252
  */
4306
- startAhead: (run, scope, out, inline, indent, sets, elsewhere, from, to, pass, span) => {
4307
- if (!mayRunAhead(run.state, inline) || !passesAhead(run, scope, sets, elsewhere)) return null;
4253
+ startAhead: (run, scope, out, sets, elsewhere, from, to, pass, span) => {
4254
+ if (!mayRunAhead(run.state) || !passesAhead(run, scope, sets, elsewhere)) return null;
4308
4255
  let done = NOTHING;
4309
4256
  let failed = NOTHING;
4310
4257
  const pending = new Promise((resolve, reject) => {
4311
4258
  done = resolve;
4312
4259
  failed = reject;
4313
4260
  });
4314
- const joined = passesFrom(run, out, pending, false, from, to, indent, pass, span, true);
4261
+ const joined = passesFrom(run, out, pending, from, to, pass, span, true);
4315
4262
  return {
4316
4263
  join: () => {
4317
4264
  done();
@@ -4323,10 +4270,6 @@ const runtime = {
4323
4270
  }
4324
4271
  };
4325
4272
  },
4326
- startPlace,
4327
- endPlace,
4328
- indentText,
4329
- indentedText,
4330
4273
  embed,
4331
4274
  embedScope,
4332
4275
  embedKeyed,
@@ -4671,10 +4614,6 @@ const HELPERS = [
4671
4614
  "contentSets",
4672
4615
  "passAhead",
4673
4616
  "startAhead",
4674
- "startPlace",
4675
- "endPlace",
4676
- "indentText",
4677
- "indentedText",
4678
4617
  "truthy",
4679
4618
  "isEmpty",
4680
4619
  "equals",
@@ -4861,7 +4800,7 @@ var Generator = class {
4861
4800
  return [
4862
4801
  "// Precompiled by Kiln. Don't edit this file: precompile the template again.",
4863
4802
  "export default {",
4864
- `\tkiln: 4,`,
4803
+ `\tkiln: 5,`,
4865
4804
  `\tautoescape: ${JSON.stringify(this.#env.autoescape)},`,
4866
4805
  `\tsource: ${JSON.stringify(source)},`,
4867
4806
  " create(rt) {",
@@ -4988,7 +4927,7 @@ var Generator = class {
4988
4927
  const next = `${base}_${index + 1}(run, scope, out)`;
4989
4928
  const body = lines.map((line) => line.replace(WAIT_LINE, (_, tabs, result, ahead) => {
4990
4929
  const then = `${result}.then(() => ${next})`;
4991
- const rest = `restAhead(run, out, ${result}, inl, ind, (run, out) => ${next}, ${span})`;
4930
+ const rest = `restAhead(run, out, ${result}, (run, out) => ${next}, ${span})`;
4992
4931
  return `${tabs}if (${result} !== undefined) return ${ahead === AHEAD ? rest : ahead === GUARDED ? `contentSets(run) ? ${then} : ${rest}` : then};`;
4993
4932
  }));
4994
4933
  const last = index === segments.length - 1;
@@ -5039,8 +4978,6 @@ var Generator = class {
5039
4978
  "let steps = state.steps;",
5040
4979
  "const signal = state.signal;",
5041
4980
  `signal !== undefined && signal.aborted && aborted(run, ${span});`,
5042
- "const ind = out.indent;",
5043
- "const inl = out.inline;",
5044
4981
  "let s = \"\";",
5045
4982
  `let ${[
5046
4983
  "q",
@@ -5188,7 +5125,7 @@ var Generator = class {
5188
5125
  }
5189
5126
  #statement(statement, context) {
5190
5127
  switch (statement.type) {
5191
- case "Text": return [this.#text(statement)];
5128
+ case "Text": return [`s += ${JSON.stringify(statement.value)};`];
5192
5129
  case "Output": return this.#output(statement.expression, statement.span, context);
5193
5130
  case "If": return this.#if(statement, context);
5194
5131
  case "For": return this.#for(statement, context);
@@ -5205,26 +5142,6 @@ var Generator = class {
5205
5142
  default: return unsupported();
5206
5143
  }
5207
5144
  }
5208
- /** Text, with its lines indented to where it is inserted. See `indentText`. */
5209
- #text(statement) {
5210
- const text = JSON.stringify(statement.value);
5211
- if (!statement.lines) return `s += ${text};`;
5212
- const lines = JSON.stringify(statement.lines);
5213
- const entry = this.#constant(`text:${statement.span.start}:${statement.span.end}`, "T", `indentedText(${text}, ${lines})`);
5214
- return `s += ind === "" ? ${text} : ${entry}.indent === ind && !out.inline ? ${entry}.indented : indentText(${entry}, ind, s === "" && out.inline);`;
5215
- }
5216
- /**
5217
- * Inserts content at the indentation of the tag that inserts it, with `startPlace` and `endPlace`. Tags at the start
5218
- * of a line need nothing. Saved values go in temporaries rather than a closure, so the function's locals stay fast.
5219
- */
5220
- #place(at, call) {
5221
- if (at === "") return call;
5222
- const [saved, inline] = [this.#temp(), this.#temp()];
5223
- return `(${saved} = out.indent, ${inline} = out.inline, startPlace(out, ${this.#at(at)}), endPlace(out, ${saved}, ${inline}, ${call}))`;
5224
- }
5225
- #at(at) {
5226
- return at === void 0 ? "undefined" : JSON.stringify(at);
5227
- }
5228
5145
  /** Statements inside another, such as a loop's body. */
5229
5146
  #body(list, context) {
5230
5147
  const inner = {
@@ -5513,7 +5430,7 @@ var Generator = class {
5513
5430
  const call = (part, value) => `${name}_${part}(${partParams}${value === void 0 ? "" : `, ${value}`})`;
5514
5431
  const one = `(run, out, j) => ${name}(run, scope, out, ${loop.values}, ${loop.length}, j, j + 1${keys})`;
5515
5432
  const { sets, elsewhere } = this.#setsOf(statement);
5516
- const handOff = (from, tabs, rest) => from === 0 ? `${tabs}return ${loop.index} + 1 < stop ? passAhead(run, scope, out, ${rest}, inl, ind, ${sets}, ${elsewhere}, ${loop.index} + 1, stop, ${one}, ${loop.span}) : ${rest};` : `${tabs}return ${rest};`;
5433
+ const handOff = (from, tabs, rest) => from === 0 ? `${tabs}return ${loop.index} + 1 < stop ? passAhead(run, scope, out, ${rest}, ${sets}, ${elsewhere}, ${loop.index} + 1, stop, ${one}, ${loop.span}) : ${rest};` : `${tabs}return ${rest};`;
5517
5434
  const continued = (from) => segments.slice(from).flatMap((lines, offset) => this.#forgetLines(lines).flatMap((line) => {
5518
5435
  const next = from + offset + 1;
5519
5436
  const value = VALUE_LINE.exec(line);
@@ -5602,7 +5519,7 @@ var Generator = class {
5602
5519
  const ahead = `a${loop.id}`;
5603
5520
  const { index, span } = loop;
5604
5521
  const { sets, elsewhere } = this.#setsOf(statement);
5605
- const fork = `if (${ahead} === null && ${index} + 1 < stop) ${ahead} = startAhead(run, ${loop.outer}, out, inl, ind, ${sets}, ${elsewhere}, ${index} + 1, stop, (run, out, j) => drive(${name}(run, out, j, j + 1)), ${span});`;
5522
+ const fork = `if (${ahead} === null && ${index} + 1 < stop) ${ahead} = startAhead(run, ${loop.outer}, out, ${sets}, ${elsewhere}, ${index} + 1, stop, (run, out, j) => drive(${name}(run, out, j, j + 1)), ${span});`;
5606
5523
  const body = this.#forgetLines(this.#setFlags(lines)).flatMap((line) => {
5607
5524
  if (line.trim() === FORK) return [line.replace(FORK, fork)];
5608
5525
  const wait = WAIT_LINE.exec(line);
@@ -5767,7 +5684,7 @@ var Generator = class {
5767
5684
  ...target.lines,
5768
5685
  ...variables.lines,
5769
5686
  ...variables.charge(span),
5770
- ...this.#wait(span, this.#place(statement.indent, variables.embed(span, target.name, "null", statement.ignoreMissing)), context.top)
5687
+ ...this.#wait(span, variables.embed(span, target.name, "null", statement.ignoreMissing), context.top)
5771
5688
  ];
5772
5689
  }
5773
5690
  /**
@@ -5855,7 +5772,7 @@ var Generator = class {
5855
5772
  `${slots} = new Map();`,
5856
5773
  ...fills.map((fill) => `${slots}.set(${JSON.stringify(fill.name)}, { body: ${this.#nested(fill.body, statement.span, context)}, run, scope: ${context.scope}, sets: ${mayWrite(fill.body)} });`),
5857
5774
  ...variables.charge(span),
5858
- ...this.#wait(span, this.#place(statement.indent, variables.embed(span, target.name, slots, false)), context.top),
5775
+ ...this.#wait(span, variables.embed(span, target.name, slots, false), context.top),
5859
5776
  ...fills.some((fill) => setsVariables(fill.body)) ? this.#forgetAll() : fills.some((fill) => containsNode(fill.body, (record) => record.type === "Block")) ? this.#afterBlocks() : []
5860
5777
  ];
5861
5778
  }
@@ -5863,7 +5780,6 @@ var Generator = class {
5863
5780
  #slot(statement, context) {
5864
5781
  const span = this.#span(statement.span);
5865
5782
  const fill = this.#temp();
5866
- const at = statement.indent;
5867
5783
  const sets = [...setsIn(statement.body)];
5868
5784
  const scope = sets.length > 0 ? this.#temp() : context.scope;
5869
5785
  let fallback = this.#body(statement.body, {
@@ -5875,23 +5791,10 @@ var Generator = class {
5875
5791
  ...fallback,
5876
5792
  ...sets.flatMap((name) => this.#forget(name))
5877
5793
  ];
5878
- if (at !== "" && !statement.body.every(isBlank)) {
5879
- const [saved, inline] = [this.#temp(), this.#temp()];
5880
- fallback = [
5881
- `${saved} = out.indent;`,
5882
- `${inline} = out.inline;`,
5883
- `startPlace(out, ${this.#at(at)});`,
5884
- "{",
5885
- ...indent(["const ind = out.indent;", ...fallback]),
5886
- "}",
5887
- `out.indent = ${saved};`,
5888
- `if (out.inline) out.inline = ${inline};`
5889
- ];
5890
- }
5891
5794
  return [
5892
5795
  `${fill} = run.slots === null ? undefined : run.slots.get(${JSON.stringify(statement.name)});`,
5893
5796
  `if (${fill} !== undefined) {`,
5894
- ...indent(this.#wait(span, this.#place(at, `fillSlot(run, ${span}, ${fill}, out)`), context.top)),
5797
+ ...indent(this.#wait(span, `fillSlot(run, ${span}, ${fill}, out)`, context.top)),
5895
5798
  "} else {",
5896
5799
  ...indent(fallback),
5897
5800
  "}"
@@ -5905,7 +5808,7 @@ var Generator = class {
5905
5808
  if (context.inLoop) return unsupported();
5906
5809
  this.#pending.push([statement.body, context.strategy]);
5907
5810
  const span = this.#span(statement.span);
5908
- return [...this.#wait(span, this.#place(statement.indent, `placeBlock(run, ${span}, ${JSON.stringify(statement.name)}, ${context.scope}, out)`), context.top), ...this.#afterBlocks()];
5811
+ return [...this.#wait(span, `placeBlock(run, ${span}, ${JSON.stringify(statement.name)}, ${context.scope}, out)`, context.top), ...this.#afterBlocks()];
5909
5812
  }
5910
5813
  /** Forgets every variable lookup after a block is placed when the block, perhaps a child template's version, may set any variable. */
5911
5814
  #afterBlocks() {