@aglyn/plugins-ai 1.0.0-beta.291 → 1.0.0-beta.293

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-site-import-job.component.js +5 -4
  3. package/src/lib/components/ai-site-import-job.component.js.map +1 -1
  4. package/src/lib/components/ai-site-import-start.component.js +3 -3
  5. package/src/lib/components/ai-site-import-start.component.js.map +1 -1
  6. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  7. package/src/lib/components/ai-site-start-card.component.js +129 -29
  8. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  9. package/src/lib/components/ai-site-start-steps.component.d.ts +15 -3
  10. package/src/lib/components/ai-site-start-steps.component.js +42 -25
  11. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  12. package/src/lib/components/ai-site-style-previews.d.ts +17 -0
  13. package/src/lib/components/ai-site-style-previews.js +26 -95
  14. package/src/lib/components/ai-site-style-previews.js.map +1 -1
  15. package/src/lib/declarations.server.js +22 -0
  16. package/src/lib/declarations.server.js.map +1 -1
  17. package/src/lib/jobs/ai-job-import-step.d.ts +21 -2
  18. package/src/lib/jobs/ai-job-import-step.js +179 -49
  19. package/src/lib/jobs/ai-job-import-step.js.map +1 -1
  20. package/src/lib/jobs/ai-job-layout-language.d.ts +27 -3
  21. package/src/lib/jobs/ai-job-layout-language.js +156 -113
  22. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  23. package/src/lib/jobs/ai-job-layout-step.js +56 -17
  24. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  25. package/src/lib/jobs/ai-job-page-language.d.ts +25 -15
  26. package/src/lib/jobs/ai-job-page-language.js +120 -66
  27. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  28. package/src/lib/jobs/ai-job-page-step.js +27 -7
  29. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  30. package/src/lib/jobs/ai-job-site-datasets.d.ts +12 -4
  31. package/src/lib/jobs/ai-job-site-datasets.js +36 -16
  32. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  33. package/src/lib/jobs/ai-jobs.js +6 -2
  34. package/src/lib/jobs/ai-jobs.js.map +1 -1
  35. package/src/lib/jobs/ai-layout-stock-photos.d.ts +50 -1
  36. package/src/lib/jobs/ai-layout-stock-photos.js +586 -35
  37. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  38. package/src/lib/jobs/ai-site-import-compile.d.ts +147 -0
  39. package/src/lib/jobs/ai-site-import-compile.js +1143 -0
  40. package/src/lib/jobs/ai-site-import-compile.js.map +1 -0
  41. package/src/lib/jobs/ai-site-import-document.d.ts +9 -36
  42. package/src/lib/jobs/ai-site-import-document.js +23 -489
  43. package/src/lib/jobs/ai-site-import-document.js.map +1 -1
  44. package/src/lib/jobs/ai-site-import-look.d.ts +54 -7
  45. package/src/lib/jobs/ai-site-import-look.js +163 -52
  46. package/src/lib/jobs/ai-site-import-look.js.map +1 -1
  47. package/src/lib/jobs/ai-site-import-publish.d.ts +7 -1
  48. package/src/lib/jobs/ai-site-import-publish.js +19 -5
  49. package/src/lib/jobs/ai-site-import-publish.js.map +1 -1
  50. package/src/lib/jobs/ai-site-late-photos.js +4 -2
  51. package/src/lib/jobs/ai-site-late-photos.js.map +1 -1
  52. package/src/lib/jobs/ai-site-publish.d.ts +10 -1
  53. package/src/lib/jobs/ai-site-publish.js +8 -3
  54. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  55. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.d.ts +23 -0
  56. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js +677 -0
  57. package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js.map +1 -0
  58. package/src/lib/layout-language/ai-layout-compiler.d.ts +26 -0
  59. package/src/lib/layout-language/ai-layout-compiler.js +677 -33
  60. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  61. package/src/lib/layout-language/ai-layout-frame-hollows.js +5 -1
  62. package/src/lib/layout-language/ai-layout-frame-hollows.js.map +1 -1
  63. package/src/lib/layout-language/ai-layout-frame-source.d.ts +196 -0
  64. package/src/lib/layout-language/ai-layout-frame-source.js +726 -0
  65. package/src/lib/layout-language/ai-layout-frame-source.js.map +1 -0
  66. package/src/lib/layout-language/ai-layout-frame.d.ts +22 -0
  67. package/src/lib/layout-language/ai-layout-frame.js +121 -29
  68. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  69. package/src/lib/layout-language/ai-layout-language.d.ts +103 -37
  70. package/src/lib/layout-language/ai-layout-language.js +85 -120
  71. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  72. package/src/lib/model/ai-credit-estimate.d.ts +11 -7
  73. package/src/lib/model/ai-credit-estimate.js +11 -7
  74. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  75. package/src/lib/model/ai-site-import.d.ts +307 -13
  76. package/src/lib/model/ai-site-import.js +227 -19
  77. package/src/lib/model/ai-site-import.js.map +1 -1
  78. package/src/lib/model/ai-site-look.d.ts +65 -1
  79. package/src/lib/model/ai-site-look.js +141 -23
  80. package/src/lib/model/ai-site-look.js.map +1 -1
  81. package/src/lib/model/ai-site-photos.d.ts +2 -0
  82. package/src/lib/model/ai-site-photos.js.map +1 -1
  83. package/src/lib/model/ai-site-start-steps.d.ts +4 -3
  84. package/src/lib/model/ai-site-start-steps.js +11 -3
  85. package/src/lib/model/ai-site-start-steps.js.map +1 -1
  86. package/src/lib/model/ai-site-start.d.ts +23 -2
  87. package/src/lib/model/ai-site-start.js +25 -3
  88. package/src/lib/model/ai-site-start.js.map +1 -1
  89. package/src/lib/providers/routing.d.ts +11 -0
  90. package/src/lib/providers/routing.js +23 -0
  91. package/src/lib/providers/routing.js.map +1 -1
  92. package/src/lib/runtime/ai-doctrine-validators.d.ts +4 -2
  93. package/src/lib/runtime/ai-doctrine-validators.js +7 -2
  94. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  95. package/src/lib/runtime/ai-icon-library.d.ts +4 -0
  96. package/src/lib/runtime/ai-icon-library.js +4 -0
  97. package/src/lib/runtime/ai-icon-library.js.map +1 -1
  98. package/src/lib/runtime/ai-node-tree.js +5 -1
  99. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  100. package/src/lib/runtime/ai-palette.d.ts +2 -0
  101. package/src/lib/runtime/ai-palette.generated.js +19 -3
  102. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  103. package/src/lib/runtime/ai-palette.js +2 -1
  104. package/src/lib/runtime/ai-palette.js.map +1 -1
  105. package/src/lib/site-import/fixtures/site-layout-recordings.d.ts +50 -0
  106. package/src/lib/site-import/fixtures/site-layout-recordings.js +86 -0
  107. package/src/lib/site-import/fixtures/site-layout-recordings.js.map +1 -0
  108. package/src/lib/site-import/site-import-crawl.d.ts +18 -1
  109. package/src/lib/site-import/site-import-crawl.js +70 -10
  110. package/src/lib/site-import/site-import-crawl.js.map +1 -1
  111. package/src/lib/site-import/site-import-css.d.ts +110 -0
  112. package/src/lib/site-import/site-import-css.js +826 -0
  113. package/src/lib/site-import/site-import-css.js.map +1 -0
  114. package/src/lib/site-import/site-import-html.d.ts +116 -1
  115. package/src/lib/site-import/site-import-html.js +538 -46
  116. package/src/lib/site-import/site-import-html.js.map +1 -1
  117. package/src/lib/site-import/site-import-layout.d.ts +79 -0
  118. package/src/lib/site-import/site-import-layout.js +1608 -0
  119. package/src/lib/site-import/site-import-layout.js.map +1 -0
  120. package/src/lib/site-import/site-import-nav.d.ts +40 -0
  121. package/src/lib/site-import/site-import-nav.js +437 -0
  122. package/src/lib/site-import/site-import-nav.js.map +1 -0
  123. package/src/lib/site-import/site-import-page.d.ts +8 -1
  124. package/src/lib/site-import/site-import-page.js +24 -2
  125. package/src/lib/site-import/site-import-page.js.map +1 -1
  126. package/src/lib/assets/site-styles/beauty.webp +0 -0
  127. package/src/lib/assets/site-styles/blog.webp +0 -0
  128. package/src/lib/assets/site-styles/business.webp +0 -0
  129. package/src/lib/assets/site-styles/coming-soon.webp +0 -0
  130. package/src/lib/assets/site-styles/education.webp +0 -0
  131. package/src/lib/assets/site-styles/events.webp +0 -0
  132. package/src/lib/assets/site-styles/fitness.webp +0 -0
  133. package/src/lib/assets/site-styles/landing.webp +0 -0
  134. package/src/lib/assets/site-styles/music.webp +0 -0
  135. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  136. package/src/lib/assets/site-styles/personal.webp +0 -0
  137. package/src/lib/assets/site-styles/photography.webp +0 -0
  138. package/src/lib/assets/site-styles/portfolio.webp +0 -0
  139. package/src/lib/assets/site-styles/professional.webp +0 -0
  140. package/src/lib/assets/site-styles/realestate.webp +0 -0
  141. package/src/lib/assets/site-styles/restaurant.webp +0 -0
  142. package/src/lib/assets/site-styles/store.webp +0 -0
  143. package/src/lib/assets/site-styles/studio.webp +0 -0
  144. package/src/lib/assets/site-styles/trades.webp +0 -0
  145. package/src/lib/assets/site-styles/wellness.webp +0 -0
  146. package/src/lib/assets/site-styles/yoga.webp +0 -0
  147. package/src/lib/site-import/site-import-review.d.ts +0 -40
  148. package/src/lib/site-import/site-import-review.js +0 -149
  149. package/src/lib/site-import/site-import-review.js.map +0 -1
