@tileflow/core 0.1.0-alpha.32 → 0.1.0-alpha.33

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/build.js CHANGED
@@ -4211,6 +4211,38 @@ function isTileflowThemeName(value) {
4211
4211
  return isTileflowPortableId(value) && value !== "system";
4212
4212
  }
4213
4213
 
4214
+ // src/sun.ts
4215
+ var tileflowSunMetadataKey = "tileflow:sun";
4216
+ var tileflowDefaultSunPreset = Object.freeze({
4217
+ azimuth: 210,
4218
+ altitude: 60,
4219
+ color: "#ffffff",
4220
+ intensity: 0.5,
4221
+ shadowIntensity: 1,
4222
+ ambient: Object.freeze({ color: "#ffffff", intensity: 0.5 })
4223
+ });
4224
+ var degrees = Math.PI / 180;
4225
+ function normalizeTileflowAzimuth(azimuth) {
4226
+ const turned = azimuth % 360;
4227
+ return turned < 0 ? turned + 360 : turned === 0 ? 0 : turned;
4228
+ }
4229
+ function tileflowSunMetadata(preset) {
4230
+ return Object.freeze({ version: 1, ...preset });
4231
+ }
4232
+ function tileflowSunLight(direction, base) {
4233
+ const radial = base?.position?.[0] ?? 1.15;
4234
+ return {
4235
+ ...base ?? {},
4236
+ anchor: "map",
4237
+ position: [
4238
+ radial,
4239
+ Number(normalizeTileflowAzimuth(direction.azimuth).toFixed(3)),
4240
+ // MapLibre lights the extrusions from above the horizon only.
4241
+ Number(Math.min(90, Math.max(0, 90 - direction.altitude)).toFixed(3))
4242
+ ]
4243
+ };
4244
+ }
4245
+
4214
4246
  // src/themes/visual-semantics.ts