@@ -834,6 +834,32 @@ const MAKERS = [
834
834
  return found;
835
835
  });
836
836
  }
837
+ /**
838
+ * The worlds a drink is sold in (2026-10-29, AGL-4092): where "water" on a
839
+ * menu is a bottle of it, never a lake, and a "drink" a soda.
840
+ */ const FOOD_WORLDS = [
841
+ 'taco',
842
+ 'taqueria',
843
+ 'burrito',
844
+ 'mexican food',
845
+ 'street food',
846
+ 'food truck',
847
+ 'food',
848
+ 'restaurant',
849
+ 'cafe',
850
+ 'caterer',
851
+ 'catering',
852
+ 'menu',
853
+ 'meal',
854
+ 'cuisine',
855
+ 'bakery',
856
+ 'deli',
857
+ 'pizza',
858
+ 'burger',
859
+ 'barbecue',
860
+ 'bbq',
861
+ 'diner'
862
+ ];
837
863
  /**
838
864
  * The kin of a few objects whose own word is not enough (AGL-3660): a "melt"
839
865
  * is any melting thing (the beta.239 "Wax melts" tile showed resin fluid
@@ -1180,16 +1206,10 @@ const MAKERS = [
1180
1206
  // A fountain drink is a soda, never a well's fountain (AGL-4092).
1181
1207
  objects: [
1182
1208
  'drink',
1183
- 'soda'
1184
- ],
1185
- within: [
1186
- 'taco',
1187
- 'taqueria',
1188
- 'burrito',
1189
- 'mexican food',
1190
- 'street food',
1191
- 'food truck'
1209
+ 'soda',
1210
+ 'cola'
1192
1211
  ],
1212
+ within: FOOD_WORLDS,
1193
1213
  // Never "fountain drink" itself: a well's page address says it word for word.
1194
1214
  kin: [
1195
1215
  'soda',
@@ -1197,18 +1217,88 @@ const MAKERS = [
1197
1217
  'iced tea',
1198
1218
  'agua fresca',
1199
1219
  'lemonade',
1200
- 'soda cup'
1220
+ 'soda cup',
1221
+ 'soda can',
1222
+ 'soda bottle',
1223
+ 'cola'
1201
1224
  ],
1202
1225
  queries: [
1203
1226
  'soda cup',
1204
1227
  'agua fresca'
1205
1228
  ]
1229
+ },
1230
+ {
1231
+ // Bottled water is a bottle of water (2026-10-29, AGL-4092): Pit Row
1232
+ // Tacos' "Bottled Water" searched "taco water", then its broad "tacos",
1233
+ // and took tomatoes beside a bowl of salsa.
1234
+ objects: [
1235
+ 'water'
1236
+ ],
1237
+ within: FOOD_WORLDS,
1238
+ kin: [
1239
+ 'bottled water',
1240
+ 'water bottle',
1241
+ 'bottle of water',
1242
+ 'mineral water',
1243
+ 'drinking water',
1244
+ 'sparkling water'
1245
+ ],
1246
+ queries: [
1247
+ 'bottled water',
1248
+ 'water bottle'
1249
+ ]
1250
+ },
1251
+ {
1252
+ // An agua fresca is a glass of fruit water, never a taco (2026-10-29, AGL-4092).
1253
+ objects: [
1254
+ 'fresca',
1255
+ 'horchata',
1256
+ 'lemonade',
1257
+ 'limeade'
1258
+ ],
1259
+ within: FOOD_WORLDS,
1260
+ kin: [
1261
+ 'agua fresca',
1262
+ 'horchata',
1263
+ 'lemonade',
1264
+ 'limeade',
1265
+ 'fruit water',
1266
+ 'fruit drink',
1267
+ 'infused water',
1268
+ 'fruit juice'
1269
+ ],
1270
+ queries: [
1271
+ 'agua fresca',
1272
+ 'lemonade'
1273
+ ]
1206
1274
  }
1207
1275
  ];
1208
1276
  /** An object's kin where the site or the subject is of its world, else `null`. */ function objectKin(object, world) {
1209
1277
  var _OBJECT_KIN_find;
1210
1278
  return (_OBJECT_KIN_find = OBJECT_KIN.find((entry)=>entry.objects.some((word)=>aiStockStem(word) === object) && entry.within.some((word)=>world.includes(stemPhrase(word))))) != null ? _OBJECT_KIN_find : null;
1211
1279
  }
1280
+ /**
1281
+ * Whether a record's or a product's thing is a photo of itself alone
1282
+ * (2026-10-29, AGL-4092): its object has kin ({@link OBJECT_KIN}), and
1283
+ * neither its words nor its kin name the craft itself ({@link AiStockSiteTerms.core}).
1284
+ * Pit Row Tacos' "Bottled Water" is bottled water: no photo of the taco
1285
+ * trailer's world is one, and its broad "tacos" took tomatoes beside a bowl
1286
+ * of salsa. A soap shop's "Lavender Soap Bar" names its soap, and a soap's
1287
+ * photo still shows it. Such a thing is searched by its own words and kin
1288
+ * alone, never by the craft's photos, and takes none of another record's.
1289
+ * Pure.
1290
+ */ export function aiStockThingOfItsOwn(subject, terms) {
1291
+ const object = aiStockObjectWord(subject);
1292
+ if (!object) return false;
1293
+ const kin = objectKin(object, [
1294
+ ...terms.domain,
1295
+ ...stemList(subject)
1296
+ ]);
1297
+ if (!kin) return false;
1298
+ const core = new Set(terms.core);
1299
+ const namesCore = (phrase)=>withPairs(stemList(phrase)).some((term)=>core.has(term));
1300
+ return !namesCore(subject) && !kin.kin.some(namesCore);
1301
+ }
1212
1302
  /**
1213
1303
  * The kin of a few common crafts: the words a photo of that world is
1214
1304
  * tagged with, and the broad searches that find it. A craft not listed
@@ -2120,6 +2210,81 @@ const MAKERS = [
2120
2210
  'superbike',
2121
2211
  'studio',
2122
2212
  'posing'
2213
+ ],
2214
+ // Never "garage" or "workshop": a parts shop's mechanic works in one.
2215
+ road: [
2216
+ 'road',
2217
+ 'roads',
2218
+ 'street',
2219
+ 'streets',
2220
+ 'highway',
2221
+ 'asphalt',
2222
+ 'traffic',
2223
+ 'city',
2224
+ 'urban',
2225
+ 'travel',
2226
+ 'trip',
2227
+ 'road trip',
2228
+ 'vacation',
2229
+ 'touring',
2230
+ 'tourer',
2231
+ 'motorcycle suit',
2232
+ 'leathers',
2233
+ 'sportbike',
2234
+ 'sport bike',
2235
+ 'sports bike',
2236
+ 'superbike',
2237
+ 'super bike',
2238
+ 'cafe racer',
2239
+ 'model',
2240
+ 'posing',
2241
+ 'studio'
2242
+ ],
2243
+ ground: [
2244
+ 'dirt',
2245
+ 'mud',
2246
+ 'muddy',
2247
+ 'dust',
2248
+ 'dusty',
2249
+ 'sand',
2250
+ 'sandy',
2251
+ 'dune',
2252
+ 'dunes',
2253
+ 'desert',
2254
+ 'gravel',
2255
+ 'trail',
2256
+ 'terrain',
2257
+ 'off-road',
2258
+ 'offroad',
2259
+ 'track',
2260
+ 'dirt track',
2261
+ 'grass track',
2262
+ 'motocross track',
2263
+ 'jump',
2264
+ 'berm',
2265
+ 'dirt bike',
2266
+ 'dirtbike',
2267
+ 'enduro',
2268
+ 'supercross'
2269
+ ]
2270
+ },
2271
+ // A team's riders in their gear and their racing (AGL-4092): the library
2272
+ // answers "motocross paddock" with horses and "motocross pits" with
2273
+ // avocados, so neither is asked.
2274
+ team: {
2275
+ words: [
2276
+ 'team',
2277
+ 'teams',
2278
+ 'club',
2279
+ 'clubs',
2280
+ 'squad'
2281
+ ],
2282
+ making: [
2283
+ 'motocross rider gear',
2284
+ 'dirt bike racing'
2285
+ ],
2286
+ broad: [
2287
+ 'motocross track'
2123
2288
  ]
2124
2289
  }
2125
2290
  },
@@ -2202,7 +2367,6 @@ const MAKERS = [
2202
2367
  'salsa',
2203
2368
  'mexican',
2204
2369
  'mexican food',
2205
- 'street food',
2206
2370
  'food truck',
2207
2371
  'taco truck',
2208
2372
  'griddle',
@@ -2214,6 +2378,52 @@ const MAKERS = [
2214
2378
  'pastor',
2215
2379
  'asada'
2216
2380
  ],
2381
+ // Street food is anyone's (2026-10-29, AGL-4092): a man with a cart in
2382
+ // the rain and a woman with a bagel cart in Antalya, tagged "street food",
2383
+ // filled Pit Row Tacos' gallery. It names the trailer's world only beside
2384
+ // its own food or its truck.
2385
+ near: [
2386
+ 'street food'
2387
+ ],
2388
+ // Its truck is a taco truck: an ice cream van or a hot dog stand tagged
2389
+ // "food truck" is another trailer's (2026-10-29, AGL-4092).
2390
+ rivals: {
2391
+ words: [
2392
+ 'ice cream',
2393
+ 'gelato',
2394
+ 'dessert',
2395
+ 'hot dog',
2396
+ 'hotdog',
2397
+ 'pizza',
2398
+ 'burger',
2399
+ 'burgers',
2400
+ 'crepe',
2401
+ 'crepes',
2402
+ 'donut',
2403
+ 'doughnut',
2404
+ 'kebab',
2405
+ 'sushi',
2406
+ 'popcorn',
2407
+ 'cotton candy',
2408
+ 'waffle',
2409
+ 'pretzel',
2410
+ 'bagel',
2411
+ 'simit',
2412
+ 'fruit stand'
2413
+ ],
2414
+ core: [
2415
+ 'taco',
2416
+ 'tacos',
2417
+ 'taqueria',
2418
+ 'tortilla',
2419
+ 'tortillas',
2420
+ 'burrito',
2421
+ 'quesadilla',
2422
+ 'nachos',
2423
+ 'salsa',
2424
+ 'mexican'
2425
+ ]
2426
+ },
2217
2427
  broad: [
2218
2428
  'tacos',
2219
2429
  'street tacos',
@@ -2365,6 +2575,7 @@ const MAKERS = [
2365
2575
  /** Stems and stem pairs of every clause that names its world, and of those that only say what it is asked for. */ const said = new Set();