4215
4247
  var visualNumberProperties = /* @__PURE__ */ new Set([
4216
4248
  "angle",
@@ -4369,7 +4401,9 @@ var themeTypographyKeys = [
4369
4401
  "water"
4370
4402
  ];
4371
4403
  var themeTypographyDomains = ["places", "poi", "roads", "water"];
4372
- var themeLightingKeys = ["anchor", "color", "intensity", "position"];
4404
+ var themeLightingKeys = ["ambient", "anchor", "color", "intensity", "position", "sun"];
4405
+ var themeSunKeys = ["altitude", "azimuth", "color", "intensity", "shadowIntensity"];
4406
+ var themeAmbientKeys = ["color", "intensity"];
4373
4407
  function resolveTileflowTheme(theme) {
4374
4408
  assertThemeDocument(theme);
4375
4409
  const resolver = new ThemeValueResolver(theme);
@@ -4380,11 +4414,12 @@ function resolveTileflowTheme(theme) {
4380
4414
  number: resolver.resolveCategory("number")
4381
4415
  };
4382
4416
  const typography = resolver.resolveTypography(theme.typography);
4383
- const lighting = resolver.resolveLighting(theme.lighting);
4417
+ const { light: lighting, sun } = resolver.resolveLighting(theme.lighting);
4384
4418
  return {
4385
4419
  colorScheme: theme.colorScheme,
4386
4420
  id: theme.id,
4387
4421
  lighting,
4422
+ ...sun ? { sun } : {},
4388
4423
  tokens,
4389
4424
  typography,
4390
4425
  version: theme.version
@@ -4902,6 +4937,65 @@ var ThemeValueResolver = class {
4902
4937
  };
4903
4938
  }
4904
4939
  resolveLighting(lighting) {
4940
+ const { ambient, sun, ...flat } = lighting;
4941
+ const light = this.#resolveFlatLight(flat);
4942
+ if (sun === void 0 && ambient === void 0) return { light };
4943
+ const resolvedSun = this.resolveTree(sun ?? {}, "theme.lighting.sun");
4944
+ const resolvedAmbient = this.resolveTree(ambient ?? {}, "theme.lighting.ambient");
4945
+ const defaults4 = tileflowDefaultSunPreset;
4946
+ const number = (value, path, fallback, range2) => {
4947
+ if (value === void 0) return fallback;
4948
+ assertFiniteNumber(value, path);
4949
+ if (range2 && (value < range2[0] || value > range2[1])) {
4950
+ throw new Error(`Tileflow ${path} must be between ${range2[0]} and ${range2[1]}.`);
4951
+ }
4952
+ return value;
4953
+ };
4954
+ const colour = (value, path, fallback) => {
4955
+ if (value === void 0) return fallback;
4956
+ assertColor(value, path);
4957
+ return value;
4958
+ };
4959
+ const preset = {
4960
+ azimuth: normalizeTileflowAzimuth(
4961
+ number(resolvedSun.azimuth, "theme.lighting.sun.azimuth", defaults4.azimuth)
4962
+ ),
4963
+ altitude: number(
4964
+ resolvedSun.altitude,
4965
+ "theme.lighting.sun.altitude",
4966
+ defaults4.altitude,
4967
+ [-90, 90]
4968
+ ),
4969
+ color: colour(resolvedSun.color, "theme.lighting.sun.color", defaults4.color),
4970
+ intensity: number(
4971
+ resolvedSun.intensity,
4972
+ "theme.lighting.sun.intensity",
4973
+ defaults4.intensity,
4974
+ [0, 1]
4975
+ ),
4976
+ shadowIntensity: number(
4977
+ resolvedSun.shadowIntensity,
4978
+ "theme.lighting.sun.shadowIntensity",
4979
+ defaults4.shadowIntensity,
4980
+ [0, 1]
4981
+ ),
4982
+ ambient: {
4983
+ color: colour(
4984
+ resolvedAmbient.color,
4985
+ "theme.lighting.ambient.color",
4986
+ defaults4.ambient.color
4987
+ ),
4988
+ intensity: number(
4989
+ resolvedAmbient.intensity,
4990
+ "theme.lighting.ambient.intensity",
4991
+ defaults4.ambient.intensity,
4992
+ [0, 1]
4993
+ )
4994
+ }
4995
+ };
4996
+ return { light: sun === void 0 ? light : tileflowSunLight(preset, light), sun: preset };
4997
+ }
4998
+ #resolveFlatLight(lighting) {
4905
4999
  const result = this.resolveTree(lighting, "theme.lighting");
4906
5000
  if (result.anchor !== void 0 && result.anchor !== "map" && result.anchor !== "viewport") {
4907
5001
  throw themeTypeError("theme.lighting.anchor", "map or viewport", result.anchor);
@@ -5078,6 +5172,24 @@ function assertThemeTypographyStyleFields(style, path) {
5078
5172
  function assertThemeLighting(value, path) {
5079
5173
  const lighting = assertPlainThemeRecord(value, path);
5080
5174
  assertExactThemeKeys(lighting, path, themeLightingKeys);
5175
+ if (Object.hasOwn(lighting, "sun")) {
5176
+ const sun = assertPlainThemeRecord(lighting.sun, `${path}.sun`);
5177
+ assertExactThemeKeys(sun, `${path}.sun`, themeSunKeys);
5178
+ for (const key of ["altitude", "azimuth", "intensity", "shadowIntensity"]) {
5179
+ if (Object.hasOwn(sun, key))
5180
+ assertThemeCategoryValue(sun[key], "number", `${path}.sun.${key}`);
5181
+ }
5182
+ if (Object.hasOwn(sun, "color"))
5183
+ assertThemeCategoryValue(sun.color, "color", `${path}.sun.color`);
5184
+ }
5185
+ if (Object.hasOwn(lighting, "ambient")) {
5186
+ const ambient = assertPlainThemeRecord(lighting.ambient, `${path}.ambient`);
5187
+ assertExactThemeKeys(ambient, `${path}.ambient`, themeAmbientKeys);
5188
+ if (Object.hasOwn(ambient, "intensity"))
5189
+ assertThemeCategoryValue(ambient.intensity, "number", `${path}.ambient.intensity`);
5190
+ if (Object.hasOwn(ambient, "color"))
5191
+ assertThemeCategoryValue(ambient.color, "color", `${path}.ambient.color`);
5192
+ }
5081
5193
  if (Object.hasOwn(lighting, "anchor") && lighting.anchor !== "map" && lighting.anchor !== "viewport") {
5082
5194
  throw themeTypeError(`${path}.anchor`, "map or viewport", lighting.anchor);
5083
5195
  }
@@ -5244,6 +5356,7 @@ function inferThemeCategoryFromPath(path) {
5244
5356
  const tokenCategory = path.match(/^theme\.tokens\.(color|font|image|number)(?:\.|$)/u)?.[1];
5245
5357
  if (isThemeTokenCategory(tokenCategory)) return tokenCategory;
5246
5358
  if (/^theme\.lighting\.position(?:\[\d+\])?$/u.test(path)) return "number";
5359
+ if (/^theme\.lighting\.sun\.(?:altitude|azimuth|shadowIntensity)$/u.test(path)) return "number";
5247
5360
  const segments = path.replace(/\[\d+\]/g, "").split(".");
5248
5361
  return [...segments].reverse().map((segment) => classifyTileflowVisualProperty(segment)).find((category) => category !== void 0);
5249
5362
  }
@@ -6217,7 +6330,7 @@ function compileRoads(request, context) {
6217
6330
  });
6218
6331
  }
6219
6332
  }
6220
- compileSidewalks(request?.sidewalks, context, contributions);
6333
+ compileSidewalks(request?.sidewalks, areaStyles.pedestrian?.fill?.color, context, contributions);
6221
6334
  compileRoundabouts(request?.roundabouts, context, contributions);
6222
6335
  compileCrossings(request?.crossings, context, contributions);
6223
6336
  if (semantics.oneWayMarkers && visible.size > 0) {
@@ -6286,15 +6399,15 @@ function roadPhysicalCohort(roadClass) {
6286
6399
  if (roadClass === "minor" || roadClass === "service" || roadClass === "track") return "local";
6287
6400
  return "path";
6288
6401
  }
6289
- function compileSidewalks(request, context, contributions) {
6402
+ function compileSidewalks(request, pedestrianAreaColor, context, contributions) {
6290
6403
  const { fields, layers } = context.data.schema;
6291
6404
  if (!layers.sidewalk) return;
6292
6405
  const config = mergeTileflowDesign(
6293
6406
  {
6294
6407
  surface: {
6295
- color: context.colors.roads.casing,
6408
+ color: pedestrianAreaColor ?? context.colors.road,
6296
6409
  minZoom: 17,
6297
- opacity: 0.96
6410
+ opacity: 1
6298
6411
  }
6299
6412
  },
6300
6413
  request
@@ -6946,10 +7059,10 @@ function roadWidth(roadClass, scale) {
6946
7059
  [16, 3.4]
6947
7060
  ]
6948
7061
  };
6949
- return zoom.linear(stops[roadClass].map(([z15, value]) => [z15, value * scale]));
7062
+ return zoom.linear(stops[roadClass].map(([z16, value]) => [z16, value * scale]));
6950
7063
  }
6951
7064
  function widen(value, addition) {
6952
- return zoom.linear(value.stops.map(([z15, width]) => [z15, width + addition]));
7065
+ return zoom.linear(value.stops.map(([z16, width]) => [z16, width + addition]));
6953
7066
  }
6954
7067
  function structureFilter(field2, structure) {
6955
7068
  if (structure === "surface") {
@@ -8462,24 +8575,39 @@ function validateStops(stops, api) {
8462
8575
  }
8463
8576
  }
8464
8577
  function validateOperandCount(count, api) {
8465
- if (count > tileflowDataExpressionLimits.maxOperands) {
8466
- throw new Error(
8467
- `${api} supports at most ${tileflowDataExpressionLimits.maxOperands} operands.`
8578
+ const limit = tileflowDataExpressionLimits.maxOperands;
8579
+ if (count > limit) {
8580
+ throw limitError(
8581
+ `${api} received ${count} operands; it supports at most ${limit}. Nest ${api} calls of at most ${limit} operands each.`
8468
8582
  );
8469
8583
  }
8470
8584
  }
8471
8585
  function validateBranchCount(count, api) {
8472
- if (count > tileflowDataExpressionLimits.maxBranches) {
8473
- throw new Error(
8474
- `${api} supports at most ${tileflowDataExpressionLimits.maxBranches} branches.`
8586
+ const limit = tileflowDataExpressionLimits.maxBranches;
8587
+ if (count > limit) {
8588
+ throw limitError(
8589
+ `${api} received ${count} branches; it supports at most ${limit}. Split the lookup into nested ${api} groups of at most ${limit} branches, or reduce the mapping.`
8475
8590
  );
8476
8591
  }
8477
8592
  }
8478
8593
  function validateStopCount(count, api) {
8479
- if (count > tileflowDataExpressionLimits.maxStops) {
8480
- throw new Error(`${api} supports at most ${tileflowDataExpressionLimits.maxStops} stops.`);
8594
+ const limit = tileflowDataExpressionLimits.maxStops;
8595
+ if (count > limit) {
8596
+ throw limitError(
8597
+ `${api} received ${count} stops; it supports at most ${limit}. Remove stops the curve can interpolate.`
8598
+ );
8481
8599
  }
8482
8600
  }
8601
+ function limitError(message) {
8602
+ const site = authoringCallSite(new Error().stack);
8603
+ return new Error(site ? `${message} Called at ${site}.` : message);
8604
+ }
8605
+ function authoringCallSite(stack) {
8606
+ const locations = (stack ?? "").split("\n").slice(1).map((line) => /\(?([^()\s]+?):(\d+):(\d+)\)?$/.exec(line.trim())).filter((match2) => match2 !== null).map(([, file, line, column]) => ({ file: file.replace(/^file:\/\//, ""), line, column }));
8607
+ const own = locations[0]?.file;
8608
+ const site = locations.find(({ file }) => file !== own && !file.startsWith("node:"));
8609
+ return site ? `${site.file}:${site.line}:${site.column}` : void 0;
8610
+ }
8483
8611
  function node(value) {
8484
8612
  if (isTileflowExpression(value)) return cloneJson19(value.value);
8485
8613
  if (isDataFieldReference(value)) return ["get", cloneJson19(value)];
@@ -8673,7 +8801,11 @@ function visitExpression(value, path, variables, issues) {
8673
8801
  return;
8674
8802
  }
8675
8803
  if ((value.length - 2) / 2 > branchLimit) {
8676
- addExpressionIssue(issues, path, `Expression case exceeds ${branchLimit} branches.`);
8804
+ addExpressionIssue(
8805
+ issues,
8806
+ path,
8807
+ `Expression case has ${(value.length - 2) / 2} branches and exceeds ${branchLimit}.`
8808
+ );
8677
8809
  return;
8678
8810
  }
8679
8811
  for (let index = 1; index < value.length; index += 1) visit(value[index], index);
@@ -8689,7 +8821,11 @@ function visitExpression(value, path, variables, issues) {
8689
8821
  return;
8690
8822
  }
8691
8823
  if ((value.length - 3) / 2 > branchLimit) {
8692
- addExpressionIssue(issues, path, `Expression match exceeds ${branchLimit} branches.`);
8824
+ addExpressionIssue(
8825
+ issues,
8826
+ path,
8827
+ `Expression match has ${(value.length - 3) / 2} branches and exceeds ${branchLimit}.`
8828
+ );
8693
8829
  return;
8694
8830
  }
8695
8831
  visit(value[1], 1);
@@ -10616,7 +10752,7 @@ function validateExpressionThemeValues(value, expectedCategory, context, path) {
10616
10752
  if (!parsed.success || parsed.data.category !== expectedCategory) {
10617
10753
  context.addIssue({
10618
10754
  code: "custom",
10619
- message: expectedCategory === void 0 ? "Structural expressions cannot contain theme-token references" : `Expected a ${expectedCategory} theme-token reference`,
10755
+ message: expectedCategory === void 0 ? `Structural expressions cannot contain theme-token references. ${structuralThemeValueHint}` : parsed.success ? `Expected a ${expectedCategory} theme-token reference, received ${parsed.data.category} token "${parsed.data.token}". ${expressionOperandHint(expectedCategory)}` : `Expected a ${expectedCategory} theme-token reference`,
10620
10756
  path
10621
10757
  });
10622
10758
  }
@@ -10625,9 +10761,11 @@ function validateExpressionThemeValues(value, expectedCategory, context, path) {
10625
10761
  if (candidate.kind === "theme-fixed") {
10626
10762
  const parsed = expectedCategory === "number" ? z5.union([fixedNumberSchema, fixedNumberArraySchema]).safeParse(candidate) : expectedCategory === "color" || expectedCategory === "image" ? fixedStringSchema.safeParse(candidate) : void 0;
10627
10763
  if (!parsed?.success) {
10764
+ const received = fixedValueKind(candidate.value);
10765
+ const literal2 = JSON.stringify(candidate.value);
10628
10766
  context.addIssue({
10629
10767
  code: "custom",
10630
- message: expectedCategory === void 0 ? "Structural expressions cannot contain theme-fixed values" : `Expected a fixed ${expectedCategory} value`,
10768
+ message: expectedCategory === void 0 ? `Structural expressions cannot contain theme-fixed values. ${structuralThemeValueHint}` : received !== void 0 && received !== expectedCategoryKind(expectedCategory) ? `Expected a fixed ${expectedCategory} value, received a fixed ${received}. ${expressionOperandHint(expectedCategory)} Write ${literal2} instead of fixed(${literal2}).` : `Expected a fixed ${expectedCategory} value`,
10631
10769
  path
10632
10770
  });
10633
10771
  }
@@ -10647,6 +10785,20 @@ function validateExpressionThemeValues(value, expectedCategory, context, path) {
10647
10785
  validateExpressionThemeValues(entry, expectedCategory, context, [...path, key]);
10648
10786
  }
10649
10787
  }
10788
+ var structuralThemeValueHint = "fixed() and theme tokens apply only to visual properties such as colours, sizes, and images; write structural values directly.";
10789
+ function expressionOperandHint(category) {
10790
+ return `In ${category === "image" ? "an" : "a"} ${category} expression, fixed() and theme tokens belong in its ${category} results; conditions and other operands take plain values.`;
10791
+ }
10792
+ function fixedValueKind(value) {
10793
+ if (typeof value === "number") return "number";
10794
+ if (typeof value === "string") return "string";
10795
+ if (typeof value === "boolean") return "boolean";
10796
+ if (Array.isArray(value)) return "array";
10797
+ return void 0;
10798
+ }
10799
+ function expectedCategoryKind(category) {
10800
+ return category === "number" ? "number" : "string";
10801
+ }
10650
10802
  var numberExpressionSchema = expressionSchemaFor("number");
10651
10803
  var colorExpressionSchema = expressionSchemaFor("color");
10652
10804
  var imageExpressionSchema = expressionSchemaFor("image");
@@ -10759,10 +10911,21 @@ var themeTypographySchema = themeTypographyStyleSchema.extend({
10759
10911
  water: themeTypographyStyleSchema.optional()
10760
10912
  });
10761
10913
  var themeLightingSchema = z5.object({
10914
+ ambient: z5.object({
10915
+ color: themeColorValueSchema.optional(),
10916
+ intensity: themeNumberValueSchema.optional()
10917
+ }).strict().optional(),
10762
10918
  anchor: z5.enum(["map", "viewport"]).optional(),
10763
10919
  color: themeColorValueSchema.optional(),
10764
10920
  intensity: themeNumberValueSchema.optional(),
10765
- position: z5.tuple([themeNumberValueSchema, themeNumberValueSchema, themeNumberValueSchema]).optional()
10921
+ position: z5.tuple([themeNumberValueSchema, themeNumberValueSchema, themeNumberValueSchema]).optional(),
10922
+ sun: z5.object({
10923
+ altitude: themeNumberValueSchema.optional(),
10924
+ azimuth: themeNumberValueSchema.optional(),
10925
+ color: themeColorValueSchema.optional(),
10926
+ intensity: themeNumberValueSchema.optional(),
10927
+ shadowIntensity: themeNumberValueSchema.optional()
10928
+ }).strict().optional()
10766
10929
  }).strict();
10767
10930
  var tileflowThemeSchema = z5.object({
10768
10931
  colorScheme: z5.enum(["light", "dark"]),
@@ -12117,9 +12280,43 @@ function parseOrThrow(schema, input, name) {
12117
12280
  if (result.success) return result.data;
12118
12281
  throw new TileflowResolvedMapValidationError(
12119
12282
  name,
12120
- validationMessagesFromIssues(result.error.issues)
12283
+ validationMessagesFromIssues(expandUnionIssues(result.error.issues, [], input))
12121
12284
  );
12122
12285
  }
12286
+ function expandUnionIssues(issues, base, input) {
12287
+ return issues.flatMap((issue) => {
12288
+ const path = [...base, ...issue.path];
12289
+ if (issue.code !== "invalid_union" || issue.errors.length === 0) return [{ ...issue, path }];
12290
+ const candidates = issue.errors.filter((branch) => !branch.some(isUnionBranchMismatch));
12291
+ if (candidates.length === 0) {
12292
+ return [{ ...issue, path, message: unmatchedUnionMessage(valueAtPath(input, path)) }];
12293
+ }
12294
+ const fewest = Math.min(...candidates.map((branch) => branch.length));
12295
+ const best = candidates.filter((branch) => branch.length === fewest);
12296
+ return best.length === 1 ? expandUnionIssues(best[0], path, input) : [{ ...issue, path }];
12297
+ });
12298
+ }
12299
+ function isUnionBranchMismatch(issue) {
12300
+ if (issue.path.length === 0)
12301
+ return issue.code === "invalid_type" || issue.code === "invalid_value";
12302
+ return issue.path.length === 1 && (issue.code === "invalid_value" || issue.code === "invalid_union" && issue.errors.length === 0);
12303
+ }
12304
+ function unmatchedUnionMessage(value) {
12305
+ const kind = value !== null && typeof value === "object" ? value.kind : void 0;
12306
+ if (kind === "theme-fixed" || kind === "theme-token") {
12307
+ return `This property is structural. ${structuralThemeValueHint}`;
12308
+ }
12309
+ const received = value === null ? "null" : Array.isArray(value) ? "an array" : typeof value;
12310
+ return `Invalid input: no accepted form takes ${received === "object" ? "this object" : received}`;
12311
+ }
12312
+ function valueAtPath(input, path) {
12313
+ let value = input;
12314
+ for (const key of path) {
12315
+ if (value === null || typeof value !== "object" || !Object.hasOwn(value, key)) return void 0;
12316
+ value = value[key];
12317
+ }
12318
+ return value;
12319
+ }
12123
12320
  function validationMessagesFromIssues(issues) {
12124
12321
  return issues.flatMap((issue) => {
12125
12322
  const basePath = issue.path.join(".");
@@ -12183,6 +12380,71 @@ function findUnsafeObjectStructure(input) {
12183
12380
  return void 0;
12184
12381
  }
12185
12382
 
12383
+ // src/route-inks.ts
12384
+ var tileflowRouteMetadataKey = "tileflow:route";
12385
+ var tileflowRouteTokens = Object.freeze({
12386
+ color: Object.freeze({
12387
+ line: "route.line",
12388
+ casing: "route.casing",
12389
+ core: "route.core",
12390
+ glow: "route.glow",
12391
+ alternative: "route.alternative"
12392
+ }),
12393
+ number: Object.freeze({
12394
+ glowOpacity: "route.glow.opacity",
12395
+ coreOpacity: "route.core.opacity"
12396
+ })
12397
+ });
12398
+ var tileflowDefaultRouteInks = Object.freeze({
12399
+ light: Object.freeze({
12400
+ line: "#2563eb",
12401
+ casing: "#1e3a8a",
12402
+ core: "#dbeafe",
12403
+ glow: "#2563eb",
12404
+ alternative: "#94a3b8",
12405
+ glowOpacity: 0.16,
12406
+ coreOpacity: 0
12407
+ }),
12408
+ dark: Object.freeze({
12409
+ line: "#60a5fa",
12410
+ casing: "#0b1220",
12411
+ core: "#eff6ff",
12412
+ glow: "#60a5fa",
12413
+ alternative: "#64748b",
12414
+ glowOpacity: 0.4,
12415
+ coreOpacity: 0.7
12416
+ })
12417
+ });
12418
+ var colourKeys = Object.keys(
12419
+ tileflowRouteTokens.color
12420
+ );
12421
+ var numberKeys = Object.keys(
12422
+ tileflowRouteTokens.number
12423
+ );
12424
+ function resolveTileflowRouteInks(theme) {
12425
+ const defaults4 = tileflowDefaultRouteInks[theme.colorScheme];
12426
+ const inks = { ...defaults4 };
12427
+ for (const key of colourKeys) {
12428
+ const value = theme.tokens.color[tileflowRouteTokens.color[key]];
12429
+ if (value !== void 0) inks[key] = value;
12430
+ }
12431
+ for (const key of numberKeys) {
12432
+ const token = tileflowRouteTokens.number[key];
12433
+ const value = theme.tokens.number[token];
12434
+ if (value === void 0) continue;
12435
+ if (!(value >= 0 && value <= 1)) {
12436
+ throw new Error(
12437
+ `Tileflow theme "${theme.id}" sets number token "${token}" to ${value}; route opacities run from 0 to 1.`
12438
+ );
12439
+ }
12440
+ inks[key] = value;
12441
+ }
12442
+ return Object.freeze(inks);
12443
+ }
12444
+ function tileflowRouteMetadata(inks) {
12445
+ return Object.freeze({ version: 1, ...inks });
12446
+ }
12447
+
12186
12448
  // src/terrain/index.ts
12187
12449
  function resolveTerrain(terrain, apiBaseUrl) {
12188
12450
  if (!terrain || terrain === "none") return void 0;
@@ -12851,6 +13113,47 @@ function isSafeArtifactName(value) {
12851
13113
  });
12852
13114
  }
12853
13115
 
13116
+ // src/cartography/layout-zoom-diagnostics.ts
13117
+ function diagnoseFractionalLayoutZoomSteps(layers) {
13118
+ const diagnostics = [];
13119
+ for (const layer of layers) {
13120
+ const layout = layer.layout;
13121
+ if (layout === null || typeof layout !== "object") continue;
13122
+ for (const [property, value] of Object.entries(layout)) {
13123
+ const stops = fractionalZoomSteps(value);
13124
+ if (stops.length === 0) continue;
13125
+ const [origin] = readTileflowCompilerProvenance(layer);
13126
+ const listed = stops.map((stop) => String(stop)).join(", ");
13127
+ diagnostics.push({
13128
+ code: "TF_LAYOUT_FRACTIONAL_ZOOM_STEP",
13129
+ ...origin ? { domain: origin.owner } : {},
13130
+ message: `${property} steps at zoom ${listed}; layout properties are evaluated at each tile's integer zoom, so the step takes effect at zoom ${stops.map(Math.ceil).join(", ")}.`,
13131
+ path: `layers.${String(layer.id)}.layout.${property}`,
13132
+ phase: "lowering",
13133
+ severity: "warning",
13134
+ suggestion: "Step at whole zooms, or move the change to a paint property or a zoom range.",
13135
+ ...origin ? { target: origin.target } : {}
13136
+ });
13137
+ }
13138
+ }
13139
+ return diagnostics;
13140
+ }
13141
+ function fractionalZoomSteps(value) {
13142
+ if (!Array.isArray(value)) return [];
13143
+ const stops = [];
13144
+ if (value[0] === "step" && isZoom(value[1])) {
13145
+ for (let index = 3; index < value.length; index += 2) {
13146
+ const stop = value[index];
13147
+ if (typeof stop === "number" && !Number.isInteger(stop)) stops.push(stop);
13148
+ }
13149
+ }
13150
+ for (const entry of value) stops.push(...fractionalZoomSteps(entry));
13151
+ return stops;
13152
+ }
13153
+ function isZoom(value) {
13154
+ return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
13155
+ }
13156
+
12854
13157
  // src/cartography/overlay-placement-manifest.ts
12855
13158
  var tileflowOverlayPlacementManifestMetadataKey = "tileflow:overlay-placement-manifest";
12856
13159
  var tileflowOverlayPlacementManifestSchemaVersion = 1;
@@ -14055,6 +14358,8 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
14055
14358
  ...atmosphere ? { [tileflowAtmosphereMetadataKey]: { version: 1, ...atmosphere } } : {},
14056
14359
  "tileflow:theme": selected.name,
14057
14360
  "tileflow:colorScheme": resolvedTheme.colorScheme,
14361
+ [tileflowRouteMetadataKey]: tileflowRouteMetadata(resolveTileflowRouteInks(resolvedTheme)),
14362
+ ...resolvedTheme.sun ? { [tileflowSunMetadataKey]: tileflowSunMetadata(resolvedTheme.sun) } : {},
14058
14363
  "tileflow:data": data.identity,
14059
14364
  "tileflow:sources": sourceIdentities,
14060
14365
  ...Object.keys(loweredOverlays.identities).length > 0 ? { "tileflow:overlays": loweredOverlays.identities } : {},
@@ -14081,7 +14386,16 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
14081
14386
  runCompilationPhase("assets", () => assertTextAssets(style, config));
14082
14387
  runCompilationPhase("assets", () => assertGlyphFontStacks(style, config));
14083
14388
  runCompilationPhase("validation", () => assertMapLibreStyle(style, config.id));
14084
- return { diagnostics, report, style, ...inspection ? { inspection } : {} };
14389
+ const layoutDiagnostics = runCompilationPhase(
14390
+ "validation",
14391
+ () => diagnoseFractionalLayoutZoomSteps(plannedLayers)
14392
+ );
14393
+ return {
14394
+ diagnostics: [...diagnostics, ...layoutDiagnostics],
14395
+ report,
14396
+ style,
14397
+ ...inspection ? { inspection } : {}
14398
+ };
14085
14399
  }
14086
14400
  function finalizeTileflowLayers(input) {
14087
14401
  const ids = /* @__PURE__ */ new Set();
@@ -14726,6 +15040,97 @@ function hasControlCharacter(value) {
14726
15040
  return false;
14727
15041
  }
14728
15042
 
15043
+ // src/capture-shot.ts
15044
+ import { z as z9 } from "zod";
15045
+ var tileflowCaptureShotLimits = Object.freeze({
15046
+ blendThemes: Object.freeze({ maximum: 8, minimum: 2 }),
15047
+ defaultFps: 30,
15048
+ durationMs: Object.freeze({ maximum: 6e4 }),
15049
+ fps: Object.freeze([24, 25, 30, 50, 60]),
15050
+ keyframes: Object.freeze({ maximum: 64, minimum: 2 }),
15051
+ maximumFrames: 3600
15052
+ });
15053
+ var tileflowCaptureShotBlendSchema = z9.object({
15054
+ themes: z9.array(tileflowThemeNameSchema).min(tileflowCaptureShotLimits.blendThemes.minimum).max(tileflowCaptureShotLimits.blendThemes.maximum),
15055
+ position: z9.number().finite().min(0)
15056
+ }).strict().superRefine((blend, context) => {
15057
+ if (new Set(blend.themes).size !== blend.themes.length) {
15058
+ context.addIssue({ code: "custom", message: "Expected distinct themes", path: ["themes"] });
15059
+ }
15060
+ if (blend.position > blend.themes.length - 1) {
15061
+ context.addIssue({
15062
+ code: "custom",
15063
+ message: `Expected a position from 0 to ${blend.themes.length - 1}`,
15064
+ path: ["position"]
15065
+ });
15066
+ }
15067
+ });
15068
+ var tileflowCaptureShotKeyframeSchema = z9.object({
15069
+ at: z9.number().int().min(0).max(tileflowCaptureShotLimits.durationMs.maximum),
15070
+ camera: tileflowCaptureCenterCameraSchema,
15071
+ blend: tileflowCaptureShotBlendSchema.optional()
15072
+ }).strict();
15073
+ var tileflowCaptureShotFields = {
15074
+ theme: tileflowThemeNameSchema,
15075
+ viewport: tileflowCaptureViewportSchema,
15076
+ fps: z9.literal(tileflowCaptureShotLimits.fps).optional(),
15077
+ keyframes: z9.array(tileflowCaptureShotKeyframeSchema).min(tileflowCaptureShotLimits.keyframes.minimum).max(tileflowCaptureShotLimits.keyframes.maximum),
15078
+ easing: z9.enum(["smooth", "linear"]).optional()
15079
+ };
15080
+ var tileflowCaptureShotSchema = z9.object({ map: tileflowPortableIdSchema, ...tileflowCaptureShotFields }).strict().superRefine(checkShotTiming);
15081
+ var tileflowMapShotSchema = z9.object(tileflowCaptureShotFields).strict().superRefine(checkShotTiming);
15082
+ function tileflowCaptureShotFrameCount(shot) {
15083
+ const fps = shot.fps ?? tileflowCaptureShotLimits.defaultFps;
15084
+ const duration = shot.keyframes.at(-1)?.at ?? 0;
15085
+ return Math.floor(duration * fps / 1e3 + 1e-9) + 1;
15086
+ }
15087
+ function checkShotTiming(shot, context) {
15088
+ const { keyframes } = shot;
15089
+ if (keyframes[0] && keyframes[0].at !== 0) {
15090
+ context.addIssue({
15091
+ code: "custom",
15092
+ message: "Expected the first keyframe at 0 milliseconds",
15093
+ path: ["keyframes", 0, "at"]
15094
+ });
15095
+ }
15096
+ for (let index = 1; index < keyframes.length; index += 1) {
15097
+ if (keyframes[index].at <= keyframes[index - 1].at) {
15098
+ context.addIssue({
15099
+ code: "custom",
15100
+ message: "Expected a time after the previous keyframe",
15101
+ path: ["keyframes", index, "at"]
15102
+ });
15103
+ }
15104
+ }
15105
+ const blended = keyframes.filter((keyframe) => keyframe.blend !== void 0);
15106
+ if (blended.length > 0) {
15107
+ const themes = JSON.stringify(blended[0].blend.themes);
15108
+ keyframes.forEach((keyframe, index) => {
15109
+ if (!keyframe.blend) {
15110
+ context.addIssue({
15111
+ code: "custom",
15112
+ message: "Expected a blend on every keyframe when one keyframe blends themes",
15113
+ path: ["keyframes", index, "blend"]
15114
+ });
15115
+ } else if (JSON.stringify(keyframe.blend.themes) !== themes) {
15116
+ context.addIssue({
15117
+ code: "custom",
15118
+ message: "Expected the same themes, in the same order, on every keyframe",
15119
+ path: ["keyframes", index, "blend", "themes"]
15120
+ });
15121
+ }
15122
+ });
15123
+ }
15124
+ const frames = tileflowCaptureShotFrameCount(shot);
15125
+ if (frames > tileflowCaptureShotLimits.maximumFrames) {
15126
+ context.addIssue({
15127
+ code: "custom",
15128
+ message: `Expected at most ${tileflowCaptureShotLimits.maximumFrames} frames; this shot renders ${frames}`,
15129
+ path: ["keyframes", keyframes.length - 1, "at"]
15130
+ });
15131
+ }
15132
+ }
15133
+
14729
15134
  // src/maps/operations.ts
14730
15135
  var resetValue = deepFreeze({ $tileflow: "reset" });
14731
15136
  var disableValue = deepFreeze({ op: "disable" });
@@ -14778,6 +15183,7 @@ var tileflowMapMergeStrategies = {
14778
15183
  overlays: "keyed-resources",
14779
15184
  projection: "atomic",
14780
15185
  scenes: "leaf",
15186
+ shots: "leaf",
14781
15187
  sources: "keyed-resources",
14782
15188
  systemThemes: "atomic",
14783
15189
  terrain: "atomic",
@@ -15154,6 +15560,7 @@ function parseTileflowMap(map) {
15154
15560
  for (const node2 of lineage.reverse()) {
15155
15561
  const resolved = node2 === map ? resolvedLeaf : resolveMap(node2);
15156
15562
  validateMapScenes(node2, resolved.id);
15563
+ validateMapShots(node2, resolved.id);
15157
15564
  const parsed = parseResolvedTileflowMap(resolved);
15158
15565
  if (node2 === map) parsedLeaf = parsed;
15159
15566
  }
@@ -15161,40 +15568,53 @@ function parseTileflowMap(map) {
15161
15568
  return parsedLeaf;
15162
15569
  }
15163
15570
  function validateMapScenes(map, mapId) {
15164
- if (map.scenes === void 0) return;
15165
- if (!isPlainRecord5(map.scenes)) {
15166
- throw new Error(`Invalid Tileflow map "${map.id}". scenes: Expected a plain object.`);
15571
+ validateMapCaptureEntries(map, mapId, "scenes", (input) => {
15572
+ const result = tileflowCaptureSceneSchema.safeParse(input);
15573
+ return result.success ? tileflowCaptureSceneFitIssue(result.data) : result.error.issues[0];
15574
+ });
15575
+ }
15576
+ function validateMapShots(map, mapId) {
15577
+ validateMapCaptureEntries(map, mapId, "shots", (input) => {
15578
+ const result = tileflowCaptureShotSchema.safeParse(input);
15579
+ return result.success ? void 0 : result.error.issues[0];
15580
+ });
15581
+ }
15582
+ function validateMapCaptureEntries(map, mapId, key, findIssue) {
15583
+ const entries = map[key];
15584
+ if (entries === void 0) return;
15585
+ if (!isPlainRecord5(entries)) {
15586
+ throw new Error(`Invalid Tileflow map "${map.id}". ${key}: Expected a plain object.`);
15167
15587
  }
15588
+ const label = key === "scenes" ? "scene" : "shot";
15168
15589
  const namesByCaseFold = /* @__PURE__ */ new Map();
15169
- for (const [sceneName, input] of Object.entries(map.scenes)) {
15170
- const nameResult = tileflowCaptureSceneNameSchema.safeParse(sceneName);
15590
+ for (const [name, input] of Object.entries(entries)) {
15591
+ const nameResult = tileflowCaptureSceneNameSchema.safeParse(name);
15171
15592
  if (!nameResult.success) {
15172
15593
  throw new Error(
15173
- `Invalid Tileflow map "${map.id}". scenes.${sceneName}: ${nameResult.error.issues[0]?.message ?? "Invalid scene name"}`
15594
+ `Invalid Tileflow map "${map.id}". ${key}.${name}: ${nameResult.error.issues[0]?.message ?? `Invalid ${label} name`}`
15174
15595
  );
15175
15596
  }
15176
- const normalizedSceneName = nameResult.data;
15177
- const folded = normalizedSceneName.toLowerCase();
15597
+ const normalizedName = nameResult.data;
15598
+ const folded = normalizedName.toLowerCase();
15178
15599
  const existing = namesByCaseFold.get(folded);
15179
15600
  if (existing) {
15180
15601
  throw new Error(
15181
- `Invalid Tileflow map "${map.id}". scenes.${sceneName}: Expected an id that does not normalize to "${existing}".`
15602
+ `Invalid Tileflow map "${map.id}". ${key}.${name}: Expected an id that does not normalize to "${existing}".`
15182
15603
  );
15183
15604
  }
15184
- namesByCaseFold.set(folded, normalizedSceneName);
15605
+ namesByCaseFold.set(folded, normalizedName);
15185
15606
  if (!isPlainRecord5(input)) {
15186
- throw new Error(`Invalid Tileflow map "${map.id}". scenes.${sceneName}: Expected an object.`);
15607
+ throw new Error(`Invalid Tileflow map "${map.id}". ${key}.${name}: Expected an object.`);
15187
15608
  }
15188
15609
  if (Object.hasOwn(input, "map")) {
15189
15610
  throw new Error(
15190
- `Invalid Tileflow map "${map.id}". scenes.${sceneName}.map: Unrecognized key; a singular map scene inherits its map id.`
15611
+ `Invalid Tileflow map "${map.id}". ${key}.${name}.map: Unrecognized key; a singular map ${label} inherits its map id.`
15191
15612
  );
15192
15613
  }
15193
- const result = tileflowCaptureSceneSchema.safeParse({ ...input, map: mapId });
15194
- const issue = result.success ? tileflowCaptureSceneFitIssue(result.data) : result.error.issues[0];
15195
- if (!result.success || issue) {
15614
+ const issue = findIssue({ ...input, map: mapId });
15615
+ if (issue) {
15196
15616
  throw new Error(
15197
- `Invalid Tileflow map "${map.id}". scenes.${sceneName}${issue?.path.length ? `.${issue.path.join(".")}` : ""}: ${issue?.message ?? "Invalid scene"}`
15617
+ `Invalid Tileflow map "${map.id}". ${key}.${name}${issue.path.length ? `.${issue.path.join(".")}` : ""}: ${issue.message}`
15198
15618
  );
15199
15619
  }
15200
15620
  }
@@ -15206,10 +15626,10 @@ function isPlainRecord5(value) {
15206
15626
  }
15207
15627
 
15208
15628
  // src/icon-composition.ts
15209
- import { z as z10 } from "zod";
15629
+ import { z as z11 } from "zod";
15210
15630
 
15211
15631
  // src/icon-package.ts
15212
- import { z as z9 } from "zod";
15632
+ import { z as z10 } from "zod";
15213
15633
  var tileflowIconIdPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
15214
15634
  var tileflowIconPackageLimits = {
15215
15635
  decodeConcurrency: 4,
@@ -15228,19 +15648,19 @@ var tileflowHostedAlphaCompatibility = {
15228
15648
  },
15229
15649
  maxMapsPerDeploy: 20
15230
15650
  };
15231
- var sha256Schema = z9.string().regex(/^[a-f0-9]{64}$/);
15651
+ var sha256Schema = z10.string().regex(/^[a-f0-9]{64}$/);
15232
15652
  var tileflowIconPackageContentHashSchema = sha256Schema;
15233
- var tileflowIconIdSchema = z9.string().max(64).regex(tileflowIconIdPattern);
15234
- var tileflowRenderedIconManifestEntrySchema = z9.object({
15653
+ var tileflowIconIdSchema = z10.string().max(64).regex(tileflowIconIdPattern);
15654
+ var tileflowRenderedIconManifestEntrySchema = z10.object({
15235
15655
  name: tileflowIconIdSchema,
15236
15656
  appearance: tileflowIconAppearanceSchema.optional(),
15237
15657
  layout: tileflowIconLayoutSchema.optional(),
15238
- pixelSha256: z9.object({
15658
+ pixelSha256: z10.object({
15239
15659
  oneX: sha256Schema,
15240
15660
  twoX: sha256Schema
15241
15661
  }).strict()
15242
15662
  }).strict();
15243
- var tileflowIconPackageLabelSchema = z9.string().superRefine((value, context) => {
15663
+ var tileflowIconPackageLabelSchema = z10.string().superRefine((value, context) => {
15244
15664
  if (value !== value.trim() || value.length === 0) {
15245
15665
  context.addIssue({
15246
15666
  code: "custom",
@@ -15260,32 +15680,32 @@ var tileflowIconPackageLabelSchema = z9.string().superRefine((value, context) =>
15260
15680
  });
15261
15681
  }
15262
15682
  });
15263
- var spriteDimensionsSchema = z9.object({
15264
- height: z9.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension),
15265
- pixelRatio: z9.union([z9.literal(1), z9.literal(2)]),
15266
- width: z9.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension)
15683
+ var spriteDimensionsSchema = z10.object({
15684
+ height: z10.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension),
15685
+ pixelRatio: z10.union([z10.literal(1), z10.literal(2)]),
15686
+ width: z10.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension)
15267
15687
  }).strict();
15268
15688
  function iconPackageFileSchema(name, contentType) {
15269
- return z9.object({
15270
- byteLength: z9.number().int().nonnegative().max(tileflowIconPackageLimits.maxGeneratedFileBytes),
15271
- contentType: z9.literal(contentType),
15272
- name: z9.literal(name),
15689
+ return z10.object({
15690
+ byteLength: z10.number().int().nonnegative().max(tileflowIconPackageLimits.maxGeneratedFileBytes),
15691
+ contentType: z10.literal(contentType),
15692
+ name: z10.literal(name),
15273
15693
  sha256: sha256Schema
15274
15694
  }).strict();
15275
15695
  }
15276
- var tileflowIconPackageManifestSchema = z9.object({
15277
- files: z9.tuple([
15696
+ var tileflowIconPackageManifestSchema = z10.object({
15697
+ files: z10.tuple([
15278
15698
  iconPackageFileSchema("sprite.json", "application/json"),
15279
15699
  iconPackageFileSchema("sprite.png", "image/png"),
15280
15700
  iconPackageFileSchema("sprite@2x.json", "application/json"),
15281
15701
  iconPackageFileSchema("sprite@2x.png", "image/png")
15282
15702
  ]),
15283
- format: z9.enum(["tileflow-icon-package-v1", "tileflow-icon-package-v2"]),
15284
- iconNames: z9.array(tileflowIconIdSchema).min(1).max(tileflowIconPackageLimits.maxIconCount),
15285
- renderedIcons: z9.array(tileflowRenderedIconManifestEntrySchema).min(1).max(tileflowIconPackageLimits.maxIconCount),
15286
- sprites: z9.object({
15287
- oneX: spriteDimensionsSchema.extend({ pixelRatio: z9.literal(1) }),
15288
- twoX: spriteDimensionsSchema.extend({ pixelRatio: z9.literal(2) })
15703
+ format: z10.enum(["tileflow-icon-package-v1", "tileflow-icon-package-v2"]),
15704
+ iconNames: z10.array(tileflowIconIdSchema).min(1).max(tileflowIconPackageLimits.maxIconCount),
15705
+ renderedIcons: z10.array(tileflowRenderedIconManifestEntrySchema).min(1).max(tileflowIconPackageLimits.maxIconCount),
15706
+ sprites: z10.object({
15707
+ oneX: spriteDimensionsSchema.extend({ pixelRatio: z10.literal(1) }),
15708
+ twoX: spriteDimensionsSchema.extend({ pixelRatio: z10.literal(2) })
15289
15709
  }).strict()
15290
15710
  }).strict().superRefine((manifest, context) => {
15291
15711
  if (manifest.renderedIcons.some(
@@ -15384,57 +15804,57 @@ function containsControlCharacter(value) {
15384
15804
 
15385
15805
  // src/icon-composition.ts
15386
15806
  var tileflowIconCompositionMaximumBytes = 1024 * 1024;
15387
- var idsSchema = z10.array(tileflowIconIdSchema).max(tileflowIconPackageLimits.maxIconCount).refine(
15807
+ var idsSchema = z11.array(tileflowIconIdSchema).max(tileflowIconPackageLimits.maxIconCount).refine(
15388
15808
  (ids) => new Set(ids).size === ids.length && ids.every((id2, index) => index === 0 || compareCodeUnits8(ids[index - 1], id2) < 0),
15389
15809
  "Icon exports must be unique and sorted by code unit"
15390
15810
  );
15391
- var localContributorSchema = z10.object({ kind: z10.literal("local"), iconIds: idsSchema }).strict();
15392
- var packageContributorSchema = z10.object({
15393
- kind: z10.literal("package"),
15394
- package: z10.string().max(214).regex(/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/u),
15811
+ var localContributorSchema = z11.object({ kind: z11.literal("local"), iconIds: idsSchema }).strict();
15812
+ var packageContributorSchema = z11.object({
15813
+ kind: z11.literal("package"),
15814
+ package: z11.string().max(214).regex(/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/u),
15395
15815
  iconIds: idsSchema
15396
15816
  }).strict();
15397
- var setContributorSchema = z10.object({
15398
- kind: z10.literal("icon-set"),
15817
+ var setContributorSchema = z11.object({
15818
+ kind: z11.literal("icon-set"),
15399
15819
  reference: tileflowIconSetReferenceSchema,
15400
15820
  teamId: tileflowIconSetTeamIdSchema,
15401
15821
  setId: tileflowIconSetIdSchema,
15402
15822
  versionId: tileflowIconSetVersionIdSchema,
15403
- version: z10.number().int().positive().max(Number.MAX_SAFE_INTEGER),
15823
+ version: z11.number().int().positive().max(Number.MAX_SAFE_INTEGER),
15404
15824
  packageId: tileflowIconSetPackageIdSchema,
15405
15825
  contentHash: tileflowIconPackageContentHashSchema,
15406
15826
  iconIds: idsSchema.min(1)
15407
15827
  }).strict();
15408
- var tileflowRenderedIconIdentitySchema = z10.object({
15409
- kind: z10.literal("rendered-icon"),
15828
+ var tileflowRenderedIconIdentitySchema = z11.object({
15829
+ kind: z11.literal("rendered-icon"),
15410
15830
  id: tileflowIconIdSchema,
15411
15831
  appearance: tileflowIconAppearanceSchema.optional(),
15412
15832
  layout: tileflowIconLayoutSchema.optional(),
15413
- width: z10.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension / 2),
15414
- height: z10.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension / 2),
15415
- pixelSha256: z10.object({
15833
+ width: z11.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension / 2),
15834
+ height: z11.number().int().positive().max(tileflowIconPackageLimits.maxAtlasDimension / 2),
15835
+ pixelSha256: z11.object({
15416
15836
  oneX: tileflowIconPackageContentHashSchema,
15417
15837
  twoX: tileflowIconPackageContentHashSchema
15418
15838
  }).strict()
15419
15839
  }).strict();
15420
- var tileflowIconCompositionSchema = z10.object({
15840
+ var tileflowIconCompositionSchema = z11.object({
15421
15841
  // An explicit map keeps declaration order independent of TypeScript's literal cache.
15422
- format: z10.enum({
15842
+ format: z11.enum({
15423
15843
  "tileflow-icon-composition-v1": "tileflow-icon-composition-v1",
15424
15844
  "tileflow-icon-composition-v2": "tileflow-icon-composition-v2"
15425
15845
  }),
15426
- compositionVersion: z10.union([z10.literal(1), z10.literal(2)]),
15846
+ compositionVersion: z11.union([z11.literal(1), z11.literal(2)]),
15427
15847
  packageHash: tileflowIconPackageContentHashSchema,
15428
- contributors: z10.array(
15429
- z10.discriminatedUnion("kind", [
15848
+ contributors: z11.array(
15849
+ z11.discriminatedUnion("kind", [
15430
15850
  localContributorSchema,
15431
15851
  packageContributorSchema,
15432
15852
  setContributorSchema
15433
15853
  ])
15434
15854
  ).min(1).max(tileflowIconSourceLimit),
15435
- winners: z10.array(
15855
+ winners: z11.array(
15436
15856
  tileflowRenderedIconIdentitySchema.omit({ kind: true }).extend({
15437
- contributor: z10.number().int().min(0).max(tileflowIconSourceLimit - 1)
15857
+ contributor: z11.number().int().min(0).max(tileflowIconSourceLimit - 1)
15438
15858
  })
15439
15859
  ).min(1).max(tileflowIconPackageLimits.maxIconCount)
15440
15860
  }).strict().superRefine((receipt, context) => {
@@ -15786,23 +16206,23 @@ function compileTileflowMapWithInspection(config, options) {
15786
16206
  }
15787
16207
 
15788
16208
  // src/renderer-deployment.ts
15789
- import { z as z14 } from "zod";
16209
+ import { z as z15 } from "zod";
15790
16210
 
15791
16211
  // src/native-build-record.ts
15792
- import { z as z12 } from "zod";
16212
+ import { z as z13 } from "zod";
15793
16213
 
15794
16214
  // src/native-profile-definition.ts
15795
- import { z as z11 } from "zod";
16215
+ import { z as z12 } from "zod";
15796
16216
  var tileflowNativeProfileSchema = strictNativeObject({
15797
- id: z11.literal("native-v1"),
15798
- renderer: z11.literal("native"),
15799
- schemaVersion: z11.literal(1),
15800
- styleVersion: z11.literal(8),
15801
- validatorStyleSpec: z11.literal("24.8.5"),
15802
- reactNativeStyleSpec: z11.literal("26.2.1"),
15803
- maplibreReactNative: z11.literal("11.3.10"),
15804
- android: z11.literal("13.2.0"),
15805
- ios: z11.literal("6.26.0")
16217
+ id: z12.literal("native-v1"),
16218
+ renderer: z12.literal("native"),
16219
+ schemaVersion: z12.literal(1),
16220
+ styleVersion: z12.literal(8),
16221
+ validatorStyleSpec: z12.literal("24.8.5"),
16222
+ reactNativeStyleSpec: z12.literal("26.2.1"),
16223
+ maplibreReactNative: z12.literal("11.3.10"),
16224
+ android: z12.literal("13.2.0"),
16225
+ ios: z12.literal("6.26.0")
15806
16226
  });
15807
16227
  var tileflowNativeProfile = Object.freeze({
15808
16228
  id: "native-v1",
@@ -15815,8 +16235,8 @@ var tileflowNativeProfile = Object.freeze({
15815
16235
  android: "13.2.0",
15816
16236
  ios: "6.26.0"
15817
16237
  });
15818
- var tileflowNativeProfileIdSchema = z11.literal("native-v1");
15819
- var tileflowRendererSchema = z11.enum(["web", "native"]);
16238
+ var tileflowNativeProfileIdSchema = z12.literal("native-v1");
16239
+ var tileflowRendererSchema = z12.enum(["web", "native"]);
15820
16240
 
15821
16241
  // src/native-profile-helpers.ts
15822
16242
  var tileflowNativeProfileLimits = Object.freeze({
@@ -15897,20 +16317,20 @@ function isBoundedNativeJson(input, stage = "input") {
15897
16317
  }
15898
16318
 
15899
16319
  // src/native-build-record.ts
15900
- var hashSchema = z12.string().regex(/^[a-f0-9]{64}$/u);
15901
- var layerCountSchema = z12.number().int().min(0).max(tileflowNativeProfileLimits.maximumLayers);
16320
+ var hashSchema = z13.string().regex(/^[a-f0-9]{64}$/u);
16321
+ var layerCountSchema = z13.number().int().min(0).max(tileflowNativeProfileLimits.maximumLayers);
15902
16322
  var layerTransformationSchema = strictNativeObject({
15903
16323
  inputLayer: layerCountSchema,
15904
16324
  outputStart: layerCountSchema,
15905
- outputCount: z12.number().int().min(1).max(32),
15906
- properties: z12.array(z12.enum(["line-cap", "line-dasharray"])).min(1).max(2).refine(
16325
+ outputCount: z13.number().int().min(1).max(32),
16326
+ properties: z13.array(z13.enum(["line-cap", "line-dasharray"])).min(1).max(2).refine(
15907
16327
  (properties2) => properties2.length === 1 || properties2[0] === "line-cap" && properties2[1] === "line-dasharray",
15908
16328
  "Expected unique, ordered properties"
15909
16329
  )
15910
16330
  });
15911
16331
  var symbolOverlapTransformationSchema = strictNativeObject({
15912
16332
  inputLayer: layerCountSchema,
15913
- properties: z12.array(z12.enum(["icon-overlap", "text-overlap"])).min(1).max(2).refine(
16333
+ properties: z13.array(z13.enum(["icon-overlap", "text-overlap"])).min(1).max(2).refine(
15914
16334
  (properties2) => properties2.length === 1 || properties2[0] === "icon-overlap" && properties2[1] === "text-overlap",
15915
16335
  "Expected unique, ordered properties"
15916
16336
  )
@@ -15922,9 +16342,9 @@ var tileflowNativeStyleTransformationSchema = strictNativeObject({
15922
16342
  loweredStyleSha256: hashSchema,
15923
16343
  inputLayers: layerCountSchema,
15924
16344
  outputLayers: layerCountSchema,
15925
- projection: z12.enum(["none", "mercator-to-implicit", "globe-to-mercator"]),
15926
- layers: z12.array(layerTransformationSchema).max(tileflowNativeProfileLimits.maximumLayers),
15927
- symbolOverlap: z12.array(symbolOverlapTransformationSchema).max(tileflowNativeProfileLimits.maximumLayers)
16345
+ projection: z13.enum(["none", "mercator-to-implicit", "globe-to-mercator"]),
16346
+ layers: z13.array(layerTransformationSchema).max(tileflowNativeProfileLimits.maximumLayers),
16347
+ symbolOverlap: z13.array(symbolOverlapTransformationSchema).max(tileflowNativeProfileLimits.maximumLayers)
15928
16348
  }).superRefine((style, context) => {
15929
16349
  let previous = -1;
15930
16350
  let added = 0;
@@ -15960,14 +16380,14 @@ var tileflowNativeStyleTransformationSchema = strictNativeObject({
15960
16380
  }
15961
16381
  });
15962
16382
  var tileflowNativeBuildRecordSchema = strictNativeObject({
15963
- schemaVersion: z12.literal(2),
15964
- renderer: z12.literal("native"),
15965
- profile: z12.literal("native-v1"),
15966
- validation: z12.literal("static-artifacts"),
15967
- preparationVersion: z12.literal("native-lowering-v1"),
15968
- engines: strictNativeObject({ android: z12.literal("13.2.0"), ios: z12.literal("6.26.0") }),
16383
+ schemaVersion: z13.literal(2),
16384
+ renderer: z13.literal("native"),
16385
+ profile: z13.literal("native-v1"),
16386
+ validation: z13.literal("static-artifacts"),
16387
+ preparationVersion: z13.literal("native-lowering-v1"),
16388
+ engines: strictNativeObject({ android: z13.literal("13.2.0"), ios: z13.literal("6.26.0") }),
15969
16389
  buildManifestSha256: hashSchema,
15970
- transformations: z12.array(tileflowNativeStyleTransformationSchema).max(4096)
16390
+ transformations: z13.array(tileflowNativeStyleTransformationSchema).max(4096)
15971
16391
  }).superRefine((record3, context) => {
15972
16392
  let previous = "";
15973
16393
  for (const [index, item] of record3.transformations.entries()) {
@@ -24423,7 +24843,7 @@ var latest_default = {
24423
24843
  };
24424
24844
 
24425
24845
  // src/native-profile.ts
24426
- import { z as z13 } from "zod";
24846
+ import { z as z14 } from "zod";
24427
24847
 
24428
24848
  // src/native-url-policy.ts
24429
24849
  var tileflowNativeUrlLimits = Object.freeze({ maximumLength: 2048 });
@@ -24578,7 +24998,7 @@ var { resolveTileflowNativeResourceUrl } = createNativeUrlPolicy(
24578
24998
  );
24579
24999
 
24580
25000
  // src/native-profile.ts
24581
- var tileflowNativeDiagnosticCodeSchema = z13.enum([
25001
+ var tileflowNativeDiagnosticCodeSchema = z14.enum([
24582
25002
  "NATIVE_UNSUPPORTED_STYLE",
24583
25003
  "NATIVE_UNSUPPORTED_SOURCE",
24584
25004
  "NATIVE_FONT_UNAVAILABLE",
@@ -24587,13 +25007,13 @@ var tileflowNativeDiagnosticCodeSchema = z13.enum([
24587
25007
  ]);
24588
25008
  var tileflowNativeDiagnosticSchema = strictNativeObject({
24589
25009
  code: tileflowNativeDiagnosticCodeSchema,
24590
- phase: z13.literal("native-compatibility"),
24591
- severity: z13.literal("error"),
24592
- path: z13.string().max(300).regex(/^(?:\/(?:[^~]|~[01])*)?$/u),
24593
- renderer: z13.literal("native"),
25010
+ phase: z14.literal("native-compatibility"),
25011
+ severity: z14.literal("error"),
25012
+ path: z14.string().max(300).regex(/^(?:\/(?:[^~]|~[01])*)?$/u),
25013
+ renderer: z14.literal("native"),
24594
25014
  profile: tileflowNativeProfileIdSchema,
24595
- message: z13.string().max(300),
24596
- suggestion: z13.string().max(300)
25015
+ message: z14.string().max(300),
25016
+ suggestion: z14.string().max(300)
24597
25017
  });
24598
25018
  var descriptions = {
24599
25019
  NATIVE_UNSUPPORTED_STYLE: [
@@ -24973,24 +25393,24 @@ var tileflowRendererDeploymentLimits = Object.freeze({
24973
25393
  maximumNativeFamilyBytes: tileflowNativeProfileLimits.maximumStyleBytes,
24974
25394
  maximumThemes: 64
24975
25395
  });
24976
- var hashSchema2 = z14.string().regex(/^[a-f0-9]{64}$/u);
24977
- var recordSchema = z14.record(z14.string().min(1).max(256), z14.unknown());
24978
- var positive = z14.number().int().positive().max(Number.MAX_SAFE_INTEGER);
24979
- var sourceAssetsSchema = z14.object({
24980
- fonts: z14.array(
24981
- z14.object({
24982
- family: z14.string().min(1).max(128),
25396
+ var hashSchema2 = z15.string().regex(/^[a-f0-9]{64}$/u);
25397
+ var recordSchema = z15.record(z15.string().min(1).max(256), z15.unknown());
25398
+ var positive = z15.number().int().positive().max(Number.MAX_SAFE_INTEGER);
25399
+ var sourceAssetsSchema = z15.object({
25400
+ fonts: z15.array(
25401
+ z15.object({
25402
+ family: z15.string().min(1).max(128),
24983
25403
  sha256: hashSchema2,
24984
- style: z14.enum(["italic", "normal", "oblique"]),
24985
- weight: z14.enum(["100", "200", "300", "400", "500", "600", "700", "800", "900"])
25404
+ style: z15.enum(["italic", "normal", "oblique"]),
25405
+ weight: z15.enum(["100", "200", "300", "400", "500", "600", "700", "800", "900"])
24986
25406
  }).strict()
24987
25407
  ).max(64),
24988
- icons: z14.array(
24989
- z14.union([
24990
- z14.object({
24991
- format: z14.enum(["jpeg", "png", "svg", "webp"]),
25408
+ icons: z15.array(
25409
+ z15.union([
25410
+ z15.object({
25411
+ format: z15.enum(["jpeg", "png", "svg", "webp"]),
24992
25412
  id: tileflowPortableIdSchema,
24993
- kind: z14.enum(["icon", "pattern"]),
25413
+ kind: z15.enum(["icon", "pattern"]),
24994
25414
  sha256: hashSchema2
24995
25415
  }).strict(),
24996
25416
  tileflowRenderedIconIdentitySchema
@@ -24998,44 +25418,44 @@ var sourceAssetsSchema = z14.object({
24998
25418
  ).max(512),
24999
25419
  iconComposition: tileflowIconCompositionSchema.optional()
25000
25420
  }).strict();
25001
- var themeBuildSchema = z14.object({
25002
- colorScheme: z14.enum(["dark", "light"]),
25421
+ var themeBuildSchema = z15.object({
25422
+ colorScheme: z15.enum(["dark", "light"]),
25003
25423
  dataRequirements: recordSchema,
25004
25424
  sourceRequirements: recordSchema,
25005
25425
  styleSha256: hashSchema2,
25006
25426
  themeId: tileflowPortableIdSchema,
25007
25427
  themeVersion: positive
25008
25428
  }).strict();
25009
- var mapBuildSchema = z14.object({
25429
+ var mapBuildSchema = z15.object({
25010
25430
  assetSetSha256: hashSchema2,
25011
25431
  defaultTheme: tileflowThemeNameSchema,
25012
- lineage: z14.array(z14.object({ id: tileflowPortableIdSchema, mapVersion: positive }).strict()).min(1).max(64),
25432
+ lineage: z15.array(z15.object({ id: tileflowPortableIdSchema, mapVersion: positive }).strict()).min(1).max(64),
25013
25433
  mapRevisionSha256: hashSchema2,
25014
- mapRevisionSchemaVersion: z14.literal(2).optional(),
25434
+ mapRevisionSchemaVersion: z15.literal(2).optional(),
25015
25435
  mapVersion: positive,
25016
- semanticCompiler: z14.object({ name: z14.literal("tileflow-semantic"), version: z14.literal(1) }).strict(),
25436
+ semanticCompiler: z15.object({ name: z15.literal("tileflow-semantic"), version: z15.literal(1) }).strict(),
25017
25437
  sourceAssets: sourceAssetsSchema,
25018
- systemThemes: z14.object({ dark: tileflowThemeNameSchema, light: tileflowThemeNameSchema }).strict().optional(),
25019
- themes: z14.record(tileflowThemeNameSchema, themeBuildSchema)
25438
+ systemThemes: z15.object({ dark: tileflowThemeNameSchema, light: tileflowThemeNameSchema }).strict().optional(),
25439
+ themes: z15.record(tileflowThemeNameSchema, themeBuildSchema)
25020
25440
  }).strict();
25021
- var buildManifestSchema = z14.object({
25022
- schemaVersion: z14.literal(1),
25023
- maps: z14.record(tileflowPortableIdSchema, mapBuildSchema),
25024
- provenance: z14.object({
25025
- schemaVersion: z14.literal(1),
25026
- lockfile: z14.object({ format: z14.enum(["bun", "npm", "pnpm", "yarn"]), sha256: hashSchema2 }).strict().optional(),
25027
- packages: z14.record(z14.string().min(1).max(128), z14.string().min(1).max(128))
25441
+ var buildManifestSchema = z15.object({
25442
+ schemaVersion: z15.literal(1),
25443
+ maps: z15.record(tileflowPortableIdSchema, mapBuildSchema),
25444
+ provenance: z15.object({
25445
+ schemaVersion: z15.literal(1),
25446
+ lockfile: z15.object({ format: z15.enum(["bun", "npm", "pnpm", "yarn"]), sha256: hashSchema2 }).strict().optional(),
25447
+ packages: z15.record(z15.string().min(1).max(128), z15.string().min(1).max(128))
25028
25448
  }).strict().optional()
25029
25449
  }).strict();
25030
25450
  var familyShape = {
25031
25451
  buildManifest: buildManifestSchema,
25032
- styles: z14.record(tileflowThemeNameSchema, recordSchema)
25452
+ styles: z15.record(tileflowThemeNameSchema, recordSchema)
25033
25453
  };
25034
- var teamSourcesSchema = z14.record(
25454
+ var teamSourcesSchema = z15.record(
25035
25455
  tileflowPortableIdSchema,
25036
- z14.object({
25037
- tileset: z14.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/u),
25038
- type: z14.enum(["raster", "vector"])
25456
+ z15.object({
25457
+ tileset: z15.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/u),
25458
+ type: z15.enum(["raster", "vector"])
25039
25459
  }).strict()
25040
25460
  ).superRefine((sources, context) => {
25041
25461
  const entries = Object.entries(sources);
@@ -25047,21 +25467,21 @@ var teamSourcesSchema = z14.record(
25047
25467
  tilesets.add(value.tileset);
25048
25468
  }
25049
25469
  });
25050
- var viewSchema2 = z14.object({
25051
- center: z14.tuple([z14.number().min(-180).max(180), z14.number().min(-90).max(90)]).optional(),
25052
- zoom: z14.number().min(0).max(24).optional(),
25053
- bearing: z14.number().finite().optional(),
25054
- pitch: z14.number().min(0).max(85).optional()
25470
+ var viewSchema2 = z15.object({
25471
+ center: z15.tuple([z15.number().min(-180).max(180), z15.number().min(-90).max(90)]).optional(),
25472
+ zoom: z15.number().min(0).max(24).optional(),
25473
+ bearing: z15.number().finite().optional(),
25474
+ pitch: z15.number().min(0).max(85).optional()
25055
25475
  }).strict();
25056
- var tileflowRendererDeploymentArtifactSchema = z14.object({
25057
- kind: z14.literal("tileflow-map-deployment"),
25058
- schemaVersion: z14.literal(2),
25476
+ var tileflowRendererDeploymentArtifactSchema = z15.object({
25477
+ kind: z15.literal("tileflow-map-deployment"),
25478
+ schemaVersion: z15.literal(2),
25059
25479
  mapId: tileflowPortableIdSchema,
25060
25480
  teamSources: teamSourcesSchema,
25061
25481
  view: viewSchema2.optional(),
25062
- renderers: z14.object({
25063
- web: z14.object(familyShape).strict(),
25064
- native: z14.object({ ...familyShape, buildRecord: tileflowNativeBuildRecordSchema }).strict()
25482
+ renderers: z15.object({
25483
+ web: z15.object(familyShape).strict(),
25484
+ native: z15.object({ ...familyShape, buildRecord: tileflowNativeBuildRecordSchema }).strict()
25065
25485
  }).strict()
25066
25486
  }).strict().superRefine((artifact, context) => {
25067
25487
  const fail = () => context.addIssue({
@@ -25186,30 +25606,30 @@ function object(value) {
25186
25606
  function equal(left, right) {
25187
25607
  return left === void 0 || right === void 0 ? left === right : serializeCanonicalJson(left) === serializeCanonicalJson(right);
25188
25608
  }
25189
- var artifactName = z14.string().min(1).max(256).refine(
25609
+ var artifactName = z15.string().min(1).max(256).refine(
25190
25610
  (value) => [...value].every((char) => {
25191
25611
  const code = char.codePointAt(0);
25192
25612
  return code >= 32 && code !== 127;
25193
25613
  })
25194
25614
  );
25195
- var semanticSchema = z14.object({
25196
- version: z14.literal(2),
25197
- domains: z14.object({
25198
- poi: z14.object({
25199
- deduplication: z14.object({
25200
- identity: z14.tuple([
25201
- z14.literal("source"),
25202
- z14.literal("source-layer"),
25203
- z14.literal("feature-id")
25615
+ var semanticSchema = z15.object({
25616
+ version: z15.literal(2),
25617
+ domains: z15.object({
25618
+ poi: z15.object({
25619
+ deduplication: z15.object({
25620
+ identity: z15.tuple([
25621
+ z15.literal("source"),
25622
+ z15.literal("source-layer"),
25623
+ z15.literal("feature-id")
25204
25624
  ]),
25205
- representationPriority: z14.tuple([
25206
- z14.literal("marker"),
25207
- z14.literal("icon"),
25208
- z14.literal("combined"),
25209
- z14.literal("label")
25625
+ representationPriority: z15.tuple([
25626
+ z15.literal("marker"),
25627
+ z15.literal("icon"),
25628
+ z15.literal("combined"),
25629
+ z15.literal("label")
25210
25630
  ])
25211
25631
  }).strict(),
25212
- fields: z14.object({
25632
+ fields: z15.object({
25213
25633
  category: artifactName,
25214
25634
  filterRank: artifactName,
25215
25635
  icon: artifactName,
@@ -25217,18 +25637,18 @@ var semanticSchema = z14.object({
25217
25637
  sizeRank: artifactName,
25218
25638
  type: artifactName
25219
25639
  }).strict(),
25220
- hitTesting: z14.object({
25221
- frequency: z14.literal("animation-frame"),
25222
- order: z14.literal("rendered-topmost")
25640
+ hitTesting: z15.object({
25641
+ frequency: z15.literal("animation-frame"),
25642
+ order: z15.literal("rendered-topmost")
25223
25643
  }).strict(),
25224
- identity: z14.literal("maplibre-feature-id-if-present"),
25225
- layers: z14.array(
25226
- z14.object({
25227
- anchor: z14.literal("pointer-coordinate"),
25228
- category: z14.enum(tileflowPoiCategories),
25644
+ identity: z15.literal("maplibre-feature-id-if-present"),
25645
+ layers: z15.array(
25646
+ z15.object({
25647
+ anchor: z15.literal("pointer-coordinate"),
25648
+ category: z15.enum(tileflowPoiCategories),
25229
25649
  layerId: artifactName,
25230
- priority: z14.number().int().min(0).max(4095),
25231
- representation: z14.enum(["combined", "icon", "label", "marker"]),
25650
+ priority: z15.number().int().min(0).max(4095),
25651
+ representation: z15.enum(["combined", "icon", "label", "marker"]),
25232
25652
  source: artifactName,
25233
25653
  sourceLayer: artifactName
25234
25654
  }).strict()
@@ -25254,8 +25674,8 @@ function semanticIdentity(style) {
25254
25674
  const poi2 = manifest.domains.poi;
25255
25675
  return poi2 ? { ...poi2, layers: poi2.layers.map(({ priority: _priority, ...identity }) => identity) } : manifest;
25256
25676
  }
25257
- var mapIdSchema = z14.string().regex(/^map_[A-Za-z0-9_-]{16}$/u);
25258
- var publicUrlSchema = z14.string().min(1).max(2048).refine((value) => {
25677
+ var mapIdSchema = z15.string().regex(/^map_[A-Za-z0-9_-]{16}$/u);
25678
+ var publicUrlSchema = z15.string().min(1).max(2048).refine((value) => {
25259
25679
  try {
25260
25680
  const url = new URL(value);
25261
25681
  return url.protocol === "https:" && !url.username && !url.password && !url.search && !url.hash && url.toString() === value && !/tf_(?:public|native|live)_/u.test(value);
@@ -25263,22 +25683,22 @@ var publicUrlSchema = z14.string().min(1).max(2048).refine((value) => {
25263
25683
  return false;
25264
25684
  }
25265
25685
  });
25266
- var webResponseTheme = z14.object({ styleId: z14.string().min(1).max(128).optional(), styleUrl: publicUrlSchema }).strict();
25267
- var nativeResponseTheme = z14.object({ styleUrl: publicUrlSchema, revision: hashSchema2 }).strict();
25268
- var tileflowRendererDeploymentResponseSchema = z14.object({
25269
- kind: z14.literal("tileflow-map-deployment-result"),
25270
- schemaVersion: z14.literal(2),
25271
- changed: z14.boolean(),
25686
+ var webResponseTheme = z15.object({ styleId: z15.string().min(1).max(128).optional(), styleUrl: publicUrlSchema }).strict();
25687
+ var nativeResponseTheme = z15.object({ styleUrl: publicUrlSchema, revision: hashSchema2 }).strict();
25688
+ var tileflowRendererDeploymentResponseSchema = z15.object({
25689
+ kind: z15.literal("tileflow-map-deployment-result"),
25690
+ schemaVersion: z15.literal(2),
25691
+ changed: z15.boolean(),
25272
25692
  mapId: mapIdSchema,
25273
- deploymentId: z14.string().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/u),
25693
+ deploymentId: z15.string().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/u),
25274
25694
  version: positive,
25275
- worldConversionId: z14.string().min(1).max(128).optional(),
25276
- renderers: z14.object({
25277
- web: z14.object({ themes: z14.record(tileflowThemeNameSchema, webResponseTheme) }).strict(),
25278
- native: z14.object({
25279
- profile: z14.literal("native-v1"),
25695
+ worldConversionId: z15.string().min(1).max(128).optional(),
25696
+ renderers: z15.object({
25697
+ web: z15.object({ themes: z15.record(tileflowThemeNameSchema, webResponseTheme) }).strict(),
25698
+ native: z15.object({
25699
+ profile: z15.literal("native-v1"),
25280
25700
  manifestUrl: publicUrlSchema,
25281
- themes: z14.record(tileflowThemeNameSchema, nativeResponseTheme)
25701
+ themes: z15.record(tileflowThemeNameSchema, nativeResponseTheme)
25282
25702
  }).strict()
25283
25703
  }).strict()
25284
25704
  }).strict().superRefine((value, context) => {