2366
2576
  const asked = new Set();
2367
2577
  /** The business's own clause, as stems and stem pairs: what its lead is read from. */ let own = [];
2578
+ /** Every word of the business's own clause, those naming a world only beside another kept: "team" of "motocross race team". */ let ownAll = [];
2368
2579
  let ownSeen = false;
2369
2580
  /** The last word of the first clause that names the world: "soap" of "for handmade cold-process soap". */ let firstWorld = '';
2370
2581
  let named = false;
@@ -2387,6 +2598,7 @@ const MAKERS = [
2387
2598
  if (!ownSeen && businessOf(clause).length) {
2388
2599
  ownSeen = true;
2389
2600
  own = kept.filter((word)=>!LEAD_GENERIC.has(word));
2601
+ ownAll = kept;
2390
2602
  }
2391
2603
  if (kept.length) named = true;
2392
2604
  // What it makes names its world by what the things are made of, never
@@ -2465,10 +2677,14 @@ const MAKERS = [
2465
2677
  core: group.rivals.core.map(groupTerm)
2466
2678
  });
2467
2679
  }
2680
+ // A team of the craft's world is shown racing, never at the repair shop's bench (AGL-4092).
2681
+ const ownStems = new Set(ownAll.flatMap((word)=>stemList(word)));
2468
2682
  for (const group of major){
2683
+ var _ref;
2469
2684
  for (const word of group.match)core.add(groupTerm(word));
2470
- broad.push(...group.broad);
2471
- makingSearches.push(...group.making);
2685
+ const team = group.team && group.team.words.some((word)=>ownStems.has(aiStockStem(word))) ? group.team : null;
2686
+ broad.push(...group.broad, ...(_ref = team == null ? void 0 : team.broad) != null ? _ref : []);
2687
+ makingSearches.push(...team ? team.making : group.making);
2472
2688
  }
2473
2689
  // A two-word name of a listed world names it whole: "dirt bike", never
2474
2690
  // "bike" (a bicycle's) where the type says it nowhere else (AGL-4065).
@@ -2501,13 +2717,19 @@ const MAKERS = [
2501
2717
  ].some((term)=>term === stem || term.includes(' ') && term.split(' ').includes(stem) && ownTerms.has(term))) lead.add(stem);
2502
2718
  }
2503
2719
  // A wider world's names lead only where the business's own words say them
2504
- // (AGL-4092): a motocross team's world is off-road, never "motorcycle" alone.
2720
+ // (AGL-4092): a motocross team's world is off-road, never "motorcycle" alone,
2721
+ // and a street bike's words are never its pictures' without the ground.
2722
+ const road = new Set();
2723
+ const ground = new Set();
2505
2724
  for (const group of leading){
2725
+ var _group_wider_road, _group_wider_ground;
2506
2726
  if (!group.wider) continue;
2507
2727
  const wider = group.wider.words.map(groupTerm);
2508
2728
  if (wider.some((term)=>ownTerms.has(term))) continue;
2509
2729
  for (const term of wider)lead.delete(term);
2510
2730
  for (const word of group.wider.shunLead)shunLead.add(groupTerm(word));
2731
+ for (const word of (_group_wider_road = group.wider.road) != null ? _group_wider_road : [])road.add(groupTerm(word));
2732
+ for (const word of (_group_wider_ground = group.wider.ground) != null ? _group_wider_ground : [])ground.add(groupTerm(word));
2511
2733
  }
2512
2734
  // A trade's world, named by the world it serves: "dirt bike" for a dirt bike parts shop.
2513
2735
  const served = (craftGroup == null ? void 0 : craftGroup.of) ? groups.filter((group)=>group !== craftGroup).flatMap((group)=>group.match).filter((word)=>typeTerms.includes(groupTerm(word))).sort((a, b)=>positionOf(groupTerm(a)) - positionOf(groupTerm(b)))[0] : undefined;
@@ -2575,7 +2797,14 @@ const MAKERS = [
2575
2797
  shunLead: [
2576
2798
  ...shunLead
2577
2799
  ]
2578
- });
2800
+ }, road.size ? {
2801
+ road: [
2802
+ ...road
2803
+ ],
2804
+ ground: [
2805
+ ...ground
2806
+ ]
2807
+ } : {});
2579
2808
  }
2580
2809
  /**
2581
2810
  * Words that say a picture is one of a set, never what it shows (AGL-3923):
@@ -3363,6 +3592,15 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3363
3592
  * read as "size", and took a soap dispenser.
3364
3593
  */ const PRODUCT_SIZES = /\b(?:(?:starter|travel|trial|sample|mini|full|half|family|value|jumbo|large|small|regular|standard|big)[- ])?sized?s?\b/gi;
3365
3594
  /** The wrapper words a gift is named by, searched with the craft: "soap gift box". */ const GIFT_WRAPPERS = words('gift gifts box boxes basket baskets hamper hampers');
3595
+ /** A product's subjects, its name's first, its sizes left out ({@link aiStockProductSearches}). */ function aiStockProductSubjects(slot) {
3596
+ var _ref;
3597
+ var _slot_product;
3598
+ return ((_ref = (_slot_product = slot.product) == null ? void 0 : _slot_product.subjects) != null ? _ref : []).map((raw)=>aiStockSubjectWords(raw.replace(PRODUCT_SIZES, ' '), '')).filter(Boolean);
3599
+ }
3600
+ /** A product's own subject: its name's noun phrase ({@link aiStockProductSearches}). */ const aiStockProductSubject = (slot)=>{
3601
+ var _aiStockProductSubjects_;
3602
+ return (_aiStockProductSubjects_ = aiStockProductSubjects(slot)[0]) != null ? _aiStockProductSubjects_ : '';
3603
+ };
3366
3604
  /**
3367
3605
  * A product's searches (AGL-3676), most specific first: each of its subjects
3368
3606
  * — its name's noun phrase, then its photo's — with the shop's category
@@ -3409,8 +3647,7 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3409
3647
  * product names it. A size never names the product: "Bath Gift Set Starter
3410
3648
  * Size" is a bath gift set.
3411
3649
  */ export function aiStockProductSearches(slot, craft, domain = [], fallback = {}) {
3412
- var _ref, _subjects_, _fallback_held, _fallback_core, _fallback_leadWord, _ref1, _fallback_broad, _fallback_broad1;
3413
- var _slot_product;
3650
+ var _subjects_, _fallback_held, _fallback_core, _fallback_leadWord, _ref, _fallback_core1, _fallback_broad;
3414
3651
  const orientation = aiStockOrientation(slot.aspect);
3415
3652
  const size = orientation === 'vertical' ? {
3416
3653
  minHeight: 900
@@ -3422,7 +3659,7 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3422
3659
  ...domain,
3423
3660
  ...craftStems
3424
3661
  ]);
3425
- const subjects = ((_ref = (_slot_product = slot.product) == null ? void 0 : _slot_product.subjects) != null ? _ref : []).map((raw)=>aiStockSubjectWords(raw.replace(PRODUCT_SIZES, ' '), '')).filter(Boolean);
3662
+ const subjects = aiStockProductSubjects(slot);
3426
3663
  // The product's head noun is its name's: "candle" of "Hand-Poured Soy Candle".
3427
3664
  const own = (_subjects_ = subjects[0]) != null ? _subjects_ : '';
3428
3665
  const object = aiStockObjectWord(own);
@@ -3453,12 +3690,12 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3453
3690
  ];
3454
3691
  // A trade's product is named by the world it serves: "dirt bike skid plate", never "part skid plate".
3455
3692
  const prefix = trade ? (_fallback_leadWord = fallback.leadWord) != null ? _fallback_leadWord : '' : craft;
3456
- const shun = ((_ref1 = kin == null ? void 0 : kin.shun) != null ? _ref1 : []).map(aiStockStem);
3693
+ const shun = ((_ref = kin == null ? void 0 : kin.shun) != null ? _ref : []).map(aiStockStem);
3457
3694
  const queries = [];
3458
3695
  for (const subject of subjects){
3459
- var _ref2;
3696
+ var _ref1;
3460
3697
  const stems = stemList(subject);
3461
- const qualifier = (_ref2 = kin == null ? void 0 : kin.qualifier) != null ? _ref2 : '';
3698
+ const qualifier = (_ref1 = kin == null ? void 0 : kin.qualifier) != null ? _ref1 : '';
3462
3699
  const query = kin ? !qualifier || stems.includes(aiStockStem(qualifier)) ? subject : kin.after ? `${subject} ${qualifier}` : `${qualifier} ${subject}` : prefix && !stems.some((stem)=>world.has(stem)) ? `${prefix} ${subject}` : subject;
3463
3700
  queries.push({
3464
3701
  query,
@@ -3493,8 +3730,20 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3493
3730
  const held = [
3494
3731
  ...queries
3495
3732
  ];
3733
+ // A thing of its own is a photo of itself, never of the shop's category (AGL-4092): "Bottled Water" is no taco.
3734
+ const itsOwn = Boolean(own) && aiStockThingOfItsOwn(own, {
3735
+ domain: [
3736
+ ...world
3737
+ ],
3738
+ core: [
3739
+ ...core,
3740
+ ...craftStems,
3741
+ ...(_fallback_core1 = fallback.core) != null ? _fallback_core1 : []
3742
+ ]
3743
+ });
3744
+ const broadOf = itsOwn ? [] : (_fallback_broad = fallback.broad) != null ? _fallback_broad : [];
3496
3745
  // 2. A photo OF its category, which may be one the job already shows.
3497
- for (const query of (_fallback_broad = fallback.broad) != null ? _fallback_broad : [])queries.push({
3746
+ for (const query of broadOf)queries.push({
3498
3747
  query,
3499
3748
  subject: own,
3500
3749
  object: '',
@@ -3518,7 +3767,7 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3518
3767
  tier: 'weak'
3519
3768
  });
3520
3769
  // The craft's own broad searches, any hit naming the craft.
3521
- for (const query of (_fallback_broad1 = fallback.broad) != null ? _fallback_broad1 : [])queries.push({
3770
+ for (const query of broadOf)queries.push({
3522
3771
  query,
3523
3772
  subject: own,
3524
3773
  object: '',
@@ -3655,10 +3904,17 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3655
3904
  // own object among the first tags, and searched by its object's kin, never
3656
3905
  // the category's world alone (AGL-3660).
3657
3906
  const collection = part === 'collection' && Boolean(terms.craft) && !work;
3907
+ // A record of a thing of its own is a photo of that thing, never of the
3908
+ // site's world (AGL-4092): a taco trailer's "Bottled Water" took tomatoes
3909
+ // from its broad "tacos".
3910
+ const itsOwn = Boolean(slot.record) && !work && Boolean(subject) && aiStockThingOfItsOwn(subject, {
3911
+ domain: terms.domain,
3912
+ core
3913
+ });
3658
3914
  // A picture's broad searches find a photo OF the business's own world,
3659
3915
  // never one naming it in a word of a tag (AGL-4092); a hero's first tag
3660
3916
  // already names it.
3661
- const broad = kin && collection || work ? [] : terms.broad.filter(shown).map((query)=>_extends({
3917
+ const broad = kin && collection || work || itsOwn ? [] : terms.broad.filter(shown).map((query)=>_extends({
3662
3918
  query,
3663
3919
  broad: true,
3664
3920
  category: collection
@@ -3671,11 +3927,14 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3671
3927
  // the site's own world, and "Around town" of its customers out where it is.
3672
3928
  const thingless = Boolean(subject) && !object && !work;
3673
3929
  const out = thingless && slot.role !== 'hero' && PLACE_PHRASES.test(slot.alt);
3674
- // The maker at work, held to the craft: never "hands" (AGL-3660).
3930
+ // The maker at work, held to the craft: never "hands" (AGL-3660), and a
3931
+ // photo OF the business's own world, never a taco bowl salad for a taco
3932
+ // trailer's crew at work (AGL-4092).
3675
3933
  const makers = (work ? [] : (_terms_making = terms.making) != null ? _terms_making : []).filter(shown).map((query)=>({
3676
3934
  query,
3677
3935
  broad: true,
3678
- category: true
3936
+ category: true,
3937
+ own: true
3679
3938
  }));
3680
3939
  // A portrait in its role, in the site's world, where the libraries know a word for it.
3681
3940
  const roleWord = slot.people ? (_ref = (_aiStockPeopleRole = aiStockPeopleRole(slot.alt, sectionName)) == null ? void 0 : _aiStockPeopleRole.query) != null ? _ref : '' : '';
@@ -3706,6 +3965,18 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
3706
3965
  query: `${leadWord} ${subject}`.trim(),
3707
3966
  own: true
3708
3967
  }
3968
+ ] : itsOwn ? [
3969
+ // Its own words and its kin, never qualified by the site's world: "bottled water", never "taco bottled water".
3970
+ {
3971
+ query: subject,
3972
+ held: true,
3973
+ leads: true
3974
+ },
3975
+ ...kin ? kin.queries.map((query)=>({
3976
+ query,
3977
+ held: true,
3978
+ leads: true
3979
+ })) : []
3709
3980
  ] : ofTheWorld ? [
3710
3981
  {
3711
3982
  query: `${leadWord} ${subjectStems.some((stem)=>!leadStems.includes(stem)) ? subject.split(/\s+/).filter((word)=>!leadStems.includes(aiStockStem(word))).join(' ') : ''}`.trim(),
@@ -4047,6 +4318,252 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
4047
4318
  ]);
4048
4319
  return groups.filter((group)=>!group.some((stem)=>named.has(stem))).flat();
4049
4320
  }
4321
+ /**
4322
+ * Cities, states and countries a library's street photos are tagged with
4323
+ * (2026-10-29, AGL-4092), as stem phrases. Only where a tag says the photo is
4324
+ * of a street or a town ({@link STREET_HEADS}) does one say where it is set:
4325
+ * tacos tagged "mexico" are a dish, a cart tagged "antalya, turkey, street"
4326
+ * is a street in Turkey. A word that is as often something else ("chile",
4327
+ * "jordan", "nice") is not one.
4328
+ */ const NAMED_PLACES = [
4329
+ // Countries and regions.
4330
+ 'afghanistan',
4331
+ 'africa',
4332
+ 'albania',
4333
+ 'algeria',
4334
+ 'argentina',
4335
+ 'armenia',
4336
+ 'asia',
4337
+ 'australia',
4338
+ 'austria',
4339
+ 'bali',
4340
+ 'bangladesh',
4341
+ 'belgium',
4342
+ 'bolivia',
4343
+ 'bosnia',
4344
+ 'brazil',
4345
+ 'bulgaria',
4346
+ 'cambodia',
4347
+ 'canada',
4348
+ 'china',
4349
+ 'colombia',
4350
+ 'croatia',
4351
+ 'cuba',
4352
+ 'cyprus',
4353
+ 'czech',
4354
+ 'czechia',
4355
+ 'denmark',
4356
+ 'dominican republic',
4357
+ 'ecuador',
4358
+ 'egypt',
4359
+ 'england',
4360
+ 'estonia',
4361
+ 'ethiopia',
4362
+ 'europe',
4363
+ 'finland',
4364
+ 'france',
4365
+ 'germany',
4366
+ 'ghana',
4367
+ 'greece',
4368
+ 'guatemala',
4369
+ 'holland',
4370
+ 'hungary',
4371
+ 'iceland',
4372
+ 'india',
4373
+ 'indonesia',
4374
+ 'iran',
4375
+ 'iraq',
4376
+ 'ireland',
4377
+ 'israel',
4378
+ 'italy',
4379
+ 'jamaica',
4380
+ 'japan',
4381
+ 'kenya',
4382
+ 'korea',
4383
+ 'laos',
4384
+ 'latvia',
4385
+ 'lebanon',
4386
+ 'lithuania',
4387
+ 'malaysia',
4388
+ 'malta',
4389
+ 'mexico',
4390
+ 'mongolia',
4391
+ 'montenegro',
4392
+ 'morocco',
4393
+ 'myanmar',
4394
+ 'nepal',
4395
+ 'netherlands',
4396
+ 'new zealand',
4397
+ 'nigeria',
4398
+ 'norway',
4399
+ 'pakistan',
4400
+ 'panama',
4401
+ 'peru',
4402
+ 'philippines',
4403
+ 'poland',
4404
+ 'portugal',
4405
+ 'romania',
4406
+ 'russia',
4407
+ 'scotland',
4408
+ 'serbia',
4409
+ 'singapore',
4410
+ 'slovakia',
4411
+ 'slovenia',
4412
+ 'spain',
4413
+ 'sri lanka',
4414
+ 'sweden',
4415
+ 'switzerland',
4416
+ 'syria',
4417
+ 'taiwan',
4418
+ 'tanzania',
4419
+ 'thailand',
4420
+ 'tunisia',
4421
+ 'turkey',
4422
+ 'ukraine',
4423
+ 'united kingdom',
4424
+ 'uruguay',
4425
+ 'uzbekistan',
4426
+ 'venezuela',
4427
+ 'vietnam',
4428
+ 'wales',
4429
+ // Cities.
4430
+ 'amsterdam',
4431
+ 'antalya',
4432
+ 'athens',
4433
+ 'bangkok',
4434
+ 'barcelona',
4435
+ 'beijing',
4436
+ 'berlin',
4437
+ 'bogota',
4438
+ 'bruges',
4439
+ 'brussels',
4440
+ 'budapest',
4441
+ 'buenos aires',
4442
+ 'cairo',
4443
+ 'cancun',
4444
+ 'cologne',
4445
+ 'copenhagen',
4446
+ 'cusco',
4447
+ 'delhi',
4448
+ 'dubai',
4449
+ 'dublin',
4450
+ 'edinburgh',
4451
+ 'florence',
4452
+ 'frankfurt',
4453
+ 'hamburg',
4454
+ 'hanoi',
4455
+ 'havana',
4456
+ 'ho chi minh',
4457
+ 'hong kong',
4458
+ 'istanbul',
4459
+ 'jaipur',
4460
+ 'jakarta',
4461
+ 'jerusalem',
4462
+ 'kathmandu',
4463
+ 'kolkata',
4464
+ 'krakow',
4465
+ 'kuala lumpur',
4466
+ 'kyoto',
4467
+ 'lisbon',
4468
+ 'london',
4469
+ 'lyon',
4470
+ 'madrid',
4471
+ 'manila',
4472
+ 'marrakech',
4473
+ 'marrakesh',
4474
+ 'milan',
4475
+ 'montreal',
4476
+ 'moscow',
4477
+ 'mumbai',
4478
+ 'munich',
4479
+ 'naples',
4480
+ 'oaxaca',
4481
+ 'osaka',
4482
+ 'oslo',
4483
+ 'paris',
4484
+ 'porto',
4485
+ 'prague',
4486
+ 'quito',
4487
+ 'rio de janeiro',
4488
+ 'rome',
4489
+ 'saigon',
4490
+ 'salzburg',
4491
+ 'seoul',
4492
+ 'seville',
4493
+ 'shanghai',
4494
+ 'stockholm',
4495
+ 'sydney',
4496
+ 'taipei',
4497
+ 'tokyo',
4498
+ 'toronto',
4499
+ 'vancouver',
4500
+ 'venice',
4501
+ 'vienna',
4502
+ 'warsaw',
4503
+ 'zurich',
4504
+ // The United States' most photographed cities, and the states their photos name.
4505
+ 'atlanta',
4506
+ 'boston',
4507
+ 'brooklyn',
4508
+ 'chicago',
4509
+ 'denver',
4510
+ 'detroit',
4511
+ 'honolulu',
4512
+ 'las vegas',
4513
+ 'los angeles',
4514
+ 'manhattan',
4515
+ 'miami',
4516
+ 'new orleans',
4517
+ 'new york',
4518
+ 'nyc',
4519
+ 'philadelphia',
4520
+ 'san francisco',
4521
+ 'seattle',
4522
+ 'california',
4523
+ 'florida',
4524
+ 'hawaii',
4525
+ 'illinois',
4526
+ 'nevada'
4527
+ ].map(stemPhrase);
4528
+ /**
4529
+ * A tag's last word that says the photo is of a street, a town or a city
4530
+ * (AGL-4092): "street", "city street", "old town", "skyscraper". Never
4531
+ * "road": a motocross track's "off-road" and "dirt road" are not streets.
4532
+ */ const STREET_HEADS = new Set([
4533
+ 'street',
4534
+ 'alley',
4535
+ 'alleyway',
4536
+ 'avenue',
4537
+ 'sidewalk',
4538
+ 'city',
4539
+ 'downtown',
4540
+ 'urban',
4541
+ 'skyline',
4542
+ 'skyscraper',
4543
+ 'cityscape',
4544
+ 'building',
4545
+ 'architecture',
4546
+ 'town',
4547
+ 'village',
4548
+ 'market',
4549
+ 'bazaar',
4550
+ 'traffic'
4551
+ ].map(aiStockStem));
4552
+ /**
4553
+ * Whether a hit is a street, a town or a city its tags place somewhere the
4554
+ * site's own words never name (2026-10-29, AGL-4092): Pit Row Tacos, a taco
4555
+ * trailer near Buda, Texas, showed a food truck under the Chicago
4556
+ * skyscrapers ("food truck, chicago, skyscraper, … city, urban, downtown")
4557
+ * and a woman with a bagel cart in Antalya ("food cart, woman, street, …,
4558
+ * antalya, turkey"), whatever its captions said. `here` is the site's own
4559
+ * stems: its business type's and its audience's. Pure.
4560
+ */ export function aiStockForeignStreet(photo, here) {
4561
+ var _photo_tags;
4562
+ const tags = ((_photo_tags = photo.tags) != null ? _photo_tags : []).map((tag)=>stemList(tag)).filter((stems)=>stems.length);
4563
+ if (!tags.some((stems)=>STREET_HEADS.has(stems[stems.length - 1]))) return false;
4564
+ const own = new Set(here);
4565
+ return NAMED_PLACES.some((place)=>tags.some((stems)=>` ${stems.join(' ')} `.includes(` ${place} `)) && !place.split(' ').every((stem)=>own.has(stem)));
4566
+ }
4050
4567
  /**
4051
4568
  * Whether a hit carries a topic its site never named ({@link SENSITIVE_TOPICS}):
4052
4569
  * a cross, a grave, a flag, a gun, a glass of wine, a child, a mannequin.
@@ -4080,11 +4597,16 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
4080
4597
  * the subject's two-word phrase 3, each of its other words 1, and the
4081
4598
  * site's world 1, plus a quarter when it is among the first tags.
4082
4599
  */ export function aiStockRelevance(photo, judgement) {
4083
- var _judgement_rivals, _judgement_subject, _judgement_named, _judgement_shun, _judgement_refuse, _judgement_refuseLead, _judgement_needs, _judgement_shunLead, _judgement_leadAny, _judgement_kin, _judgement_requires, _judgement_category, _judgement_object, _judgement_domain, _photo_tags, _judgement_roles;
4600
+ var _judgement_named, _judgement_here, _judgement_rivals, _judgement_subject, _judgement_named1, _judgement_shun, _judgement_road, _judgement_ground, _judgement_refuse, _judgement_refuseLead, _judgement_needs, _judgement_shunLead, _judgement_leadAny, _judgement_kin, _judgement_requires, _judgement_category, _judgement_object, _judgement_domain, _photo_tags, _judgement_roles;
4084
4601
  var _judgement_served, _judgement_roleScene, _judgement_roleRefuse, _judgement_away, _judgement_world, _judgement_oddLeads;
4085
4602
  const hit = hitWords(photo);
4086
4603
  if (hit.rejected) return 0;
4087
4604
  if (aiStockSensitive(photo, judgement.named)) return 0;
4605
+ // Another city's or country's street is never the business's (AGL-4092).
4606
+ if (aiStockForeignStreet(photo, [
4607
+ ...(_judgement_named = judgement.named) != null ? _judgement_named : [],
4608
+ ...(_judgement_here = judgement.here) != null ? _judgement_here : []
4609
+ ])) return 0;
4088
4610
  // Glass art is not pottery: a rival craft's photo names this craft's own words.
4089
4611
  for (const rival of (_judgement_rivals = judgement.rivals) != null ? _judgement_rivals : [])if (rival.words.some((word)=>hit.all.has(word)) && !rival.core.some((word)=>hit.all.has(word))) return 0;
4090
4612
  // A trade's thing is of the world it serves, whatever else names it (AGL-4092).
@@ -4093,10 +4615,13 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
4093
4615
  // What the slot or the brief names lets a shunned word, a room or a fragrance in.
4094
4616
  const owned = new Set([
4095
4617
  ...subject,
4096
- ...(_judgement_named = judgement.named) != null ? _judgement_named : []
4618
+ ...(_judgement_named1 = judgement.named) != null ? _judgement_named1 : []
4097
4619
  ]);
4098
4620
  // A dispenser is not a soapmaker's, nor a pump a bar's (AGL-3660).
4099
4621
  if (((_judgement_shun = judgement.shun) != null ? _judgement_shun : []).some((word)=>hit.all.has(word) && !owned.has(word))) return 0;
4622
+ // A street bike is never an off-road business's picture without the ground it rides (AGL-4092):
4623
+ // a man in a motorcycle suit on a road trip, tagged "motocross", and a model in a garage tagged "road".
4624
+ if (((_judgement_road = judgement.road) != null ? _judgement_road : []).some((word)=>hit.all.has(word) && !owned.has(word)) && !((_judgement_ground = judgement.ground) != null ? _judgement_ground : []).some((word)=>hit.all.has(word))) return 0;
4100
4625
  // A family session is never a bride, however the photographer's brief names weddings.
4101
4626
  if (((_judgement_refuse = judgement.refuse) != null ? _judgement_refuse : []).some((word)=>hit.all.has(word))) return 0;
4102
4627
  // A teacher's portrait is never OF a child, whatever else it names.
@@ -6189,6 +6714,17 @@ const WORKSPACE = {
6189
6714
  if (!aiLayoutSpeaksOtherThanEnglish(input.language)) return '';
6190
6715
  return aiStockBusinessNoun(input.business) || aiStockPhotoWordsSubject((_input_photoWords = input.photoWords) != null ? _input_photoWords : '') || ((_input_kindWords = input.kindWords) != null ? _input_kindWords : '').trim();
6191
6716
  }
6717
+ /**
6718
+ * Which of a list's records are each of a thing of its own (2026-10-29,
6719
+ * AGL-4092, {@link aiStockThingOfItsOwn}), by position: a taco trailer's
6720
+ * "Bottled Water" is a bottle of water, and the list's other photos are
6721
+ * tacos, so it never takes one of theirs. None on a site in another
6722
+ * language, whose record names no English thing. Pure.
6723
+ */ export function aiStockRecordsOfTheirOwn(input, names) {
6724
+ if (aiLayoutSpeaksOtherThanEnglish(input.language)) return names.map(()=>false);
6725
+ const terms = aiStockSourceTerms(input);
6726
+ return names.map((name)=>aiStockThingOfItsOwn(aiStockSubjectWords(name, ''), terms));
6727
+ }
6192
6728
  /**
6193
6729
  * How a search's hits are judged for a slot (AGL-3660), as the source judges
6194
6730
  * them: by the search's own words, held to the world it was asked for — the
@@ -6201,8 +6737,8 @@ const WORKSPACE = {
6201
6737
  * and the brief do not name, unless its first tags name the business's own
6202
6738
  * world too (AGL-4092): Pit Row Tacos' "Come hungry" took a cat. Pure.
6203
6739
  */ export function aiStockJudgementFor(slot, request, subject, site, sectionName = '', world = site) {
6204
- var _request_refuse, _ref, _request_subject, _request_shun, _request_refuseLead;
6205
- var _slot_product, _world_lead, _request_allow, _request_shun1, _request_leadAny, _request_served, _request_needs, _request_refuseLead1, _request_away, _request_needs1, _role_scene, _role_refuse;
6740
+ var _request_refuse, _ref, _request_subject, _request_shun, _site_ground, _request_refuseLead;
6741
+ var _slot_product, _world_lead, _request_allow, _request_shun1, _request_leadAny, _request_served, _request_needs, _request_refuseLead1, _request_away, _site_road, _request_needs1, _role_scene, _role_refuse;
6206
6742
  const refuse = [
6207
6743
  ...(_request_refuse = request.refuse) != null ? _request_refuse : [],
6208
6744
  ...site.adults ? CHILD_STEMS : []
@@ -6274,6 +6810,9 @@ const WORKSPACE = {
6274
6810
  away: request.away
6275
6811
  } : {}, oddLeads.length ? {
6276
6812
  oddLeads
6813
+ } : {}, ((_site_road = site.road) == null ? void 0 : _site_road.length) && !request.product ? {
6814
+ road: site.road,
6815
+ ground: (_site_ground = site.ground) != null ? _site_ground : []
6277
6816
  } : {}, request.worldless ? {
6278
6817
  domain: [],
6279
6818
  rivals: []
@@ -6300,10 +6839,12 @@ const WORKSPACE = {
6300
6839
  * hero nor a product takes only a photo OF the business's own world among its
6301
6840
  * first tags (AGL-4092): a taco trailer's "Race day" took a chicken salad
6302
6841
  * tagged "taco bowl". Pure.
6303
- */ export function aiStockCraftSearches(slot, world) {
6842
+ */ export function aiStockCraftSearches(slot, world, subject = '') {
6304
6843
  // A portfolio's record of the work is never filled by the craft's own
6305
6844
  // photos (AGL-3856), nor is any picture of a site that shows its work (AGL-3942).
6306
6845
  if (!world.core.length || aiStockShowsTheWork(slot, world) || aiStockShowsItsWork(slot, world)) return [];
6846
+ // Nor is a record or a product of a thing of its own (AGL-4092): "Bottled Water" is no taco.
6847
+ if ((slot.record || slot.product) && subject && aiStockThingOfItsOwn(subject, world)) return [];
6307
6848
  const orientation = aiStockOrientation(slot.aspect);
6308
6849
  const size = slot.role === 'hero' ? {
6309
6850
  minWidth: 1600
@@ -6334,7 +6875,7 @@ const WORKSPACE = {
6334
6875
  * The source for one page, or `null` when this deployment has no stock
6335
6876
  * photo library or no media door, which leaves every slot to the starters.
6336
6877
  */ export function aiLayoutStockPhotoSource(input, deps = {}) {
6337
- var _deps_provider, _deps_ingest, _input_kind, _deps_now;
6878
+ var _deps_provider, _deps_ingest, _input_kind, _input_audience, _input_name, _deps_now;
6338
6879
  const provider = ((_deps_provider = deps.provider) != null ? _deps_provider : stockPhotoProvider)();
6339
6880
  const ingest = ((_deps_ingest = deps.ingest) != null ? _deps_ingest : pluginMediaIngest)();
6340
6881
  if (!provider || !ingest || !input.hostId || !input.uid) return null;
@@ -6350,6 +6891,14 @@ const WORKSPACE = {
6350
6891
  const wider = aiStockWiderTerms(terms, (_input_kind = input.kind) != null ? _input_kind : '');
6351
6892
  const unlisted = aiStockWorldIsUnlisted(terms);
6352
6893
  const proper = aiStockProperWords(input.business);
6894
+ // Where the site's own words say it is: a street there may be its own (AGL-4092).
6895
+ const here = [
6896
+ ...new Set(stemList([
6897
+ input.business,
6898
+ (_input_audience = input.audience) != null ? _input_audience : '',
6899
+ (_input_name = input.name) != null ? _input_name : ''
6900
+ ].join(' ')))
6901
+ ];
6353
6902
  const now = (_deps_now = deps.now) != null ? _deps_now : Date.now;
6354
6903
  return async (slots, report)=>{
6355
6904
  var _deps_budgetMs, _input_avoid;
@@ -6508,9 +7057,11 @@ const WORKSPACE = {
6508
7057
  * adult, never leads with a child, and is preferred in its role (AGL-3856).
6509
7058
  */ const judgementFor = (slot, request, subject)=>{
6510
7059
  var _input_sectionNames_slot_sectionIndex, _worldOf_get;
6511
- return aiStockJudgementFor(slot, request, subject, terms, (_input_sectionNames_slot_sectionIndex = input.sectionNames[slot.sectionIndex]) != null ? _input_sectionNames_slot_sectionIndex : '', (_worldOf_get = worldOf.get(request)) != null ? _worldOf_get : terms);
7060
+ return _extends({}, aiStockJudgementFor(slot, request, subject, terms, (_input_sectionNames_slot_sectionIndex = input.sectionNames[slot.sectionIndex]) != null ? _input_sectionNames_slot_sectionIndex : '', (_worldOf_get = worldOf.get(request)) != null ? _worldOf_get : terms), {
7061
+ here
7062
+ });
6512
7063
  };
6513
- const craftSearches = (slot, world = terms)=>aiStockCraftSearches(slot, world);
7064
+ const craftSearches = (slot, world = terms, subject = '')=>aiStockCraftSearches(slot, world, subject);
6514
7065
  /**
6515
7066
  * A slot's searches once its own world found it nothing (AGL-3923), in
6516
7067
  * order: the kind of site's world, the starter's, the slot's own words
@@ -6610,7 +7161,7 @@ const WORKSPACE = {
6610
7161
  } : {}, terms.leadWord ? {
6611
7162
  leadWord: terms.leadWord
6612
7163
  } : {})) : aiStockSearchesFor(slot, terms, subject, aiStockSlotPart(slot, sectionName), sectionName),
6613
- ...craftSearches(slot)
7164
+ ...craftSearches(slot, terms, slot.product ? aiStockProductSubject(slot) : subject)
6614
7165
  ];
6615
7166
  /** Whether the library answered any of the slot's own searches with a photo at all (AGL-4065). */ let knew = false;
6616
7167
  /** The slot's accepted hits for a search; `null` once the page's searches are spent. */ const accepted = async (request, repeat)=>{