@aglyn/plugins-ai 1.0.0-beta.285 → 1.0.0-beta.287
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/package.json +17 -17
- package/src/lib/assets/site-styles/nonprofit.webp +0 -0
- package/src/lib/assets/site-styles/professional.webp +0 -0
- package/src/lib/assets/site-styles/store.webp +0 -0
- package/src/lib/assets/site-styles/trades.webp +0 -0
- package/src/lib/components/ai-theme-proposal-card.component.js +12 -3
- package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -1
- package/src/lib/declarations.js +5 -2
- package/src/lib/declarations.js.map +1 -1
- package/src/lib/declarations.server.js +12 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.d.ts +3 -1
- package/src/lib/jobs/ai-build-capabilities.js +27 -2
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
- package/src/lib/jobs/ai-image-reads.d.ts +59 -0
- package/src/lib/jobs/ai-image-reads.js +138 -0
- package/src/lib/jobs/ai-image-reads.js.map +1 -0
- package/src/lib/jobs/ai-job-build-step.d.ts +29 -0
- package/src/lib/jobs/ai-job-build-step.js +83 -12
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-duplicate-step.d.ts +2 -1
- package/src/lib/jobs/ai-job-duplicate-step.js +6 -6
- package/src/lib/jobs/ai-job-duplicate-step.js.map +1 -1
- package/src/lib/jobs/ai-job-import-step.d.ts +4 -2
- package/src/lib/jobs/ai-job-import-step.js +15 -11
- package/src/lib/jobs/ai-job-import-step.js.map +1 -1
- package/src/lib/jobs/ai-job-insight-step.d.ts +10 -0
- package/src/lib/jobs/ai-job-insight-step.js +23 -5
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.js +2 -1
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-media-step.d.ts +2 -1
- package/src/lib/jobs/ai-job-media-step.js +6 -8
- package/src/lib/jobs/ai-job-media-step.js.map +1 -1
- package/src/lib/jobs/ai-job-navigation-step.d.ts +2 -1
- package/src/lib/jobs/ai-job-navigation-step.js +7 -9
- package/src/lib/jobs/ai-job-navigation-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.js +7 -1
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-sections.js +16 -3
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +9 -1
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +30 -8
- package/src/lib/jobs/ai-job-plan-step.js +78 -13
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-privacy-step.d.ts +4 -2
- package/src/lib/jobs/ai-job-privacy-step.js +14 -15
- package/src/lib/jobs/ai-job-privacy-step.js.map +1 -1
- package/src/lib/jobs/ai-job-products-step.js +5 -3
- package/src/lib/jobs/ai-job-products-step.js.map +1 -1
- package/src/lib/jobs/ai-job-settings-step.d.ts +2 -1
- package/src/lib/jobs/ai-job-settings-step.js +7 -8
- package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-content.d.ts +34 -1
- package/src/lib/jobs/ai-job-site-content.js +67 -8
- package/src/lib/jobs/ai-job-site-content.js.map +1 -1
- package/src/lib/jobs/ai-job-site-datasets.d.ts +53 -3
- package/src/lib/jobs/ai-job-site-datasets.js +298 -30
- package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.js +6 -3
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-store-pages.js +3 -3
- package/src/lib/jobs/ai-job-site-store-pages.js.map +1 -1
- package/src/lib/jobs/ai-job-tracking-step.d.ts +2 -1
- package/src/lib/jobs/ai-job-tracking-step.js +7 -8
- package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs-beat.d.ts +11 -7
- package/src/lib/jobs/ai-jobs-beat.js +18 -8
- package/src/lib/jobs/ai-jobs-beat.js.map +1 -1
- package/src/lib/jobs/ai-jobs-notify.d.ts +66 -1
- package/src/lib/jobs/ai-jobs-notify.js +136 -3
- package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
- package/src/lib/jobs/ai-layout-stock-photos.d.ts +59 -4
- package/src/lib/jobs/ai-layout-stock-photos.js +897 -81
- package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
- package/src/lib/jobs/ai-product-image.d.ts +14 -0
- package/src/lib/jobs/ai-product-image.js +73 -21
- package/src/lib/jobs/ai-product-image.js.map +1 -1
- package/src/lib/jobs/ai-theme-brand-inputs.d.ts +9 -1
- package/src/lib/jobs/ai-theme-brand-inputs.js +28 -2
- package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
- package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.d.ts +175 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.js +601 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-pages.d.ts +46 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-pages.js +2862 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-pages.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-plans.d.ts +74 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-plans.js +888 -0
- package/src/lib/jobs/fixtures/ai-site-agl4065-plans.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.d.ts +29 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.js +81 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.d.ts +87 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.js +225 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.js.map +1 -0
- package/src/lib/layout-language/ai-layout-compiler.d.ts +11 -0
- package/src/lib/layout-language/ai-layout-compiler.js +194 -18
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-copy.d.ts +37 -0
- package/src/lib/layout-language/ai-layout-copy.js +383 -3
- package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
- package/src/lib/layout-language/ai-layout-design.d.ts +19 -0
- package/src/lib/layout-language/ai-layout-design.js +31 -11
- package/src/lib/layout-language/ai-layout-design.js.map +1 -1
- package/src/lib/layout-language/ai-layout-listings.d.ts +7 -1
- package/src/lib/layout-language/ai-layout-listings.js +9 -1
- package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
- package/src/lib/layout-language/ai-layout-pictures.d.ts +30 -0
- package/src/lib/layout-language/ai-layout-pictures.js +131 -3
- package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
- package/src/lib/layout-language/ai-layout-storefront.d.ts +18 -4
- package/src/lib/layout-language/ai-layout-storefront.js +100 -20
- package/src/lib/layout-language/ai-layout-storefront.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +7 -0
- package/src/lib/model/ai-build-job.js +36 -7
- package/src/lib/model/ai-build-job.js.map +1 -1
- package/src/lib/model/ai-build-plan.d.ts +28 -4
- package/src/lib/model/ai-build-plan.js +49 -9
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-build-progress.js +3 -1
- package/src/lib/model/ai-build-progress.js.map +1 -1
- package/src/lib/model/ai-job-notice.d.ts +8 -0
- package/src/lib/model/ai-job-notice.js +33 -0
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/ai-job-plan-lines.d.ts +2 -1
- package/src/lib/model/ai-job-plan-lines.js +6 -1
- package/src/lib/model/ai-job-plan-lines.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +8 -0
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-permissions.d.ts +13 -0
- package/src/lib/model/ai-permissions.js +29 -1
- package/src/lib/model/ai-permissions.js.map +1 -1
- package/src/lib/model/ai-products.d.ts +18 -0
- package/src/lib/model/ai-products.js +32 -0
- package/src/lib/model/ai-products.js.map +1 -1
- package/src/lib/model/ai-site-inspiration.d.ts +3 -2
- package/src/lib/model/ai-site-inspiration.js +3 -2
- package/src/lib/model/ai-site-inspiration.js.map +1 -1
- package/src/lib/plugin.js +4 -13
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/anthropic.js +9 -2
- package/src/lib/providers/anthropic.js.map +1 -1
- package/src/lib/providers/catalog.js +14 -5
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/contract.d.ts +24 -1
- package/src/lib/providers/contract.js.map +1 -1
- package/src/lib/providers/routing.js +5 -2
- package/src/lib/providers/routing.js.map +1 -1
- package/src/lib/runtime/ai-dataset-generation.d.ts +99 -1
- package/src/lib/runtime/ai-dataset-generation.js +251 -3
- package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
- package/src/lib/runtime/ai-dev-replay.d.ts +1 -0
- package/src/lib/runtime/ai-dev-replay.js +4 -2
- package/src/lib/runtime/ai-dev-replay.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +47 -3
- package/src/lib/runtime/ai-doctrine-validators.js +343 -27
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +8 -2
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-icon-library.d.ts +27 -1
- package/src/lib/runtime/ai-icon-library.js +30 -3
- package/src/lib/runtime/ai-icon-library.js.map +1 -1
- package/src/lib/runtime/ai-products-generation.d.ts +11 -1
- package/src/lib/runtime/ai-products-generation.js +51 -4
- package/src/lib/runtime/ai-products-generation.js.map +1 -1
- package/src/lib/runtime/assist-answer-cache.d.ts +2 -0
- package/src/lib/runtime/assist-answer-cache.js +5 -2
- package/src/lib/runtime/assist-answer-cache.js.map +1 -1
- package/src/lib/server/ai-allotments.js +7 -2
- package/src/lib/server/ai-allotments.js.map +1 -1
- package/src/lib/server/ai-experiment-versions.js +5 -5
- package/src/lib/server/ai-experiment-versions.js.map +1 -1
- package/src/lib/server/ai-host-permissions-roster.d.ts +25 -0
- package/src/lib/server/ai-host-permissions-roster.js +33 -0
- package/src/lib/server/ai-host-permissions-roster.js.map +1 -0
- package/src/lib/server/ai-host-permissions.js +8 -6
- package/src/lib/server/ai-host-permissions.js.map +1 -1
- package/src/lib/server/ai-image-reads-route.d.ts +17 -0
- package/src/lib/server/ai-image-reads-route.js +106 -0
- package/src/lib/server/ai-image-reads-route.js.map +1 -0
- package/src/lib/server/ai-seo-apply.js +5 -5
- package/src/lib/server/ai-seo-apply.js.map +1 -1
- package/src/lib/server/ai-site-import-route.js +7 -4
- package/src/lib/server/ai-site-import-route.js.map +1 -1
- package/src/lib/server/assist-build.js +1 -0
- package/src/lib/server/assist-build.js.map +1 -1
- package/src/lib/server/assist-chat.d.ts +11 -7
- package/src/lib/server/assist-chat.js +185 -48
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-docs-query.d.ts +51 -0
- package/src/lib/server/assist-docs-query.js +57 -0
- package/src/lib/server/assist-docs-query.js.map +1 -0
- package/src/lib/server/assist-jobs-context.d.ts +102 -0
- package/src/lib/server/assist-jobs-context.js +227 -0
- package/src/lib/server/assist-jobs-context.js.map +1 -0
- package/src/lib/server/assist-view-context.d.ts +8 -4
- package/src/lib/server/assist-view-context.js +12 -7
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +12 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tools/ai-dataset-tool.d.ts +11 -1
- package/src/lib/tools/ai-dataset-tool.js +24 -7
- package/src/lib/tools/ai-dataset-tool.js.map +1 -1
- package/src/lib/tools/ai-duplicate-resource-tool.js +5 -6
- package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -1
- package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +0 -32
- package/src/lib/components/ai-collaborator-permissions-column.component.js +0 -132
- package/src/lib/components/ai-collaborator-permissions-column.component.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-layout-stock-photos.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n pluginMediaIngest,\n type PluginMediaIngest,\n type PluginMediaIngestResult,\n} from '@aglyn/aglyn/plugin-manager/plugin-media-ingest'\nimport {\n STOCK_PHOTO_QUERY_MAX_CHARS,\n stockPhotoProvider,\n stockPhotoSourceKey,\n type StockPhoto,\n type StockPhotoOrientation,\n type StockPhotoProvider,\n type StockPhotoSearchRequest,\n} from '@aglyn/aglyn/plugin-manager/stock-photo-provider'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport {\n AI_LAYOUT_NO_PHOTO,\n aiLayoutSeedNumber,\n type AiLayoutPicturePhoto,\n type AiLayoutPictureSlot,\n type AiLayoutPictureSource,\n} from '../layout-language/ai-layout-pictures'\nimport { aiStorefrontSays } from '../layout-language/ai-layout-storefront'\nimport { aiLayoutLabel, aiLayoutSpeaksOtherThanEnglish } from '../layout-language/ai-layout-labels'\nimport type { AiBuildPlan } from '../model/ai-build-plan'\nimport { aiSiteKind, aiSiteKindOfInputs } from '../model/ai-site-kinds'\nimport { aiStockBusinessNoun } from './ai-stock-business-nouns'\n\n/**\n * STOCK PHOTOS FOR A LANGUAGE PAGE'S PICTURE SLOTS (AGL-3660).\n *\n * The source `aiResolveLayoutPictures` asks before it falls back to the\n * starter photos. It names no library: it asks core for the deployment's\n * stock photo provider (`core.stock-photos`) and for the media library's\n * server door (`core.media-ingest`), and builds no source at all when either\n * is missing, so a deployment without a key behaves exactly as before.\n *\n * What the live starts of 2026-10-10 taught (Juniper Clay Works, a ceramic\n * artist's portfolio, and Willow Wick Candles, a candle store), each photo\n * traced through the library's cached answers:\n *\n * - The site's words were read as \"portfolio\" and \"online\" — the kind of\n * SITE, not the craft — so every search said \"serving bowl portfolio\" and\n * the hero asked for \"portfolio\": a wallet, fashion models, and a blank\n * paper mockup that read as an empty panel beside the brushes.\n * - A hit naming the object anywhere won: a robin tagged \"food bowl\" filled\n * \"Speckled serving bowl\", a lilac branch tagged \"bud, vase\" filled \"Tall\n * bud vase\", letterpress type tagged \"set\" filled \"Nesting bowl set\" (its\n * head noun was read as \"set\"), and an antique tea set tagged \"brown\n * candle\" filled \"Candle Gift Set\".\n * - The page's 20 seconds ran out after four photos (each copy took ~5s, one\n * after another), and the slots left took the starter photos: the laptop\n * desk with pink roses under \"Candle Wick Trimmer\" and a work card, and the\n * windowsill plants under another.\n *\n * So, for each slot:\n *\n * 1. **The site's terms** ({@link aiStockSiteTerms}): the business is the\n * first clause of its type that says more than what kind of site it is\n * (\"ceramic artist\" from \"a portfolio for a ceramic artist who makes\n * stoneware bowls\"), its craft one word (\"ceramic\"), and its DOMAIN the\n * words a photo of its world names: the craft, the business type's own\n * nouns (\"stoneware\", \"soy\") and, for common crafts, their kin (\"pottery\",\n * \"clay\", \"wax\"). Its broad searches ask for the world itself (\"handmade\n * ceramics\", \"pottery\").\n * 2. **Search.** A picture of a thing asks for its subject — the noun phrase\n * of the caption, filler dropped — qualified by the craft where it does\n * not already name the domain (\"ceramic serving bowl\"), then the craft and\n * the object alone (\"ceramic bowl\"), then the broad searches. A hero asks\n * for the business, then broad; an about picture for the business's\n * people, then broad. The orientation and a minimum size come from the\n * slot's frame.\n * 3. **Accept, or reject.** A hit tagged as a mockup, a blank or a template\n * never fills anything. A picture of a thing takes only a hit naming its\n * OBJECT (the head noun, past \"set\", \"gift\", \"kit\": \"bowl\" in \"nesting\n * bowl set\", \"candle\" in \"candle gift set\") AND either the site's domain\n * or the subject's own two-word phrase (\"bud vase\"). A broad, hero or\n * about search takes only a hit naming the domain. The accepted are\n * ranked: the object in the hit's first tags (what the photo is OF) over\n * a mention in its last, the subject's other words, the domain. Among\n * equals the job's seed picks, so two sites differ and one job repeats.\n * What the beta.239 Ember & Oak start added: \"hand-poured\", \"handmade\"\n * and \"by hand\" never make \"hands\" a subject, and a story of the craft\n * asks for the maker at work (\"candle making\"); a hit carrying a topic\n * the brief never named (a cross, a grave, a flag, a gun, wine, a child,\n * a mannequin) never fills anything; a product, and a collection tile,\n * take only a hit naming its head noun among the first tags, held to the\n * shop's category; and an object whose word is not enough (\"melt\") is\n * named and searched by its kin (\"wax melt\", \"melt warmer\"), never by the\n * category alone. And from the Kiln & Clover portfolio: nudity never fills\n * anything, for any business; a hit naming a rival craft (glass, for a\n * potter) counts only when it names the craft's own words too.\n * 4. **Never twice.** A photo is placed once per job: not twice on a page,\n * and not on a page when another page (or another pass, in this process)\n * of the same job already placed it. The caller hands in what the job's\n * other pages hold (`avoid`); a pass repeated over its own page keeps its\n * own.\n * 5. **Keep, all at once.** The choosing is done first, slot by slot; the\n * copies then run side by side, a few at a time, so a page of eight\n * pictures takes about as long as two. A photo the site's library already\n * holds (by its source key) is reused; otherwise its bytes are copied\n * into the site's own library as the member who started the job, credited\n * to its photographer. A copy that fails tries the slot's next accepted\n * hit.\n *\n * 6. **Fall back to the craft, never off it** (the beta.241 Saltmarsh Soap\n * Co start, a store \"for handmade cold-process soap\": its craft read as\n * nothing, its hero searched \"shop\" and took a florist's bouquet, and four\n * of five products took the starters' laptop desk and living room). A\n * business that is only a place takes its craft from what it is for\n * (\"soap shop\"); a hero names the craft itself ({@link AiStockSiteTerms.core});\n * a product, after its own searches, tries its head noun anywhere among\n * the tags, its gift wrapper with the craft and the craft's broad\n * searches, and then — a product or a hero only — reuses an on-topic photo\n * the job already shows rather than take a starter. Every slot of a\n * craft's site tries the craft's broad searches last.\n * 7. **A product takes the surest photo, even a borrowed one** (the beta.242\n * Tidewater Soap Works start: a sauna for \"Bath Gift Set\", colognes for\n * \"Natural Body Lotion\", a bathroom shelf for \"Soap Bar Trio\" and a soap\n * dispenser for its starter size, while the collection tiles beside them\n * were good). A product's searches are ranked by how sure they are: its\n * own photo (the head noun or its kin among the first tags), then a photo\n * OF its category, new or one the job already shows, then a weak hit of\n * its own. No product shows a room or a scene, a fragrance bottle, or what\n * its kin shuns (a pump for a bar) unless it names it; \"bath\" in a bath\n * gift set is what the set is for; a size is never the product.\n * 8. **What the photo is OF** (the beta.259 starts, AGL-3856: a typewriter\n * printing \"terms of service\" as a family law firm's hero, a yoga pose on\n * a beach and a heart-shaped potato as a strength gym's events, a horse's\n * head of a \"western film\" as a photographer's \"Film\" card). A listed\n * craft may name what its photos are never OF among their first tags\n * (`shunLead`: a document for a law practice, yoga for a strength gym) and\n * its rival worlds (a movie's for a photographer's film); a comma after a\n * place goes on naming the place (\"Columbus, Ohio\"), never the world; an\n * event's or a lesson's word (\"basics\", \"class\", \"session\") is never its\n * object; a word the table does not list beside a craft it does\n * (\"wedding\" of \"a wedding and portrait photographer\") is not the craft;\n * and a hero whose second tag names the world too leads one whose first\n * alone does.\n * 9. **A world from the name** (the beta.261 Synchronicity Gym start,\n * AGL-3856: its business type \"a local service business\" named no world,\n * so its hero searched nothing and was left a black scrim, and its\n * closing band's \"Ready to train\" took a subway train). A business type\n * that names no world takes the craft its name, else its audience, names\n * where this module lists it (\"gym\" of \"Synchronicity Gym\"); and a\n * training word's other senses (a railway's train, an elevator's lift, a\n * newspaper's press, a boat's row) never fill a gym's picture.\n *\n * A slot the library could not fill because it never answered — down, or\n * out of time before its first answer — or because the site's library\n * refused to store, is left `null` for the starter photos. A slot the\n * library answered and nothing acceptable came back for is answered\n * {@link AI_LAYOUT_NO_PHOTO} and keeps its no-photo treatment: the beta.257\n * Copper Kettle Catering hero, held to \"caterer\" while catering photos are\n * tagged \"catering\", took the starters' pottery workbench (AGL-3831). A\n * named object is never given one while the library answers anything of the\n * site's world: the broad searches come first. Nothing here throws, and none\n * of it is an AI model call: photos cost no AI credits.\n */\n\n/** Wall clock the whole page's photos may take, inside the step's own signal. */\nexport const AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS = 30_000\n\n/** Searches one page may send to the provider; a repeated query is answered from the page's own memory. */\nexport const AI_LAYOUT_STOCK_SEARCHES_PER_PAGE = 18\n\n/** The hits a pick is made among. */\nexport const AI_LAYOUT_STOCK_PICK_WINDOW = 40\n\n/** The accepted hits a slot keeps in hand, in case a copy fails. */\nconst AI_LAYOUT_STOCK_TRIES_PER_SLOT = 3\n\n/** Copies made side by side. */\nconst AI_LAYOUT_STOCK_COPIES_AT_ONCE = 4\n\n/** The largest photo copied: inside one direct upload. */\nexport const AI_LAYOUT_STOCK_MAX_BYTES = 3 * 1024 * 1024\n\n/**\n * The media library's refusals that are about ONE photo's own bytes, as the\n * console's `ingestMedia` returns them (AGL-3923): 415 for a type or contents\n * it does not accept, 413 for a photo too large to store, 451 for a file\n * held in quarantine. The slot then tries its next hit, and the page goes on\n * storing. Every other refusal (403 from the storage band, the site's scope\n * or a lockdown; 500) holds for the whole page.\n */\nexport const AI_STOCK_PHOTO_OWN_REFUSALS: ReadonlySet<number> = new Set([413, 415, 451])\n\n/**\n * The unit job input naming the screen drafts the job's other pages were\n * written to, whose photos a page does not place again (AGL-3660).\n */\nexport const AI_STOCK_PHOTO_PAGES_INPUT = 'stockPhotoPages'\n\n/**\n * The unit job input naming library photos (`media:` references) another\n * part of the job already shows outside its pages — a dataset's records\n * (AGL-3616) — which a page does not place again.\n */\nexport const AI_STOCK_PHOTO_AVOID_INPUT = 'stockPhotoAvoid'\n\n/**\n * The unit job input holding the photos another part of the job placed\n * outside its pages — a dataset's records — with their size and words\n * (AGL-3988): what a picture the library failed takes before any starter.\n */\nexport const AI_STOCK_PHOTO_JOB_PHOTOS_INPUT = 'stockPhotoJobPhotos'\n\n/**\n * The unit job input a guided start's page is built under (AGL-3988): its\n * site step runs a late photo pass once every page is built, so a picture\n * the library failed that none of the job's photos fits yet keeps a neutral\n * starter for that pass to fill, rather than lose its frame, and the page\n * reports it. A page built by any other job keeps #1831's rule.\n */\nexport const AI_STOCK_PHOTO_LATE_PASS_INPUT = 'stockPhotoLatePass'\n\n/** The job photos a unit input holds ({@link AI_STOCK_PHOTO_JOB_PHOTOS_INPUT}): library photos with a size; anything else is dropped. */\nexport function aiStockJobPhotosOf(value: unknown): AiLayoutPicturePhoto[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry) => {\n const photo = entry as Partial<AiLayoutPicturePhoto> | null\n const src = typeof photo?.src === 'string' ? photo.src : ''\n const width = Number(photo?.width)\n const height = Number(photo?.height)\n if (!src.startsWith('media:') || !(width > 0) || !(height > 0)) return []\n const alt = typeof photo?.alt === 'string' ? photo.alt.trim() : ''\n return [{ src, width, height, ...(alt ? { alt } : {}) }]\n })\n}\n\nconst words = (list: string) => new Set(list.trim().split(/\\s+/))\n\n/** Words that carry no subject. */\nconst STOPWORDS = words(\n 'a an the and or of in on at to for with from by into onto over under near our your their my his her its ' +\n 'this that these those is are be being was were who whom which where while as about than then very just ' +\n 'small local best new top quality premium family-owned family owned independent professional ' +\n 'business company services service page photo picture image showing shows show ' +\n 'someone people person one two three some many several',\n)\n\n/**\n * Words that describe a picture's look, not what it shows, dropped from a\n * subject. A word that is as often a noun (\"light\", \"set\") is not one.\n */\nconst FILLER = words(\n 'beautiful beautifully stunning gorgeous lovely pretty elegant modern contemporary rustic cozy cosy warm cool ' +\n 'soft bright natural simple minimal minimalist delicate unique special artisan artisanal handmade ' +\n 'hand-made hand-thrown handthrown hand-crafted handcrafted crafted hand-built handbuilt hand-poured ' +\n 'hand-painted hand-dyed hand-stitched poured finished styled perfect wheel-thrown wheelthrown thrown ' +\n 'fresh clean calm serene quiet peaceful vibrant colorful colourful sunlit sunny golden glossy matte textured ' +\n 'close-up closeup up view views detail details detailed shot shots overhead flat lay flatlay flat-lay ' +\n 'top-down wide angle featuring featured displayed arranged sitting resting placed standing lined ' +\n 'single pair collection assortment selection group few various array range large tiny big little ' +\n 'tall short wide narrow everyday classic signature original favorite favourite bestselling best-selling ' +\n 'small-batch batch limited edition custom bespoke ' +\n // How a soap is made, never what it shows: \"cold\" and \"process\" named a supermarket fridge (Saltmarsh, 2026-10-10).\n 'cold-process cold-processed hot-process hot-processed melt-and-pour ' +\n 'white black grey gray beige cream ivory brown tan blue green red pink yellow orange purple speckled ' +\n 'gentle airy inviting welcoming cheerful happy smiling friendly',\n)\n\n/** The nouns that name a place of business, not its craft: \"studio\" in \"ceramics studio\". */\nconst VENUES = words(\n 'studio studios shop shops store stores boutique company co workshop gallery atelier agency brand practice ' +\n 'salon house collective lab market services service firm clinic center centre parlor parlour bar ' +\n 'class classes lessons school academy',\n)\n\n/** The person who does the craft, not the craft: \"artist\" in \"ceramic artist\". */\nconst ROLES = words(\n 'artist artists maker makers artisan artisans owner owners founder founders creator creators',\n)\n\n/** Words naming what kind of SITE it is, never what it shows: \"portfolio\" in \"a portfolio for a ceramic artist\". */\nconst SITE_KINDS = words(\n 'portfolio portfolios website websites site sites blog blogs online web webshop ecommerce e-commerce ' +\n 'landing personal homepage storefront',\n)\n\n/** Verbs a business type uses to say what it does; what follows them is its domain, never its business. */\nconst DOING =\n /(?<![\\w-])(?:makes?|making|made|sells?|selling|sold|offers?|offering|creates?|creating|specializ(?:es|ing)|specialis(?:es|ing)|provides?|providing|featuring|showcasing|shoots?|shooting)(?![\\w-])/g\n\n/** Where a business type's own clause ends. */\nconst BUSINESS_BREAK =\n /[,;:.()]|\\s[-–—]\\s|\\b(?:in|for|near|serving|based|located|that|which|who|with|from|since|and|&)\\b/\n\n/** A clause after one of these says where or for whom, never what: \"in Austin\", \"for busy parents\". */\nconst PLACE_OR_AUDIENCE =\n /^(?:in|near|serving|based|located|across|around|throughout|for)$/\n\n/**\n * Words naming a set or a wrapper of a thing, never the thing: the OBJECT\n * of \"nesting bowl set\" is the bowl, of \"candle gift set\" the candle.\n */\nconst WRAPPERS = words(\n 'set sets kit kits gift gifts bundle bundles pack packs box boxes trio duo pair collection sampler assortment ' +\n 'series range line group lot bunch ' +\n // What an event or a lesson is, never what it shows (AGL-3856): \"Intro to\n // barbell basics\" is of a barbell, \"Small-group strength class\" of strength.\n 'class classes session sessions lesson lessons course courses workshop workshops seminar seminars ' +\n 'meetup meetups program programs programme programmes basics intro introduction fundamentals',\n)\n\n/**\n * A hit tagged with any of these is never placed: a mockup's blank panel is\n * an empty frame on the page (the Juniper Clay hero), a template or a\n * graphic is not a photo of anything.\n */\nconst REJECTED_TAGS = words(\n 'mockup mock-up mock blank template templates clipart clip-art illustration vector logo icon ' +\n 'ai-generated generated render rendering 3d',\n)\n\n/**\n * Rooms and scenes, never a product (AGL-3660): the beta.242 Tidewater Soap\n * Works start put a wooden sauna under \"Bath Gift Set\" and a bathroom shelf of\n * baskets under \"Soap Bar Trio\". A product's hit whose first tags name one of\n * these is turned down unless the product or the brief names it too.\n */\nconst PRODUCT_SCENES = new Set(\n [\n 'sauna',\n 'bathroom',\n 'bathtub',\n 'shower',\n 'toilet',\n 'sink',\n 'washbasin',\n 'faucet',\n 'tap',\n 'shelf',\n 'shelves',\n 'interior',\n 'bedroom',\n 'kitchen',\n 'room',\n 'livingroom',\n 'hotel',\n 'lobby',\n ].map(aiStockStem),\n)\n\n/**\n * A fragrance's bottle, never a lotion, a cream or a soap (AGL-3660): the same\n * start's \"Natural Body Lotion\" showed blue cologne bottles tagged \"perfume,\n * bottle, lotion\". Turned down among a product's first tags unless the\n * product or the brief is a fragrance.\n */\nconst FRAGRANCE_BOTTLES = new Set(\n ['perfume', 'perfumes', 'perfumery', 'cologne', 'colognes', 'parfum', 'eau', 'atomizer', 'fragrance'].map(\n aiStockStem,\n ),\n)\n\n/**\n * Topics a business's photos never carry unless its own words name them\n * (AGL-3660, the beta.239 Ember & Oak start, whose \"Gifts for melt fans\" tile\n * showed devotional candles with crosses and names). A hit tagged with any\n * word of a topic is rejected unless the site's business type or brief says\n * one of the topic's words or its `allow` words. The last topic is not\n * sensitive but is never the thing: the same start's story band showed bronze\n * mannequin hands tagged \"wax\".\n */\nconst SENSITIVE_TOPICS: ReadonlyArray<{\n words: readonly string[]\n allow?: readonly string[]\n /** Rejected whatever the brief says. */\n always?: boolean\n}> = [\n {\n // Religion.\n words: [\n 'cross',\n 'crosses',\n 'crucifix',\n 'church',\n 'chapel',\n 'cathedral',\n 'jesus',\n 'christ',\n 'christian',\n 'christianity',\n 'god',\n 'bible',\n 'rosary',\n 'prayer',\n 'pray',\n 'praying',\n 'worship',\n 'worships',\n 'religion',\n 'religious',\n 'faith',\n 'islam',\n 'islamic',\n 'muslim',\n 'mosque',\n 'quran',\n 'temple',\n 'buddha',\n 'buddhism',\n 'buddhist',\n 'hindu',\n 'hinduism',\n 'synagogue',\n 'jewish',\n 'judaism',\n 'ecclesiastical',\n 'saint',\n 'altar',\n 'sacrificial',\n 'nativity',\n 'priest',\n 'nun',\n 'monk',\n ],\n allow: ['ministry', 'parish', 'congregation', 'wedding'],\n },\n {\n // Death and mourning.\n words: [\n 'funeral',\n 'memorial',\n 'grave',\n 'gravestone',\n 'cemetery',\n 'tomb',\n 'death',\n 'dead',\n 'grief',\n 'mourning',\n 'condolence',\n 'coffin',\n 'skull',\n ],\n allow: ['hospice', 'mortuary', 'cremation', 'obituary', 'halloween'],\n },\n {\n // Politics.\n words: [\n 'political',\n 'politics',\n 'protest',\n 'protester',\n 'demonstration',\n 'rally',\n 'flag',\n 'election',\n 'vote',\n 'voting',\n 'parliament',\n 'government',\n ],\n allow: ['advocacy', 'campaign', 'candidate', 'council', 'nonprofit'],\n },\n {\n // Weapons and war.\n words: [\n 'gun',\n 'rifle',\n 'pistol',\n 'weapon',\n 'firearm',\n 'ammunition',\n 'bullet',\n 'sword',\n 'war',\n 'military',\n 'army',\n 'soldier',\n ],\n allow: ['hunting', 'archery', 'martial', 'fencing', 'veteran'],\n },\n {\n // Alcohol, for a business that does not serve it.\n words: [\n 'alcohol',\n 'wine',\n 'beer',\n 'whiskey',\n 'whisky',\n 'vodka',\n 'cocktail',\n 'liquor',\n 'rum',\n 'gin',\n 'champagne',\n 'drunk',\n ],\n allow: [\n 'winery',\n 'vineyard',\n 'brewery',\n 'distillery',\n 'pub',\n 'tavern',\n 'taproom',\n 'bartender',\n 'sommelier',\n 'spirits',\n ],\n },\n {\n // Tobacco and drugs.\n // \"cbd\" and \"cannabinoid\": a hemp cream tube was the next \"body lotion\" answer (Tidewater, 2026-10-11).\n words: ['cigarette', 'smoking', 'tobacco', 'cannabis', 'marijuana', 'drug', 'drugs', 'cbd', 'cannabinoid', 'thc'],\n allow: ['dispensary', 'vape', 'cigar'],\n },\n {\n // Children, for a business that is not about them.\n words: ['child', 'children', 'kid', 'kids', 'baby', 'babies', 'toddler', 'infant'],\n allow: [\n 'nursery',\n 'daycare',\n 'preschool',\n 'kindergarten',\n 'school',\n 'tutor',\n 'tutoring',\n 'parent',\n 'parents',\n 'parenting',\n 'family',\n 'families',\n 'pediatric',\n 'paediatric',\n 'newborn',\n 'maternity',\n ],\n },\n {\n // Nudity, for every business: no word of a brief lets it in (Kiln &\n // Clover, 2026-10-10: a nude torso sculpture filled \"About the artist\").\n // Never bare \"body\": a skincare shop's body lotion is its product.\n words: [\n 'nude',\n 'nudes',\n 'nudity',\n 'naked',\n 'torso',\n 'breast',\n 'breasts',\n 'erotic',\n 'sensual',\n 'lingerie',\n 'bikini',\n ],\n allow: [],\n always: true,\n },\n {\n // Figures, never the maker: mannequin hands are not a candlemaker's.\n words: [\n 'mannequin',\n 'mannequins',\n 'dummy',\n 'statue',\n 'sculpture',\n 'figurine',\n 'doll',\n 'dolls',\n 'waxwork',\n ],\n allow: ['sculptor', 'museum', 'fashion', 'boutique', 'clothing', 'apparel', 'toy', 'toys'],\n },\n]\n\n/** Each topic's words and the words that allow it, as stems. */\nconst SENSITIVE_STEMS = SENSITIVE_TOPICS.map((topic) => ({\n words: new Set(topic.words.map(aiStockStem)),\n allow: new Set(\n topic.always\n ? []\n : [...topic.words, ...(topic.allow ?? [])].map(aiStockStem),\n ),\n}))\n\n/**\n * Hands are never a picture's subject (AGL-3660): \"hand-poured\", \"handmade\"\n * and \"by hand\" say how a thing was made, and a search for \"hands\" found\n * bronze mannequin hands for the beta.239 Ember & Oak story band. Each of\n * these is dropped from a picture's words; a hand only stays where it names\n * a thing sold for hands (\"hand cream\").\n */\nconst HAND_IDIOMS: readonly RegExp[] = [\n /\\b(?:made\\s+|poured\\s+|crafted\\s+|finished\\s+|done\\s+)?by\\s+(?:our\\s+|my\\s+|their\\s+)?(?:own\\s+)?hands?\\b/g,\n /\\bwith\\s+(?:our|my|their)\\s+(?:own\\s+)?(?:two\\s+)?hands\\b/g,\n /\\bhand[- ]?(?:poured|made|crafted|thrown|built|painted|dyed|stitched|sewn|knit|knitted|carved|tied|lettered|blown|bound|rolled|dipped|picked|forged|woven|cut|finished|mixed|cast|formed|shaped|pressed|printed|wrapped|selected|blended|turned|glazed)\\b/g,\n /\\bhands?\\b(?!\\s+(?:creams?|soaps?|lotions?|wash|towels?|saniti[sz]ers?|salves?|balms?|tools?|saws?|planes?|drills?|mixers?|puppets?|bags?|warmers?))/g,\n]\n\n/** A text without its hands. */\nfunction withoutHands(text: string): string {\n return HAND_IDIOMS.reduce(\n (out, idiom) => out.replace(idiom, ' '),\n text.toLowerCase(),\n )\n}\n\n/** Whether a text says how a thing was made by hand: a maker at work. */\nfunction saysMadeByHand(text: string): boolean {\n const lower = text.toLowerCase()\n return HAND_IDIOMS.some((idiom) => {\n idiom.lastIndex = 0\n const found = idiom.test(lower)\n idiom.lastIndex = 0\n return found\n })\n}\n\n/**\n * The kin of a few objects whose own word is not enough (AGL-3660): a \"melt\"\n * is any melting thing (the beta.239 \"Wax melts\" tile showed resin fluid\n * art), so a wax melt names one of these phrases. `within` is the world they\n * are of; `qualifier` the word a search adds; `queries` the searches for the\n * object itself, which stand in for the shop's category alone: a candle is\n * not a wax melt.\n */\nconst OBJECT_KIN: ReadonlyArray<{\n objects: readonly string[]\n within: readonly string[]\n /** The word a product's search adds where its subject lacks it; none where the subject is enough. */\n qualifier?: string\n /** Whether the qualifier follows the subject: \"bath gift set soap\". */\n after?: boolean\n kin: readonly string[]\n queries: readonly string[]\n /** Words a photo of the object never carries unless the product names them: a pump for a bar of soap. */\n shun?: readonly string[]\n}> = [\n {\n objects: ['melt', 'tart', 'cube'],\n within: ['wax', 'candle', 'soy'],\n qualifier: 'wax',\n kin: [\n 'wax melt',\n 'wax melts',\n 'wax cube',\n 'wax cubes',\n 'wax tart',\n 'wax tarts',\n 'melt warmer',\n 'wax warmer',\n 'tart warmer',\n 'oil burner',\n 'oil warmer',\n 'aroma burner',\n 'scent warmer',\n 'fragrance warmer',\n ],\n queries: ['wax melts', 'wax melt warmer', 'scented wax cubes'],\n },\n {\n // A \"bar\" is a pub's before it is a soap's (the Saltmarsh \"cold-process\n // soap bar\" search answered a pint of beer second): a soap bar is named\n // by soap, and searched by it.\n objects: ['bar'],\n within: ['soap', 'soapmaker', 'skincare'],\n qualifier: 'soap',\n kin: [\n 'soap bar',\n 'soap bars',\n 'bar of soap',\n 'bars of soap',\n 'soap',\n 'soaps',\n 'handmade soap',\n 'soap block',\n 'soap cubes',\n ],\n queries: ['soap bars', 'handmade soap bar'],\n // A bar is never a pump or a liquid soap (the beta.242 Tidewater start).\n shun: ['pump', 'pumps', 'liquid', 'dispenser', 'dispensers'],\n },\n {\n // \"Bath\" in \"bath gift set\", \"bath bomb\" or \"bath salts\" is what the\n // products are for, never the room: the beta.242 Tidewater Soap Works\n // start (2026-10-11) put a wooden sauna under \"Bath Gift Set\", its tags\n // \"sauna, steam, bath\". A bath set is named by soap and bath products,\n // and searched with soap.\n objects: ['bath'],\n within: ['soap', 'soapmaker', 'skincare', 'spa', 'cosmetic'],\n qualifier: 'soap',\n after: true,\n kin: [\n 'soap',\n 'soaps',\n 'soap bar',\n 'soap bars',\n 'handmade soap',\n 'bath bomb',\n 'bath bombs',\n 'bath salt',\n 'bath salts',\n 'bath product',\n 'bath products',\n 'bath set',\n 'toiletries',\n ],\n queries: ['soap gift set', 'bath products', 'bath bombs'],\n shun: ['pump', 'pumps', 'liquid', 'dispenser', 'dispensers'],\n },\n {\n // A lotion is any cream for the skin; a perfume bottle tagged \"lotion\"\n // is not one (the same start's \"Natural Body Lotion\" showed colognes).\n objects: ['lotion', 'moisturizer', 'moisturiser'],\n within: ['soap', 'soapmaker', 'skincare', 'lotion', 'cosmetic', 'beauty', 'spa'],\n kin: [\n 'lotion',\n 'lotions',\n 'body lotion',\n 'hand lotion',\n 'cream',\n 'creams',\n 'hand cream',\n 'body cream',\n 'skin cream',\n 'face cream',\n 'cream jar',\n 'body butter',\n 'moisturizer',\n 'moisturiser',\n ],\n queries: ['body lotion', 'hand cream', 'cream jar', 'moisturizer'],\n },\n]\n\n/** An object's kin where the site or the subject is of its world, else `null`. */\nfunction objectKin(\n object: string,\n world: readonly string[],\n): (typeof OBJECT_KIN)[number] | null {\n return (\n OBJECT_KIN.find(\n (entry) =>\n entry.objects.some((word) => aiStockStem(word) === object) &&\n entry.within.some((word) => world.includes(aiStockStem(word))),\n ) ?? null\n )\n}\n\n/**\n * The kin of a few common crafts: the words a photo of that world is\n * tagged with, and the broad searches that find it. A craft not listed\n * still has its own words; this only widens what counts as its world.\n */\nconst CRAFT_KIN: ReadonlyArray<{\n match: readonly string[]\n kin: readonly string[]\n broad: readonly string[]\n /** The maker at work: what a story of the craft shows, never \"hands\" (AGL-3660). */\n making: readonly string[]\n /**\n * Crafts a photo of this one is mistaken for, and the words only this\n * craft's photos say: a hit naming a rival counts as of this world only\n * when it names one of them too (Kiln & Clover, 2026-10-10: red and yellow\n * glass art filled a ceramic artist's Work hero, glass being fired and\n * \"vase\" too).\n */\n rivals?: { words: readonly string[]; core: readonly string[] }\n /**\n * Words no photo of this craft carries unless the slot or the brief names\n * them (AGL-3660): the beta.242 Tidewater start put a black soap dispenser\n * under \"Bath Gift Set Starter Size\", let in as a rival because its tags\n * also said \"cosmetics\".\n */\n shun?: readonly string[]\n /**\n * Words that, among a hit's FIRST tags, say the photo is of something other\n * than the craft's world, however its later tags name it (AGL-3856): the\n * beta.259 Hartwell Reyes Family Law hero was a typewriter printing \"terms\n * of service\", tagged \"law, general terms and conditions, attorney\". Turned\n * down unless the slot or the brief names them.\n */\n shunLead?: readonly string[]\n /**\n * Whether its pictures are of people at a moment and a place, searched by\n * them ({@link aiStockScene}): a photographer's \"Mountain Wedding Day\" is a\n * couple in the mountains, never a close-up of roses (AGL-3856).\n */\n scenes?: boolean\n /**\n * The maker and their tools, which a record of the work is never OF unless\n * it names them (AGL-3856): a photographer's \"Mountain Elopements\" is never\n * a press photographer, nor a camera.\n */\n maker?: readonly string[]\n}> = [\n {\n match: [\n 'ceramic',\n 'ceramics',\n 'pottery',\n 'potter',\n 'stoneware',\n 'porcelain',\n 'earthenware',\n 'clay',\n ],\n kin: [\n 'ceramic',\n 'ceramics',\n 'pottery',\n 'potter',\n 'stoneware',\n 'porcelain',\n 'earthenware',\n 'clay',\n 'glaze',\n 'kiln',\n ],\n broad: ['handmade ceramics', 'pottery'],\n rivals: {\n words: ['glass', 'glassware', 'glasswork', 'glassblowing', 'blown', 'stained', 'murano', 'crystal'],\n core: ['ceramic', 'ceramics', 'pottery', 'potter', 'stoneware', 'porcelain', 'earthenware', 'clay', 'terracotta'],\n },\n making: ['pottery wheel', 'potter at work'],\n },\n {\n match: ['candle', 'candlemaker', 'candlemaking'],\n kin: [\n 'candle',\n 'candlelight',\n 'wax',\n 'soy',\n 'wick',\n 'scented',\n 'votive',\n 'candlestick',\n ],\n broad: ['handmade candles', 'scented candles'],\n making: ['candle making', 'pouring wax'],\n },\n {\n match: [\n 'jewelry',\n 'jewellery',\n 'jeweler',\n 'jeweller',\n 'silversmith',\n 'goldsmith',\n ],\n kin: [\n 'jewelry',\n 'jewellery',\n 'ring',\n 'necklace',\n 'earring',\n 'bracelet',\n 'silver',\n 'gold',\n 'gemstone',\n ],\n broad: ['handmade jewelry', 'jewelry'],\n making: ['jewelry making', 'jeweler at work'],\n },\n {\n match: ['soap', 'soapmaker', 'skincare'],\n // Never \"natural\": a florist's bouquet tagged \"natural\" was the\n // Saltmarsh Soap Co hero (2026-10-10).\n kin: ['soap', 'skincare', 'lotion', 'cream', 'bath', 'spa', 'cosmetic'],\n broad: ['handmade soap', 'natural skincare'],\n // \"Soap making\" is answered with soap bubbles; a bar is what a soapmaker makes.\n making: ['soap making', 'handmade soap'],\n // Soap bubbles, a dispenser and detergent are soap, never a soapmaker's:\n // the same start's story band showed bubbles in flight.\n rivals: {\n words: ['bubble', 'bubbles', 'soapy', 'dispenser', 'detergent', 'dishwashing', 'laundry'],\n core: [\n 'bar',\n 'bars',\n 'handmade',\n 'homemade',\n 'loaf',\n 'lye',\n 'glycerin',\n 'skincare',\n 'lotion',\n 'cosmetic',\n 'spa',\n 'artisan',\n ],\n },\n shun: ['dispenser', 'dispensers'],\n },\n {\n match: [\n 'wood',\n 'woodwork',\n 'woodworking',\n 'woodworker',\n 'carpenter',\n 'carpentry',\n 'furniture',\n 'joinery',\n ],\n kin: [\n 'wood',\n 'wooden',\n 'woodwork',\n 'timber',\n 'furniture',\n 'carpentry',\n 'oak',\n 'walnut',\n ],\n broad: ['woodworking', 'wooden furniture'],\n making: ['woodworking workshop', 'carpenter at work'],\n },\n {\n match: ['bakery', 'baker', 'bread', 'pastry', 'cake', 'patisserie'],\n kin: [\n 'bakery',\n 'bread',\n 'pastry',\n 'cake',\n 'baking',\n 'baked',\n 'dough',\n 'croissant',\n ],\n broad: ['bakery', 'fresh bread'],\n making: ['baker kneading dough', 'baking bread'],\n },\n {\n match: ['coffee', 'cafe', 'café', 'roaster', 'espresso'],\n kin: [\n 'coffee',\n 'cafe',\n 'espresso',\n 'latte',\n 'cappuccino',\n 'barista',\n 'beans',\n ],\n broad: ['coffee shop', 'coffee'],\n making: ['barista making coffee'],\n },\n {\n // A caterer is named \"caterer\" and its photos \"catering\", \"buffet\",\n // \"food\": the beta.257 Copper Kettle Catering hero, held to \"caterer\"\n // alone, accepted none of forty hits (AGL-3831).\n match: ['caterer', 'catering', 'cater'],\n kin: [\n 'catering',\n 'caterer',\n 'cater',\n 'buffet',\n 'banquet',\n 'platter',\n 'food',\n 'meal',\n 'cuisine',\n ],\n broad: ['caterer', 'catering buffet'],\n making: ['chef cooking', 'catering chef'],\n // An airline's meal cart is catering too, never a caterer's: the same\n // start's search answered a plane at Düsseldorf tagged \"catering\" first.\n rivals: {\n words: ['airport', 'airplane', 'plane', 'aircraft', 'aviation', 'airline', 'airfield'],\n core: [],\n },\n },\n {\n match: ['barbecue', 'barbeque', 'bbq', 'smokehouse', 'pitmaster'],\n kin: [\n 'barbecue',\n 'barbeque',\n 'bbq',\n 'grill',\n 'grilled',\n 'brisket',\n 'smoked',\n 'smoker',\n 'ribs',\n 'meat',\n ],\n broad: ['barbecue', 'bbq meat'],\n making: ['pitmaster', 'grilling meat'],\n },\n {\n match: ['florist', 'flower', 'floral'],\n kin: ['flower', 'floral', 'bouquet', 'florist', 'bloom', 'blossom'],\n broad: ['florist', 'flower bouquet'],\n making: ['florist arranging flowers'],\n },\n {\n match: [\n 'knit',\n 'knitting',\n 'yarn',\n 'weaving',\n 'weaver',\n 'textile',\n 'textiles',\n 'quilt',\n 'quilting',\n 'sewing',\n ],\n kin: [\n 'knit',\n 'knitting',\n 'yarn',\n 'wool',\n 'weaving',\n 'textile',\n 'fabric',\n 'quilt',\n 'sewing',\n ],\n broad: ['handmade textiles', 'yarn'],\n making: ['knitting', 'weaving loom'],\n },\n {\n match: ['leather', 'leatherwork', 'leathercraft'],\n kin: ['leather', 'wallet', 'bag', 'belt', 'stitching'],\n broad: ['leather craft', 'leather goods'],\n making: ['leather crafting'],\n },\n {\n // A law practice is its people and its office: never a document, a\n // statute or a statue of justice (the beta.259 Hartwell Reyes hero).\n match: ['law', 'legal', 'lawyer', 'attorney', 'solicitor', 'barrister', 'paralegal', 'notary'],\n kin: ['law', 'legal', 'lawyer', 'attorney', 'counsel', 'office', 'client', 'consultation', 'meeting', 'advice', 'mediation'],\n broad: ['lawyer office', 'lawyer client meeting'],\n making: ['lawyer meeting client', 'lawyer office'],\n // Policing is not a family firm's; a statue of justice is a symbol, not its people.\n shun: ['police', 'policeman', 'cop', 'handcuffs', 'prisoner', 'arrest', 'crime', 'criminal', 'justitia', 'themis', 'goddess'],\n shunLead: [\n 'term',\n 'condition',\n 'paragraph',\n 'codex',\n 'regulation',\n 'statute',\n 'document',\n 'contract',\n 'typewriter',\n 'constitution',\n 'certificate',\n ],\n },\n {\n // A strength gym's photos are of lifting and training; a yoga pose on a\n // beach is tagged \"strength\" too (the beta.259 Ironline Strength Studio\n // events).\n match: ['gym', 'fitness', 'strength', 'barbell', 'crossfit', 'weightlifting', 'powerlifting', 'bodybuilding', 'kettlebell'],\n kin: [\n 'gym',\n 'fitness',\n 'workout',\n 'training',\n 'exercise',\n 'barbell',\n 'dumbbell',\n 'weight',\n 'weightlifting',\n 'deadlift',\n 'squat',\n 'kettlebell',\n 'athlete',\n 'strength',\n 'muscle',\n ],\n broad: ['gym', 'weight training'],\n making: ['coach training athlete', 'barbell training'],\n shunLead: [\n 'yoga', 'pilates', 'meditation', 'ballet', 'ballerina', 'dance', 'dancer', 'karate', 'kickboxing', 'boxing', 'boxer', 'beach', 'circus',\n // Another sport's ball, never \"medicine ball\": a basketball court covered a deadlift night (AGL-3864),\n // a cricket ball on a wooden court another (AGL-3856).\n 'basketball', 'football', 'soccer', 'baseball', 'volleyball', 'tennis', 'golf', 'rugby', 'hockey',\n 'cricket', 'squash', 'badminton', 'shuttlecock', 'bowling', 'billiards', 'snooker', 'pool', 'lacrosse', 'softball',\n 'handball', 'pingpong', 'pong',\n ],\n // A training word's other senses (AGL-3856): \"train\" is a railway's, \"lift\"\n // an elevator's or a ski lift's, \"press\" a newspaper's, \"row\" a boat's. The\n // beta.261 Synchronicity Gym's closing band, \"Ready to train\", took a\n // subway train at a station.\n shun: [\n 'railway', 'railroad', 'rail', 'locomotive', 'subway', 'metro', 'tram', 'tramway', 'commuter', 'freight',\n 'transport', 'transportation', 'traffic', 'vehicle', 'bus', 'truck', 'airplane', 'aircraft',\n 'elevator', 'escalator', 'chairlift', 'forklift', 'crane',\n 'newspaper', 'journalism', 'journalist', 'printing',\n 'boat', 'ship', 'canoe', 'kayak', 'sailboat',\n ],\n },\n {\n // A photographer's own photos are of a camera or a shoot; \"film\" is a\n // movie's word too, and \"western film\" a horse (the beta.259 Juniper and\n // Rye Photography \"Film\" card).\n match: ['photographer', 'photography', 'photo', 'photograph'],\n scenes: true,\n maker: ['photographer', 'photographers', 'camera', 'cameras', 'lens', 'lenses', 'tripod', 'dslr', 'slr', 'journalist', 'paparazzi'],\n kin: ['photographer', 'photography', 'photo', 'photograph', 'photoshoot', 'camera', 'lens'],\n broad: ['photographer camera', 'photography'],\n making: ['photographer at work', 'photographer camera'],\n rivals: {\n words: ['movie', 'cinema', 'cinematography', 'filmmaking', 'filming', 'videography', 'video', 'actor', 'projector', 'hollywood', 'western'],\n core: ['camera', 'photograph', 'photography', 'photographer', 'photo', 'photoshoot', 'analog'],\n },\n },\n]\n\n/** Lowercase words, letters only, without stopwords. */\nfunction contentWords(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/https?:\\/\\/\\S+|\\S+@\\S+|\\+?\\d[\\d\\s().-]{5,}\\d/g, ' ')\n .replace(/[^a-zÀ-ɏ\\s-]/g, ' ')\n .split(/\\s+/)\n .map((word) => word.replace(/^-+|-+$/g, ''))\n .filter((word) => word.length > 1 && !STOPWORDS.has(word))\n}\n\n/**\n * A word's singular, for matching only: \"bowls\" and \"bowl\", \"vases\" and\n * \"vase\", \"berries\" and \"berry\", \"dishes\" and \"dish\" meet. Both sides of a\n * comparison are reduced the same way, so an odd stem still matches itself.\n */\nexport function aiStockStem(word: string): string {\n const lower = word.toLowerCase()\n if (lower.length > 4 && lower.endsWith('ies')) return `${lower.slice(0, -3)}y`\n if (lower.length > 4 && /(?:ches|shes|sses|xes|zes)$/.test(lower))\n return lower.slice(0, -2)\n if (lower.length > 3 && lower.endsWith('s') && !/(?:ss|us|is)$/.test(lower))\n return lower.slice(0, -1)\n return lower\n}\n\n/** A text's words as stems, in order; a hyphenated word counts as its parts. */\nfunction stemList(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-zÀ-ɏ]+/)\n .filter((word) => word.length > 1)\n .map(aiStockStem)\n}\n\n/** Where a noun phrase ends: punctuation, a preposition, a conjunction. */\nconst CLAUSE_BREAK =\n /[,;:.()]|\\s[-–—]\\s|\\b(?:with|on|in|at|against|beside|next|near|under|over|by|from|for|during|while|atop|inside|across|beneath|through|into|onto|amid|among|and|of|that|which|who)\\b|&/\n\n/** A business type's clauses, each with the word that opened it. */\nfunction businessClauses(\n businessType: string,\n): Array<{ opener: string; words: string[] }> {\n const text = businessType.toLowerCase().replace(DOING, ' | ')\n const clauses: Array<{ opener: string; words: string[] }> = []\n const breaker = new RegExp(`${BUSINESS_BREAK.source}|\\\\|`, 'g')\n let at = 0\n let opener = ''\n for (const match of text.matchAll(breaker)) {\n clauses.push({ opener, words: contentWords(text.slice(at, match.index)) })\n opener = match[0].trim()\n at = (match.index ?? 0) + match[0].length\n }\n clauses.push({ opener, words: contentWords(text.slice(at)) })\n return clauses\n}\n\n/** A clause's words that name the business: no site kind, no filler. */\nconst businessOf = (clause: readonly string[]) =>\n clause.filter((word) => !SITE_KINDS.has(word) && !FILLER.has(word))\n\n/**\n * The kind of business in a few words: the first clause of the business\n * type that says more than what kind of site it is, before a place, an\n * audience or what it makes, filler dropped, its last three words (the head\n * of an English noun phrase is at its end). \"ceramic artist\" from \"a\n * portfolio for a ceramic artist who makes stoneware bowls\"; \"candle shop\"\n * from \"a small-batch candle shop selling hand-poured soy candles online\".\n */\nexport function aiStockBusinessWords(businessType: string): string {\n for (const { words: clause } of businessClauses(businessType)) {\n const named = businessOf(clause)\n if (named.length) return named.slice(-3).join(' ')\n }\n return ''\n}\n\n/**\n * The business's craft in one word: the last of its words that is not the\n * place it is done in nor the person doing it, singular — \"ceramic\" from\n * \"ceramics studio\" or \"ceramic artist\", \"yoga\" from \"yoga studio\". Empty\n * when the business is only a place (\"a shop\").\n */\nexport function aiStockCraftWords(business: string): string {\n const named = business\n .split(/\\s+/)\n .filter(\n (word) =>\n word &&\n !VENUES.has(word) &&\n !ROLES.has(word) &&\n !FILLER.has(word) &&\n !SITE_KINDS.has(word),\n )\n const craft = named[named.length - 1]\n return craft ? aiStockStem(craft) : ''\n}\n\n/** What a site's photos are searched and judged by (AGL-3660). */\nexport interface AiStockSiteTerms {\n /** The kind of business, in a few words: \"ceramic artist\". */\n business: string\n /** Its craft, one singular word: \"ceramic\". */\n craft: string\n /**\n * The stems a photo of the site's world names: the business's own words,\n * what the things it makes are made of, and the craft's kin. Empty for a\n * site whose words name no world (a type left blank), and then no hit is\n * held to it.\n */\n domain: string[]\n /** The searches for the site's world itself, broadest last. */\n broad: string[]\n /** The searches for its maker at work, for a story of the craft (AGL-3660); empty for a craft not listed. */\n making: string[]\n /** Whether a picture naming people at a moment is searched by its scene ({@link aiStockScene}, AGL-3856). */\n scenes?: boolean\n /** Every stem of the business type or brief: what lets a sensitive topic in ({@link SENSITIVE_TOPICS}). */\n named: string[]\n /** Rival crafts' words, each with the words that must then be named too ({@link CRAFT_KIN}). */\n rivals: Array<{ words: string[]; core: string[] }>\n /**\n * The stems a photo of the craft ITSELF names, one of which a hero and a\n * product's fallbacks must name (AGL-3660): the craft and, for a listed\n * craft, its own names (\"soap\", \"soapmaker\", \"skincare\"). Empty where the\n * site names no craft.\n */\n core: string[]\n /** Words no photo of the site's craft carries unless the slot or the brief names them ({@link CRAFT_KIN}). */\n shun: string[]\n /** Words no photo of the site's craft is OF, among its first tags, unless the slot or the brief names them ({@link CRAFT_KIN}). */\n shunLead: string[]\n /** Whether the site is for adults alone, so no photo of a child is placed on it ({@link aiStockAdultsOnly}, AGL-3856). */\n adults?: boolean\n /** Where the site's own words set its pictures ({@link aiStockSetting}): a record's moment is set there where its words say nowhere (AGL-3856). */\n setting?: string\n /** The craft's maker and tools as stems, which a record of its work never leads with ({@link CRAFT_KIN}, AGL-3856). */\n maker?: string[]\n /**\n * What a craft whose pictures are people at a moment shows wherever a page\n * would show its maker ({@link aiStockWorkScenes}, AGL-3942): the scenes\n * its site's own words name, set where the site is.\n */\n work?: AiStockScene[]\n}\n\n/** The site's terms, read from its business type. */\nexport function aiStockSiteTerms(businessType: string): AiStockSiteTerms {\n let business = aiStockBusinessWords(businessType)\n let craft = aiStockCraftWords(business)\n const domain = new Set<string>()\n /** The things it makes, by their head nouns. */\n const made = new Set<string>()\n /** The last word of the first clause that names the world: \"soap\" of \"for handmade cold-process soap\". */\n let firstWorld = ''\n let named = false\n let making = false\n let place = false\n for (const { opener, words: clause } of businessClauses(businessType)) {\n if (opener === '|') making = true\n // Where it is, and who it is for, are not its world — once something has named it.\n if (named && PLACE_OR_AUDIENCE.test(opener)) {\n making = false\n place = true\n continue\n }\n // A comma goes on naming the place (AGL-3856): \"Ohio\" of \"in Columbus,\n // Ohio\" and \"North Carolina\" of \"in Asheville, North Carolina\" are not\n // the business's world.\n if (place && opener === ',') continue\n place = false\n const kept = businessOf(clause).filter(\n (word) => !VENUES.has(word) && !ROLES.has(word),\n )\n if (kept.length) named = true\n // What it makes names its world by what the things are made of, never\n // the things: \"stoneware\" of \"stoneware bowls\", \"soy\" of \"soy candles\".\n // A bowl is not a ceramic world; a robin's food bowl is not pottery.\n // A set or a gift is never a world: \"gift\" of \"gift sets\" is not one.\n const world = (making ? kept.slice(0, -1) : kept).filter(\n (word) => !WRAPPERS.has(word),\n )\n for (const word of world)\n for (const stem of stemList(word)) domain.add(stem)\n const last = world[world.length - 1]\n if (!firstWorld && last) firstWorld = aiStockStem(last)\n if (making)\n for (const word of kept.slice(-1))\n for (const stem of stemList(word)) made.add(stem)\n }\n // A business named only by what it sells (\"a shop selling pottery\") is of that world.\n if (!domain.size) for (const stem of made) domain.add(stem)\n const groups = CRAFT_KIN.filter((group) =>\n group.match.some(\n (word) =>\n domain.has(aiStockStem(word)) ||\n made.has(aiStockStem(word)) ||\n aiStockStem(word) === craft,\n ),\n )\n // A business that is only a place (\"an online shop for handmade\n // cold-process soap\") takes its craft from what it is for: the Saltmarsh\n // Soap Co start (2026-10-10) read its craft as nothing, so its hero searched\n // \"shop\" (a florist's bouquet) and no product was held to soap.\n if (!craft) {\n const listed = groups[0]?.match\n .map(aiStockStem)\n .find((stem) => domain.has(stem) || made.has(stem))\n craft = listed || firstWorld || [...made][0] || ''\n if (craft && !stemList(business).includes(craft))\n business = `${craft} ${business}`.trim()\n } else if (groups[0] && !groups.some((group) => group.match.some((word) => aiStockStem(word) === craft))) {\n // A word the table does not list, beside a craft it does, says what kind\n // of that craft it is (AGL-3856): \"wedding\" of \"a wedding and portrait\n // photographer\" is a photographer's subject, never a craft to search by.\n craft =\n groups[0].match.map(aiStockStem).find((stem) => domain.has(stem) || made.has(stem)) ?? craft\n }\n if (craft) domain.add(craft)\n const broad: string[] = []\n const makingSearches: string[] = []\n const rivals: Array<{ words: string[]; core: string[] }> = []\n const core = new Set<string>(craft ? [craft] : [])\n const shun = new Set<string>()\n const shunLead = new Set<string>()\n for (const group of groups) {\n for (const word of group.shun ?? []) shun.add(aiStockStem(word))\n for (const word of group.shunLead ?? []) shunLead.add(aiStockStem(word))\n for (const word of group.match) core.add(aiStockStem(word))\n for (const word of group.kin) domain.add(aiStockStem(word))\n broad.push(...group.broad)\n makingSearches.push(...group.making)\n if (group.rivals)\n rivals.push({\n words: group.rivals.words.map(aiStockStem),\n core: group.rivals.core.map(aiStockStem),\n })\n }\n if (!broad.length) broad.push(business, craft)\n return {\n business,\n craft,\n domain: [...domain].filter((stem) => stem.length > 1),\n broad: [...new Set(broad.map((query) => query.trim()).filter(Boolean))],\n making: [...new Set(makingSearches)],\n ...(groups.some((group) => group.scenes) ? { scenes: true } : {}),\n ...(groups.some((group) => group.maker?.length)\n ? { maker: [...new Set(groups.flatMap((group) => group.maker ?? []).map(aiStockStem))] }\n : {}),\n named: [...new Set(stemList(businessType))],\n rivals,\n core: [...core],\n shun: [...shun],\n shunLead: [...shunLead],\n }\n}\n\n/**\n * Words that say a picture is one of a set, never what it shows (AGL-3923):\n * the beta.266 Mexicano portfolio's gallery was \"Project one\" to \"Project\n * four\", and searched \"project\" (students at a whiteboard), \"project four\"\n * (lavender) and \"four\" (a running track's lane numbers).\n */\nconst PLACEHOLDER_SUBJECTS = words(\n 'project projects piece pieces item items example examples sample samples entry entries untitled work works ' +\n 'selected recent latest ' +\n 'four five six seven eight nine ten first second third fourth fifth sixth seventh eighth ninth tenth',\n)\n\n/** A phrase's content words without its filler; all filler, and nothing is left. */\nfunction subjectOf(list: readonly string[]): string[] {\n return list.filter((word) => !FILLER.has(word) && !PLACEHOLDER_SUBJECTS.has(word))\n}\n\n/**\n * A picture's subject in a few words (AGL-3660): the noun phrase its alt\n * text opens with — its first clause holding more than filler, cut where a\n * preposition starts the setting, filler dropped, its last three words (the\n * head noun is the last) — else its section's name.\n */\nexport function aiStockSubjectWords(alt: string, sectionName: string): string {\n // \"Hand-poured\", \"by hand\" and \"hands\" say how it was made, never what it shows.\n for (const clause of withoutHands(alt).split(CLAUSE_BREAK)) {\n const found = subjectOf(contentWords(clause ?? ''))\n if (found.length) return found.slice(-3).join(' ')\n }\n return subjectOf(contentWords(withoutHands(sectionName))).slice(0, 2).join(' ')\n}\n\n/**\n * The thing a subject shows, one singular word: its last word that is not\n * a set or a wrapper of it — \"bowl\" from \"nesting bowl set\", \"candle\" from\n * \"candle gift set\", \"vase\" from \"bud vase\". Its last word when every word\n * is one (\"gift set\").\n */\nexport function aiStockObjectWord(subject: string): string {\n const list = subject.split(/\\s+/).filter(Boolean)\n const object =\n [...list].reverse().find((word) => !WRAPPERS.has(word)) ??\n list[list.length - 1] ??\n ''\n return object ? aiStockStem(object) : ''\n}\n\nconst clip = (query: string) =>\n query.replace(/\\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUERY_MAX_CHARS).trim()\n\n/** The frame's orientation: a wide frame wants a landscape photo, a tall one a portrait. */\nexport function aiStockOrientation(aspect: number): StockPhotoOrientation {\n if (aspect > 1.15) return 'horizontal'\n if (aspect < 0.87) return 'vertical'\n return 'any'\n}\n\n/**\n * One search a slot tries. A `broad` one asks for the site's world and\n * takes any hit of it; any other picture of a thing takes only a hit naming\n * the thing.\n */\nexport interface AiStockSearch extends StockPhotoSearchRequest {\n broad?: boolean\n /** The words its hits are scored by, where they are not the slot's own subject (a product's searches, AGL-3676). */\n subject?: string\n /** A word every hit must name: a product's photo names the shop's category (AGL-3676). */\n requires?: string\n /**\n * Words of which a hit must name ONE, `requires` among them (AGL-3660): a\n * shop's category or the slot's own word of its world, so a soap shop's\n * body lotion is held to \"lotion\", never to \"soap\".\n */\n category?: readonly string[]\n /** The thing every hit must name, where it is not the subject's own: a product's head noun (AGL-3660). */\n object?: string\n /** Phrases that name the object where its own word is not enough: \"wax melt\" ({@link OBJECT_KIN}). */\n kin?: readonly string[]\n /** Whether the object must be among the hit's first tags, what the photo is OF (AGL-3660). */\n lead?: boolean\n /** Whether the hit's first tags must name the site's world, where the object need not lead (AGL-3660). */\n leadWorld?: boolean\n /**\n * Whether the hit's FIRST tag must name the site's world (AGL-3760): what\n * the photo is of, most of all. A hero is the site's opening picture; the\n * copper-fern-candle-co start (beta.246) took a latte with a candle behind\n * it, its tags \"coffee, mobile wallpaper 4k, latte art, …, candle\".\n */\n first?: boolean\n /** Phrases (as stems) of which one must be among the hit's first tags: a borrowed photo is OF the product's category (AGL-3660). */\n leadAny?: readonly string[]\n /** Whether its hits must name its object, whatever the slot's role: a scene's people (AGL-3856). */\n strict?: boolean\n /** Words its hits never carry, whatever the brief names: a bride in a family session ({@link aiStockScene}). */\n refuse?: readonly string[]\n /** Stems of which every hit names one, whatever else it names: a scene's people, never roses alone ({@link aiStockScene}). */\n needs?: readonly string[]\n /** Stems its own words name, which let a topic in as the brief's do: a family session's children ({@link aiStockScene}). */\n allow?: readonly string[]\n /** Stems no hit's first tags carry: a photographer or a camera on a portfolio's record, a toy frog ({@link aiStockRecordScene}, AGL-3856). */\n refuseLead?: readonly string[]\n /** Whether its hits are held to no world of the site's: a portfolio's record is of its subject, never of the craft (AGL-3856). */\n worldless?: boolean\n /** Stems of the places its hits are not set in, which none of their first tags name: a Blue Ridge couple's beach ({@link aiStockSettingAway}, AGL-3942). */\n away?: readonly string[]\n /** Whether it fills a product: no room, no scene, no fragrance bottle ({@link PRODUCT_SCENES}, AGL-3660). */\n product?: boolean\n /** Words its hits never carry unless the slot or the brief names them ({@link AiStockSiteTerms.shun}). */\n shun?: readonly string[]\n /**\n * How sure a product's search is (AGL-3660). Absent: its own photo, the\n * head noun among the first tags. `borrow`: a photo OF its category, which\n * may repeat one the job already shows. `weak`: the head noun anywhere, or\n * the category anywhere — taken only once nothing surer is left.\n */\n tier?: 'borrow' | 'weak'\n}\n\n/** A slot's part of a page, where it asks for more than its role: a collection tile or a story of the craft (AGL-3660). */\nexport type AiStockSlotPart = 'collection' | 'story'\n\n/**\n * A slot's part (AGL-3660): a tile of a collections band is product-like,\n * held to the shop's category and its own object; a picture of a story of\n * the craft, or of a thing made by hand, shows the maker at work.\n */\nexport function aiStockSlotPart(\n slot: Pick<AiLayoutPictureSlot, 'role' | 'alt'>,\n sectionName: string,\n): AiStockSlotPart | undefined {\n if (slot.role === 'hero') return undefined\n if (slot.role === 'gallery' && aiStorefrontSays('collections', sectionName))\n return 'collection'\n if (\n aiStorefrontSays('story', sectionName) ||\n saysMadeByHand(slot.alt) ||\n saysMadeByHand(sectionName)\n )\n return 'story'\n return undefined\n}\n\n/**\n * The people a picture of a moment shows (AGL-3856): what its words name, the\n * search that asks for them, the words a photo of them leads with, those of\n * which it must name one anywhere, and what it never carries unless the\n * words name it. A family session is never a bride.\n */\nconst PEOPLE_SCENES: ReadonlyArray<{\n words: readonly string[]\n query: (named: ReadonlySet<string>) => string\n subject: string\n lead: readonly string[]\n people: readonly string[]\n shun: readonly string[]\n}> = [\n {\n words: ['family', 'families', 'kid', 'kids', 'child', 'children', 'newborn', 'baby', 'parent', 'parents', 'mother', 'father'],\n query: () => 'family',\n subject: 'family',\n lead: ['family', 'families', 'child', 'children', 'kid', 'kids', 'mother', 'father', 'parents', 'mom', 'dad', 'daughter', 'son', 'baby', 'toddler'],\n people: ['family', 'child', 'children', 'kid', 'kids', 'mother', 'father', 'parent', 'parents', 'daughter', 'son', 'baby', 'toddler', 'mom', 'dad'],\n shun: ['bride', 'groom', 'bridal', 'wedding', 'newlywed', 'newlyweds', 'marriage'],\n },\n {\n words: [\n 'wedding', 'weddings', 'elopement', 'elopements', 'elope', 'eloping', 'bride', 'brides', 'bridal', 'groom', 'engagement',\n 'engaged', 'couple', 'couples', 'newlywed', 'newlyweds', 'honeymoon', 'ceremony', 'ceremonies', 'reception', 'receptions', 'vows',\n ],\n query: (named) => (['wedding', 'weddings', 'bride', 'bridal', 'groom'].some((word) => named.has(word)) ? 'wedding couple' : 'couple'),\n subject: 'couple',\n lead: ['couple', 'couples', 'bride', 'groom', 'wedding', 'newlyweds', 'lovers', 'elopement', 'bride and groom'],\n people: ['couple', 'bride', 'groom', 'newlywed', 'newlyweds', 'lovers', 'husband', 'wife', 'man', 'woman'],\n shun: [],\n },\n]\n\n/**\n * A portrait session (AGL-3856), read for a record's cover alone: \"Milestone\n * Portraits\" is a person's portrait, never a cat's. A page's \"portrait of the\n * photographer\" keeps its own words.\n */\nconst PORTRAIT_SCENE: (typeof PEOPLE_SCENES)[number] = {\n words: ['portrait', 'portraits', 'headshot', 'headshots'],\n query: () => 'portrait',\n subject: 'portrait',\n lead: ['portrait', 'woman', 'man', 'couple', 'person', 'people'],\n people: ['woman', 'women', 'man', 'men', 'couple', 'person', 'people', 'bride', 'groom', 'mother', 'father', 'family'],\n shun: [],\n}\n\n/**\n * Words a photo of a child is tagged with (AGL-3856), as stems. Pixabay tags\n * a schoolgirl \"girl\", \"schoolgirl\" or \"school girl\" far more often than\n * \"child\", so a site for adults that names a school let children in: the\n * beta.264 Brightpath Adult Learning Center's \"Meet your teachers\" showed a\n * teen graduate, a schoolgirl and kids.\n */\nconst CHILD_STEMS = [\n ...new Set(\n (\n 'child children childhood kid kids baby babies toddler toddlers infant infants newborn boy boys girl girls ' +\n 'schoolgirl schoolgirls schoolboy schoolboys schoolchild schoolchildren schoolkid schoolkids pupil pupils ' +\n 'teen teens teenager teenagers teenage preteen youth kindergarten preschool'\n )\n .split(' ')\n .map(aiStockStem),\n ),\n]\n\n/** Words of which a photo of one of the business's people names one: an adult, at work or in their role. */\nconst ADULT_PEOPLE_STEMS = [\n ...new Set(\n (\n 'man men woman women adult adults businessman businesswoman businessmen professional ' +\n 'professionals staff worker workers employee employees team colleague colleagues coworker coworkers ' +\n 'teacher teachers instructor instructors tutor tutors lecturer professor educator faculty coach coaches ' +\n 'trainer trainers chef chefs cook baker barista doctor doctors dentist nurse nurses hygienist therapist ' +\n 'physician stylist hairdresser barber artist musician photographer entrepreneur founder owner manager ' +\n 'leader speaker volunteer volunteers mechanic electrician plumber carpenter craftsman technician'\n )\n .split(' ')\n .map(aiStockStem),\n ),\n]\n\n/**\n * The roles a list of the business's people names (AGL-3856): the words that\n * name each, the words a photo of someone in it is tagged with, and the word\n * a search for them leads with, where the libraries know one. A teacher is\n * shown teaching, a coach coaching, never a student or a whistle. A team or\n * a staff is anyone at work: its words are preferred, never required.\n *\n * A role whose photos are often of someone merely tagged with it carries the\n * words of it being done, one of which the photo's first tags must name\n * (`scene`), and the words of something else being done, which none of them\n * may (`refuse`): the beta.265 Northgate Adult Learning Center's \"Meet your\n * teachers\" placed a woman painting at an easel (\"artist, teacher of\n * drawing\"), a model in a traditional dress (\"woman, model, show, teacher\")\n * and an elderly man's portrait (\"teacher, professor, man, senior\").\n */\nconst PEOPLE_ROLES: ReadonlyArray<{\n words: readonly string[]\n kin: readonly string[]\n query?: string\n loose?: boolean\n scene?: readonly string[]\n refuse?: readonly string[]\n}> = [\n {\n words: ['instructor', 'teacher', 'tutor', 'educator', 'faculty', 'professor', 'lecturer', 'mentor'],\n kin: ['teacher', 'instructor', 'tutor', 'educator', 'professor', 'lecturer', 'teaching', 'lecture', 'faculty'],\n query: 'teacher',\n scene: [\n 'teaching', 'teach', 'classroom', 'class', 'lecture', 'lesson', 'lessons', 'tutor', 'tutoring', 'blackboard', 'chalkboard',\n 'whiteboard', 'board', 'seminar', 'student', 'students', 'learner', 'learners', 'presentation',\n ],\n refuse: [\n 'model', 'modeling', 'fashion', 'pose', 'posing', 'beauty', 'glamour', 'cosplay', 'artist', 'artists', 'painter',\n 'painting', 'paint', 'easel', 'canvas', 'draw', 'draws', 'drawing', 'calligraphy',\n ],\n },\n { words: ['coach', 'trainer'], kin: ['coach', 'coaching', 'trainer', 'instructor'], query: 'coach' },\n { words: ['chef', 'cook', 'baker'], kin: ['chef', 'cook', 'cooking', 'baker', 'baking'], query: 'chef' },\n { words: ['stylist', 'barber', 'hairdresser', 'colorist'], kin: ['stylist', 'barber', 'hairdresser', 'hairstylist', 'haircut'], query: 'hairdresser' },\n {\n words: ['doctor', 'dentist', 'hygienist', 'nurse', 'therapist', 'practitioner', 'physician'],\n kin: ['doctor', 'dentist', 'hygienist', 'nurse', 'therapist', 'physician', 'medical'],\n },\n {\n words: ['staff', 'team', 'crew', 'member', 'manager', 'founder', 'owner', 'partner', 'associate', 'employee'],\n kin: ['staff', 'team', 'worker', 'employee', 'colleague', 'coworker', 'professional', 'businessman', 'businesswoman', 'owner', 'manager'],\n loose: true,\n },\n]\n\n/** A role {@link aiStockPeopleRole} reads: its kin's stems, its search word, and whether a photo must name it. */\nexport interface AiStockPeopleRole {\n kin: string[]\n query: string\n required: boolean\n /** Stems of the role being done, one of which a photo's first tags name ({@link AI_STOCK_ROLE_TAGS_READ}). */\n scene?: string[]\n /** Stems of something else being done, which none of a photo's first tags name. */\n refuse?: string[]\n}\n\n/** How many of a photo's first tags show a role being done: \"teacher, presentation, education, man, students\" (AGL-3856). */\nexport const AI_STOCK_ROLE_TAGS_READ = 6\n\n/**\n * The role a person's words say, else the first of the other texts that names\n * one (their list's name): \"Online learning coach\" of the \"Instructors\" list\n * is a coach. `null` where none names a listed role.\n */\nexport function aiStockPeopleRole(...texts: readonly string[]): AiStockPeopleRole | null {\n for (const text of texts) {\n const named = new Set(stemList(text))\n const role = PEOPLE_ROLES.find((entry) => entry.words.some((word) => named.has(aiStockStem(word))))\n if (role)\n return {\n kin: [...new Set(role.kin.map(aiStockStem))],\n query: role.query ?? '',\n required: !role.loose,\n ...(role.scene ? { scene: [...new Set(role.scene.map(aiStockStem))] } : {}),\n ...(role.refuse ? { refuse: [...new Set(role.refuse.map(aiStockStem))] } : {}),\n }\n }\n return null\n}\n\n/** A role's refusals, less what the person's own words name: a \"Drawing instructor\" may be drawing. */\nexport function aiStockRoleRefusals(role: Pick<AiStockPeopleRole, 'refuse'>, words: string): string[] {\n const named = new Set(stemList(words))\n return (role.refuse ?? []).filter((stem) => !named.has(stem))\n}\n\n/** A site's audience in its own words, when it is adults: \"Adults finishing a high school diploma\". */\nconst ADULT_AUDIENCE = /\\b(?:adults?|grown[- ]?ups?|seniors?|retirees?|older (?:adults|people)|professionals|employees|workforce|job ?seekers)\\b/i\n/** Words that say a site is for children too, whatever else it says. */\nconst YOUNG_AUDIENCE =\n /\\b(?:kids?|child(?:ren)?|teens?|teenagers?|youth|young people|famil(?:y|ies)|boys?|girls?|bab(?:y|ies)|toddlers?|k-12|elementary|middle school|preschool|kindergarten|pupils?)\\b/i\n\n/**\n * Whether a site is for adults alone (AGL-3856), as its audience, its name\n * or its business type says: \"Adults finishing a high school diploma\",\n * \"Brightpath Adult Learning Center\". Then no photo of a child is placed\n * anywhere on it, whatever else its words name (\"school\").\n */\nexport function aiStockAdultsOnly(texts: ReadonlyArray<string | undefined>): boolean {\n const said = texts.filter(Boolean).join(' . ')\n return ADULT_AUDIENCE.test(said) && !YOUNG_AUDIENCE.test(said)\n}\n\n/**\n * Words a photo by the sea is tagged with: never one set in the mountains, a\n * forest or a city (AGL-3942). Never \"palm\" or \"wave\", a hand's as often.\n */\nconst SEASIDE = [\n 'beach', 'beaches', 'sea', 'seaside', 'seashore', 'ocean', 'coast', 'coastal', 'shore', 'shoreline', 'surf', 'waves',\n 'caribbean', 'tropical', 'island', 'lagoon', 'bay', 'pier',\n]\n/** Words a photo of a desert is tagged with. */\nconst DESERT = ['desert', 'dune', 'dunes', 'cactus', 'sahara']\n/** Words a photo of a city is tagged with. */\nconst CITYSCAPE = ['city', 'urban', 'downtown', 'street', 'skyline', 'skyscraper', 'skyscrapers', 'subway', 'metro']\n\n/**\n * Where a picture of a moment is set, by the words that name it, the word a\n * search and a photo say it with, whether it is a place a photo can show on\n * its own (a landscape, not a season), and the words of the places it is\n * not, which none of a photo's first tags may name (AGL-3942): the beta.267\n * Copper Hollow Film & Portrait galleries, a Blue Ridge photographer's,\n * showed two couples on a beach, tagged \"beach, couple, nature, mountain\"\n * and \"romantic wedding couple, the beach\".\n */\nconst SCENE_SETTINGS: ReadonlyArray<{ words: readonly string[]; said: string; landscape?: boolean; away?: readonly string[] }> = [\n {\n words: ['mountain', 'mountains', 'ridgetop', 'ridge', 'summit', 'peak', 'alpine', 'overlook', 'parkway'],\n said: 'mountains',\n landscape: true,\n away: [...SEASIDE, ...DESERT, ...CITYSCAPE],\n },\n { words: ['fall', 'autumn', 'foliage'], said: 'autumn', away: ['winter', 'snow', 'snowy', 'spring', 'blossom'] },\n { words: ['winter', 'snow', 'snowy'], said: 'winter', away: [...SEASIDE, 'summer', 'tropical'] },\n { words: ['beach', 'coast', 'seaside', 'shore', 'ocean'], said: 'beach', landscape: true, away: ['snow', 'snowy', 'ski', 'skiing', ...CITYSCAPE] },\n { words: ['forest', 'woods', 'woodland'], said: 'forest', landscape: true, away: [...SEASIDE, ...DESERT, ...CITYSCAPE] },\n { words: ['spring', 'blossom', 'blossoms'], said: 'spring', away: ['winter', 'snow', 'snowy', 'autumn', 'fall'] },\n { words: ['city', 'urban', 'downtown'], said: 'city', landscape: true, away: [...SEASIDE, ...DESERT] },\n]\n\n/** The stems of the places a setting is not ({@link SCENE_SETTINGS}); none for no setting. */\nexport function aiStockSettingAway(setting: string): string[] {\n const entry = SCENE_SETTINGS.find((candidate) => candidate.said === setting)\n return entry?.away ? [...new Set(entry.away.map(aiStockStem))] : []\n}\n\n/** What a picture of a moment shows ({@link aiStockScene}). */\nexport interface AiStockScene {\n /** The searches that ask for it, the people and their setting first. */\n queries: string[]\n /** The words its photo is scored by: the people, and the setting. */\n subject: string\n /** The thing a photo of it leads with, and its kin. */\n object: string\n lead: string[]\n /** Words of which a photo of it names one. */\n people: string[]\n shun: string[]\n /** The stems of its words, which let in what they name: a family's children. */\n named: string[]\n /** Stems of the places it is not set in, which none of a photo's first tags name ({@link aiStockSettingAway}, AGL-3942). */\n away: string[]\n}\n\n/**\n * The scene a picture's words name (AGL-3856): the people at a moment, and\n * where — \"Ridgetop Elopement\" a couple in the mountains, \"Mountain Wedding\n * Day\" a wedding couple in the mountains, \"Family Session in the Fall\" a\n * family in autumn — read from every word, never only the first clause.\n * `null` where it names no people.\n */\nexport function aiStockScene(text: string, siteSetting = ''): AiStockScene | null {\n const named = sceneWords(text)\n const scene = PEOPLE_SCENES.find((entry) => entry.words.some((word) => named.has(word)))\n if (!scene) return null\n const setting = aiStockSetting(text)\n const query = scene.query(named)\n return {\n queries: [...new Set([setting ? `${query} ${setting}` : '', query].filter(Boolean))],\n subject: [scene.subject, setting].filter(Boolean).join(' '),\n object: scene.subject,\n lead: scene.lead.map((phrase) => stemList(phrase).join(' ')),\n people: scene.people.map(aiStockStem),\n shun: scene.shun.filter((word) => !named.has(word)).map(aiStockStem),\n named: [...new Set(stemList(text))],\n // Searched where its own words set it; never shown anywhere the site is not.\n away: aiStockSettingAway(setting || siteSetting),\n }\n}\n\n/** A text's lowercase words, letters only. */\nconst sceneWords = (text: string) =>\n new Set(\n text\n .toLowerCase()\n .split(/[^a-zÀ-ɏ]+/)\n .filter(Boolean),\n )\n\n/** Where a text's words set a picture ({@link SCENE_SETTINGS}): \"mountains\" of \"Couples planning mountain weddings\"; empty for none. */\nexport function aiStockSetting(text: string): string {\n const named = sceneWords(text)\n return SCENE_SETTINGS.find((entry) => entry.words.some((word) => named.has(word)))?.said ?? ''\n}\n\n/**\n * The moment a portfolio's record shows (AGL-3856): read from the record's\n * own name first, then from what it is filed under, then as a portrait, and\n * set where its name, its category or else the site's own words say. A\n * photographer's \"Getting Ready\" filed under \"Weddings and elopements\" is a\n * wedding couple in the mountains; \"Milestone Portraits\" filed under \"Family\n * portraits\" a family. Its searches end on the people alone (\"couple\"), so a\n * moment no photo shows in its setting still shows its people. `null` where\n * neither names people at a moment nor a portrait.\n */\nexport function aiStockRecordScene(name: string, category = '', siteSetting = ''): AiStockScene | null {\n const texts = [name, category].filter((text) => text.trim())\n const source =\n texts.find((text) => PEOPLE_SCENES.some((entry) => entry.words.some((word) => sceneWords(text).has(word)))) ??\n texts.find((text) => PORTRAIT_SCENE.words.some((word) => sceneWords(text).has(word)))\n if (!source) return null\n const named = sceneWords(source)\n const scene = PEOPLE_SCENES.find((entry) => entry.words.some((word) => named.has(word))) ?? PORTRAIT_SCENE\n const setting = texts.map(aiStockSetting).find(Boolean) ?? siteSetting\n const query = scene.query(named)\n const all = sceneWords(texts.join(' '))\n return {\n queries: [...new Set([setting ? `${query} ${setting}` : '', query, scene.subject].filter(Boolean))],\n subject: [scene.subject, setting].filter(Boolean).join(' '),\n object: scene.subject,\n // A record's cover leads with its people: a wedding's table decor is not \"Overlook Ceremonies\".\n lead: scene.lead.filter((phrase) => !RECORD_SCENE_UNPEOPLED.has(phrase)).map((phrase) => stemList(phrase).join(' ')),\n people: scene.people.map(aiStockStem),\n shun: scene.shun.filter((word) => !all.has(word)).map(aiStockStem),\n named: [...new Set(stemList(texts.join(' ')))],\n away: aiStockSettingAway(setting),\n }\n}\n\n/**\n * The work a craft whose pictures are people at a moment shows (AGL-3942):\n * the scenes its site's own words name, in the order they name them, each\n * set where the site is — a wedding photographer \"for couples planning\n * mountain weddings, and families\" shows a wedding couple in the mountains\n * and a family in the mountains. A family session still never shows a\n * bride, whatever else the site names. Empty where its words name no people.\n */\nexport function aiStockWorkScenes(text: string, setting = ''): AiStockScene[] {\n const list = text\n .toLowerCase()\n .split(/[^a-zÀ-ɏ]+/)\n .filter(Boolean)\n const found = PEOPLE_SCENES.map((scene) => ({ scene, at: list.findIndex((word) => scene.words.includes(word)) }))\n .filter((entry) => entry.at >= 0)\n .sort((a, b) => a.at - b.at)\n return found.map(({ scene }) => {\n const named = new Set(list.filter((word) => scene.words.includes(word)))\n const query = scene.query(named)\n return {\n queries: [...new Set([setting ? `${query} ${setting}` : '', query].filter(Boolean))],\n subject: [scene.subject, setting].filter(Boolean).join(' '),\n object: scene.subject,\n lead: scene.lead.filter((phrase) => !RECORD_SCENE_UNPEOPLED.has(phrase)).map((phrase) => stemList(phrase).join(' ')),\n people: scene.people.map(aiStockStem),\n shun: scene.shun.map(aiStockStem),\n named: [...new Set([...named].map(aiStockStem))],\n away: aiStockSettingAway(setting),\n }\n })\n}\n\n/** Whether a setting is a place a photo shows on its own, a landscape searched by its name: \"mountains\", never \"autumn\". */\nexport function aiStockSettingIsLandscape(setting: string): boolean {\n return SCENE_SETTINGS.some((entry) => entry.said === setting && entry.landscape === true)\n}\n\n/**\n * A scene's lead words a record's cover never leads with alone\n * ({@link aiStockRecordScene}): the moment with no one in it (a wedding's table\n * decor for \"Overlook Ceremonies\"), or children with no family (a ski class\n * for \"Milestone Portraits\").\n */\nconst RECORD_SCENE_UNPEOPLED = words('wedding elopement child children kid kids baby toddler')\n\n/**\n * What a portfolio's record is never OF, among its first tags, unless its own\n * words name it (AGL-3856): an animal, a toy or a figurine. The beta.265\n * Laurel Ridge \"Gallery collections\" covers were a toy frog with a camera, a\n * toy duck and a cat's portrait.\n */\nconst RECORD_ODD_LEADS = words(\n 'animal animals cat cats kitten dog dogs puppy pet pets bird birds frog frogs duck ducks horse horses cow rabbit bunny ' +\n 'toy toys figurine figurines lego doll dolls teddy puppet miniature',\n)\n\n/** An object's kin phrases as stems, or none. */\nconst kinStems = (entry: (typeof OBJECT_KIN)[number] | null): string[] =>\n entry ? [...new Set(entry.kin.map((phrase) => stemList(phrase).join(' ')))] : []\n\n/** What a product falls back to once its own searches find nothing ({@link aiStockProductSearches}). */\nexport interface AiStockProductFallback {\n /** The site's broad searches ({@link AiStockSiteTerms.broad}): \"handmade soap\". */\n broad?: readonly string[]\n /** The words a photo of the craft itself names ({@link AiStockSiteTerms.core}). */\n core?: readonly string[]\n}\n\n/**\n * A size never names a product (AGL-3660): the Tidewater start searched\n * \"soap set starter size\" for \"Bath Gift Set Starter Size\", its head noun\n * read as \"size\", and took a soap dispenser.\n */\nconst PRODUCT_SIZES =\n /\\b(?:(?:starter|travel|trial|sample|mini|full|half|family|value|jumbo|large|small|regular|standard|big)[- ])?sized?s?\\b/gi\n\n/** The wrapper words a gift is named by, searched with the craft: \"soap gift box\". */\nconst GIFT_WRAPPERS = words('gift gifts box boxes basket baskets hamper hampers')\n\n/**\n * A product's searches (AGL-3676), most specific first: each of its subjects\n * — its name's noun phrase, then its photo's — with the shop's category\n * where the phrase does not already name the shop's world (\"candle gift\n * box\"), then the category alone, a plain photo of what the shop sells. Every\n * one must find a hit naming the category — or the product's own word of the\n * shop's world, \"lotion\" in a soap shop — so no product is ever filled with a\n * lifestyle shot of something else: the beta.237 Willow Wick start put a\n * laptop and roses under \"Candle Wick Trimmer\" and an antique tea set under\n * \"Candle Gift Set\".\n *\n * And each must find a hit naming the product's own head noun among its\n * first tags (AGL-3660): the beta.239 Ember & Oak start put a bed with a book,\n * a mug and a camera (its candle a last tag) under \"Hand-Poured Soy Candle\".\n * An object whose own word is not enough ({@link OBJECT_KIN}) is searched by\n * its kin instead of the category alone, and named by them: a single taper\n * candle filled \"Wax Melt Gift Set\".\n *\n * Then, before a product is ever given a photo of something else, it falls\n * back to its own craft (AGL-3660). The Saltmarsh Soap Co start (2026-10-10)\n * found no hit naming \"bar\" or \"box\" among the first tags, and four of its\n * five products took the starter photos — a laptop and roses, a living room\n * of plants. And the beta.242 Tidewater Soap Works start (2026-10-11) showed\n * that the head noun anywhere is not enough: its own weak hits put a sauna\n * under \"Bath Gift Set\", colognes under \"Natural Body Lotion\", a bathroom\n * shelf under \"Soap Bar Trio\" and a soap dispenser under its starter size,\n * while the collection tiles beside them, searched for the category, were\n * good. So the searches are ranked by how sure they are ({@link AiStockSearch.tier}):\n *\n * 1. Its own: the head noun (or its kin) among the first tags, as above.\n * 2. `borrow`: a photo OF its category — the category alone, then the craft's\n * broad searches (\"handmade soap\", \"natural skincare\"), one of the\n * product's kin or the craft's own names among the first tags. A product\n * may repeat one the job already shows, a collection tile's photo or\n * another product's ({@link aiLayoutStockPhotoSource}): a borrowed\n * on-topic photo beats a weak specific one.\n * 3. `weak`: the same searches again, the head noun named anywhere among the\n * tags (no extra search: the page remembers its answers), a gift's own\n * wrapper with the craft (\"soap gift box\"), and the craft's broad searches,\n * any hit naming the craft itself ({@link AiStockSiteTerms.core}).\n *\n * Every one of them turns down a room or a scene, a fragrance bottle, and\n * what the product's kin shuns (a pump for a bar of soap), unless the\n * product names it. A size never names the product: \"Bath Gift Set Starter\n * Size\" is a bath gift set.\n */\nexport function aiStockProductSearches(\n slot: Pick<AiLayoutPictureSlot, 'aspect' | 'product'>,\n craft: string,\n domain: readonly string[] = [],\n fallback: AiStockProductFallback = {},\n): AiStockSearch[] {\n const orientation = aiStockOrientation(slot.aspect)\n const size = orientation === 'vertical' ? { minHeight: 900 } : { minWidth: 900 }\n const craftStems = stemList(craft)\n const world = new Set([...domain, ...craftStems])\n const subjects = (slot.product?.subjects ?? [])\n .map((raw) => aiStockSubjectWords(raw.replace(PRODUCT_SIZES, ' '), ''))\n .filter(Boolean)\n // The product's head noun is its name's: \"candle\" of \"Hand-Poured Soy Candle\".\n const own = subjects[0] ?? ''\n const object = aiStockObjectWord(own)\n const kin = object\n ? objectKin(object, [...craftStems, ...domain, ...stemList(subjects.join(' '))])\n : null\n const kinPhrases = kinStems(kin)\n // A product of the shop's world beside its category is held to either:\n // a soap shop's body lotion names \"lotion\", never \"soap\".\n const ownWorld = stemList(own).filter(\n (stem) => world.has(stem) && !WRAPPERS.has(stem) && !craftStems.includes(stem),\n )\n const category = craft && ownWorld.length ? [...craftStems, ...ownWorld] : []\n const core = [...new Set([...craftStems, ...(fallback.core ?? [])])]\n const shun = (kin?.shun ?? []).map(aiStockStem)\n type Query = {\n query: string\n subject: string\n object: string\n lead: boolean\n broad?: boolean\n tier?: 'borrow' | 'weak'\n }\n const queries: Query[] = []\n for (const subject of subjects) {\n const stems = stemList(subject)\n const qualifier = kin?.qualifier ?? ''\n const query = kin\n ? !qualifier || stems.includes(aiStockStem(qualifier))\n ? subject\n : kin.after\n ? `${subject} ${qualifier}`\n : `${qualifier} ${subject}`\n : craft && !stems.some((stem) => world.has(stem))\n ? `${craft} ${subject}`\n : subject\n queries.push({ query, subject, object, lead: true })\n }\n // The category alone stands in only for a thing that is no more than of\n // it; a thing that is its own word of the shop's world is searched by that\n // word (\"lotion\"). Its hits are still scored by the product's own words: a\n // soy candle over a taper.\n if (kin)\n for (const query of kin.queries)\n queries.push({ query, subject: own || query, object, lead: true })\n else if (object && ownWorld.includes(object))\n queries.push({ query: object, subject: own, object, lead: true })\n else if (craft)\n queries.push({ query: craft, subject: own || craft, object: craft, lead: true, tier: 'borrow' })\n const held = [...queries]\n // 2. A photo OF its category, which may be one the job already shows.\n for (const query of fallback.broad ?? [])\n queries.push({ query, subject: own, object: '', lead: true, broad: true, tier: 'borrow' })\n // 3. The head noun anywhere among the tags, by the same searches.\n for (const entry of held) queries.push({ ...entry, lead: false, tier: 'weak' })\n // A gift is its craft's: \"bath gift box\" asks for a \"soap gift box\".\n const wrapped = own\n .split(/\\s+/)\n .filter((word) => WRAPPERS.has(word) && aiStockStem(word) !== object)\n const gift = wrapped.find((word) => GIFT_WRAPPERS.has(word))\n if (craft && gift && !kin)\n queries.push({\n query: `${craft} ${wrapped.join(' ')}`,\n subject: own,\n object: aiStockStem(gift),\n lead: false,\n tier: 'weak',\n })\n // The craft's own broad searches, any hit naming the craft.\n for (const query of fallback.broad ?? [])\n queries.push({ query, subject: own, object: '', lead: false, broad: true, tier: 'weak' })\n // What a borrowed photo is OF: the product's kin, its own word of the shop's world, else the craft.\n const borrowed = kinPhrases.length ? kinPhrases : ownWorld.length ? ownWorld : core\n const seen = new Set<string>()\n const searches: AiStockSearch[] = []\n for (const entry of queries) {\n const query = clip(entry.query)\n const key = `${query}|${entry.lead}|${entry.object}|${entry.broad === true}|${entry.tier ?? ''}`\n if (!query || seen.has(key)) continue\n seen.add(key)\n const common = {\n query,\n orientation,\n ...size,\n subject: entry.subject,\n product: true,\n ...(entry.tier ? { tier: entry.tier } : {}),\n ...(shun.length ? { shun } : {}),\n }\n if (entry.broad) {\n const heldTo = [...new Set([...core, ...ownWorld])]\n searches.push({\n ...common,\n broad: true,\n ...(entry.lead\n ? {\n leadAny: borrowed,\n ...(kinPhrases.length ? { kin: kinPhrases } : {}),\n ...(heldTo.length ? { category: heldTo } : {}),\n }\n : core.length\n ? { category: core }\n : {}),\n })\n continue\n }\n searches.push({\n ...common,\n // Named anywhere, the hit's first tags are still of the shop's world:\n // a bed with a book, its candle a last tag, is not a candle's photo.\n ...(entry.lead ? { lead: true } : { leadWorld: true }),\n ...(entry.object ? { object: entry.object } : {}),\n ...(kinPhrases.length && entry.object === object ? { kin: kinPhrases } : {}),\n ...(craft ? { requires: craft } : {}),\n ...(category.length ? { category } : {}),\n })\n }\n return searches\n}\n\n/**\n * The searches a slot tries, in order, most specific first, each distinct.\n * A portrait of one of the business's people ({@link AiLayoutPictureSlot.people})\n * asks first for the role its words or its list's name (`sectionName`) say,\n * in the site's world: \"teacher classroom\" for a \"Math instructor\" (AGL-3856).\n */\nexport function aiStockSearchesFor(\n slot: Pick<AiLayoutPictureSlot, 'role' | 'alt' | 'aspect' | 'people' | 'record' | 'product'>,\n terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'domain' | 'broad'> &\n Partial<Pick<AiStockSiteTerms, 'making' | 'core' | 'scenes' | 'setting' | 'maker' | 'work'>>,\n subject: string,\n part?: AiStockSlotPart,\n sectionName = '',\n): AiStockSearch[] {\n const orientation = aiStockOrientation(slot.aspect)\n const size =\n slot.role === 'hero'\n ? { minWidth: 1600 }\n : orientation === 'vertical'\n ? { minHeight: 900 }\n : { minWidth: 900 }\n const domain = new Set(terms.domain)\n // A portfolio's record of a craft whose work is people at a moment shows the\n // moment, never the maker: the beta.265 Laurel Ridge \"Gallery collections\"\n // searched \"photographer mountain elopements\" and placed a press\n // photographer, a toy frog with a camera and a cat (AGL-3856).\n const work = aiStockShowsTheWork(slot, terms)\n // Every other picture of such a craft's site shows its work where a page\n // would show the maker (AGL-3942): the beta.267 Copper Hollow Film &\n // Portrait about page searched \"photographer at work\" and \"photographer\n // camera\", and every picture on it was a stock photographer.\n const itsWork = !work && aiStockShowsItsWork(slot, terms)\n /** Whether a query names the craft by its own name, the profession's noun: \"wedding photographer\". */\n const namesCraft = (query: string) => stemList(query).some((stem) => (terms.core ?? []).includes(stem))\n /** Whether a query names the maker, their tools or the craft: \"photographer at work\", \"photographer camera\". */\n const namesMaker = (query: string) => namesCraft(query) || stemList(query).some((stem) => (terms.maker ?? []).includes(stem))\n /** A rung of the maker's own photos, left out on a site that shows its work. */\n const shown = (query: string) => !itsWork || !namesMaker(query)\n /** A search of the slot's own words, left out on such a site only where they name the profession. */\n const said = (query: string) => !itsWork || !namesCraft(query)\n const object = aiStockObjectWord(subject)\n const subjectStems = stemList(subject)\n const kin = object ? objectKin(object, [...terms.domain, ...subjectStems]) : null\n const kinPhrases = kinStems(kin)\n // The craft qualifies a subject that does not already name the site's world.\n const namesWorld = subjectStems.some((stem) => domain.has(stem))\n // A tile of the shop's world beside its category is held to either: a soap\n // shop's \"Body care\" tile names \"body\", never \"soap\" (AGL-3660).\n const ownWorld = subjectStems.filter(\n (stem) => domain.has(stem) && !WRAPPERS.has(stem) && stem !== terms.craft,\n )\n // A hero of a craft names the craft itself: the Saltmarsh Soap Co hero\n // (2026-10-10) was a florist's bouquet tagged \"natural\" (AGL-3660).\n const core = terms.core ?? []\n const qualify = (phrase: string) =>\n terms.craft && !namesWorld && !stemList(phrase).includes(terms.craft)\n ? `${terms.craft} ${phrase}`\n : phrase\n type Query = {\n query: string\n broad?: boolean\n people?: boolean\n held?: boolean\n category?: boolean\n /** Where the site's work is searched ({@link AiStockSiteTerms.work}). */\n work?: boolean\n }\n // A collection tile is product-like: held to the shop's category and its\n // own object among the first tags, and searched by its object's kin, never\n // the category's world alone (AGL-3660).\n const collection = part === 'collection' && Boolean(terms.craft) && !work\n const broad: Query[] = (kin && collection) || work\n ? []\n : terms.broad.filter(shown).map((query) => ({ query, broad: true, category: collection }))\n // The maker at work, held to the craft: never \"hands\" (AGL-3660).\n const makers: Query[] = (work ? [] : (terms.making ?? [])).filter(shown).map((query) => ({\n query,\n broad: true,\n category: true,\n }))\n // A portrait in its role, in the site's world, where the libraries know a word for it.\n const roleWord = slot.people ? (aiStockPeopleRole(slot.alt, sectionName)?.query ?? '') : ''\n const role = roleWord ? (stemList(terms.business).includes(roleWord) ? terms.business : `${roleWord} ${terms.business}`.trim()) : ''\n // A scene's people are read from every word of the picture's, never its first clause alone.\n const scene = work\n ? aiStockRecordScene(slot.alt, slot.record?.category ?? '', terms.setting ?? '')\n : terms.scenes && slot.role !== 'hero' && part !== 'collection'\n ? aiStockScene(slot.alt, terms.setting ?? '')\n : null\n // The site's own scenes, turned per slot so a page's pictures show each of them.\n const sceneList: AiStockScene[] = []\n if (itsWork) {\n const own = terms.work ?? []\n const turn = own.length ? aiLayoutSeedNumber(`${sectionName}|${slot.alt}`) % own.length : 0\n sceneList.push(...own.slice(turn), ...own.slice(0, turn))\n }\n // The work's own subject is never qualified by the craft: \"getting ready\", never \"photographer getting ready\".\n const own = work ? (phrase: string) => phrase : qualify\n const thing: Query[] = (\n subject\n ? [\n { query: own(subject), held: true },\n ...(kin\n ? kin.queries.map((query) => ({ query, held: true }))\n : [{ query: own(object), held: true }]),\n ]\n : []\n ).filter((query) => said(query.query))\n // Never the maker, the camera, an animal or a toy, unless the record names it.\n const recordNamed = work ? new Set(stemList(`${slot.alt} ${slot.record?.category ?? ''}`)) : null\n const refuseLead = recordNamed\n ? [...new Set([...(terms.maker ?? []), ...[...RECORD_ODD_LEADS].map(aiStockStem)])].filter((stem) => !recordNamed.has(stem))\n : []\n // Where the maker's rungs were, a site that shows its work searches its work.\n const shows: Query = { query: '', work: true }\n const making = itsWork ? [shows] : makers\n const queries: Query[] =\n slot.role === 'hero'\n ? [{ query: terms.business, broad: true }, ...broad, ...(itsWork ? [shows] : [])]\n : slot.role === 'about'\n ? [\n ...(role ? [{ query: role, broad: true, people: true }] : []),\n ...(part === 'story' ? making : []),\n ...[\n {\n query: `${terms.business} ${subject}`,\n broad: true,\n people: true,\n },\n { query: terms.business, broad: true, people: true },\n ].filter((query) => said(query.query)),\n ...(part === 'story' ? [] : making),\n ...broad,\n ]\n : [...(part === 'story' ? making : []), ...(scene ? [] : thing), ...(itsWork ? [shows] : []), ...broad]\n const seen = new Set<string>()\n const searches: AiStockSearch[] = []\n // A picture of people at a moment asks for them, and where, before anything\n // else, and takes only a photo leading with them (AGL-3856): never the\n // roses of a \"Mountain Wedding Day\", nor a bride for a family session. A\n // picture of the work never leads with the maker or a camera (AGL-3942).\n const workLead = itsWork ? (terms.maker ?? []) : []\n // The site's work is held to its own scene, never to the craft's world.\n const sceneSearch = (one: AiStockScene, query: string, ofWork: boolean): AiStockSearch => {\n const refused = [...new Set([...refuseLead, ...workLead.filter((stem) => !one.named.includes(stem))])]\n return {\n query,\n orientation,\n ...size,\n strict: true,\n subject: one.subject,\n object: one.object,\n kin: one.lead,\n lead: true,\n needs: one.people,\n allow: one.named,\n ...(one.shun.length ? { refuse: one.shun } : {}),\n ...(refused.length ? { refuseLead: refused } : {}),\n ...(one.away.length ? { away: one.away } : {}),\n ...(work || ofWork ? { worldless: true } : {}),\n }\n }\n for (const query of scene?.queries ?? []) {\n seen.add(`${query}|false`)\n searches.push(sceneSearch(scene as AiStockScene, query, false))\n }\n /** The site's own scenes, then the place itself where it is a landscape: \"mountains\". */\n const workSearches = (): AiStockSearch[] => {\n const found: AiStockSearch[] = []\n for (const one of sceneList)\n for (const query of one.queries) {\n if (seen.has(`${query}|false`)) continue\n seen.add(`${query}|false`)\n found.push(sceneSearch(one, query, true))\n }\n const place = terms.setting && aiStockSettingIsLandscape(terms.setting) ? terms.setting : ''\n if (!place || seen.has(`${place}|false`)) return found\n seen.add(`${place}|false`)\n const away = aiStockSettingAway(place)\n const stems = SCENE_SETTINGS.find((entry) => entry.said === place)?.words.map(aiStockStem) ?? []\n found.push({\n query: place,\n orientation,\n ...size,\n strict: true,\n subject: place,\n object: aiStockStem(place),\n kin: [...new Set(stems)],\n lead: true,\n ...(workLead.length ? { refuseLead: [...workLead] } : {}),\n ...(away.length ? { away } : {}),\n worldless: true,\n })\n return found\n }\n for (const raw of queries) {\n if (raw.work) {\n searches.push(...workSearches())\n continue\n }\n const query = clip(raw.query)\n const key = `${query}|${raw.people === true}`\n if (!query || seen.has(key)) continue\n seen.add(key)\n const held = raw.held === true && (collection || kinPhrases.length > 0)\n searches.push({\n query,\n orientation,\n ...size,\n ...(raw.people ? { people: true } : {}),\n ...(raw.broad ? { broad: true } : {}),\n ...(held && kinPhrases.length ? { kin: kinPhrases } : {}),\n ...(held && collection ? { lead: true } : {}),\n ...(terms.craft && (raw.category || (raw.held && collection))\n ? {\n requires: terms.craft,\n ...(ownWorld.length ? { category: [terms.craft, ...ownWorld] } : {}),\n }\n : {}),\n ...(slot.role === 'hero' && core.length ? { category: core } : {}),\n // A hero is OF the site's world: its first tag names it (AGL-3760).\n ...(slot.role === 'hero' ? { first: true } : {}),\n ...(refuseLead.length ? { refuseLead } : {}),\n ...(work ? { worldless: true } : {}),\n })\n }\n return searches\n}\n\n/**\n * Whether a picture of a craft's site whose pictures are people at a moment\n * shows that work wherever a page would show the maker (AGL-3942): an about\n * picture, a story of the craft, an intro's cover. Not a record (which shows\n * its own moment, {@link aiStockShowsTheWork}), a portrait of the business's\n * people, nor a product; and only where the site's words name the work.\n */\nexport function aiStockShowsItsWork(\n slot: Pick<AiLayoutPictureSlot, 'record' | 'people' | 'product'>,\n terms: Partial<Pick<AiStockSiteTerms, 'scenes' | 'work'>>,\n): boolean {\n return Boolean(terms.scenes) && (terms.work?.length ?? 0) > 0 && !slot.record && !slot.people && !slot.product\n}\n\n/**\n * Whether a slot is a portfolio's record of a craft whose work is people at a\n * moment (AGL-3856): a photographer's \"Mountain Elopements\" shows an\n * elopement, never the photographer. Searched by the moment its words and its\n * category name, held to no world of the craft, and never led by the craft's\n * own words, an animal or a toy unless the record names them.\n */\nexport function aiStockShowsTheWork(\n slot: Pick<AiLayoutPictureSlot, 'record' | 'role' | 'people' | 'product'>,\n terms: Partial<Pick<AiStockSiteTerms, 'scenes'>>,\n): boolean {\n return Boolean(slot.record) && Boolean(terms.scenes) && slot.role !== 'hero' && !slot.people && !slot.product\n}\n\n/** What a hit is judged by. */\nexport interface AiStockJudgement {\n /** The words the picture is of; empty for a picture of the site's world. */\n subject?: string\n /** The site's domain stems ({@link AiStockSiteTerms.domain}). */\n domain?: readonly string[]\n /**\n * Whether a hit must name the subject's object. A broad search, a hero\n * and an about picture need only name the domain.\n */\n strict?: boolean\n /** A word every hit must name: a product's photo names the shop's category (AGL-3676). */\n requires?: string\n /** Words of which a hit must name one, `requires` among them ({@link AiStockSearch.category}). */\n category?: readonly string[]\n /** The thing a hit must name, where it is not the subject's own (AGL-3660). */\n object?: string\n /** Phrases naming the object where its word is not enough; one of them is then required, and stands for the category. */\n kin?: readonly string[]\n /** Whether the object must be among the hit's first tags (AGL-3660). */\n lead?: boolean\n /** Whether the hit's first tags must name the site's world ({@link AiStockSearch.leadWorld}). */\n leadWorld?: boolean\n /** Whether the hit's first tag must name the site's world ({@link AiStockSearch.first}). */\n first?: boolean\n /** The stems of the site's business type or brief, which let a sensitive topic in ({@link AiStockSiteTerms.named}). */\n named?: readonly string[]\n /** Rival crafts: a hit naming one is rejected unless it names the site's core words ({@link AiStockSiteTerms.rivals}). */\n rivals?: ReadonlyArray<{ words: readonly string[]; core: readonly string[] }>\n /** Phrases of which one must be among the hit's first tags ({@link AiStockSearch.leadAny}). */\n leadAny?: readonly string[]\n /** Whether it judges for a product: no room, no scene, no fragrance bottle (AGL-3660). */\n product?: boolean\n /** Words a hit never carries unless the subject or the brief names them ({@link AiStockSiteTerms.shun}). */\n shun?: readonly string[]\n /** Words a hit's first tags never carry unless the subject or the brief names them ({@link AiStockSiteTerms.shunLead}). */\n shunLead?: readonly string[]\n /** Words a hit never carries, whatever the brief names ({@link AiStockSearch.refuse}). */\n refuse?: readonly string[]\n /** Stems of which a hit names one ({@link AiStockSearch.needs}). */\n needs?: readonly string[]\n /** Stems no hit's first tags carry: a child, for a portrait of one of the business's people (AGL-3856). */\n refuseLead?: readonly string[]\n /** Stems naming the role a portrait shows, which a hit is preferred for naming, most of all first (AGL-3856). */\n roles?: readonly string[]\n /** Stems of the role being done, one of which a hit's first tags must name ({@link AiStockPeopleRole.scene}). */\n roleScene?: readonly string[]\n /** Stems of something else being done, which none of a hit's first tags may name ({@link AiStockPeopleRole.refuse}). */\n roleRefuse?: readonly string[]\n /** Stems of the places the picture is not set in, which none of a hit's first tags may name ({@link AiStockSearch.away}). */\n away?: readonly string[]\n}\n\n/** The words of a photo's page address at its library, its id dropped: \"robin-bird-songbird-garden-winter\". */\nfunction pageSlug(pageUrl: string): string {\n try {\n const last = decodeURIComponent(new URL(pageUrl).pathname)\n .split('/')\n .filter(Boolean)\n .pop()\n return last?.replace(/-?\\d+$/, '') ?? ''\n } catch {\n return ''\n }\n}\n\n/** A hit's words: the first few (what it is OF), every one, and each tag's phrase. */\nfunction hitWords(photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>) {\n const slug = pageSlug(photo.pageUrl)\n const tags = (photo.tags ?? [])\n .map((tag) => tag.toLowerCase().trim())\n .filter(Boolean)\n const lead = new Set(stemList([...tags.slice(0, 3), slug].join(' ')))\n const all = new Set(stemList([...tags, photo.alt ?? '', slug].join(' ')))\n const phrases = [\n ...tags.map((tag) => stemList(tag).join(' ')),\n stemList(photo.alt ?? '').join(' '),\n stemList(slug).join(' '),\n ]\n const leadPhrases = [\n ...tags.slice(0, 3).map((tag) => stemList(tag).join(' ')),\n stemList(slug).join(' '),\n ]\n /** The first tag: what the photo is most of all. */\n const firstPhrase = stemList(tags[0] ?? '').join(' ')\n const rejected = tags.some(\n (tag) =>\n REJECTED_TAGS.has(tag) ||\n tag.split(/\\s+/).some((word) => REJECTED_TAGS.has(word)),\n )\n // Whole words only, a hyphenated one kept whole: \"cross-stitch\" is not a cross.\n const words = new Set(\n [...tags, (photo.alt ?? '').toLowerCase()]\n .join(' ')\n .split(/[^a-zÀ-ɏ-]+/)\n .filter((word) => word.length > 1)\n .map(aiStockStem),\n )\n return { lead, all, phrases, leadPhrases, firstPhrase, rejected, words }\n}\n\n/** Whether a phrase is among a hit's phrases, word for word. */\nconst among = (phrases: readonly string[], phrase: string) =>\n phrases.some((found) => ` ${found} `.includes(` ${phrase} `))\n\n/**\n * Whether a hit carries a topic its site never named ({@link SENSITIVE_TOPICS}):\n * a cross, a grave, a flag, a gun, a glass of wine, a child, a mannequin.\n */\nexport function aiStockSensitive(\n photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>,\n named: readonly string[] = [],\n): boolean {\n const { words: found } = hitWords(photo)\n const site = new Set(named)\n return SENSITIVE_STEMS.some(\n (topic) =>\n [...topic.words].some((word) => found.has(word)) &&\n ![...topic.allow].some((word) => site.has(word)),\n )\n}\n\n/**\n * How well a hit shows what a slot needs (AGL-3660), or 0 when it must not\n * fill it: a mockup or a blank never; a topic the site never named never\n * ({@link aiStockSensitive}); a picture of a thing only when the hit\n * names its object AND either the site's world or the subject's own\n * two-word phrase (\"bud vase\", \"wick trimmer\"); anything else only when it\n * names the site's world (when the site names one). Among the accepted, the\n * object among the hit's first tags counts 4 (a mention among its last, 2),\n * the subject's two-word phrase 3, each of its other words 1, and the\n * site's world 1, plus a quarter when it is among the first tags.\n */\nexport function aiStockRelevance(\n photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>,\n judgement: AiStockJudgement,\n): number {\n const hit = hitWords(photo)\n if (hit.rejected) return 0\n if (aiStockSensitive(photo, judgement.named)) return 0\n // Glass art is not pottery: a rival craft's photo names this craft's own words.\n for (const rival of judgement.rivals ?? [])\n if (\n rival.words.some((word) => hit.all.has(word)) &&\n !rival.core.some((word) => hit.all.has(word))\n )\n return 0\n const subject = stemList(judgement.subject ?? '')\n // What the slot or the brief names lets a shunned word, a room or a fragrance in.\n const owned = new Set([...subject, ...(judgement.named ?? [])])\n // A dispenser is not a soapmaker's, nor a pump a bar's (AGL-3660).\n if ((judgement.shun ?? []).some((word) => hit.all.has(word) && !owned.has(word)))\n return 0\n // A family session is never a bride, however the photographer's brief names weddings.\n if ((judgement.refuse ?? []).some((word) => hit.all.has(word))) return 0\n // A teacher's portrait is never OF a child, whatever else it names.\n if ((judgement.refuseLead ?? []).some((word) => hit.lead.has(word))) return 0\n // A teacher is shown teaching: a classroom, a lecture or students among the\n // first tags, and never a model, a pose or a painting (AGL-3856).\n if (judgement.roleScene?.length || judgement.roleRefuse?.length) {\n const first = new Set(stemList((photo.tags ?? []).slice(0, AI_STOCK_ROLE_TAGS_READ).join(' ')))\n if (judgement.roleScene?.length && !judgement.roleScene.some((stem) => first.has(stem))) return 0\n const read = new Set(stemList((photo.tags ?? []).slice(0, ALT_TAGS_READ).join(' ')))\n if ((judgement.roleRefuse ?? []).some((stem) => read.has(stem))) return 0\n }\n // A Blue Ridge couple is never on a beach, however its later tags name a mountain (AGL-3942).\n if (judgement.away?.length) {\n const read = new Set(stemList((photo.tags ?? []).slice(0, ALT_TAGS_READ).join(' ')))\n if (judgement.away.some((stem) => read.has(stem))) return 0\n }\n // A wedding day shows its people: a close-up of roses tagged \"wedding\" never fills it.\n const needs = judgement.needs ?? []\n if (needs.length && !needs.some((word) => hit.all.has(word))) return 0\n // What the photo is OF: a typewriter's terms of service are not a law firm's.\n if ((judgement.shunLead ?? []).some((word) => hit.lead.has(word) && !owned.has(word)))\n return 0\n if (judgement.product) {\n // A sauna, a bathroom shelf: a room is never the product.\n for (const word of hit.lead)\n if (PRODUCT_SCENES.has(word) && !owned.has(word)) return 0\n // Colognes are not a lotion: a fragrance's bottle only for a fragrance.\n if (\n ![...FRAGRANCE_BOTTLES].some((word) => owned.has(word)) &&\n [...hit.lead].some((word) => FRAGRANCE_BOTTLES.has(word))\n )\n return 0\n }\n // A borrowed photo is OF the product's category.\n const leadAny = judgement.leadAny ?? []\n if (leadAny.length && !leadAny.some((phrase) => among(hit.leadPhrases, phrase)))\n return 0\n const kin = judgement.kin ?? []\n const kinNamed = kin.some((phrase) => among(hit.phrases, phrase))\n const kinLead = kin.some((phrase) => among(hit.leadPhrases, phrase))\n const required = stemList(judgement.requires ?? '')\n const category = (judgement.category ?? []).flatMap(stemList)\n const anyOf = category.length ? [...new Set([...required, ...category])] : []\n const demanded = required.length > 0 || anyOf.length > 0\n const meets = anyOf.length\n ? anyOf.some((stem) => hit.all.has(stem))\n : required.every((stem) => hit.all.has(stem))\n // An object's kin stands for the category: a wax melt is the candle shop's.\n if (demanded && !kinNamed && !meets) return 0\n const object =\n judgement.object ??\n (judgement.subject ? aiStockObjectWord(judgement.subject) : '')\n const domain = (judgement.domain ?? []).filter((stem) => stem !== object)\n // A hit naming the word it must name is of the site's world: a product's\n // category is that world even where it is the product's own object.\n const world =\n demanded || kinNamed || domain.some((stem) => hit.all.has(stem))\n const worldLead =\n (anyOf.length\n ? anyOf.some((stem) => hit.lead.has(stem))\n : required.length > 0 && required.every((stem) => hit.lead.has(stem))) ||\n kinLead ||\n domain.some((stem) => hit.lead.has(stem))\n if (judgement.leadWorld && !worldLead) return 0\n // The first tag alone, never the page's address: Pixabay's slug repeats a\n // late tag (\"coffee-latte-art-candle-…\"). A site whose words name no world\n // holds its hero to none.\n const worldStems = new Set([...anyOf, ...required, ...domain])\n if (judgement.first && (worldStems.size || kin.length)) {\n const firstWorld =\n hit.firstPhrase.split(' ').some((stem) => worldStems.has(stem)) ||\n kin.some((phrase) => among([hit.firstPhrase], phrase))\n if (!firstWorld) return 0\n }\n // What the photo is most of all: its first tag names the object, its kin or what it must be OF.\n const firstNamed = (phrases: readonly string[]) =>\n phrases.some((phrase) => Boolean(phrase) && among([hit.firstPhrase], phrase))\n const pair = subject.length >= 2 ? subject.slice(-2).join(' ') : ''\n const phrased = Boolean(pair) && among(hit.phrases, pair)\n let score = 0\n if (judgement.strict && object) {\n // An object with kin is named only by them: \"melt\" alone is resin art.\n const named = kin.length ? kinNamed : hit.all.has(object)\n if (!named) return 0\n const leading = kin.length ? kinLead : hit.lead.has(object)\n // A lifestyle scene whose object is a last tag is not a photo OF it.\n if (judgement.lead && !leading) return 0\n if (domain.length && !world && !phrased) return 0\n score += leading ? 4 : 2\n if (kinNamed) score += 3\n if (firstNamed(kin.length ? kin : [object])) score += 1\n } else if (domain.length) {\n if (!world) return 0\n }\n if (leadAny.length && firstNamed(leadAny)) score += 1\n if (phrased) score += 3\n for (const word of new Set(subject))\n if (word !== object && hit.all.has(word)) score += 1\n if (world) score += worldLead ? 1.25 : 1\n // A portrait in its role: a teacher at the board over a woman in a classroom.\n const roles = judgement.roles ?? []\n if (roles.some((word) => hit.lead.has(word))) score += 4\n else if (roles.some((word) => hit.all.has(word))) score += 2\n // A hero is most of all what its first tags say: \"law office, lawyer,\n // attorney\" over \"lawyers, personal injury, accident\" (AGL-3856): a second\n // of them naming its world says it is of that world, not of something else.\n if (judgement.first && worldStems.size) {\n const said = hit.leadPhrases.slice(0, -1).filter((phrase) => phrase.split(' ').some((stem) => worldStems.has(stem)))\n if (said.length >= 2) score += 0.25\n }\n return Math.max(score, 0.5)\n}\n\n/**\n * A search's acceptable hits in the order they are tried (AGL-3660): those\n * not placed yet, among the first few the library returned, those it must\n * not take dropped ({@link aiStockRelevance}), best first; the seed turns\n * the hits that score alike, so two jobs differ and one job repeats itself.\n */\nexport function aiStockRank(\n photos: readonly StockPhoto[],\n used: ReadonlySet<string>,\n seed: string,\n judgement: AiStockJudgement = {},\n): StockPhoto[] {\n const scored = photos\n .filter((photo) => !used.has(stockPhotoSourceKey(photo)))\n .slice(0, AI_LAYOUT_STOCK_PICK_WINDOW)\n .map((photo) => ({ photo, score: aiStockRelevance(photo, judgement) }))\n .filter((entry) => entry.score > 0)\n if (!scored.length) return []\n const turn = aiLayoutSeedNumber(seed)\n const ranked: StockPhoto[] = []\n for (const score of [...new Set(scored.map((entry) => entry.score))].sort(\n (a, b) => b - a,\n )) {\n const tier = scored.filter((entry) => entry.score === score)\n const start = turn % tier.length\n for (const entry of [...tier.slice(start), ...tier.slice(0, start)])\n ranked.push(entry.photo)\n }\n return ranked\n}\n\n/**\n * Whether two hits are of one shoot (AGL-3856): one contributor's photos a few\n * uploads apart, as Pixabay numbers them — the beta.265 Granite Peak Barbell\n * coaches were four of one model, 728223 to 728229 — else one page address.\n */\nexport function aiStockSameShoot(\n a: Pick<StockPhoto, 'id' | 'photographer' | 'pageUrl'>,\n b: Pick<StockPhoto, 'id' | 'photographer' | 'pageUrl'>,\n): boolean {\n const near = Number(a.id) && Number(b.id) ? Math.abs(Number(a.id) - Number(b.id)) < 100 : false\n if (a.photographer && a.photographer === b.photographer && near) return true\n const slug = pageSlug(a.pageUrl)\n return Boolean(slug) && slug === pageSlug(b.pageUrl)\n}\n\n/**\n * A search's ranked hits with those of a shoot no slot shows yet first among\n * the best (AGL-3856): a team's three cards are three people where the\n * library has them, never one model three times while another fits as well.\n * Every other order is kept.\n */\nexport function aiStockFreshShootsFirst(\n ranked: readonly StockPhoto[],\n shown: readonly StockPhoto[],\n judgement: AiStockJudgement,\n): StockPhoto[] {\n if (!shown.length || ranked.length < 2) return [...ranked]\n const best = aiStockRelevance(ranked[0] as StockPhoto, judgement)\n const top = ranked.filter((photo) => aiStockRelevance(photo, judgement) === best)\n const fresh = top.filter((photo) => !shown.some((other) => aiStockSameShoot(photo, other)))\n if (!fresh.length || fresh[0] === ranked[0]) return [...ranked]\n return [...fresh, ...ranked.filter((photo) => !fresh.includes(photo))]\n}\n\n/** The pick among a search's hits: the first {@link aiStockRank} would try, or `null`. */\nexport function aiStockPick(\n photos: readonly StockPhoto[],\n used: ReadonlySet<string>,\n seed: string,\n judgement: AiStockJudgement = {},\n): StockPhoto | null {\n return aiStockRank(photos, used, seed, judgement)[0] ?? null\n}\n\n/**\n * The library photos a stored page already shows: every `image` whose\n * source is the site's media reference. Starter photos are the platform's,\n * not the job's, and are not listed.\n */\nexport function aiStockPlacedSrcs(\n nodes: NodesMap | null | undefined,\n): string[] {\n const map = (nodes ?? {}) as unknown as Record<\n string,\n { componentId?: string; props?: Record<string, unknown> }\n >\n const out: string[] = []\n for (const node of Object.values(map)) {\n const src = node?.componentId === 'image' ? node.props?.['src'] : null\n if (typeof src === 'string' && src.startsWith('media:')) out.push(src)\n }\n return out\n}\n\n/**\n * The library photos a stored page shows, each as a slot takes it (AGL-3988):\n * its source, its size and what it shows. A photo the job placed on another\n * page is what a slot the library failed takes before any starter\n * (`aiLayoutJobPhotoPicks`). Each photo once; one without a size is left out.\n */\nexport function aiStockPlacedPhotos(nodes: NodesMap | null | undefined): AiLayoutPicturePhoto[] {\n const map = (nodes ?? {}) as unknown as Record<string, { componentId?: string; props?: Record<string, unknown> }>\n const out = new Map<string, AiLayoutPicturePhoto>()\n for (const node of Object.values(map)) {\n if (node?.componentId !== 'image') continue\n const src = node.props?.['src']\n const width = Number(node.props?.['intrinsicWidth'])\n const height = Number(node.props?.['intrinsicHeight'])\n if (typeof src !== 'string' || !src.startsWith('media:') || out.has(src)) continue\n if (!(width > 0) || !(height > 0)) continue\n const alt = typeof node.props?.['alt'] === 'string' ? (node.props['alt'] as string).trim() : ''\n out.set(src, { src, width, height, ...(alt ? { alt } : {}) })\n }\n return [...out.values()]\n}\n\n/**\n * What this process has placed for each job, by source key and asset src,\n * with the scope (the page's seed) that placed it (AGL-3660). It spans the\n * passes of one job that run here, so a page, the products or a post built\n * later does not place what an earlier one did, while a pass repeated over\n * its own page keeps its own photos. Bounded; the oldest job goes first.\n */\nconst JOB_PHOTOS = new Map<string, Map<string, string>>()\n\n/** What a job's photos map holds for a photo the media library refused for its own bytes: no page's scope (AGL-3923). */\nconst REFUSED_BY_THE_LIBRARY = '\\u0000refused'\nconst JOB_PHOTOS_MAX = 200\n\nfunction jobPhotos(key: string | null): Map<string, string> | null {\n if (!key) return null\n let placed = JOB_PHOTOS.get(key)\n if (!placed) {\n placed = new Map()\n JOB_PHOTOS.set(key, placed)\n while (JOB_PHOTOS.size > JOB_PHOTOS_MAX) {\n const oldest = JOB_PHOTOS.keys().next().value\n if (oldest === undefined) break\n JOB_PHOTOS.delete(oldest)\n }\n }\n return placed\n}\n\n/** Forgets every job's placed photos; for specs. */\nexport function aiStockForgetJobPhotos(): void {\n JOB_PHOTOS.clear()\n}\n\n/** The longest description of a photo written from the library's own words. */\nconst AI_STOCK_ALT_MAX = 160\n\n/**\n * Words a tag uses for how a photo looks or feels, never a thing it shows\n * (AGL-3856): \"extravagant\" of \"wedding dress, bride, extravagant\", \"moody\"\n * of \"forest, human, photographer\", a season or a people's name.\n */\nconst DESCRIBING = words(\n 'love romance romantic luxury luxurious fancy extravagant happiness happy beauty emotion emotions mood lifestyle ' +\n 'concept aesthetic wallpaper background retro vintage antique old young cute sexy fun funny sad positive negative healthy fit ' +\n 'strong powerful homemade tasty yummy sweet sweetness nice dark bw monochrome macro sporty active married bridal ' +\n 'female male adult good bad poc bipoc moody sunny rainy foggy misty snowy cloudy stormy dreamy shiny trendy messy ' +\n 'casual blonde blond brunette muscular athletic clever intelligent concentrated curious lonely sleepy heavy ' +\n 'nature outdoors outdoor indoors indoor scenery scenic autumn fall winter spring summer ' +\n 'physical teenage traveling ' +\n // How a photo is laid out, never a thing it shows: \"car wallpapers\" is a car (AGL-3942).\n 'wallpaper wallpapers background backgrounds backdrop backdrops texture textures ' +\n // Words a tag gives that are no noun at all: \"family, together\" is a family (AGL-3942).\n 'together alone apart away abroad ahead nearby outside inside upstairs downstairs ' +\n // Adjectives a tag gives alone, never a thing: \"students, multicultural\" (AGL-3856).\n 'multicultural multiethnic multiracial diverse international cultural traditional modern classic classical ' +\n 'domestic wild tropical rural urban ' +\n // How the photo was made, never what it shows: \"cutout, perspective\", \"men, silhouettes\".\n 'silhouette silhouettes cutout perspective bokeh closeup ' +\n // A holiday names when, never a thing: \"tet market\" is a market.\n 'tet christmas easter halloween diwali ramadan hanukkah thanksgiving ' +\n 'indian asian african american european caucasian vietnamese japanese chinese korean thai latino latina hispanic ' +\n 'japan vietnam viet nam thailand india china korea germany france italy spain england britain uk usa america ' +\n 'canada mexico brazil australia africa europe asia ' +\n // How a scene feels or looks, never a thing in it (AGL-3988): \"mountain,\n // snow, winter, cold, couple, color, landscape\" is a couple in the snow.\n 'cold warm hot chilly freezing frozen icy color colors colour colours landscape landscapes ' +\n 'panorama panoramic vista scene scenes',\n)\n\n/**\n * The sky and the light over a scene, never a thing in it (AGL-3988): \"A\n * couple with a sky at sunset\" and \"A child with clouds by a lake\" were a\n * couple at sunset and a child by a lake.\n */\nconst SCENERY = words('sky skies cloud clouds sun sunshine sunlight daylight light shadow shadows horizon')\n\n/**\n * The weather a scene is in, said as where (AGL-3988): \"A couple with a fog\n * at a wedding\" was a couple in the fog, \"A snow in the mountains\" a couple\n * in the snow.\n */\nconst WEATHER: Readonly<Record<string, string>> = {\n fog: 'in the fog',\n mist: 'in the mist',\n haze: 'in the haze',\n rain: 'in the rain',\n snow: 'in the snow',\n snowfall: 'in the snow',\n snowflakes: 'in the snow',\n wind: 'in the wind',\n}\n\n/**\n * Words a tag uses for what a person or a thing is like, said before it\n * rather than as a thing of its own (AGL-3856): \"a confident lawyer\", \"an\n * elderly couple\", \"an analog camera\", never \"a lawyer, law and a confident\".\n */\nconst QUALITIES = words(\n 'confident professional successful serious smart busy creative proud skilled experienced determined focused ' +\n 'senior junior expert friendly cheerful smiling elderly analog analogue digital mirrorless',\n)\n\n/** What a tag names that takes no article: \"chalk\" of \"board, chalk\". */\nconst MASS_NOUNS = words(\n 'food coffee tea bread wood water wax soap clay money fabric yarn wool furniture jewelry jewellery ' +\n 'pottery glass paper music art hair makeup chalk paint ink dust stone marble concrete steel metal ' +\n 'skincare equipment decor wildlife weather traffic wine beer chocolate rice sugar flour milk ' +\n 'cheese honey oil ice fire light sunlight dough sourdough pastry dessert people foliage greenery faculty staff ' +\n 'clothing bedding frosting icing flooring',\n)\n\n/** Nouns plural without an \"-s\": said without an article, \"women in a classroom\". */\nconst PLURAL_NOUNS = words('men women people children feet teeth mice geese sheep fish')\n\n/**\n * What a tag names that no photo shows as a thing of its own (AGL-3856): an\n * idea (\"law\" of \"lawyer, law\", \"feedback\" of \"board, chalk, feedback\"), a\n * doing (\"read\", \"lift\", \"fitness\", \"a workout\"), a word for the photo itself\n * (\"photo\", \"spot\"). Left out, never said with an article: \"A bookwork and a\n * read\", \"A kettlebell and fitness\", \"A board and training\" said nothing.\n */\nconst ABSTRACT_NOUNS = words(\n 'law justice advocacy business feedback review news return communication communicate discussion dialog conversation ' +\n 'success career work job satisfaction quality concept idea strategy marketing education technology health support ' +\n 'confirmation opinion rating evaluation planning project presentation optimization information internet finance ' +\n 'management leadership teamwork motivation growth strength service services help advice consulting consultation ' +\n 'marriage photography architecture travel transport transportation industry company corporate social e-business ' +\n 'fitness workout workouts exercise exercises crossfit sport sports skill skills knowledge exam exams lecture ' +\n 'session lesson course hobby leisure power energy wellness talent formation participation ' +\n 'press show day days night year years time holiday month months week weeks morning evening afternoon season seasons ' +\n 'kiss hug embrace ' +\n // A feeling, never a thing anyone holds (AGL-3988): \"A father with a care\".\n 'care worry trust hope joy peace fear faith grief pride comfort safety bliss delight passion desire feeling feelings ' +\n 'moment moments memory memories fashion style ' +\n 'photo photos picture pictures image images shot shots shoot shoots spot spots ' +\n 'read write learn study lift move remove focus relax think sit smile laugh eat swim teach enjoy celebrate explore ' +\n 'hike can',\n)\n\n/** Words ending as an idea does that are things: \"a station\", \"a city\", \"a ship\". */\nconst CONCRETE_ABSTRACT_ENDINGS = words(\n 'station mansion lotion potion ornament instrument apartment monument pavement basement garment compartment ' +\n 'equipment cement city university facility ship warship spaceship airship',\n)\n\n/** Whether a word is an idea or a doing by how it ends: \"participation\", \"unity\", \"empowerment\". */\nconst saysAnIdea = (word: string) =>\n /(?:tion|sion|ment|ness|ity|ship|ism)s?$/.test(word) && !CONCRETE_ABSTRACT_ENDINGS.has(aiStockStem(word))\n\n/**\n * Makers' names a tag gives, never what a photo shows to someone who cannot\n * see it (AGL-3856): \"A photo-camera and a sony\".\n */\nconst BRANDS = words(\n 'sony canon cannon nikon fujifilm fuji leica olympus panasonic kodak polaroid hasselblad pentax gopro dji ' +\n 'apple iphone ipad macbook imac samsung huawei android google microsoft windows dell lenovo nintendo playstation ' +\n 'xbox nike adidas puma reebok peloton bmw mercedes audi porsche ferrari lamborghini tesla ford toyota honda ' +\n 'volkswagen vw jeep chevrolet coca-cola pepsi starbucks mcdonalds ikea lego barbie disney altman ' +\n 'petri zenit praktica yashica minolta mamiya rolleiflex voigtlander contax ricoh konica lomo lomography holga zeiss',\n)\n\n/** Stopwords a description still says, as the people a photo shows: \"a family\", \"a person\". */\nconst SAID_PEOPLE = words('people person family')\n\n/** Words ending in \"-ing\" that are things, and take an article: \"a wedding\", \"a ring\". */\nconst COUNTED_ING = words(\n 'wedding ring earring building painting drawing ceiling string swing king sibling wing dumpling pudding sapling',\n)\n\n/** \"-ing\" words that are things, and take no article: \"clothing\". */\nconst UNCOUNTED_ING = words('clothing bedding frosting icing flooring stuffing seasoning filling')\n\n/** People a photo shows; the generic ones give way to a role (\"man\" to \"businessman\"). */\nconst PEOPLE_NOUNS = words(\n 'man men woman women person people human humans boy boys girl girls guy guys lady ladies child children kid kids ' +\n 'baby family couple bride groom schoolgirl schoolboy teen teenager student students graduate athlete athletes ' +\n 'businessman businesswoman businessmen lawyer attorney doctor dentist nurse chef cook baker barista ' +\n 'trainer coach teacher teachers instructor lecturer professor tutor worker workers entrepreneur model ' +\n 'photographer potter artist florist mother father parent parents grandmother grandfather grandparents ' +\n 'faculty staff team participants volunteer volunteers musician dancer leader manager owner founder ' +\n 'journalist journalists reporter reporters master masters lovers newlywed newlyweds husband wife fiance fiancee spouse ' +\n // Whoever else is about (AGL-3988): \"A family with tourists\" was a family.\n 'tourist tourists traveler travelers traveller travellers hiker hikers visitor visitors friend friends crowd ' +\n // A family's people, said as a parent with a child (AGL-3988).\n 'dad dads mom moms mum mums son sons daughter daughters toddler toddlers',\n)\n/** People said by no role: a model is whoever posed (AGL-3856), \"a woman\" of \"woman, model, show, teacher\". */\nconst GENERIC_PEOPLE = words(\n 'man men woman women person people human humans guy guys lady ladies adult boy boys girl girls model models ' +\n 'tourist tourists traveler travelers traveller travellers hiker hikers visitor visitors friend friends crowd',\n)\n\n/** A parent a photo shows, said with the child beside them: \"A father with a girl\" (AGL-3988). */\nconst PARENTS = words('father mother dad mom mum parent parents grandfather grandmother grandparent grandparents')\n\n/** A child a photo shows beside a parent (AGL-3988). */\nconst CHILDREN = words('child children kid kids baby babies toddler toddlers girl girls boy boys son sons daughter daughters')\n\n/** How a family's word is said: \"a dad\" is a father (AGL-3988). */\nconst SAID_AS: Readonly<Record<string, string>> = { dad: 'father', dads: 'fathers', mom: 'mother', moms: 'mothers', mum: 'mother', mums: 'mothers' }\n\n/**\n * A body's parts, never a thing a photo is described by (AGL-3856): \"A girl\n * with a hand\" said nothing, and \"A body in a gym\" is a gym.\n */\nconst BODY_PARTS = words(\n 'hand hands finger fingers arm arms leg legs foot feet body bodies face faces eye eyes skin head heads lip lips mouth nose ' +\n 'ear ears neck shoulder shoulders knee knees',\n)\n\n/**\n * Words for a kind of thing, said only where nothing names the thing itself\n * (AGL-3856): \"A domestic cat and an animal\" is a cat.\n */\nconst KINDS_OF_THING = words('animal animals pet pets creature creatures mammal mammals object objects thing things item items')\n\n/** How many of a photo's first tags a person leads its description from, where it names a thing too: \"A camera\" of \"petri, camera, film, photography, photographer\" (AGL-3856). */\nconst ALT_PERSON_TAGS_READ = 4\n/** How many of a photo's first tags a role is said from, over a man or a woman before it: \"A man\" of \"bed, book, man, …, student\" (AGL-3856). */\nconst ALT_ROLE_TAGS_READ = 6\n\n/** What a person in a photo wears, said \"in\": \"a bride in a wedding dress\". */\nconst CLOTHING = words('dress gown suit uniform costume coat jacket robe apron')\n\n/**\n * Places a photo is set in, each with how a phrase says it is there: \"a\n * train at a station\", \"a lawyer in court\", \"a couple at a wedding\".\n */\nconst PLACES: Readonly<Record<string, string>> = {\n station: 'at',\n market: 'at',\n desk: 'at',\n table: 'at',\n counter: 'at',\n school: 'at',\n college: 'at',\n university: 'at',\n wedding: 'at',\n sunset: 'at',\n sunrise: 'at',\n dusk: 'at',\n dawn: 'at',\n beach: 'on',\n bed: 'on',\n sofa: 'on',\n couch: 'on',\n bench: 'on',\n trail: 'on',\n path: 'on',\n bridge: 'on',\n street: 'on',\n court: 'in',\n courtroom: 'in',\n office: 'in',\n kitchen: 'in',\n gym: 'in',\n studio: 'in',\n classroom: 'in',\n class: 'in',\n hall: 'in',\n room: 'in',\n garden: 'in',\n park: 'in',\n shop: 'in',\n store: 'in',\n bakery: 'in',\n cafe: 'in',\n restaurant: 'in',\n workshop: 'in',\n library: 'in',\n salon: 'in',\n clinic: 'in',\n forest: 'in',\n city: 'in',\n church: 'in',\n field: 'in',\n meadow: 'in',\n valley: 'in',\n mountain: 'in',\n hill: 'on',\n cliff: 'on',\n river: 'by',\n lake: 'by',\n lakeside: 'by',\n lakeshore: 'by',\n sea: 'by',\n ocean: 'by',\n seaside: 'by',\n coast: 'on',\n shore: 'on',\n sundown: 'at',\n waterfall: 'at',\n}\n\n/** Places that are things too, a photo's subject where nothing else is: \"a desk in a classroom\". */\nconst OBJECT_PLACES = words('desk table counter bridge bed sofa couch bench')\n\n/** Places said without an article: \"in court\", \"at sunset\". */\nconst BARE_PLACES = words('court sunset sunrise sundown dusk dawn')\n\n/** Places said in words of their own: a mountain tag is \"in the mountains\". */\nconst PLACES_SAID: Readonly<Record<string, string>> = {\n mountain: 'the mountains',\n lakeside: 'the lake',\n lakeshore: 'the lake',\n sea: 'the sea',\n ocean: 'the ocean',\n seaside: 'the sea',\n coast: 'the coast',\n shore: 'the shore',\n}\n\n/** Places that say when, said after where: \"a couple in the mountains at sunset\" (AGL-3988). */\nconst TIME_PLACES = words('sunset sunrise sundown dusk dawn')\n\n/** Places out of doors, said after a thing to sit on: \"a couple on a bench by the lake\" (AGL-3988). */\nconst OUTDOORS = words(\n 'forest field meadow valley mountain hill cliff river lake lakeside lakeshore waterfall beach park garden trail sea ocean seaside coast shore',\n)\n\n/** Words inside a tag that say one thing is where another is: \"couple on bench\" (AGL-3988). */\nconst TAG_PREPOSITIONS = words('on in at by with under near beside')\n\n/**\n * A tag that is a phrase of its own, read as its parts (AGL-3988): \"couple\n * on bench\" is a couple, and a bench they are on. The beta.270 Sugar Hollow\n * About page read it whole, as a place, and said \"A lakeside on a couple on\n * bench\".\n */\nfunction tagParts(tag: string): string[] {\n const list = tag.toLowerCase().trim().split(/\\s+/)\n const at = list.findIndex((word, index) => index > 0 && index < list.length - 1 && TAG_PREPOSITIONS.has(word))\n return at > 0 ? [list.slice(0, at).join(' '), list.slice(at + 1).join(' ')] : [tag]\n}\n\n/** How many of a photo's first tags its description reads: the things and people it is OF. */\nconst ALT_TAGS_READ = 8\n/** How far a photo's tags are read for where it is set, said last: \"in a gym\" of a kettlebell's seventh tag. */\nconst ALT_PLACE_TAGS_READ = 10\n\n/** A tag's words, a word for the photo itself taken off a compound: \"photo-camera\" is a camera. */\nfunction tagWords(tag: string): string[] {\n return tag\n .toLowerCase()\n .replace(/[^a-zÀ-ɏ\\s'-]/g, ' ')\n .replace(/\\b(?:photo|picture|image)-(?=[a-z])/g, '')\n .split(/\\s+/)\n .filter(Boolean)\n}\n\n/**\n * A tag as a phrase of an English description (AGL-3856): \"a wedding dress\",\n * \"an attorney\", \"books\", \"chalk\", \"Columbus\"; `null` for a tag that names no\n * thing (\"extravagant\", \"feedback\", \"training\", \"sony\") or is too long to be\n * one.\n */\nfunction describedTag(tag: string, proper: ReadonlySet<string>): string | null {\n const describing = (word: string) =>\n FILLER.has(word) ||\n DESCRIBING.has(word) ||\n QUALITIES.has(word) ||\n /(?:ous|ful)$/.test(word) ||\n (word.length > 4 && /[^e]ed$/.test(word))\n const all = tagWords(tag)\n // \"Beautiful flowers\" shows flowers; \"roasted\" shows nothing; \"photo model\"\n // is a model and \"traveling couples\" are couples: a word before the last\n // that is a doing says what they do, never what they are.\n const list = all.filter(\n (word, index) =>\n !describing(word) &&\n !(all.length > 1 && /^(?:photo|picture|image)$/.test(word)) &&\n !(index < all.length - 1 && index > 0 && word.endsWith('ing') && !COUNTED_ING.has(word)),\n )\n if (!list.length || all.length > 3) return null\n // A phrase of no thing (\"up close\") or a doing (\"take pictures\", \"to lift\", \"work out\") is not what it shows.\n if (list.every((word) => STOPWORDS.has(word) && !SAID_PEOPLE.has(word))) return null\n if (/^(?:to|take|taking|make|making|get|do|go|lie|in|on|at|for|with|by|of)$/.test(list[0] as string)) return null\n if (/^(?:out|up|off|down|away|on|in)$/.test(list[list.length - 1] as string)) return null\n if (list.some((word) => BRANDS.has(word))) return null\n if (list.every((word) => proper.has(word)))\n return list.map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`).join(' ')\n // Two people named side by side are both shown: \"bride groom\" is a bride and groom (AGL-3942).\n if (list.length === 2 && list.every((word) => PEOPLE_NOUNS.has(word)) && list[0] !== list[1])\n return `${articleFor(list[0] as string)} ${list[0]} and ${list[1]}`\n const last = list[list.length - 1] as string\n // An idea or a doing, never a thing: \"law\", \"feedback\", \"customer satisfaction\", \"participation\", \"weightlifting\".\n if (ABSTRACT_NOUNS.has(last) || ABSTRACT_NOUNS.has(aiStockStem(last)) || saysAnIdea(last)) return null\n const doing = last.endsWith('ing') && !COUNTED_ING.has(aiStockStem(last)) && !UNCOUNTED_ING.has(last)\n if (doing) return null\n const phrase = list.join(' ')\n const plural =\n PLURAL_NOUNS.has(last) || (aiStockStem(last) !== last && !/^(?:lens|canvas|atlas|gas|bus)$/.test(last))\n if (plural || MASS_NOUNS.has(last) || (STOPWORDS.has(list[0] as string) && !SAID_PEOPLE.has(list[0] as string)))\n return spelled(phrase)\n return `${articleFor(phrase)} ${spelled(phrase)}`\n}\n\n/** Letters said one by one, written in capitals: \"an SLR camera\", \"a DSLR\" (AGL-3942). */\nconst INITIALISMS = words('slr dslr tv dj diy bbq suv atv uv vr')\n\n/** A phrase as a description writes it, its initialisms in capitals. */\nconst spelled = (phrase: string) =>\n phrase\n .split(' ')\n .map((word) => (INITIALISMS.has(word) ? word.toUpperCase() : word))\n .join(' ')\n\n/** \"a\" or \"an\" before a phrase, an initialism by how its first letter is said: \"an SLR\", \"a DSLR\". */\nconst articleFor = (phrase: string) => {\n const first = phrase.split(' ')[0] ?? ''\n if (INITIALISMS.has(first)) return /^[aefhilmnorsx]/.test(first) ? 'an' : 'a'\n return /^(?:[aeio]|u(?!ni|s[eu]))/.test(phrase) ? 'an' : 'a'\n}\n\n/** Words a description never ends on: an article, a preposition, a conjunction. */\nconst DANGLING_END = /(?:\\s+(?:a|an|the|and|or|with|in|on|at|by|of|for|to|from|into|onto))+$/i\n\n/** One thing a photo's tags name, as {@link aiStockTagsAlt} says it. */\ninterface AiStockAltPart {\n said: string\n stems: string[]\n /** Its last word: what it is. */\n head: string\n kind: 'person' | 'place' | 'thing'\n /** The position of the tag that first named it. */\n index: number\n}\n\n/** Whether two words name one thing, one inside the other: \"law\" and \"lawyer\", \"cam\" and \"camera\". */\nfunction nearSynonyms(a: string, b: string): boolean {\n const [short, long] = a.length <= b.length ? [a, b] : [b, a]\n return short.length >= 3 && short !== long && (long.startsWith(short) || long.endsWith(short))\n}\n\n/**\n * A photo described from its own tags (AGL-3856): a short English phrase of\n * concrete things, never the library's comma-separated list: \"A train at a\n * station\", \"A confident lawyer in court\", \"A portrait of a businessman\", \"A\n * photographer with a camera on a beach\", \"A kettlebell in a gym\", \"An analog\n * camera\". It says one person at most (a role over a man or a woman, an adult\n * over a girl), what they hold or wear, or one or two things, and where:\n *\n * - an idea or a doing (\"law\", \"feedback\", \"training\", \"a read\",\n * \"participation\"), a maker's name (\"sony\"), a word for the photo itself\n * (\"photo\", \"spot\") and a look (\"moody\", \"analog\" alone, a season) are left\n * out; a quality (\"elderly\", \"analog\") is said before the one thing it\n * qualifies;\n * - of two words for one thing the first tag's stays (\"book\" over\n * \"bookwork\", \"camera\" over \"photo-camera\"), unless the later phrase holds\n * it whole (\"wedding dress\" over \"wedding\");\n * - a second thing comes only from the first two tags and where no place is\n * said, what a person holds only from the first three, where it is set\n * from the first ten;\n * - no word is said twice: never \"an elderly couple and an elderly\";\n * - the sky, the clouds and the light are no thing anyone holds, and the\n * weather is said as where it is: \"a couple in the fog at a wedding\",\n * \"a couple in the snow in the mountains\", never \"a couple with a sky at\n * sunset\" or \"a snow in the mountains\"; a feeling (\"care\", \"worry\") is no\n * thing either; whoever else is about (\"tourists\") is never said beside a\n * family; a parent beside a child is said with them (\"a father with a\n * girl\"); a tag that is a phrase of its own (\"couple on bench\") is read as\n * its parts; a time of day comes after where (\"in the mountains at\n * sunset\"), and a bench out of doors says where it stands (\"on a bench by\n * the lake\") (AGL-3988).\n *\n * `null` where no tag names a thing.\n */\nexport function aiStockTagsAlt(tags: readonly string[], proper: ReadonlySet<string> = new Set()): string | null {\n const parts: AiStockAltPart[] = []\n let quality = ''\n let portrait = false\n /** The weather it is in, said as where ({@link WEATHER}). */\n let weather = ''\n const read = tags.slice(0, ALT_PLACE_TAGS_READ).flatMap((tag, index) => tagParts(tag).map((part) => ({ tag: part, index })))\n for (const { tag, index } of read) {\n const lower = tag.toLowerCase().trim()\n const reading = index < ALT_TAGS_READ\n if (reading && (lower === 'portrait' || lower === 'portraits')) {\n portrait = true\n continue\n }\n if (QUALITIES.has(lower)) {\n if (reading) quality ||= lower\n continue\n }\n // The sky is never a thing a photo is described by; the weather is where it is.\n if (SCENERY.has(lower)) continue\n if (WEATHER[lower]) {\n if (reading) weather ||= WEATHER[lower] as string\n continue\n }\n const family = SAID_AS[lower]\n const said = family ? `${articleFor(family)} ${family}`.replace(/^an? (?=\\S+s$)/, '') : describedTag(tag, proper)\n if (!said) continue\n const bare = said.replace(/^an?\\s+/, '')\n const stems = stemList(bare)\n const head = bare.split(/\\s+/).pop()?.toLowerCase() ?? ''\n if (!head) continue\n const headStem = aiStockStem(head)\n const kind: AiStockAltPart['kind'] =\n PEOPLE_NOUNS.has(head) || PEOPLE_NOUNS.has(headStem) ? 'person' : PLACES[headStem] ? 'place' : 'thing'\n // Past the first tags only where it is set is read.\n if (!reading && kind !== 'place') continue\n // A hand or a body is never what a photo is described by.\n if (kind === 'thing' && (BODY_PARTS.has(head) || BODY_PARTS.has(headStem))) continue\n if (parts.some((part) => stems.every((stem) => part.stems.includes(stem)))) continue\n const part = { said, stems, head: headStem, kind, index }\n // A longer phrase of the same thing takes its place: \"elderly couple\" for \"couple\".\n const holds = parts.findIndex((held) => held.head === headStem && held.stems.every((stem) => stems.includes(stem)))\n if (holds >= 0) {\n parts.splice(holds, 1, { ...part, index: (parts[holds] as AiStockAltPart).index })\n continue\n }\n // Two words for one thing (\"book\" and \"bookwork\", \"cam\" and \"camera\"): the\n // first tag's stays; a person's are told apart by their role below.\n if (kind !== 'person' && parts.some((held) => held.kind !== 'person' && nearSynonyms(held.head, headStem))) continue\n parts.push(part)\n }\n // One person: a role among the first tags over a man, a woman, a girl\n // (\"businessman\" over \"man\"), else the first; a role tagged later is not\n // what the photo shows (\"bed, book, man, …, student\" is a man), nor is one\n // a model posed as (\"woman, model, show, teacher\" is a woman).\n const people = parts.filter((part) => part.kind === 'person')\n const posed = people.some((part) => part.head === 'model')\n let places = parts.filter((part) => part.kind === 'place')\n let things = parts.filter((part) => part.kind === 'thing')\n // A kind of thing only where nothing names the thing: \"a cat\", never \"a cat and an animal\".\n if (things.some((part) => !KINDS_OF_THING.has(part.head))) things = things.filter((part) => !KINDS_OF_THING.has(part.head))\n // A person tagged after the things a photo is of is not who it shows:\n // \"petri, camera, film, photography, photographer\" is a camera, and \"men,\n // silhouettes, camera, nature, photographer\" men with a camera.\n const leads = (part: AiStockAltPart) => portrait || part.index < ALT_PERSON_TAGS_READ || !things.length\n const role = posed\n ? undefined\n : people.find((part) => !GENERIC_PEOPLE.has(part.head) && part.index < ALT_ROLE_TAGS_READ && leads(part))\n // A parent beside a child is said with them (AGL-3988): \"A father with a\n // girl\", never \"a child with clouds\" of \"child, clouds, dad, dock, father\".\n const parent = people.find((part) => PARENTS.has(part.head) && part.index < ALT_ROLE_TAGS_READ)\n const child = people.find((part) => CHILDREN.has(part.head) && part.index < ALT_ROLE_TAGS_READ)\n const family = parent && child && (!role || role === parent || role === child) ? parent : undefined\n const person = family ?? role ?? people.find(leads)\n // Nothing but places: a desk is the thing in a classroom; \"a school in a classroom\" says one place.\n if (!person && !things.length && places.length > 1) {\n const object = places.find((part) => OBJECT_PLACES.has(part.head))\n if (object) {\n things = [object]\n places = places.filter((part) => part !== object)\n } else places = places.slice(0, 1)\n }\n const place = places[0]\n if (!person && !things.length && !place && !weather) return null\n /** Every word said so far, so none is said twice. */\n const said = new Set<string>()\n const fresh = (part: AiStockAltPart) => {\n const list = stemList(part.said.replace(/^an?\\s+/, ''))\n if (list.some((stem) => said.has(stem))) return false\n for (const stem of list) said.add(stem)\n return true\n }\n /** A quality before a single counted word: \"a confident lawyer\", \"an analog camera\". */\n const qualified = (part: AiStockAltPart) =>\n quality && /^an? \\S+$/.test(part.said) && !said.has(aiStockStem(quality))\n ? `${articleFor(quality)} ${quality} ${part.said.replace(/^an?\\s+/, '')}`\n : part.said\n let phrase = ''\n if (person && fresh(person)) {\n phrase = portrait ? `a portrait of ${person.said}` : qualified(person)\n const held = family && child && child !== person ? child : things.find((part) => part.index <= 2)\n if (!portrait && held && fresh(held)) phrase += ` ${CLOTHING.has(held.head) ? 'in' : 'with'} ${held.said}`\n } else if (things[0] && fresh(things[0])) {\n phrase = qualified(things[0])\n const second = things[1]\n if (second && second.index <= 1 && !place && fresh(second)) phrase += ` and ${second.said}`\n }\n /** A place as it is said alone: \"a classroom\", \"the mountains\", \"sunset\". */\n const placeOf = (part: AiStockAltPart) =>\n PLACES_SAID[part.head] ?? (BARE_PLACES.has(part.head) && /^an? \\S+$/.test(part.said) ? part.head : part.said)\n /** A place as it is said after what is there: \"in the mountains\", \"at sunset\", \"on a bench\". */\n const whereOf = (part: AiStockAltPart) => `${PLACES[part.head] ?? 'in'} ${placeOf(part)}`\n // The weather is said before where (AGL-3988): \"a couple in the fog at a\n // wedding\"; alone, it is what the photo shows: \"snow in the mountains\".\n if (weather && phrase) phrase += ` ${weather}`\n else if (weather) phrase = weather.replace(/^in the /, '')\n if (place && fresh(place)) {\n // A second place where the first is a time of day or a bench out of\n // doors: \"a couple in the mountains at sunset\", \"a couple on a bench by\n // the lake\"; never a bed in a room.\n const second = places.find(\n (part) =>\n part !== place &&\n !OBJECT_PLACES.has(part.head) &&\n !TIME_PLACES.has(part.head) &&\n (TIME_PLACES.has(place.head) || (place.head === 'bench' && OUTDOORS.has(part.head))),\n )\n const after = second && fresh(second) ? second : null\n const [first, last] = after && TIME_PLACES.has(place.head) ? [after, place] : [place, after]\n const tail = last ? ` ${whereOf(last)}` : ''\n phrase = phrase ? `${phrase} ${whereOf(first)}${tail}` : `${placeOf(first)}${tail}`\n }\n // Never a dangling article or preposition, whatever a tag left behind.\n phrase = phrase.replace(DANGLING_END, '').trim()\n if (!phrase || /^(?:a|an|the)$/i.test(phrase)) return null\n const out = `${phrase.charAt(0).toUpperCase()}${phrase.slice(1)}`\n return out.length > AI_STOCK_ALT_MAX ? out.slice(0, AI_STOCK_ALT_MAX).replace(/[\\s,]+\\S*$/, '') : out\n}\n\n/** The thing a description names: its subject's object, a trailing \"speaking calmly\" or \"dusted\" dropped. */\nfunction describedObject(text: string, sectionName: string): string {\n const list = aiStockSubjectWords(text, sectionName).split(/\\s+/).filter(Boolean)\n while (list.length > 1 && /(?:ing|ed|ly)$/.test(list[list.length - 1] as string)) list.pop()\n return aiStockObjectWord(list.join(' '))\n}\n\n/**\n * THE WORDS A PLACED STOCK PHOTO IS DESCRIBED BY (AGL-3805, AGL-3856).\n *\n * A slot's alt text is the model's, written for the picture the page asked\n * for before any photo was found, and a slot is filled by whatever the\n * library answers for its search: a hero searched by the business, a gallery\n * picture by its subject, a site in another language by English words alone.\n * Kept as written, it described a photo the page does not show: the beta.253\n * Panadería La Concha Dorada start (job eg4maZMGtN) captioned a round cake\n * dusted \"HOME MADE\" on a cloth \"Conchas recién horneadas sobre una charola en\n * el mostrador de la panadería\", and none of its nine photos showed what its\n * words said: a birthday cake with candles was \"the family kneading pan\n * dulce\", a plate of macarons the shop's display case.\n *\n * So the photo placed answers for its own words. `null` keeps the slot's: on\n * an English site whose words name the thing the photo is OF — their\n * subject's object (`aiStockSubjectWords`, a trailing \"speaking calmly\"\n * dropped) among the hit's first two tags. Any word of the subject among its\n * first three was not enough: the beta.259 Hartwell Reyes Family Law hero kept\n * \"Two attorneys speaking calmly with a client in a bright Columbus office\"\n * for a typewriter whose third tag was \"attorney\" (AGL-3856). A stand-in's\n * words ({@link AiLayoutPictureSlot.standIn}) are a search's, never a\n * description, and are never kept. Otherwise the photo is described by the\n * library's own words: its description where it writes one (a Pexels hit's\n * `alt`), else its first tags as an English phrase ({@link aiStockTagsAlt}),\n * never the library's tag list, and where no tag names a thing, the slot's\n * own subject: its words, else its section's name. The libraries write in English, and no model\n * translates them, so a site in another language takes the platform's own\n * words for an illustrative photo in its language (`aiLayoutLabel`), true of\n * any photo, as does a hit whose words name no thing.\n */\nexport function aiStockPhotoAlt(\n photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>,\n slot: Pick<AiLayoutPictureSlot, 'alt' | 'product' | 'standIn'>,\n input: { language?: string; sectionName?: string; proper?: ReadonlySet<string> } = {},\n): string | null {\n if (aiLayoutSpeaksOtherThanEnglish(input.language)) return aiLayoutLabel('illustrativePhoto', input.language)\n if (!slot.standIn) {\n const first = new Set(stemList((photo.tags ?? []).slice(0, 2).join(' ')))\n const objects = [slot.alt, ...(slot.product?.subjects ?? [])].map((text) => describedObject(text, input.sectionName ?? ''))\n if (objects.some((object) => object && first.has(object))) return null\n }\n const own = (photo.alt ?? '').replace(/\\s+/g, ' ').trim()\n if (own) return own.length > AI_STOCK_ALT_MAX ? `${own.slice(0, AI_STOCK_ALT_MAX).replace(/\\s+\\S*$/, '')}…` : own\n // No tag names a thing: the slot's own subject, as its words or its section's name say it, never a tag list.\n const subject = [slot.alt, input.sectionName ?? '']\n .map((text) => text.replace(/\\s+/g, ' ').trim())\n .find((text) => /[A-Za-zÀ-ɏ]/.test(text))\n const fallback = subject ? `${subject.charAt(0).toUpperCase()}${subject.slice(1)}`.slice(0, AI_STOCK_ALT_MAX) : ''\n return aiStockTagsAlt(photo.tags ?? [], input.proper) ?? (fallback || aiLayoutLabel('illustrativePhoto', input.language))\n}\n\n/** The names a business type writes with a capital, lowercased: \"columbus\", \"ohio\" (AGL-3856). */\nexport function aiStockProperWords(businessType: string): Set<string> {\n const found = new Set<string>()\n for (const [index, word] of businessType.split(/[^A-Za-zÀ-ɏ'-]+/).filter(Boolean).entries())\n if (index > 0 && /^[A-ZÀ-Þ]/.test(word)) found.add(word.toLowerCase())\n return found\n}\n\nconst EXTENSIONS: Record<string, string> = {\n 'image/jpeg': 'jpg',\n 'image/png': 'png',\n 'image/webp': 'webp',\n}\n\nexport interface AiLayoutStockPhotoSourceInput {\n hostId: string\n /** The member the photos are stored as: the job's creator. */\n uid: string\n /** The job's seed, as the starter photos turn by; also the scope a photo is placed under. */\n seed: string\n /** The site's business type, else the job's brief. */\n business: string\n /** The site's language, from its plan (AGL-3750); absent, English. */\n language?: string\n /**\n * The plan's photo words, in English (AGL-3760): what a site in another\n * language is searched by, in place of its business type and its alt texts,\n * unless its business type names a business listed in English\n * (`aiStockBusinessNoun`, AGL-3779), which leads.\n */\n photoWords?: string\n /**\n * The English name of the kind of site the person picked (AGL-3771): what a\n * site in another language is searched by when its business type names no\n * business listed in English (`aiStockBusinessNoun`, AGL-3779) and its plan\n * gave no photo words, rather than its business type in its own language.\n */\n kindWords?: string\n /**\n * The business's name, as the person typed it (AGL-3856): what an English\n * site is searched by when its business type names no world (\"a local\n * service business\") and its name names a craft this module lists\n * (\"Synchronicity Gym\"). Never its world otherwise.\n */\n name?: string\n /** Who the site is for, as the person typed it: searched as the name is, after it (AGL-3856). */\n audience?: string\n /**\n * The id of the kind of site the person picked (\"education\"): what a site\n * is searched by when nothing else names its world (AGL-3856).\n */\n kind?: string\n /** The page's section names, by plan index. */\n sectionNames: readonly string[]\n /**\n * The job the member started (`aiOriginJobId`), so a photo is placed once\n * across its pages. Absent, only the page itself is kept free of repeats.\n */\n jobId?: string\n /** Asset srcs or source keys the job's other pages already show. */\n avoid?: readonly string[]\n /** The most searches this source sends; a page's own bound where absent. A store's products search more (AGL-3676). */\n searches?: number\n signal?: AbortSignal\n}\n\nexport interface AiLayoutStockPhotoDeps {\n provider?: () => StockPhotoProvider | null\n ingest?: () => PluginMediaIngest | null\n budgetMs?: number\n /** The clock a refusal is dated by (AGL-3988); specs hand in a fixed one. */\n now?: () => number\n}\n\n/** A slot's choice: the accepted hits it may be filled from, best first, and the query that found them. */\ninterface AiStockChoice {\n candidates: StockPhoto[]\n query: string\n /** The search that answered them, as it was sent (AGL-3988): what the late photo pass asks again. */\n request: StockPhotoSearchRequest\n /** A photo another slot of the job already shows, reused rather than an off-topic one (AGL-3660). */\n repeat?: boolean\n}\n\n/** The words of a search that only this module reads, never sent to a library. */\nconst SEARCH_JUDGMENT_KEYS = [\n 'broad',\n 'subject',\n 'requires',\n 'object',\n 'kin',\n 'lead',\n 'leadWorld',\n 'first',\n 'category',\n 'strict',\n 'refuse',\n 'needs',\n 'allow',\n 'refuseLead',\n 'worldless',\n 'away',\n] as const\n\n/** A search as it is sent to the library: its words and size, none of how its hits are judged. */\nexport function aiStockSearchRequest(wanted: AiStockSearch): StockPhotoSearchRequest {\n const request: Record<string, unknown> = { ...wanted }\n for (const key of SEARCH_JUDGMENT_KEYS) delete request[key]\n return request as unknown as StockPhotoSearchRequest\n}\n\n/**\n * A search as a job keeps it to ask again (AGL-3988): only what a library's\n * request is made of, so asked again it is the same request, which the\n * provider's 24-hour cache answers.\n */\nexport function aiStockKeptRequest(request: StockPhotoSearchRequest): StockPhotoSearchRequest {\n return {\n query: request.query,\n ...(request.orientation ? { orientation: request.orientation } : {}),\n ...(request.minWidth ? { minWidth: request.minWidth } : {}),\n ...(request.minHeight ? { minHeight: request.minHeight } : {}),\n ...(request.people ? { people: true } : {}),\n }\n}\n\n/**\n * The library's own record of a photo copied into a site (AGL-3923, AGL-3988):\n * what the media library stores beside the bytes as `stockPhoto`, with the\n * credit its license asks for. One shape for every copy a job makes, a\n * page's and the late photo pass's.\n */\nexport function aiStockIngestRequest(\n provider: Pick<StockPhotoProvider, 'credit'>,\n input: { hostId: string; uid: string; photo: StockPhoto; bytes: { bytes: Uint8Array; contentType: string }; alt: string; query: string },\n): Parameters<PluginMediaIngest['ingest']>[0] {\n const { photo, bytes } = input\n const credit = provider.credit(photo)\n return {\n hostId: input.hostId,\n uid: input.uid,\n fileName: `${photo.provider}-${photo.id}.${EXTENSIONS[bytes.contentType] ?? 'jpg'}`,\n contentType: bytes.contentType,\n bytes: bytes.bytes,\n alt: input.alt,\n description: credit.text,\n stockPhoto: {\n key: stockPhotoSourceKey(photo),\n provider: photo.provider,\n providerLabel: credit.providerLabel,\n id: photo.id,\n pageUrl: photo.pageUrl,\n photographer: photo.photographer,\n ...(photo.photographerUrl ? { photographerUrl: photo.photographerUrl } : {}),\n license: credit.license,\n licenseUrl: credit.licenseUrl,\n attributionRequired: credit.attributionRequired,\n query: input.query,\n },\n }\n}\n\n/**\n * A job's language and English photo words (AGL-3760), the English name of\n * its kind of site (AGL-3771), and the business's name and audience as the\n * person typed them (AGL-3856), as a stock photo source takes them.\n */\nexport function aiStockPhotoWordsOf(job: {\n plan?: Pick<AiBuildPlan, 'language' | 'photoWords'> | null\n inputs?: Readonly<Record<string, unknown>> | null\n}): Pick<AiLayoutStockPhotoSourceInput, 'language' | 'photoWords' | 'kindWords' | 'name' | 'audience' | 'kind'> {\n const plan = job.plan\n const kind = job.inputs ? aiSiteKindOfInputs(job.inputs) : null\n // \"Restaurant & café\" searches as \"restaurant cafe\".\n const kindWords = kind ? kind.label.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '').replace(/&/g, ' ').replace(/\\s+/g, ' ').trim().toLowerCase() : ''\n const said = (key: string) => {\n const value = job.inputs?.[key]\n return typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim() : ''\n }\n const name = said('businessName')\n const audience = said('audience')\n return {\n ...(plan?.language ? { language: plan.language } : {}),\n ...(plan?.photoWords ? { photoWords: plan.photoWords } : {}),\n ...(kindWords ? { kindWords } : {}),\n ...(kind ? { kind: kind.id } : {}),\n ...(name ? { name } : {}),\n ...(audience ? { audience } : {}),\n }\n}\n\n/**\n * The subject a plan's photo words lead with (AGL-3769): its first word that\n * is not filler, with the place or person words that follow it — \"bakery\" of\n * \"bakery pan dulce conchas\", \"candle shop\" of \"candle shop soy candles\",\n * \"ceramic artist\" of \"ceramic artist stoneware bowls\". The words are subject\n * first, never an English noun phrase with its head last, and what follows\n * the subject may be the brief's own names in English letters: Panaderia La\n * Espiga Dorada's \"pan dulce conchas\" read as the business, made \"concha\" its\n * craft, and placed purple ceanothus flowers, tagged \"ceanothus concha\", as\n * its hero. Empty when every word is filler.\n */\nexport function aiStockPhotoWordsSubject(photoWords: string): string {\n const list = contentWords(photoWords)\n const start = list.findIndex((word) => !FILLER.has(word) && !SITE_KINDS.has(word))\n if (start < 0) return ''\n let end = start + 1\n while (end < list.length && (VENUES.has(list[end]) || ROLES.has(list[end]))) end += 1\n return list.slice(start, end).join(' ')\n}\n\n/**\n * What a source's photos are searched and judged by (AGL-3760, AGL-3769): a\n * site in another language by an English subject ({@link aiStockSourceSubject}:\n * its business named in English, else its plan's photo words' subject, else\n * its kind of site), every other site by its business type. One reading for\n * every slot of every source — hero, background, gallery, card, product,\n * post — so no slot searches by words another slot is held against. A site for\n * adults alone ({@link aiStockAdultsOnly}) is told so, whatever its world.\n */\nexport function aiStockSourceTerms(\n input: Pick<AiLayoutStockPhotoSourceInput, 'business' | 'language' | 'photoWords' | 'kindWords' | 'name' | 'audience' | 'kind'>,\n): AiStockSiteTerms {\n const terms = sourceWorldTerms(input)\n // Where the site's own words set it: a photographer \"in the Blue Ridge\" for \"mountain weddings\" (AGL-3856).\n const setting = aiStockSetting([input.business, input.audience ?? ''].join(' . '))\n // A craft whose pictures are people at a moment shows the moments its site names (AGL-3942).\n const work = terms.scenes ? aiStockWorkScenes([input.business, input.audience ?? ''].join(' . '), setting) : []\n return {\n ...terms,\n ...(aiStockAdultsOnly([input.audience, input.name, input.business]) ? { adults: true } : {}),\n ...(setting ? { setting } : {}),\n ...(work.length ? { work } : {}),\n }\n}\n\n/** What a source's photos are searched by: its world, as {@link aiStockSourceTerms} reads it. */\nfunction sourceWorldTerms(\n input: Pick<AiLayoutStockPhotoSourceInput, 'business' | 'language' | 'photoWords' | 'kindWords' | 'name' | 'audience' | 'kind'>,\n): AiStockSiteTerms {\n const english = aiStockSourceSubject(input)\n const terms = aiStockSiteTerms(english || input.business)\n if (english || (terms.domain.length && !aiStockIsAbbreviation(input.business))) return terms\n // A business type that names no world (\"a local service business\"), or\n // one the libraries do not know (\"LMS\"), is searched by the craft its\n // name, else its audience, names (AGL-3856): the beta.261 Synchronicity Gym\n // hero searched nothing at all and was left a black scrim, and its closing\n // band, held to no world, took a subway train for \"Ready to train\". Then by\n // the kind of site its name says (\"Adult Hybrid Learning Center\"), and\n // last by the kind of site the person picked: the beta.262 Adult Hybrid\n // Learning Center searched \"lms\" and shipped no photo at all.\n const craft = aiStockListedCraft(input.name ?? '') || aiStockListedCraft(input.audience ?? '')\n const kind = craft ? '' : aiStockNamedKind(input.name ?? '') || aiStockNamedKind(input.audience ?? '') || (input.kind ?? '')\n const found = craft ? aiStockSiteTerms(craft) : aiStockKindTerms(kind)\n if (!found) return terms\n return { ...found, named: [...new Set([...terms.named, ...found.named])] }\n}\n\n/**\n * Whether a business type is only an abbreviation the libraries do not know\n * (AGL-3856): \"LMS\", \"CRM\", \"B2B\". Its letters are no world to search.\n */\nexport function aiStockIsAbbreviation(businessType: string): boolean {\n const list = businessType.trim().split(/\\s+/).filter(Boolean)\n return list.length > 0 && list.length <= 2 && list.every((word) => /^[A-Z0-9&/.-]{2,6}s?$/.test(word) && /[A-Z]/.test(word))\n}\n\n/**\n * What a picture of each kind of site the guided start offers shows, where\n * nothing else says (AGL-3856): the words it is searched by, the words a\n * photo of it is tagged with, and its broad searches. A kind whose subject\n * is a craft {@link CRAFT_KIN} lists takes that craft's own.\n */\nconst KIND_SUBJECTS: Readonly<\n Record<string, { subject: string; kin?: readonly string[]; broad?: readonly string[]; shunLead?: readonly string[] }>\n> = {\n business: {\n subject: 'small business',\n kin: ['business', 'office', 'team', 'meeting', 'workplace', 'coworkers', 'entrepreneur', 'shop', 'service', 'customer'],\n broad: ['small business owner', 'team meeting office'],\n },\n trades: {\n subject: 'contractor',\n kin: ['contractor', 'construction', 'repair', 'renovation', 'tools', 'worker', 'handyman', 'plumber', 'electrician', 'house', 'roof'],\n broad: ['home repair contractor', 'construction worker tools'],\n },\n professional: {\n subject: 'consultant',\n kin: ['consultant', 'consulting', 'office', 'meeting', 'client', 'advisor', 'finance', 'accountant', 'lawyer', 'desk', 'business'],\n broad: ['consultant client meeting', 'professional office'],\n },\n wellness: {\n subject: 'wellness',\n kin: ['wellness', 'health', 'therapy', 'therapist', 'massage', 'spa', 'relaxation', 'clinic', 'healthcare'],\n broad: ['wellness therapy', 'massage therapy'],\n },\n restaurant: {\n subject: 'restaurant',\n kin: ['restaurant', 'dining', 'food', 'dish', 'chef', 'meal', 'cafe', 'cuisine', 'dinner', 'lunch'],\n broad: ['restaurant dining', 'restaurant food'],\n },\n store: {\n subject: 'boutique',\n kin: ['boutique', 'shop', 'store', 'shopping', 'retail', 'products', 'display', 'shelf'],\n broad: ['boutique shop', 'retail store display'],\n },\n portfolio: {\n subject: 'artist',\n kin: ['art', 'artist', 'design', 'creative', 'studio', 'workspace', 'painting', 'drawing'],\n broad: ['artist studio', 'creative workspace'],\n // \"Artist\" names a bee and a tattooist as often as a painter (AGL-3923):\n // the beta.266 Mexicano hero's first pick was \"artist bee, giant artist bee\".\n shunLead: ['bee', 'insect', 'insects', 'tattoo', 'makeup', 'cosmetics'],\n },\n studio: {\n subject: 'design studio',\n kin: ['design', 'designer', 'studio', 'creative', 'agency', 'team', 'workspace', 'office'],\n broad: ['design studio team', 'creative agency office'],\n },\n photography: { subject: 'photographer' },\n blog: {\n subject: 'writer',\n kin: ['writer', 'writing', 'notebook', 'laptop', 'desk', 'journal', 'reading', 'book'],\n broad: ['writer desk laptop', 'writing notebook'],\n },\n events: {\n subject: 'event',\n kin: ['event', 'celebration', 'party', 'wedding', 'venue', 'reception', 'gathering', 'decoration', 'banquet'],\n broad: ['event celebration', 'event venue decoration'],\n },\n fitness: { subject: 'gym' },\n yoga: {\n subject: 'yoga',\n kin: ['yoga', 'meditation', 'mindfulness', 'pose', 'mat', 'relaxation', 'stretching'],\n broad: ['yoga class', 'meditation'],\n },\n beauty: {\n subject: 'salon',\n kin: ['salon', 'beauty', 'hair', 'hairdresser', 'makeup', 'nails', 'manicure', 'stylist', 'spa', 'cosmetics'],\n broad: ['beauty salon', 'hair salon'],\n },\n realestate: {\n subject: 'real estate',\n kin: ['house', 'home', 'estate', 'property', 'interior', 'apartment', 'realtor', 'architecture', 'living'],\n broad: ['house exterior', 'home interior'],\n },\n education: {\n subject: 'classroom',\n kin: ['classroom', 'student', 'students', 'education', 'learning', 'e-learning', 'teacher', 'teaching', 'class', 'lecture', 'study', 'studying', 'course', 'school', 'seminar', 'training', 'book', 'books', 'laptop'],\n broad: ['adult students classroom', 'online learning', 'adult education'],\n },\n nonprofit: {\n subject: 'volunteers',\n kin: ['volunteer', 'volunteers', 'charity', 'helping', 'donation', 'nonprofit', 'team', 'people'],\n broad: ['charity volunteers', 'volunteers helping'],\n },\n music: {\n subject: 'musician',\n kin: ['music', 'musician', 'band', 'concert', 'guitar', 'stage', 'singer', 'instrument', 'piano', 'drums'],\n broad: ['live music band', 'musician guitar'],\n },\n personal: {\n subject: 'workspace',\n kin: ['workspace', 'desk', 'laptop', 'office', 'professional', 'notebook', 'coffee'],\n broad: ['workspace desk laptop', 'professional workspace'],\n },\n landing: {\n subject: 'startup team',\n kin: ['startup', 'team', 'technology', 'laptop', 'office', 'workspace', 'business', 'meeting'],\n broad: ['startup team office', 'modern workspace'],\n },\n 'coming-soon': {\n subject: 'workspace',\n kin: ['workspace', 'desk', 'laptop', 'office', 'notebook', 'coffee'],\n broad: ['modern workspace', 'workspace desk laptop'],\n },\n}\n\n/** Words a business's name or audience uses for a kind of site (AGL-3856): \"Learning Center\" is a school's. */\nconst NAMED_KINDS: ReadonlyArray<{ words: readonly string[]; kind: string }> = [\n {\n kind: 'education',\n words: ['learning', 'academy', 'school', 'tutoring', 'tutor', 'tutors', 'college', 'institute', 'university', 'courses', 'classes', 'lessons', 'education', 'students', 'learners'],\n },\n { kind: 'beauty', words: ['salon', 'barber', 'barbershop', 'nails', 'spa', 'lashes', 'brows'] },\n { kind: 'realestate', words: ['realty', 'realtor', 'realtors', 'properties', 'homes', 'estate'] },\n { kind: 'restaurant', words: ['restaurant', 'bistro', 'kitchen', 'grill', 'diner', 'eatery', 'cafe', 'café', 'tavern', 'pizzeria'] },\n { kind: 'trades', words: ['plumbing', 'roofing', 'hvac', 'electric', 'electrical', 'landscaping', 'construction', 'contracting', 'remodeling', 'painting', 'handyman'] },\n { kind: 'nonprofit', words: ['foundation', 'charity', 'church', 'ministry', 'nonprofit', 'volunteers'] },\n { kind: 'yoga', words: ['yoga', 'meditation', 'mindfulness'] },\n { kind: 'music', words: ['band', 'music', 'orchestra', 'choir', 'records'] },\n { kind: 'wellness', words: ['wellness', 'therapy', 'massage', 'clinic', 'chiropractic', 'counseling'] },\n]\n\n/** The kind of site a business's name or audience names ({@link NAMED_KINDS}), or empty. */\nexport function aiStockNamedKind(text: string): string {\n const named = new Set(text.toLowerCase().split(/[^a-zÀ-ɏ]+/).filter(Boolean))\n return NAMED_KINDS.find((entry) => entry.words.some((word) => named.has(word)))?.kind ?? ''\n}\n\n/** What a kind of site's pictures are searched and judged by ({@link KIND_SUBJECTS}); `null` for a kind not listed. */\nexport function aiStockKindTerms(kind: string): AiStockSiteTerms | null {\n const entry = KIND_SUBJECTS[kind]\n if (!entry) return null\n const base = aiStockSiteTerms(entry.subject)\n if (!entry.kin?.length) return base\n const kin = entry.kin.map(aiStockStem)\n return {\n ...base,\n domain: [...new Set([...base.domain, ...kin])],\n broad: [...(entry.broad ?? base.broad)],\n // A hero names one of the kind's own words, never only the subject's.\n core: [...new Set([...base.core, ...kin])],\n ...(entry.shunLead?.length ? { shunLead: [...new Set([...base.shunLead, ...entry.shunLead.map(aiStockStem)])] } : {}),\n }\n}\n\n/**\n * The kind of site each starter is the shape of (`AiSiteKind.starter`): what\n * a picture is searched by, widened past the kind the person picked, where\n * nothing narrower found one (AGL-3923).\n */\nconst STARTER_KINDS: Readonly<Record<string, string>> = {\n business: 'business',\n 'physical-shop': 'store',\n portfolio: 'portfolio',\n landing: 'landing',\n}\n\n/** A kind's common photos ({@link KIND_GENERIC}): the words searched, and the words one of which a hit must name. */\ninterface AiStockGenericSet {\n kin: readonly string[]\n broad: readonly string[]\n}\n\nconst OFFICE: AiStockGenericSet = {\n kin: ['office', 'workspace', 'desk', 'laptop', 'computer', 'meeting', 'business', 'work', 'workplace', 'team', 'notebook', 'coffee', 'teamwork', 'conference'],\n broad: ['office workspace', 'business meeting', 'workspace desk laptop'],\n}\n\nconst WORKSPACE: AiStockGenericSet = {\n kin: ['workspace', 'desk', 'laptop', 'notebook', 'coffee', 'office', 'book', 'books', 'workplace'],\n broad: ['workspace desk laptop', 'notebook coffee desk'],\n}\n\n/**\n * The last searches a picture tries, for each kind of site the guided start\n * offers (AGL-3923): plain, common photos of where that kind's work happens,\n * which every library holds many of, held to their own words. Never a face\n * as the lead, never a child, never a product nor a rival business: a\n * restaurant's are its tables and plates, never an office. A kind with no set\n * keeps a slot nothing fits without a photo (AGL-3831).\n */\nconst KIND_GENERIC: Readonly<Record<string, AiStockGenericSet>> = {\n business: OFFICE,\n trades: {\n kin: ['tools', 'tool', 'toolbox', 'workbench', 'workshop', 'construction', 'repair', 'renovation', 'drill', 'hammer', 'wrench', 'roof', 'house', 'carpentry'],\n broad: ['tools workbench', 'home renovation', 'construction tools'],\n },\n professional: {\n kin: ['office', 'desk', 'documents', 'document', 'meeting', 'conference', 'laptop', 'workplace', 'business', 'notebook', 'paperwork', 'consulting'],\n broad: ['office desk documents', 'business meeting', 'conference room'],\n },\n wellness: {\n kin: ['spa', 'massage', 'wellness', 'relaxation', 'relax', 'towel', 'towels', 'candle', 'stones', 'therapy', 'treatment', 'aromatherapy'],\n broad: ['spa stones towel', 'massage room', 'wellness spa'],\n },\n restaurant: {\n kin: ['restaurant', 'table', 'dining', 'food', 'plate', 'dish', 'meal', 'kitchen', 'cafe', 'dinner', 'lunch', 'cuisine'],\n broad: ['restaurant interior', 'restaurant table food', 'food plate'],\n },\n store: {\n kin: ['shop', 'store', 'retail', 'shelf', 'shelves', 'display', 'interior', 'boutique', 'storefront', 'counter'],\n broad: ['shop interior', 'retail store'],\n },\n portfolio: {\n kin: ['studio', 'workspace', 'desk', 'art', 'design', 'creative', 'sketch', 'drawing', 'paint', 'painting', 'brush', 'brushes', 'canvas', 'pencil', 'pencils', 'paper'],\n broad: ['art supplies', 'creative workspace', 'art studio'],\n },\n studio: {\n kin: ['design', 'studio', 'workspace', 'desk', 'laptop', 'sketch', 'creative', 'office', 'drawing', 'pencil'],\n broad: ['design studio workspace', 'creative workspace', 'workspace desk laptop'],\n },\n photography: {\n kin: ['camera', 'cameras', 'photography', 'lens', 'photographer', 'studio', 'film', 'tripod'],\n broad: ['camera lens', 'photography studio', 'vintage camera'],\n },\n blog: {\n kin: ['notebook', 'desk', 'writing', 'laptop', 'coffee', 'journal', 'book', 'books', 'workspace', 'pen', 'typewriter'],\n broad: ['writing desk notebook', 'laptop coffee desk'],\n },\n events: {\n kin: ['event', 'venue', 'wedding', 'reception', 'party', 'celebration', 'table', 'decoration', 'banquet', 'hall', 'flowers'],\n broad: ['event venue decoration', 'banquet table', 'party decoration'],\n },\n fitness: {\n kin: ['gym', 'fitness', 'weights', 'dumbbell', 'dumbbells', 'barbell', 'kettlebell', 'workout', 'exercise', 'training'],\n broad: ['gym equipment', 'dumbbells gym', 'fitness gym'],\n },\n yoga: {\n kin: ['yoga', 'mat', 'meditation', 'studio', 'relaxation', 'candle', 'zen', 'mindfulness'],\n broad: ['yoga mat', 'yoga studio', 'meditation candle'],\n },\n beauty: {\n kin: ['salon', 'beauty', 'hair', 'makeup', 'cosmetics', 'nails', 'manicure', 'spa', 'mirror', 'brush', 'brushes'],\n broad: ['beauty salon interior', 'makeup brushes cosmetics', 'hair salon chair'],\n },\n realestate: {\n kin: ['house', 'home', 'interior', 'living', 'room', 'property', 'architecture', 'apartment', 'kitchen', 'estate'],\n broad: ['house exterior', 'home interior living room', 'modern kitchen interior'],\n },\n education: {\n kin: ['classroom', 'books', 'book', 'library', 'school', 'desk', 'education', 'learning', 'study', 'studying', 'notebook', 'chalkboard', 'blackboard', 'lecture'],\n broad: ['library books', 'classroom', 'study desk books'],\n },\n nonprofit: {\n kin: ['volunteer', 'volunteers', 'volunteering', 'charity', 'donation', 'donations', 'community', 'helping', 'help', 'hands'],\n broad: ['volunteers charity', 'donation box', 'community volunteering'],\n },\n music: {\n kin: ['music', 'guitar', 'piano', 'instrument', 'instruments', 'concert', 'stage', 'microphone', 'drums', 'studio', 'vinyl'],\n broad: ['guitar instrument', 'concert stage lights', 'music studio microphone'],\n },\n personal: WORKSPACE,\n landing: {\n kin: ['office', 'workspace', 'desk', 'laptop', 'computer', 'meeting', 'business', 'work', 'workplace', 'team', 'technology', 'startup'],\n broad: ['modern office', 'workspace desk laptop', 'business meeting'],\n },\n 'coming-soon': WORKSPACE,\n}\n\n/** The kind of site whose common photos each starter falls back to. */\nconst STARTER_GENERIC_KIND: Readonly<Record<string, string>> = {\n business: 'business',\n 'physical-shop': 'store',\n portfolio: 'portfolio',\n landing: 'landing',\n}\n\n/** Stems no common photo leads with: a face, a portrait (AGL-3923). */\nconst FACE_STEMS = ['face', 'portrait', 'selfie', 'headshot'].map(aiStockStem)\n\n/** The starter a kind of site follows ({@link STARTER_KINDS}); a kind not listed follows the business starter. */\nfunction starterOfKind(kind: string): string {\n const starter = aiSiteKind(kind)?.starter ?? 'business'\n return STARTER_KINDS[starter] ? starter : 'business'\n}\n\n/** A kind of site's common photos as a world to search and judge by ({@link KIND_GENERIC}); `null` for a kind with no set. */\nexport function aiStockKindGenericTerms(kind: string): AiStockSiteTerms | null {\n const set = KIND_GENERIC[kind]\n if (!set) return null\n const kin = [...new Set(set.kin.map(aiStockStem))]\n return {\n business: '',\n craft: '',\n domain: kin,\n broad: [...set.broad],\n making: [],\n named: [],\n rivals: [],\n core: kin,\n shun: [],\n shunLead: [],\n }\n}\n\n/**\n * Whether a site's world is only its own words (AGL-3923): no craft this\n * module lists and no kind of site named it, so its broad searches are its\n * business and its craft read back (\"freelencing\"), which a library may not\n * know at all.\n */\nexport function aiStockWorldIsUnlisted(terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'broad'>): boolean {\n const own = [...new Set([terms.business, terms.craft].map((word) => word.trim()).filter(Boolean))]\n return terms.broad.length > 0 && terms.broad.length === own.length && terms.broad.every((query, index) => query === own[index])\n}\n\n/**\n * Whether a site's world agrees with the kind of site the person picked\n * (AGL-3923): it was read from the kind, or names one of the kind's own\n * words. A gym whose owner picked Business & services does not, and is never\n * given an office.\n */\nfunction worldOfKind(terms: Pick<AiStockSiteTerms, 'craft' | 'broad' | 'domain'>, kind: string): boolean {\n const own = aiStockKindTerms(kind)\n if (!own) return false\n if (own.craft === terms.craft && own.broad.join('|') === terms.broad.join('|')) return true\n const words = new Set([...own.domain, ...(aiStockKindGenericTerms(kind)?.domain ?? [])])\n return terms.domain.some((stem) => words.has(stem))\n}\n\n/**\n * What a picture is searched by once nothing narrower found it a photo\n * (AGL-3923), widest last.\n *\n * - A site whose world is its own words alone ({@link aiStockWorldIsUnlisted})\n * widens to the kind of site the person picked, the kind its starter is the\n * shape of, and last the kind's own common photos ({@link KIND_GENERIC}),\n * else its starter's.\n * - Any other site widens only to its kind's own common photos, and only\n * where its world agrees with that kind ({@link worldOfKind}): a portfolio\n * read from its kind takes art supplies before no photo at all, and a\n * barbecue caterer whose kind says nothing of food never takes an office\n * (AGL-3831). A kind with no set keeps a slot nothing fits without a photo.\n *\n * A rung that would search what an earlier one did is left out.\n *\n * The beta.265 Kasvora Marketing Solutions start (job BK3r4I8bF1) typed its\n * business as \"Freelencing site offer services\": its world was the one word\n * \"freelencing\", which no library tags, so its cover hero searched it, found\n * nothing, and shipped a flat dark band with no photo.\n */\nexport function aiStockWiderTerms(\n terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'broad' | 'domain'>,\n kind: string,\n): Array<{ rung: 'kind' | 'starter' | 'generic'; terms: AiStockSiteTerms }> {\n const rungs: Array<{ rung: 'kind' | 'starter' | 'generic'; terms: AiStockSiteTerms }> = []\n const seen = new Set<string>([JSON.stringify([terms.craft, [...terms.broad]])])\n const add = (rung: 'kind' | 'starter' | 'generic', found: AiStockSiteTerms | null) => {\n if (!found || !found.broad.length) return\n const key = JSON.stringify([found.craft, found.broad])\n if (seen.has(key)) return\n seen.add(key)\n rungs.push({ rung, terms: found })\n }\n if (!aiStockWorldIsUnlisted(terms)) {\n if (kind && worldOfKind(terms, kind)) add('generic', aiStockKindGenericTerms(kind))\n return rungs\n }\n const starter = starterOfKind(kind)\n if (kind) add('kind', aiStockKindTerms(kind))\n add('starter', aiStockKindTerms(STARTER_KINDS[starter] ?? 'business'))\n add('generic', aiStockKindGenericTerms(kind) ?? aiStockKindGenericTerms(STARTER_GENERIC_KIND[starter] ?? 'business'))\n return rungs\n}\n\n/**\n * The first word of a text that names a craft {@link CRAFT_KIN} lists, as\n * its table writes it: \"gym\" of \"Synchronicity Gym\", \"law\" of \"Hartwell\n * Reyes Family Law\". Empty where it names none, so a name that is only a\n * name (\"Hillside\") never becomes a world.\n */\nexport function aiStockListedCraft(text: string): string {\n for (const stem of stemList(text))\n for (const group of CRAFT_KIN) {\n const word = group.match.find((match) => aiStockStem(match) === stem)\n if (word) return word\n }\n return ''\n}\n\n/**\n * What a site in another language is searched by ({@link aiStockSourceTerms}),\n * in this order (AGL-3779):\n *\n * 1. The English name of the business its type names, where the curated table\n * knows it ({@link aiStockBusinessNoun}): \"florist\" for \"Una floristería en\n * Sevilla\". It leads whatever the plan's photo words say, because the words\n * are the model's and the table is not: a live plan for that florist gave\n * \"wedding bouquets event flowers\", whose subject, \"wedding\", would have\n * searched every slot, its hero included, by weddings.\n * 2. Its photo words' subject (AGL-3760, AGL-3769), for a business the table\n * does not list.\n * 3. The English name of its kind of site (AGL-3771), where the plan gave\n * none. Panaderia El Trigal's pages searched \"con pan dulce\" and placed the\n * Río Dulce; searched by its kind, a bakery's hero took a coffee mug\n * (\"restaurant cafe\"), which is why it comes last.\n *\n * The photo words' other words were never searched by (AGL-3769), so a site\n * the table names is searched by its name alone. Empty for every other site.\n */\nfunction aiStockSourceSubject(\n input: Pick<AiLayoutStockPhotoSourceInput, 'business' | 'language' | 'photoWords' | 'kindWords'>,\n): string {\n if (!aiLayoutSpeaksOtherThanEnglish(input.language)) return ''\n return (\n aiStockBusinessNoun(input.business) ||\n aiStockPhotoWordsSubject(input.photoWords ?? '') ||\n (input.kindWords ?? '').trim()\n )\n}\n\n/**\n * The source for one page, or `null` when this deployment has no stock\n * photo library or no media door, which leaves every slot to the starters.\n */\nexport function aiLayoutStockPhotoSource(\n input: AiLayoutStockPhotoSourceInput,\n deps: AiLayoutStockPhotoDeps = {},\n): AiLayoutPictureSource | null {\n const provider = (deps.provider ?? stockPhotoProvider)()\n const ingest = (deps.ingest ?? pluginMediaIngest)()\n if (!provider || !ingest || !input.hostId || !input.uid) return null\n // The libraries are tagged in English (AGL-3760). A Spanish bakery's type,\n // \"Una panadería familiar de San Antonio con pan dulce…\", read as the\n // business \"con pan dulce\", and its hero searched that and placed the Río\n // Dulce at dusk; a site in another language is searched by its plan's\n // English photo words' subject ({@link aiStockSourceTerms}), and its slots'\n // alt texts, in its own language, name no subject a search could use.\n const english = aiStockSourceSubject(input)\n const terms = aiStockSourceTerms(input)\n // Where a picture's own world finds nothing, the wider worlds it tries (AGL-3923).\n const wider = aiStockWiderTerms(terms, input.kind ?? '')\n const unlisted = aiStockWorldIsUnlisted(terms)\n const proper = aiStockProperWords(input.business)\n const now = deps.now ?? Date.now\n return async (slots, report) => {\n const timeout = AbortSignal.timeout(\n deps.budgetMs ?? AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS,\n )\n const signal = input.signal\n ? AbortSignal.any([input.signal, timeout])\n : timeout\n const scope = input.seed\n const job = jobPhotos(input.jobId ? `${input.hostId}:${input.jobId}` : null)\n const avoid = new Set(input.avoid ?? [])\n /** Placed elsewhere in the job: by another page in this process, or one the caller read. */\n const elsewhere = (key: string) =>\n avoid.has(key) || (job?.has(key) === true && job.get(key) !== scope)\n /** Source keys this page has claimed for a slot, or turned down. */\n const claimed = new Set<string>()\n /** The photos this page's slots have claimed, first choices, by slot order. */\n const shown: StockPhoto[] = []\n /** Asset srcs this page has placed. */\n const placedSrcs = new Set<string>()\n const answers = new Map<string, Promise<StockPhoto[] | null>>()\n /** The wider world a widened search is judged by (AGL-3923); a search not listed is judged by the site's. */\n const worldOf = new WeakMap<AiStockSearch, AiStockSiteTerms>()\n let searches = 0\n let storing = true\n /** Slots a photo was chosen for and could not be copied into the library (AGL-3923). */\n const uncopied = new Set<AiLayoutPictureSlot>()\n /** Each slot's picks the image hosts would not hand over, and when (AGL-3988). */\n const refusedPicks = new Map<AiLayoutPictureSlot, { keys: string[]; at: number }>()\n /** Whether the library answered any search of this page: a slot left empty then found nothing fitting. */\n let answered = false\n const remember = (sourceKey: string, src: string) => {\n placedSrcs.add(src)\n job?.set(sourceKey, scope)\n job?.set(src, scope)\n }\n /** A search's hits; the same words twice are answered from memory, and `null` once the page's searches are spent. */\n const search = (wanted: AiStockSearch): Promise<StockPhoto[] | null> => {\n const request = aiStockSearchRequest(wanted)\n const key = JSON.stringify([\n request.query,\n request.orientation,\n request.people === true,\n ])\n const known = answers.get(key)\n if (known) return known\n if (searches >= (input.searches ?? AI_LAYOUT_STOCK_SEARCHES_PER_PAGE))\n return Promise.resolve(null)\n searches += 1\n const asked = provider\n .search(request, { signal })\n .then((found) => {\n if (found) answered = true\n return found?.photos ?? []\n })\n .catch(() => [] as StockPhoto[])\n answers.set(key, asked)\n return asked\n }\n /** The photo's own words where the slot's do not describe it ({@link aiStockPhotoAlt}). */\n const altFor = (photo: StockPhoto, slot: AiLayoutPictureSlot) =>\n aiStockPhotoAlt(photo, slot, {\n ...(input.language ? { language: input.language } : {}),\n sectionName: input.sectionNames[slot.sectionIndex] ?? '',\n proper,\n })\n /** The photo placed in the site's library, a copy it holds or a new one; `null` when it cannot be placed. */\n const keep = async (\n photo: StockPhoto,\n slot: AiLayoutPictureSlot,\n query: string,\n repeat = false,\n ): Promise<AiLayoutPicturePhoto | null> => {\n const sourceKey = stockPhotoSourceKey(photo)\n const alt = altFor(photo, slot)\n const described = alt === null ? {} : { alt }\n try {\n const kept = await ingest.findStockPhoto({\n hostId: input.hostId,\n sourceKey,\n })\n if (kept) {\n // Held because a slot of this page or another page of the job shows it.\n if (!repeat && (placedSrcs.has(kept.src) || elsewhere(kept.src)))\n return null\n remember(sourceKey, kept.src)\n return {\n src: kept.src,\n width: kept.width ?? photo.width,\n height: kept.height ?? photo.height,\n ...described,\n }\n }\n // A refusal to store (the storage band, a lockdown) holds for the\n // whole page, so the rest of it reuses what it can and copies nothing.\n if (!storing || signal.aborted) return null\n const bytes = await provider.download(photo, {\n maxBytes: AI_LAYOUT_STOCK_MAX_BYTES,\n signal,\n })\n if (!bytes || signal.aborted || !storing) {\n // A copy the library would not hand over is otherwise silent (AGL-3923).\n if (!bytes && !signal.aborted) {\n uncopied.add(slot)\n // Asked for again by the late photo pass, once the burst is over (AGL-3988).\n const held = refusedPicks.get(slot) ?? { keys: [], at: 0 }\n if (!held.keys.includes(sourceKey)) held.keys.push(sourceKey)\n held.at = now()\n refusedPicks.set(slot, held)\n console.warn('ai layout pictures: a stock photo could not be downloaded', { provider: photo.provider, id: photo.id })\n }\n return null\n }\n const stored = await ingest.ingest(\n aiStockIngestRequest(provider, { hostId: input.hostId, uid: input.uid, photo, bytes, alt: alt ?? slot.alt, query }),\n )\n if (stored.ok) {\n remember(sourceKey, stored.src)\n return {\n src: stored.src,\n width: stored.width ?? photo.width,\n height: stored.height ?? photo.height,\n ...described,\n }\n }\n const refusal = stored as Extract<\n PluginMediaIngestResult,\n { ok: false }\n >\n // One photo's own bytes refused (AGL-3923): the beta.267 Brightvale\n // start's first pick, Pixabay 10157445, came labeled image/png and was\n // not PNG, and that one 415 stopped every copy on all four of its\n // pages, which then showed the starters' pottery bench and coffee\n // shop. Such a refusal is this photo's: the slot tries its next hit.\n const ofThisPhoto = AI_STOCK_PHOTO_OWN_REFUSALS.has(refusal.status)\n if (ofThisPhoto) {\n uncopied.add(slot)\n // Never tried again by this page's other slots, nor by the job's other pages.\n claimed.add(sourceKey)\n job?.set(sourceKey, REFUSED_BY_THE_LIBRARY)\n } else storing = false\n console.warn(\n 'ai layout pictures: the media library refused a stock photo',\n {\n status: refusal.status,\n reason: refusal.reason,\n provider: photo.provider,\n id: photo.id,\n holds: ofThisPhoto ? 'this photo' : 'the page',\n },\n )\n } catch (error) {\n uncopied.add(slot)\n console.warn('ai layout pictures: a stock photo could not be kept', {\n error: String(error),\n })\n }\n return null\n }\n\n /**\n * How a search's hits are judged for a slot. On a site for adults alone no\n * hit names a child; a portrait of one of the business's people names an\n * adult, never leads with a child, and is preferred in its role (AGL-3856).\n */\n const judgementFor = (\n slot: AiLayoutPictureSlot,\n request: AiStockSearch,\n subject: string,\n ): AiStockJudgement => {\n const refuse = [...(request.refuse ?? []), ...(terms.adults ? CHILD_STEMS : [])]\n const role = slot.people ? aiStockPeopleRole(slot.alt, input.sectionNames[slot.sectionIndex] ?? '') : null\n return {\n ...judgementOf(slot, request, subject, worldOf.get(request) ?? terms),\n ...(refuse.length ? { refuse: [...new Set(refuse)] } : {}),\n // An occupation is shown in it (a teacher, a coach); a team is any adult at work.\n ...(slot.people\n ? {\n needs: request.needs?.length ? request.needs : role?.required ? role.kin : ADULT_PEOPLE_STEMS,\n refuseLead: [...new Set([...CHILD_STEMS, ...(request.refuseLead ?? [])])],\n ...(role ? { roles: role.kin } : {}),\n // A teacher is shown teaching, never posing or painting (AGL-3856).\n ...(role?.scene?.length ? { roleScene: role.scene } : {}),\n ...(role?.refuse?.length ? { roleRefuse: aiStockRoleRefusals(role, slot.alt) } : {}),\n }\n : {}),\n }\n }\n /**\n * A search's own judgement, as its words set it, held to the world it was\n * asked for: the site's own, or a wider one where the site's found nothing\n * (AGL-3923). What lets a sensitive topic in is always the site's own words.\n */\n const judgementOf = (\n slot: AiLayoutPictureSlot,\n request: AiStockSearch,\n subject: string,\n world: AiStockSiteTerms,\n ): AiStockJudgement => ({\n subject: request.subject ?? (request.broad ? '' : subject),\n domain: world.domain,\n strict:\n (slot.role === 'gallery' && !request.broad) || !!request.requires || !!request.strict,\n named: request.allow?.length ? [...new Set([...terms.named, ...request.allow])] : terms.named,\n rivals: world.rivals,\n ...(world.shun.length || request.shun?.length\n ? { shun: [...new Set([...world.shun, ...(request.shun ?? [])])] }\n : {}),\n ...(world.shunLead.length ? { shunLead: world.shunLead } : {}),\n ...(request.product ? { product: true } : {}),\n ...(request.leadAny?.length ? { leadAny: request.leadAny } : {}),\n ...(request.requires ? { requires: request.requires } : {}),\n ...(request.category ? { category: request.category } : {}),\n ...(request.object ? { object: request.object } : {}),\n ...(request.kin ? { kin: request.kin } : {}),\n ...(request.lead ? { lead: true } : {}),\n ...(request.leadWorld ? { leadWorld: true } : {}),\n ...(request.first ? { first: true } : {}),\n ...(request.refuse?.length ? { refuse: request.refuse } : {}),\n ...(request.needs?.length ? { needs: request.needs } : {}),\n ...(request.refuseLead?.length ? { refuseLead: request.refuseLead } : {}),\n ...(request.away?.length ? { away: request.away } : {}),\n // A portfolio's record is of its own subject, never of the craft's world (AGL-3856).\n ...(request.worldless ? { domain: [], rivals: [] } : {}),\n })\n /**\n * The craft's own photos, the last thing a slot of a craft's site is\n * filled from (AGL-3660): its broad searches, any hit naming the craft\n * itself. Never a desk, a laptop or a living room for a soap shop.\n */\n const craftSearches = (slot: AiLayoutPictureSlot, world: AiStockSiteTerms = terms): AiStockSearch[] => {\n // A portfolio's record of the work is never filled by the craft's own\n // photos (AGL-3856), nor is any picture of a site that shows its work (AGL-3942).\n if (!world.core.length || aiStockShowsTheWork(slot, world) || aiStockShowsItsWork(slot, world)) return []\n const orientation = aiStockOrientation(slot.aspect)\n const size =\n slot.role === 'hero'\n ? { minWidth: 1600 }\n : orientation === 'vertical'\n ? { minHeight: 900 }\n : { minWidth: 900 }\n return world.broad.map((query) => ({\n query: clip(query),\n orientation,\n ...size,\n broad: true,\n category: world.core,\n ...(slot.role === 'hero' ? { first: true } : {}),\n ...(slot.product ? { product: true, tier: 'weak' as const } : {}),\n }))\n }\n\n /**\n * A slot's searches once its own world found it nothing (AGL-3923), in\n * order: the kind of site's world, the starter's, the slot's own words\n * alone held to no world, and last the starter's common photos. Each is\n * judged by the world it was asked for. A product, a portrait of the\n * business's people and a record's cover keep their own fallbacks.\n */\n const widerSearches = (slot: AiLayoutPictureSlot, subject: string, sectionName: string): AiStockSearch[] => {\n if (!wider.length || slot.product || slot.people || slot.record) return []\n const part = aiStockSlotPart(slot, sectionName)\n const asked: AiStockSearch[] = []\n const ask = (world: AiStockSiteTerms, requests: readonly AiStockSearch[]) => {\n for (const request of requests) {\n worldOf.set(request, world)\n asked.push(request)\n }\n }\n for (const { rung, terms: world } of wider) {\n if (rung === 'generic') continue\n ask(world, [...aiStockSearchesFor(slot, world, subject, part, sectionName), ...craftSearches(slot, world)])\n }\n const orientation = aiStockOrientation(slot.aspect)\n const size = slot.role === 'hero' ? { minWidth: 1600 } : orientation === 'vertical' ? { minHeight: 900 } : { minWidth: 900 }\n // The slot's own words, only where the site's world is its own words\n // alone, held to the kind's common world (AGL-3923), never to no world:\n // the beta.267 Brightvale closing band's \"ready talk marketing\" was\n // answered with a tin-can telephone, and its pets-and-owners answers\n // name no office either.\n const common = wider.find((rung) => rung.rung === 'generic')?.terms\n if (subject && unlisted && common) {\n const object = aiStockObjectWord(subject)\n const own = [...new Set([subject, object].map(clip).filter(Boolean))]\n ask(\n common,\n own.map((query) => ({ query, orientation, ...size, subject, strict: true })),\n )\n }\n // The kind's common photos: OF its world among their first tags, never\n // led by a face, never of a child (AGL-3923).\n for (const { rung, terms: world } of wider)\n if (rung === 'generic')\n ask(\n world,\n world.broad.map((query) => ({\n query: clip(query),\n orientation,\n ...size,\n broad: true,\n category: world.core,\n ...(slot.role === 'hero' ? { first: true } : { leadWorld: true }),\n refuse: CHILD_STEMS,\n refuseLead: FACE_STEMS,\n })),\n )\n return asked\n }\n\n // 1. Choose, slot by slot, so the page's choices never collide: each\n // slot claims its best accepted hit before the next slot looks.\n const choices: Array<AiStockChoice | null> = []\n for (const [index, slot] of slots.entries()) {\n if (signal.aborted) {\n choices.push(null)\n continue\n }\n const sectionName = input.sectionNames[slot.sectionIndex] ?? ''\n const subject = english ? '' : aiStockSubjectWords(slot.alt, sectionName)\n let choice: AiStockChoice | null = null\n const requests = [\n ...(slot.product\n ? aiStockProductSearches(slot, terms.craft, terms.domain, {\n broad: terms.broad,\n core: terms.core,\n })\n : aiStockSearchesFor(\n slot,\n terms,\n subject,\n aiStockSlotPart(slot, sectionName),\n sectionName,\n )),\n ...craftSearches(slot),\n ]\n /** The slot's accepted hits for a search; `null` once the page's searches are spent. */\n const accepted = async (\n request: AiStockSearch,\n repeat: boolean,\n ): Promise<StockPhoto[] | null> => {\n const found = await search(request)\n if (found === null) return null\n const blocked = new Set<string>()\n if (!repeat) {\n for (const key of claimed) blocked.add(key)\n for (const hit of found) {\n const key = stockPhotoSourceKey(hit)\n if (elsewhere(key)) blocked.add(key)\n }\n }\n // A photo the library refused for its own bytes is never a repeat either (AGL-3923).\n for (const hit of found) {\n const key = stockPhotoSourceKey(hit)\n if (job?.get(key) === REFUSED_BY_THE_LIBRARY) blocked.add(key)\n }\n const judgement = judgementFor(slot, request, subject)\n const ranked = aiStockRank(found, blocked, `${input.seed}:${index}:${request.query}`, judgement)\n // A team's portraits are of different people where the hits allow (AGL-3856).\n return slot.people && !repeat ? aiStockFreshShootsFirst(ranked, shown, judgement) : ranked\n }\n /** The first of these searches with a hit to take: a new one, or one the job already shows. */\n const choose = async (\n tried: readonly AiStockSearch[],\n repeat: boolean,\n ): Promise<AiStockChoice | null> => {\n for (const request of tried) {\n if (signal.aborted) return null\n // Spent searches answer nothing; those already asked still answer from memory.\n const ranked = await accepted(request, repeat)\n if (!ranked?.length) continue\n if (!repeat) {\n claimed.add(stockPhotoSourceKey(ranked[0] as StockPhoto))\n shown.push(ranked[0] as StockPhoto)\n }\n return {\n candidates: ranked.slice(0, AI_LAYOUT_STOCK_TRIES_PER_SLOT),\n query: request.query,\n request: aiStockKeptRequest(aiStockSearchRequest(request)),\n ...(repeat ? { repeat: true } : {}),\n }\n }\n return null\n }\n // 2. Nothing new of its own: a product or a hero reuses an on-topic\n // photo another slot of the job already shows (a product may repeat\n // a collection tile's photo, or another product's) before the\n // starters' desk or living room fills it (AGL-3660). Any other\n // picture keeps \"never twice\". A product goes by how sure each\n // search is: its own and its category's photos, new and then\n // repeated, before a weak hit of its own (the Tidewater sauna).\n const repeats = Boolean(slot.product) || slot.role === 'hero'\n const sure = slot.product\n ? requests.filter((request) => request.tier !== 'weak')\n : requests\n const unsure = slot.product\n ? requests.filter((request) => request.tier === 'weak')\n : []\n // 3. Nothing of its own world at all: the wider worlds (AGL-3923), new\n // and then, for a hero, one the job already shows.\n const widened = widerSearches(slot, subject, sectionName)\n const phases: Array<[readonly AiStockSearch[], boolean]> = [\n [sure, false],\n ...(repeats ? [[sure, true] as [readonly AiStockSearch[], boolean]] : []),\n ...(unsure.length\n ? [\n [unsure, false] as [readonly AiStockSearch[], boolean],\n [unsure, true] as [readonly AiStockSearch[], boolean],\n ]\n : []),\n ...(widened.length ? [[widened, false] as [readonly AiStockSearch[], boolean]] : []),\n ...(widened.length && repeats ? [[widened, true] as [readonly AiStockSearch[], boolean]] : []),\n ]\n for (const [tried, repeat] of phases) {\n if (choice || signal.aborted) break\n choice = await choose(tried, repeat)\n }\n choices.push(choice)\n }\n\n // 3. Keep, a few at a time; a copy that fails tries the slot's next\n // accepted hit no other slot has claimed. A repeat waits for the\n // slot it repeats, so the library never holds a photo twice.\n const photos: Array<AiLayoutPicturePhoto | null> = slots.map(() => null)\n /** What this pass placed, by source key. */\n const placedByKey = new Map<string, AiLayoutPicturePhoto>()\n const fill = async (index: number) => {\n const choice = choices[index]\n const slot = slots[index]\n if (!choice || !slot) return\n for (const [rank, candidate] of choice.candidates.entries()) {\n if (signal.aborted) return\n const key = stockPhotoSourceKey(candidate)\n if (choice.repeat) {\n // Placed for another slot, it is described for this one.\n const shown = placedByKey.get(key)\n const alt = shown ? altFor(candidate, slot) : null\n const placed = shown\n ? { src: shown.src, width: shown.width, height: shown.height, ...(alt === null ? {} : { alt }) }\n : await keep(candidate, slot, choice.query, true)\n if (placed) {\n photos[index] = placed\n return\n }\n continue\n }\n if (rank > 0) {\n if (claimed.has(key)) continue\n claimed.add(key)\n }\n const placed = await keep(candidate, slot, choice.query)\n if (placed) {\n placedByKey.set(key, placed)\n photos[index] = placed\n return\n }\n }\n }\n const firsts = slots\n .map((_slot, index) => index)\n .filter((index) => !choices[index]?.repeat)\n let next = 0\n const worker = async () => {\n while (next < firsts.length) {\n const index = firsts[next] as number\n next += 1\n await fill(index)\n }\n }\n await Promise.all(\n Array.from(\n { length: Math.min(AI_LAYOUT_STOCK_COPIES_AT_ONCE, firsts.length) },\n worker,\n ),\n )\n for (const [index, choice] of choices.entries())\n if (choice?.repeat) await fill(index)\n // A slot left without a photo because its picks were refused: what they\n // were, for the late photo pass to ask for again (AGL-3988).\n for (const [index, slot] of slots.entries()) {\n const held = refusedPicks.get(slot)\n const choice = choices[index]\n if (photos[index] || !held?.keys.length || !choice) continue\n report?.refused.set(slot, { request: choice.request, keys: held.keys, at: new Date(held.at).toISOString() })\n }\n // The library answered and nothing in it fits: no photo rather than a\n // starter that shows another business (AGL-3831). A library that never\n // answered, or a site that refused to store, leaves the starters.\n // A slot whose fitting photo could not be copied was failed by the\n // library, as one that never answered is, and takes a starter rather\n // than lose its picture (AGL-3923).\n return answered && storing\n ? photos.map((photo, index) => photo ?? (uncopied.has(slots[index] as AiLayoutPictureSlot) ? null : AI_LAYOUT_NO_PHOTO))\n : photos\n }\n}\n"],"names":["pluginMediaIngest","STOCK_PHOTO_QUERY_MAX_CHARS","stockPhotoProvider","stockPhotoSourceKey","AI_LAYOUT_NO_PHOTO","aiLayoutSeedNumber","aiStorefrontSays","aiLayoutLabel","aiLayoutSpeaksOtherThanEnglish","aiSiteKind","aiSiteKindOfInputs","aiStockBusinessNoun","AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS","AI_LAYOUT_STOCK_SEARCHES_PER_PAGE","AI_LAYOUT_STOCK_PICK_WINDOW","AI_LAYOUT_STOCK_TRIES_PER_SLOT","AI_LAYOUT_STOCK_COPIES_AT_ONCE","AI_LAYOUT_STOCK_MAX_BYTES","AI_STOCK_PHOTO_OWN_REFUSALS","Set","AI_STOCK_PHOTO_PAGES_INPUT","AI_STOCK_PHOTO_AVOID_INPUT","AI_STOCK_PHOTO_JOB_PHOTOS_INPUT","AI_STOCK_PHOTO_LATE_PASS_INPUT","aiStockJobPhotosOf","value","Array","isArray","flatMap","entry","photo","src","width","Number","height","startsWith","alt","trim","words","list","split","STOPWORDS","FILLER","VENUES","ROLES","SITE_KINDS","DOING","BUSINESS_BREAK","PLACE_OR_AUDIENCE","WRAPPERS","REJECTED_TAGS","PRODUCT_SCENES","map","aiStockStem","FRAGRANCE_BOTTLES","SENSITIVE_TOPICS","allow","always","SENSITIVE_STEMS","topic","HAND_IDIOMS","withoutHands","text","reduce","out","idiom","replace","toLowerCase","saysMadeByHand","lower","some","lastIndex","found","test","OBJECT_KIN","objects","within","qualifier","kin","queries","shun","after","objectKin","object","world","find","word","includes","CRAFT_KIN","match","broad","rivals","core","making","shunLead","scenes","maker","contentWords","filter","length","has","endsWith","slice","stemList","CLAUSE_BREAK","businessClauses","businessType","clauses","breaker","RegExp","source","at","opener","matchAll","push","index","businessOf","clause","aiStockBusinessWords","named","join","aiStockCraftWords","business","craft","aiStockSiteTerms","domain","made","firstWorld","place","kept","stem","add","last","size","groups","group","listed","makingSearches","query","Boolean","PLACEHOLDER_SUBJECTS","subjectOf","aiStockSubjectWords","sectionName","aiStockObjectWord","subject","reverse","clip","aiStockOrientation","aspect","aiStockSlotPart","slot","role","undefined","PEOPLE_SCENES","lead","people","PORTRAIT_SCENE","CHILD_STEMS","ADULT_PEOPLE_STEMS","PEOPLE_ROLES","scene","refuse","loose","AI_STOCK_ROLE_TAGS_READ","aiStockPeopleRole","texts","required","aiStockRoleRefusals","ADULT_AUDIENCE","YOUNG_AUDIENCE","aiStockAdultsOnly","said","SEASIDE","DESERT","CITYSCAPE","SCENE_SETTINGS","landscape","away","aiStockSettingAway","setting","candidate","aiStockScene","siteSetting","sceneWords","aiStockSetting","phrase","aiStockRecordScene","name","category","all","RECORD_SCENE_UNPEOPLED","aiStockWorkScenes","findIndex","sort","a","b","aiStockSettingIsLandscape","RECORD_ODD_LEADS","kinStems","PRODUCT_SIZES","GIFT_WRAPPERS","aiStockProductSearches","fallback","subjects","orientation","minHeight","minWidth","craftStems","product","raw","own","kinPhrases","ownWorld","stems","tier","held","wrapped","gift","borrowed","seen","searches","key","common","heldTo","leadAny","leadWorld","requires","aiStockSearchesFor","terms","part","work","aiStockShowsTheWork","itsWork","aiStockShowsItsWork","namesCraft","namesMaker","shown","subjectStems","namesWorld","qualify","collection","makers","roleWord","record","sceneList","turn","thing","recordNamed","refuseLead","shows","workLead","sceneSearch","one","ofWork","refused","strict","needs","worldless","workSearches","first","pageSlug","pageUrl","decodeURIComponent","URL","pathname","pop","hitWords","tags","slug","tag","phrases","leadPhrases","firstPhrase","rejected","among","aiStockSensitive","site","aiStockRelevance","judgement","hit","rival","owned","roleScene","roleRefuse","read","ALT_TAGS_READ","kinNamed","kinLead","anyOf","demanded","meets","every","worldLead","worldStems","firstNamed","pair","phrased","score","leading","roles","Math","max","aiStockRank","photos","used","seed","scored","ranked","start","aiStockSameShoot","near","id","abs","photographer","aiStockFreshShootsFirst","best","top","fresh","other","aiStockPick","aiStockPlacedSrcs","nodes","node","Object","values","componentId","props","aiStockPlacedPhotos","Map","set","JOB_PHOTOS","REFUSED_BY_THE_LIBRARY","JOB_PHOTOS_MAX","jobPhotos","placed","get","oldest","keys","next","delete","aiStockForgetJobPhotos","clear","AI_STOCK_ALT_MAX","DESCRIBING","SCENERY","WEATHER","fog","mist","haze","rain","snow","snowfall","snowflakes","wind","QUALITIES","MASS_NOUNS","PLURAL_NOUNS","ABSTRACT_NOUNS","CONCRETE_ABSTRACT_ENDINGS","saysAnIdea","BRANDS","SAID_PEOPLE","COUNTED_ING","UNCOUNTED_ING","PEOPLE_NOUNS","GENERIC_PEOPLE","PARENTS","CHILDREN","SAID_AS","dad","dads","mom","moms","mum","mums","BODY_PARTS","KINDS_OF_THING","ALT_PERSON_TAGS_READ","ALT_ROLE_TAGS_READ","CLOTHING","PLACES","station","market","desk","table","counter","school","college","university","wedding","sunset","sunrise","dusk","dawn","beach","bed","sofa","couch","bench","trail","path","bridge","street","court","courtroom","office","kitchen","gym","studio","classroom","class","hall","room","garden","park","shop","store","bakery","cafe","restaurant","workshop","library","salon","clinic","forest","city","church","field","meadow","valley","mountain","hill","cliff","river","lake","lakeside","lakeshore","sea","ocean","seaside","coast","shore","sundown","waterfall","OBJECT_PLACES","BARE_PLACES","PLACES_SAID","TIME_PLACES","OUTDOORS","TAG_PREPOSITIONS","tagParts","ALT_PLACE_TAGS_READ","tagWords","describedTag","proper","describing","charAt","toUpperCase","articleFor","doing","plural","spelled","INITIALISMS","DANGLING_END","nearSynonyms","short","long","aiStockTagsAlt","family","parts","quality","portrait","weather","bare","reading","head","headStem","kind","holds","splice","posed","places","things","leads","parent","child","person","qualified","second","placeOf","whereOf","tail","describedObject","aiStockPhotoAlt","input","language","standIn","aiStockProperWords","entries","EXTENSIONS","SEARCH_JUDGMENT_KEYS","aiStockSearchRequest","wanted","request","aiStockKeptRequest","aiStockIngestRequest","provider","bytes","credit","hostId","uid","fileName","contentType","description","stockPhoto","providerLabel","photographerUrl","license","licenseUrl","attributionRequired","aiStockPhotoWordsOf","job","plan","inputs","kindWords","label","normalize","audience","photoWords","aiStockPhotoWordsSubject","end","aiStockSourceTerms","sourceWorldTerms","adults","english","aiStockSourceSubject","aiStockIsAbbreviation","aiStockListedCraft","aiStockNamedKind","aiStockKindTerms","KIND_SUBJECTS","trades","professional","wellness","portfolio","photography","blog","events","fitness","yoga","beauty","realestate","education","nonprofit","music","personal","landing","NAMED_KINDS","base","STARTER_KINDS","OFFICE","WORKSPACE","KIND_GENERIC","STARTER_GENERIC_KIND","FACE_STEMS","starterOfKind","starter","aiStockKindGenericTerms","aiStockWorldIsUnlisted","worldOfKind","aiStockWiderTerms","rungs","JSON","stringify","rung","aiLayoutStockPhotoSource","deps","ingest","wider","unlisted","now","Date","slots","report","timeout","AbortSignal","budgetMs","signal","any","scope","jobId","avoid","elsewhere","claimed","placedSrcs","answers","worldOf","WeakMap","storing","uncopied","refusedPicks","answered","remember","sourceKey","search","known","Promise","resolve","asked","then","catch","altFor","sectionNames","sectionIndex","keep","repeat","described","findStockPhoto","aborted","download","maxBytes","console","warn","stored","ok","refusal","ofThisPhoto","status","reason","error","String","judgementFor","judgementOf","craftSearches","widerSearches","ask","requests","choices","choice","accepted","blocked","choose","tried","candidates","repeats","sure","unsure","widened","phases","placedByKey","fill","rank","firsts","_slot","worker","from","min","toISOString"],"mappings":"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E,YAAY;QACZjB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDkB,OAAO;YAAC;YAAY;YAAU;YAAgB;SAAU;IAC1D;IACA;QACE,sBAAsB;QACtBlB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDkB,OAAO;YAAC;YAAW;YAAY;YAAa;YAAY;SAAY;IACtE;IACA;QACE,YAAY;QACZlB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDkB,OAAO;YAAC;YAAY;YAAY;YAAa;YAAW;SAAY;IACtE;IACA;QACE,mBAAmB;QACnBlB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDkB,OAAO;YAAC;YAAW;YAAW;YAAW;YAAW;SAAU;IAChE;IACA;QACE,kDAAkD;QAClDlB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDkB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;IACH;IACA;QACE,qBAAqB;QACrB,wGAAwG;QACxGlB,OAAO;YAAC;YAAa;YAAW;YAAW;YAAY;YAAa;YAAQ;YAAS;YAAO;YAAe;SAAM;QACjHkB,OAAO;YAAC;YAAc;YAAQ;SAAQ;IACxC;IACA;QACE,mDAAmD;QACnDlB,OAAO;YAAC;YAAS;YAAY;YAAO;YAAQ;YAAQ;YAAU;YAAW;SAAS;QAClFkB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;IACH;IACA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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-layout-stock-photos.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n pluginMediaIngest,\n type PluginMediaIngest,\n type PluginMediaIngestResult,\n} from '@aglyn/aglyn/plugin-manager/plugin-media-ingest'\nimport {\n STOCK_PHOTO_QUERY_MAX_CHARS,\n stockPhotoProvider,\n stockPhotoSourceKey,\n type StockPhoto,\n type StockPhotoOrientation,\n type StockPhotoProvider,\n type StockPhotoSearchRequest,\n} from '@aglyn/aglyn/plugin-manager/stock-photo-provider'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport {\n AI_LAYOUT_NO_PHOTO,\n aiLayoutSeedNumber,\n type AiLayoutPicturePhoto,\n type AiLayoutPictureSlot,\n type AiLayoutPictureSource,\n} from '../layout-language/ai-layout-pictures'\nimport { aiStorefrontSays } from '../layout-language/ai-layout-storefront'\nimport { aiLayoutLabel, aiLayoutSpeaksOtherThanEnglish } from '../layout-language/ai-layout-labels'\nimport type { AiBuildPlan } from '../model/ai-build-plan'\nimport { aiSiteKind, aiSiteKindOfInputs } from '../model/ai-site-kinds'\nimport { aiStockBusinessNoun } from './ai-stock-business-nouns'\n\n/**\n * STOCK PHOTOS FOR A LANGUAGE PAGE'S PICTURE SLOTS (AGL-3660).\n *\n * The source `aiResolveLayoutPictures` asks before it falls back to the\n * starter photos. It names no library: it asks core for the deployment's\n * stock photo provider (`core.stock-photos`) and for the media library's\n * server door (`core.media-ingest`), and builds no source at all when either\n * is missing, so a deployment without a key behaves exactly as before.\n *\n * What the live starts of 2026-10-10 taught (Juniper Clay Works, a ceramic\n * artist's portfolio, and Willow Wick Candles, a candle store), each photo\n * traced through the library's cached answers:\n *\n * - The site's words were read as \"portfolio\" and \"online\" — the kind of\n * SITE, not the craft — so every search said \"serving bowl portfolio\" and\n * the hero asked for \"portfolio\": a wallet, fashion models, and a blank\n * paper mockup that read as an empty panel beside the brushes.\n * - A hit naming the object anywhere won: a robin tagged \"food bowl\" filled\n * \"Speckled serving bowl\", a lilac branch tagged \"bud, vase\" filled \"Tall\n * bud vase\", letterpress type tagged \"set\" filled \"Nesting bowl set\" (its\n * head noun was read as \"set\"), and an antique tea set tagged \"brown\n * candle\" filled \"Candle Gift Set\".\n * - The page's 20 seconds ran out after four photos (each copy took ~5s, one\n * after another), and the slots left took the starter photos: the laptop\n * desk with pink roses under \"Candle Wick Trimmer\" and a work card, and the\n * windowsill plants under another.\n *\n * So, for each slot:\n *\n * 1. **The site's terms** ({@link aiStockSiteTerms}): the business is the\n * first clause of its type that says more than what kind of site it is\n * (\"ceramic artist\" from \"a portfolio for a ceramic artist who makes\n * stoneware bowls\"), its craft one word (\"ceramic\"), and its DOMAIN the\n * words a photo of its world names: the craft, the business type's own\n * nouns (\"stoneware\", \"soy\") and, for common crafts, their kin (\"pottery\",\n * \"clay\", \"wax\"). Its broad searches ask for the world itself (\"handmade\n * ceramics\", \"pottery\").\n * 2. **Search.** A picture of a thing asks for its subject — the noun phrase\n * of the caption, filler dropped — qualified by the craft where it does\n * not already name the domain (\"ceramic serving bowl\"), then the craft and\n * the object alone (\"ceramic bowl\"), then the broad searches. A hero asks\n * for the business, then broad; an about picture for the business's\n * people, then broad. The orientation and a minimum size come from the\n * slot's frame.\n * 3. **Accept, or reject.** A hit tagged as a mockup, a blank or a template\n * never fills anything. A picture of a thing takes only a hit naming its\n * OBJECT (the head noun, past \"set\", \"gift\", \"kit\": \"bowl\" in \"nesting\n * bowl set\", \"candle\" in \"candle gift set\") AND either the site's domain\n * or the subject's own two-word phrase (\"bud vase\"). A broad, hero or\n * about search takes only a hit naming the domain. The accepted are\n * ranked: the object in the hit's first tags (what the photo is OF) over\n * a mention in its last, the subject's other words, the domain. Among\n * equals the job's seed picks, so two sites differ and one job repeats.\n * What the beta.239 Ember & Oak start added: \"hand-poured\", \"handmade\"\n * and \"by hand\" never make \"hands\" a subject, and a story of the craft\n * asks for the maker at work (\"candle making\"); a hit carrying a topic\n * the brief never named (a cross, a grave, a flag, a gun, wine, a child,\n * a mannequin) never fills anything; a product, and a collection tile,\n * take only a hit naming its head noun among the first tags, held to the\n * shop's category; and an object whose word is not enough (\"melt\") is\n * named and searched by its kin (\"wax melt\", \"melt warmer\"), never by the\n * category alone. And from the Kiln & Clover portfolio: nudity never fills\n * anything, for any business; a hit naming a rival craft (glass, for a\n * potter) counts only when it names the craft's own words too.\n * 4. **Never twice.** A photo is placed once per job: not twice on a page,\n * and not on a page when another page (or another pass, in this process)\n * of the same job already placed it. The caller hands in what the job's\n * other pages hold (`avoid`); a pass repeated over its own page keeps its\n * own.\n * 5. **Keep, all at once.** The choosing is done first, slot by slot; the\n * copies then run side by side, a few at a time, so a page of eight\n * pictures takes about as long as two. A photo the site's library already\n * holds (by its source key) is reused; otherwise its bytes are copied\n * into the site's own library as the member who started the job, credited\n * to its photographer. A copy that fails tries the slot's next accepted\n * hit.\n *\n * 6. **Fall back to the craft, never off it** (the beta.241 Saltmarsh Soap\n * Co start, a store \"for handmade cold-process soap\": its craft read as\n * nothing, its hero searched \"shop\" and took a florist's bouquet, and four\n * of five products took the starters' laptop desk and living room). A\n * business that is only a place takes its craft from what it is for\n * (\"soap shop\"); a hero names the craft itself ({@link AiStockSiteTerms.core});\n * a product, after its own searches, tries its head noun anywhere among\n * the tags, its gift wrapper with the craft and the craft's broad\n * searches, and then — a product or a hero only — reuses an on-topic photo\n * the job already shows rather than take a starter. Every slot of a\n * craft's site tries the craft's broad searches last.\n * 7. **A product takes the surest photo, even a borrowed one** (the beta.242\n * Tidewater Soap Works start: a sauna for \"Bath Gift Set\", colognes for\n * \"Natural Body Lotion\", a bathroom shelf for \"Soap Bar Trio\" and a soap\n * dispenser for its starter size, while the collection tiles beside them\n * were good). A product's searches are ranked by how sure they are: its\n * own photo (the head noun or its kin among the first tags), then a photo\n * OF its category, new or one the job already shows, then a weak hit of\n * its own. No product shows a room or a scene, a fragrance bottle, or what\n * its kin shuns (a pump for a bar) unless it names it; \"bath\" in a bath\n * gift set is what the set is for; a size is never the product.\n * 8. **What the photo is OF** (the beta.259 starts, AGL-3856: a typewriter\n * printing \"terms of service\" as a family law firm's hero, a yoga pose on\n * a beach and a heart-shaped potato as a strength gym's events, a horse's\n * head of a \"western film\" as a photographer's \"Film\" card). A listed\n * craft may name what its photos are never OF among their first tags\n * (`shunLead`: a document for a law practice, yoga for a strength gym) and\n * its rival worlds (a movie's for a photographer's film); a comma after a\n * place goes on naming the place (\"Columbus, Ohio\"), never the world; an\n * event's or a lesson's word (\"basics\", \"class\", \"session\") is never its\n * object; a word the table does not list beside a craft it does\n * (\"wedding\" of \"a wedding and portrait photographer\") is not the craft;\n * and a hero whose second tag names the world too leads one whose first\n * alone does.\n * 9. **A world from the name** (the beta.261 Synchronicity Gym start,\n * AGL-3856: its business type \"a local service business\" named no world,\n * so its hero searched nothing and was left a black scrim, and its\n * closing band's \"Ready to train\" took a subway train). A business type\n * that names no world takes the craft its name, else its audience, names\n * where this module lists it (\"gym\" of \"Synchronicity Gym\"); and a\n * training word's other senses (a railway's train, an elevator's lift, a\n * newspaper's press, a boat's row) never fill a gym's picture.\n * 10. **The trade, never a word of it** (the 2026-10-25 booth kit, AGL-4065:\n * six trades whose photos were race cars, cyclists, horses, a Honda\n * scooter, a canoe for \"Parts for the ranch\", hotel buffets for a taco\n * trailer and an office for a landscaper). A business named by two\n * things (\"Motorcycle and dirt bike repair shop\") is both; the craft\n * named first leads, never one named only in what a customer may ask\n * (\"takes catering requests\"); a hero's first tag and a broad search's\n * hit name the business's own world ({@link AiStockSiteTerms.lead}),\n * never any word of its type (\"race\" of \"race car\"); a two-word world\n * (\"dirt bike\") is named whole; a maker's name never shows; a sentence to\n * the reader, a job or an order is never a subject, and a part or gear is\n * searched only with its world; a record's cover is searched in its world\n * first; and a listed world widens only where the library knew nothing of\n * it, never an outdoor or a trade world to an office.\n *\n * A slot the library could not fill because it never answered — down, or\n * out of time before its first answer — or because the site's library\n * refused to store, is left `null` for the starter photos. A slot the\n * library answered and nothing acceptable came back for is answered\n * {@link AI_LAYOUT_NO_PHOTO} and keeps its no-photo treatment: the beta.257\n * Copper Kettle Catering hero, held to \"caterer\" while catering photos are\n * tagged \"catering\", took the starters' pottery workbench (AGL-3831). A\n * named object is never given one while the library answers anything of the\n * site's world: the broad searches come first. Nothing here throws, and none\n * of it is an AI model call: photos cost no AI credits.\n */\n\n/** Wall clock the whole page's photos may take, inside the step's own signal. */\nexport const AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS = 30_000\n\n/** Searches one page may send to the provider; a repeated query is answered from the page's own memory. */\nexport const AI_LAYOUT_STOCK_SEARCHES_PER_PAGE = 18\n\n/** The hits a pick is made among. */\nexport const AI_LAYOUT_STOCK_PICK_WINDOW = 40\n\n/** The accepted hits a slot keeps in hand, in case a copy fails. */\nconst AI_LAYOUT_STOCK_TRIES_PER_SLOT = 3\n\n/** Copies made side by side. */\nconst AI_LAYOUT_STOCK_COPIES_AT_ONCE = 4\n\n/** The largest photo copied: inside one direct upload. */\nexport const AI_LAYOUT_STOCK_MAX_BYTES = 3 * 1024 * 1024\n\n/**\n * The media library's refusals that are about ONE photo's own bytes, as the\n * console's `ingestMedia` returns them (AGL-3923): 415 for a type or contents\n * it does not accept, 413 for a photo too large to store, 451 for a file\n * held in quarantine. The slot then tries its next hit, and the page goes on\n * storing. Every other refusal (403 from the storage band, the site's scope\n * or a lockdown; 500) holds for the whole page.\n */\nexport const AI_STOCK_PHOTO_OWN_REFUSALS: ReadonlySet<number> = new Set([413, 415, 451])\n\n/**\n * The unit job input naming the screen drafts the job's other pages were\n * written to, whose photos a page does not place again (AGL-3660).\n */\nexport const AI_STOCK_PHOTO_PAGES_INPUT = 'stockPhotoPages'\n\n/**\n * The unit job input naming library photos (`media:` references) another\n * part of the job already shows outside its pages — a dataset's records\n * (AGL-3616) — which a page does not place again.\n */\nexport const AI_STOCK_PHOTO_AVOID_INPUT = 'stockPhotoAvoid'\n\n/**\n * The unit job input holding the photos another part of the job placed\n * outside its pages — a dataset's records — with their size and words\n * (AGL-3988): what a picture the library failed takes before any starter.\n */\nexport const AI_STOCK_PHOTO_JOB_PHOTOS_INPUT = 'stockPhotoJobPhotos'\n\n/**\n * The unit job input a guided start's page is built under (AGL-3988): its\n * site step runs a late photo pass once every page is built, so a picture\n * the library failed that none of the job's photos fits yet keeps a neutral\n * starter for that pass to fill, rather than lose its frame, and the page\n * reports it. A page built by any other job keeps #1831's rule.\n */\nexport const AI_STOCK_PHOTO_LATE_PASS_INPUT = 'stockPhotoLatePass'\n\n/** The job photos a unit input holds ({@link AI_STOCK_PHOTO_JOB_PHOTOS_INPUT}): library photos with a size; anything else is dropped. */\nexport function aiStockJobPhotosOf(value: unknown): AiLayoutPicturePhoto[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry) => {\n const photo = entry as Partial<AiLayoutPicturePhoto> | null\n const src = typeof photo?.src === 'string' ? photo.src : ''\n const width = Number(photo?.width)\n const height = Number(photo?.height)\n if (!src.startsWith('media:') || !(width > 0) || !(height > 0)) return []\n const alt = typeof photo?.alt === 'string' ? photo.alt.trim() : ''\n return [{ src, width, height, ...(alt ? { alt } : {}) }]\n })\n}\n\nconst words = (list: string) => new Set(list.trim().split(/\\s+/))\n\n/** Words that carry no subject. */\nconst STOPWORDS = words(\n 'a an the and or of in on at to for with from by into onto over under near our your their my his her its ' +\n 'this that these those is are be being was were who whom which where while as about than then very just ' +\n 'small local best new top quality premium family-owned family owned independent professional ' +\n 'business company services service page photo picture image showing shows show ' +\n 'someone people person one two three some many several ' +\n // A sentence to the reader, never what a picture shows (AGL-4065): \"Tell us\n // the bike and we will say if it will fit\" searched \"tell us bike\".\n 'we us you they them i me if tell say describe send ask need want get let know see find will would could',\n)\n\n/**\n * Words of a sentence to the reader that a business type may use as a name\n * (\"IT support\", \"Fit club\", \"call center\"): never a picture's subject\n * (AGL-4065), always a business's own word.\n */\nconst SENTENCE_WORDS = words('it fit can call')\n\n/**\n * Nouns that never stand alone as what a picture shows (AGL-4065): a job, a\n * request, an order. \"Describe your job\" searched \"handyman describe job\" and\n * placed a job application form; \"OEM ATV Parts Order\" searched \"atv parts\n * order\" and placed trees tagged \"order\".\n */\nconst GENERIC_OBJECTS = words(\n 'job jobs request requests order orders service services detail details thing things stuff action cta',\n)\n\n/**\n * Things a world has many of, which a photo shows only in that world\n * (AGL-4065): a part, gear, a machine. Searched only with the site's own\n * world (\"dirt bike parts\"), never alone: \"parts\" answered a canoe on a\n * river, tagged \"part\", for a dirt bike shop's \"Parts for the ranch\".\n */\nconst WORLD_OBJECTS = words('part parts gear gears machine machines equipment spare spares accessory accessories')\n\n/**\n * The verbs a business type's clause opens with when it says what a customer\n * may ask of it (AGL-4065): \"takes quote requests\", \"books repair\n * appointments\". The verb is never the business's world.\n */\nconst TRANSACTION_VERBS = words('take takes taking book books booking accept accepts accepting welcome welcomes')\n\n/**\n * What a business does with a customer, never what its photos show\n * (AGL-4065), as stems: dropped from its world. \"Special orders\" named\n * Berm & Bolt's world, so a delivery man's \"order\" and trees tagged \"order\"\n * filled its products.\n */\nconst TRANSACTION_STEMS: ReadonlySet<string> = new Set(\n // \"Takes\" and \"books\" are verbs only where they open a clause (TRANSACTION_VERBS): a bookshop's books are its world.\n 'booking appointment order request quote estimate free inquiry pickup special around town'.split(' '),\n)\n\n/**\n * Words of a business's own clause that name its world only beside another\n * (AGL-4065): \"race\" and \"team\" of \"amateur motocross race team\" are a race\n * car's and an office's as often. Never its own world alone.\n */\nconst LEAD_GENERIC = words(\n 'amateur pro race racing team club crew group repair repairs service home house food truck trailer mobile ' +\n 'street event events custom family families',\n)\n\n/**\n * Words that describe a picture's look, not what it shows, dropped from a\n * subject. A word that is as often a noun (\"light\", \"set\") is not one.\n */\nconst FILLER = words(\n 'beautiful beautifully stunning gorgeous lovely pretty elegant modern contemporary rustic cozy cosy warm cool ' +\n 'soft bright natural simple minimal minimalist delicate unique special artisan artisanal handmade ' +\n 'hand-made hand-thrown handthrown hand-crafted handcrafted crafted hand-built handbuilt hand-poured ' +\n 'hand-painted hand-dyed hand-stitched poured finished styled perfect wheel-thrown wheelthrown thrown ' +\n 'fresh clean calm serene quiet peaceful vibrant colorful colourful sunlit sunny golden glossy matte textured ' +\n 'close-up closeup up view views detail details detailed shot shots overhead flat lay flatlay flat-lay ' +\n 'top-down wide angle featuring featured displayed arranged sitting resting placed standing lined ' +\n 'single pair collection assortment selection group few various array range large tiny big little ' +\n 'tall short wide narrow everyday classic signature original favorite favourite bestselling best-selling ' +\n 'small-batch batch limited edition custom bespoke ' +\n // How a soap is made, never what it shows: \"cold\" and \"process\" named a supermarket fridge (Saltmarsh, 2026-10-10).\n 'cold-process cold-processed hot-process hot-processed melt-and-pour ' +\n 'white black grey gray beige cream ivory brown tan blue green red pink yellow orange purple speckled ' +\n 'gentle airy inviting welcoming cheerful happy smiling friendly',\n)\n\n/** The nouns that name a place of business, not its craft: \"studio\" in \"ceramics studio\". */\nconst VENUES = words(\n 'studio studios shop shops store stores boutique company co workshop gallery atelier agency brand practice ' +\n 'salon house collective lab market services service firm clinic center centre parlor parlour bar ' +\n 'class classes lessons school academy',\n)\n\n/** The person who does the craft, not the craft: \"artist\" in \"ceramic artist\". */\nconst ROLES = words(\n 'artist artists maker makers artisan artisans owner owners founder founders creator creators',\n)\n\n/** Words naming what kind of SITE it is, never what it shows: \"portfolio\" in \"a portfolio for a ceramic artist\". */\nconst SITE_KINDS = words(\n 'portfolio portfolios website websites site sites blog blogs online web webshop ecommerce e-commerce ' +\n 'landing personal homepage storefront',\n)\n\n/** Verbs a business type uses to say what it does; what follows them is its domain, never its business. */\nconst DOING =\n /(?<![\\w-])(?:makes?|making|made|sells?|selling|sold|offers?|offering|creates?|creating|specializ(?:es|ing)|specialis(?:es|ing)|provides?|providing|featuring|showcasing|shoots?|shooting)(?![\\w-])/g\n\n/** Where a business type's own clause ends. */\nconst BUSINESS_BREAK =\n /[,;:.()]|\\s[-–—]\\s|\\b(?:in|for|near|serving|based|located|that|which|who|with|from|since|and|&)\\b/\n\n/** A clause after one of these says where or for whom, never what: \"in Austin\", \"for busy parents\". */\nconst PLACE_OR_AUDIENCE =\n /^(?:in|near|serving|based|located|across|around|throughout|for)$/\n\n/**\n * Words naming a set or a wrapper of a thing, never the thing: the OBJECT\n * of \"nesting bowl set\" is the bowl, of \"candle gift set\" the candle.\n */\nconst WRAPPERS = words(\n 'set sets kit kits gift gifts bundle bundles pack packs box boxes trio duo pair collection sampler assortment ' +\n 'series range line group lot bunch ' +\n // What an event or a lesson is, never what it shows (AGL-3856): \"Intro to\n // barbell basics\" is of a barbell, \"Small-group strength class\" of strength.\n 'class classes session sessions lesson lessons course courses workshop workshops seminar seminars ' +\n 'meetup meetups program programs programme programmes basics intro introduction fundamentals',\n)\n\n/**\n * A hit tagged with any of these is never placed: a mockup's blank panel is\n * an empty frame on the page (the Juniper Clay hero), a template or a\n * graphic is not a photo of anything.\n */\nconst REJECTED_TAGS = words(\n 'mockup mock-up mock blank template templates clipart clip-art illustration vector logo icon ' +\n 'ai-generated generated render rendering 3d',\n)\n\n/**\n * Rooms and scenes, never a product (AGL-3660): the beta.242 Tidewater Soap\n * Works start put a wooden sauna under \"Bath Gift Set\" and a bathroom shelf of\n * baskets under \"Soap Bar Trio\". A product's hit whose first tags name one of\n * these is turned down unless the product or the brief names it too.\n */\nconst PRODUCT_SCENES = new Set(\n [\n 'sauna',\n 'bathroom',\n 'bathtub',\n 'shower',\n 'toilet',\n 'sink',\n 'washbasin',\n 'faucet',\n 'tap',\n 'shelf',\n 'shelves',\n 'interior',\n 'bedroom',\n 'kitchen',\n 'room',\n 'livingroom',\n 'hotel',\n 'lobby',\n ].map(aiStockStem),\n)\n\n/**\n * A fragrance's bottle, never a lotion, a cream or a soap (AGL-3660): the same\n * start's \"Natural Body Lotion\" showed blue cologne bottles tagged \"perfume,\n * bottle, lotion\". Turned down among a product's first tags unless the\n * product or the brief is a fragrance.\n */\nconst FRAGRANCE_BOTTLES = new Set(\n ['perfume', 'perfumes', 'perfumery', 'cologne', 'colognes', 'parfum', 'eau', 'atomizer', 'fragrance'].map(\n aiStockStem,\n ),\n)\n\n/**\n * Topics a business's photos never carry unless its own words name them\n * (AGL-3660, the beta.239 Ember & Oak start, whose \"Gifts for melt fans\" tile\n * showed devotional candles with crosses and names). A hit tagged with any\n * word of a topic is rejected unless the site's business type or brief says\n * one of the topic's words or its `allow` words. The last topic is not\n * sensitive but is never the thing: the same start's story band showed bronze\n * mannequin hands tagged \"wax\".\n */\nconst SENSITIVE_TOPICS: ReadonlyArray<{\n words: readonly string[]\n allow?: readonly string[]\n /** Rejected whatever the brief says. */\n always?: boolean\n}> = [\n {\n // Religion.\n words: [\n 'cross',\n 'crosses',\n 'crucifix',\n 'church',\n 'chapel',\n 'cathedral',\n 'jesus',\n 'christ',\n 'christian',\n 'christianity',\n 'god',\n 'bible',\n 'rosary',\n 'prayer',\n 'pray',\n 'praying',\n 'worship',\n 'worships',\n 'religion',\n 'religious',\n 'faith',\n 'islam',\n 'islamic',\n 'muslim',\n 'mosque',\n 'quran',\n 'temple',\n 'buddha',\n 'buddhism',\n 'buddhist',\n 'hindu',\n 'hinduism',\n 'synagogue',\n 'jewish',\n 'judaism',\n 'ecclesiastical',\n 'saint',\n 'altar',\n 'sacrificial',\n 'nativity',\n 'priest',\n 'nun',\n 'monk',\n ],\n allow: ['ministry', 'parish', 'congregation', 'wedding'],\n },\n {\n // Death and mourning.\n words: [\n 'funeral',\n 'memorial',\n 'grave',\n 'gravestone',\n 'cemetery',\n 'tomb',\n 'death',\n 'dead',\n 'grief',\n 'mourning',\n 'condolence',\n 'coffin',\n 'skull',\n ],\n allow: ['hospice', 'mortuary', 'cremation', 'obituary', 'halloween'],\n },\n {\n // Politics.\n words: [\n 'political',\n 'politics',\n 'protest',\n 'protester',\n 'demonstration',\n 'rally',\n 'flag',\n 'election',\n 'vote',\n 'voting',\n 'parliament',\n 'government',\n ],\n allow: ['advocacy', 'campaign', 'candidate', 'council', 'nonprofit'],\n },\n {\n // Weapons and war.\n words: [\n 'gun',\n 'rifle',\n 'pistol',\n 'weapon',\n 'firearm',\n 'ammunition',\n 'bullet',\n 'sword',\n 'war',\n 'military',\n 'army',\n 'soldier',\n ],\n allow: ['hunting', 'archery', 'martial', 'fencing', 'veteran'],\n },\n {\n // Alcohol, for a business that does not serve it.\n words: [\n 'alcohol',\n 'wine',\n 'beer',\n 'whiskey',\n 'whisky',\n 'vodka',\n 'cocktail',\n 'liquor',\n 'rum',\n 'gin',\n 'champagne',\n 'drunk',\n ],\n allow: [\n 'winery',\n 'vineyard',\n 'brewery',\n 'distillery',\n 'pub',\n 'tavern',\n 'taproom',\n 'bartender',\n 'sommelier',\n 'spirits',\n ],\n },\n {\n // Tobacco and drugs.\n // \"cbd\" and \"cannabinoid\": a hemp cream tube was the next \"body lotion\" answer (Tidewater, 2026-10-11).\n words: ['cigarette', 'smoking', 'tobacco', 'cannabis', 'marijuana', 'drug', 'drugs', 'cbd', 'cannabinoid', 'thc'],\n allow: ['dispensary', 'vape', 'cigar'],\n },\n {\n // Children, for a business that is not about them.\n words: ['child', 'children', 'kid', 'kids', 'baby', 'babies', 'toddler', 'infant'],\n allow: [\n 'nursery',\n 'daycare',\n 'preschool',\n 'kindergarten',\n 'school',\n 'tutor',\n 'tutoring',\n 'parent',\n 'parents',\n 'parenting',\n 'family',\n 'families',\n 'pediatric',\n 'paediatric',\n 'newborn',\n 'maternity',\n ],\n },\n {\n // Nudity, for every business: no word of a brief lets it in (Kiln &\n // Clover, 2026-10-10: a nude torso sculpture filled \"About the artist\").\n // Never bare \"body\": a skincare shop's body lotion is its product.\n words: [\n 'nude',\n 'nudes',\n 'nudity',\n 'naked',\n 'torso',\n 'breast',\n 'breasts',\n 'erotic',\n 'sensual',\n 'lingerie',\n 'bikini',\n ],\n allow: [],\n always: true,\n },\n {\n // Figures, never the maker: mannequin hands are not a candlemaker's.\n words: [\n 'mannequin',\n 'mannequins',\n 'dummy',\n 'statue',\n 'sculpture',\n 'figurine',\n 'doll',\n 'dolls',\n 'waxwork',\n ],\n allow: ['sculptor', 'museum', 'fashion', 'boutique', 'clothing', 'apparel', 'toy', 'toys'],\n },\n]\n\n/** Each topic's words and the words that allow it, as stems. */\nconst SENSITIVE_STEMS = SENSITIVE_TOPICS.map((topic) => ({\n words: new Set(topic.words.map(aiStockStem)),\n allow: new Set(\n topic.always\n ? []\n : [...topic.words, ...(topic.allow ?? [])].map(aiStockStem),\n ),\n}))\n\n/**\n * Makers whose names a photo's tags or its page address give, which no\n * site's pictures carry unless its own words name the maker (AGL-4065): the\n * Rut Runners Racing heroes were race cars in a pit lane under their makers'\n * logos, and Holeshot Moto Repair's a Honda scooter and an Indian cruiser. A\n * name that is also a common word (\"apple\", \"puma\", \"triumph\", \"indian\") is\n * named only in the phrase that makes it the maker's. Read from the tags and\n * the address, so a logo no tag names still shows: the live check is where\n * that is seen.\n */\nconst MAKERS = [\n 'porsche', 'ferrari', 'lamborghini', 'bmw', 'mercedes', 'audi', 'volkswagen', 'vw', 'toyota', 'honda', 'yamaha',\n 'kawasaki', 'suzuki', 'ktm', 'ducati', 'harley', 'harley-davidson', 'husqvarna', 'gasgas', 'tesla', 'ford',\n 'chevrolet', 'chevy', 'dodge', 'jeep', 'nissan', 'subaru', 'mazda', 'indian motorcycle', 'triumph motorcycle',\n 'gran turismo', 'playstation', 'xbox', 'nintendo', 'nike', 'adidas', 'reebok', 'red bull', 'monster energy',\n 'coca cola', 'cocacola', 'pepsi', 'iphone', 'ipad', 'macbook', 'imac', 'samsung', 'starbucks', 'mcdonalds',\n 'mcdonald',\n]\n\n/** The makers as stems and stem phrases, as a hit's words are read. */\nconst MAKER_STEMS: ReadonlySet<string> = new Set(MAKERS.map((maker) => stemList(maker).join(' ')))\n\n/**\n * A phrase's words and each pair of them in turn, as stems (AGL-4065): \"dirt\n * bike\" names the motocross world where \"bike\" alone names a bicycle's too.\n */\nfunction withPairs(list: readonly string[]): string[] {\n const out = [...list]\n for (let index = 0; index + 1 < list.length; index += 1) out.push(`${list[index]} ${list[index + 1]}`)\n return out\n}\n\n/** A text's stems and stem pairs, every tag or phrase read on its own. */\nfunction termsOf(texts: readonly string[]): Set<string> {\n return new Set(texts.flatMap((text) => withPairs(stemList(text))))\n}\n\n/** A word or phrase as stems: \"dirt bikes\" is \"dirt bike\". */\nconst stemPhrase = (phrase: string) => stemList(phrase).join(' ')\n\n/**\n * A tag that says what a photo suits, never what it shows (AGL-4065):\n * \"samsung wallpaper\", \"iphone wallpaper\", \"lock screen\". A latte tagged so\n * shows no phone.\n */\nconst SUITS = /\\b(?:wallpapers?|backgrounds?|screens?|screensavers?|lockscreen|4k|hd)\\b/i\n\n/** The words a photo names a maker by: its tags, those of what it suits left out, its description and its page address. */\nfunction aiStockMakerTerms(photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>): Set<string> {\n const tags = (photo.tags ?? []).filter((tag) => !SUITS.test(tag))\n return termsOf([...tags, photo.alt ?? '', pageSlug(photo.pageUrl)])\n}\n\n/**\n * Hands are never a picture's subject (AGL-3660): \"hand-poured\", \"handmade\"\n * and \"by hand\" say how a thing was made, and a search for \"hands\" found\n * bronze mannequin hands for the beta.239 Ember & Oak story band. Each of\n * these is dropped from a picture's words; a hand only stays where it names\n * a thing sold for hands (\"hand cream\").\n */\nconst HAND_IDIOMS: readonly RegExp[] = [\n /\\b(?:made\\s+|poured\\s+|crafted\\s+|finished\\s+|done\\s+)?by\\s+(?:our\\s+|my\\s+|their\\s+)?(?:own\\s+)?hands?\\b/g,\n /\\bwith\\s+(?:our|my|their)\\s+(?:own\\s+)?(?:two\\s+)?hands\\b/g,\n /\\bhand[- ]?(?:poured|made|crafted|thrown|built|painted|dyed|stitched|sewn|knit|knitted|carved|tied|lettered|blown|bound|rolled|dipped|picked|forged|woven|cut|finished|mixed|cast|formed|shaped|pressed|printed|wrapped|selected|blended|turned|glazed)\\b/g,\n /\\bhands?\\b(?!\\s+(?:creams?|soaps?|lotions?|wash|towels?|saniti[sz]ers?|salves?|balms?|tools?|saws?|planes?|drills?|mixers?|puppets?|bags?|warmers?))/g,\n]\n\n/** A text without its hands. */\nfunction withoutHands(text: string): string {\n return HAND_IDIOMS.reduce(\n (out, idiom) => out.replace(idiom, ' '),\n text.toLowerCase(),\n )\n}\n\n/** Whether a text says how a thing was made by hand: a maker at work. */\nfunction saysMadeByHand(text: string): boolean {\n const lower = text.toLowerCase()\n return HAND_IDIOMS.some((idiom) => {\n idiom.lastIndex = 0\n const found = idiom.test(lower)\n idiom.lastIndex = 0\n return found\n })\n}\n\n/**\n * The kin of a few objects whose own word is not enough (AGL-3660): a \"melt\"\n * is any melting thing (the beta.239 \"Wax melts\" tile showed resin fluid\n * art), so a wax melt names one of these phrases. `within` is the world they\n * are of; `qualifier` the word a search adds; `queries` the searches for the\n * object itself, which stand in for the shop's category alone: a candle is\n * not a wax melt.\n */\nconst OBJECT_KIN: ReadonlyArray<{\n objects: readonly string[]\n within: readonly string[]\n /** The word a product's search adds where its subject lacks it; none where the subject is enough. */\n qualifier?: string\n /** Whether the qualifier follows the subject: \"bath gift set soap\". */\n after?: boolean\n kin: readonly string[]\n queries: readonly string[]\n /** Words a photo of the object never carries unless the product names them: a pump for a bar of soap. */\n shun?: readonly string[]\n}> = [\n {\n objects: ['melt', 'tart', 'cube'],\n within: ['wax', 'candle', 'soy'],\n qualifier: 'wax',\n kin: [\n 'wax melt',\n 'wax melts',\n 'wax cube',\n 'wax cubes',\n 'wax tart',\n 'wax tarts',\n 'melt warmer',\n 'wax warmer',\n 'tart warmer',\n 'oil burner',\n 'oil warmer',\n 'aroma burner',\n 'scent warmer',\n 'fragrance warmer',\n ],\n queries: ['wax melts', 'wax melt warmer', 'scented wax cubes'],\n },\n {\n // A \"bar\" is a pub's before it is a soap's (the Saltmarsh \"cold-process\n // soap bar\" search answered a pint of beer second): a soap bar is named\n // by soap, and searched by it.\n objects: ['bar'],\n within: ['soap', 'soapmaker', 'skincare'],\n qualifier: 'soap',\n kin: [\n 'soap bar',\n 'soap bars',\n 'bar of soap',\n 'bars of soap',\n 'soap',\n 'soaps',\n 'handmade soap',\n 'soap block',\n 'soap cubes',\n ],\n queries: ['soap bars', 'handmade soap bar'],\n // A bar is never a pump or a liquid soap (the beta.242 Tidewater start).\n shun: ['pump', 'pumps', 'liquid', 'dispenser', 'dispensers'],\n },\n {\n // \"Bath\" in \"bath gift set\", \"bath bomb\" or \"bath salts\" is what the\n // products are for, never the room: the beta.242 Tidewater Soap Works\n // start (2026-10-11) put a wooden sauna under \"Bath Gift Set\", its tags\n // \"sauna, steam, bath\". A bath set is named by soap and bath products,\n // and searched with soap.\n objects: ['bath'],\n within: ['soap', 'soapmaker', 'skincare', 'spa', 'cosmetic'],\n qualifier: 'soap',\n after: true,\n kin: [\n 'soap',\n 'soaps',\n 'soap bar',\n 'soap bars',\n 'handmade soap',\n 'bath bomb',\n 'bath bombs',\n 'bath salt',\n 'bath salts',\n 'bath product',\n 'bath products',\n 'bath set',\n 'toiletries',\n ],\n queries: ['soap gift set', 'bath products', 'bath bombs'],\n shun: ['pump', 'pumps', 'liquid', 'dispenser', 'dispensers'],\n },\n {\n // A lotion is any cream for the skin; a perfume bottle tagged \"lotion\"\n // is not one (the same start's \"Natural Body Lotion\" showed colognes).\n objects: ['lotion', 'moisturizer', 'moisturiser'],\n within: ['soap', 'soapmaker', 'skincare', 'lotion', 'cosmetic', 'beauty', 'spa'],\n kin: [\n 'lotion',\n 'lotions',\n 'body lotion',\n 'hand lotion',\n 'cream',\n 'creams',\n 'hand cream',\n 'body cream',\n 'skin cream',\n 'face cream',\n 'cream jar',\n 'body butter',\n 'moisturizer',\n 'moisturiser',\n ],\n queries: ['body lotion', 'hand cream', 'cream jar', 'moisturizer'],\n },\n {\n // A rider's gear is what they wear (AGL-4065): \"Riding Gear Item\" took a\n // gear wheel of a transmission, tagged \"gear, mechanics, bikes\".\n objects: ['gear'],\n within: ['motocross', 'motorcycle', 'motorbike', 'dirtbike', 'dirt bike', 'enduro', 'atv'],\n kin: [\n 'riding gear',\n 'motocross gear',\n 'protective gear',\n 'helmet',\n 'helmets',\n 'motocross helmet',\n 'motorcycle helmet',\n 'jersey',\n 'boots',\n 'goggles',\n 'gloves',\n ],\n queries: ['motocross gear', 'motocross helmet'],\n },\n {\n // A dirt bike's tire is knobby; a car's on a highway is not one (AGL-4065).\n objects: ['tire'],\n within: ['motocross', 'motorcycle', 'motorbike', 'dirtbike', 'dirt bike', 'enduro', 'atv'],\n kin: ['tire', 'tires', 'knobby tire', 'motocross tire', 'dirt bike tire', 'motorcycle tire', 'bike tire', 'wheel'],\n queries: ['dirt bike tire', 'motocross tire'],\n },\n]\n\n/** An object's kin where the site or the subject is of its world, else `null`. */\nfunction objectKin(\n object: string,\n world: readonly string[],\n): (typeof OBJECT_KIN)[number] | null {\n return (\n OBJECT_KIN.find(\n (entry) =>\n entry.objects.some((word) => aiStockStem(word) === object) &&\n entry.within.some((word) => world.includes(stemPhrase(word))),\n ) ?? null\n )\n}\n\n/**\n * The kin of a few common crafts: the words a photo of that world is\n * tagged with, and the broad searches that find it. A craft not listed\n * still has its own words; this only widens what counts as its world.\n */\nconst CRAFT_KIN: ReadonlyArray<{\n match: readonly string[]\n kin: readonly string[]\n broad: readonly string[]\n /** The maker at work: what a story of the craft shows, never \"hands\" (AGL-3660). */\n making: readonly string[]\n /**\n * Crafts a photo of this one is mistaken for, and the words only this\n * craft's photos say: a hit naming a rival counts as of this world only\n * when it names one of them too (Kiln & Clover, 2026-10-10: red and yellow\n * glass art filled a ceramic artist's Work hero, glass being fired and\n * \"vase\" too).\n */\n rivals?: { words: readonly string[]; core: readonly string[] }\n /**\n * Words no photo of this craft carries unless the slot or the brief names\n * them (AGL-3660): the beta.242 Tidewater start put a black soap dispenser\n * under \"Bath Gift Set Starter Size\", let in as a rival because its tags\n * also said \"cosmetics\".\n */\n shun?: readonly string[]\n /**\n * Words that, among a hit's FIRST tags, say the photo is of something other\n * than the craft's world, however its later tags name it (AGL-3856): the\n * beta.259 Hartwell Reyes Family Law hero was a typewriter printing \"terms\n * of service\", tagged \"law, general terms and conditions, attorney\". Turned\n * down unless the slot or the brief names them.\n */\n shunLead?: readonly string[]\n /**\n * Whether its pictures are of people at a moment and a place, searched by\n * them ({@link aiStockScene}): a photographer's \"Mountain Wedding Day\" is a\n * couple in the mountains, never a close-up of roses (AGL-3856).\n */\n scenes?: boolean\n /**\n * The maker and their tools, which a record of the work is never OF unless\n * it names them (AGL-3856): a photographer's \"Mountain Elopements\" is never\n * a press photographer, nor a camera.\n */\n maker?: readonly string[]\n /**\n * The worlds a trade of this kind serves, one of which the business type\n * must name for the trade to be listed, and then the trade is its craft\n * (AGL-4065): \"parts\" is a dirt bike shop's craft, its world the motocross\n * group's.\n */\n of?: readonly string[]\n /**\n * Words a photo of the world names beside its own, which say the world\n * only together with them (AGL-4065): a rider, a helmet, a track. Its\n * world's words for a picture of a thing, never what a hero or a broad\n * search is held to.\n */\n near?: readonly string[]\n}> = [\n {\n match: [\n 'ceramic',\n 'ceramics',\n 'pottery',\n 'potter',\n 'stoneware',\n 'porcelain',\n 'earthenware',\n 'clay',\n ],\n kin: [\n 'ceramic',\n 'ceramics',\n 'pottery',\n 'potter',\n 'stoneware',\n 'porcelain',\n 'earthenware',\n 'clay',\n 'glaze',\n 'kiln',\n ],\n broad: ['handmade ceramics', 'pottery'],\n rivals: {\n words: ['glass', 'glassware', 'glasswork', 'glassblowing', 'blown', 'stained', 'murano', 'crystal'],\n core: ['ceramic', 'ceramics', 'pottery', 'potter', 'stoneware', 'porcelain', 'earthenware', 'clay', 'terracotta'],\n },\n making: ['pottery wheel', 'potter at work'],\n },\n {\n match: ['candle', 'candlemaker', 'candlemaking'],\n kin: [\n 'candle',\n 'candlelight',\n 'wax',\n 'soy',\n 'wick',\n 'scented',\n 'votive',\n 'candlestick',\n ],\n broad: ['handmade candles', 'scented candles'],\n making: ['candle making', 'pouring wax'],\n },\n {\n match: [\n 'jewelry',\n 'jewellery',\n 'jeweler',\n 'jeweller',\n 'silversmith',\n 'goldsmith',\n ],\n kin: [\n 'jewelry',\n 'jewellery',\n 'ring',\n 'necklace',\n 'earring',\n 'bracelet',\n 'silver',\n 'gold',\n 'gemstone',\n ],\n broad: ['handmade jewelry', 'jewelry'],\n making: ['jewelry making', 'jeweler at work'],\n },\n {\n match: ['soap', 'soapmaker', 'skincare'],\n // Never \"natural\": a florist's bouquet tagged \"natural\" was the\n // Saltmarsh Soap Co hero (2026-10-10).\n kin: ['soap', 'skincare', 'lotion', 'cream', 'bath', 'spa', 'cosmetic'],\n broad: ['handmade soap', 'natural skincare'],\n // \"Soap making\" is answered with soap bubbles; a bar is what a soapmaker makes.\n making: ['soap making', 'handmade soap'],\n // Soap bubbles, a dispenser and detergent are soap, never a soapmaker's:\n // the same start's story band showed bubbles in flight.\n rivals: {\n words: ['bubble', 'bubbles', 'soapy', 'dispenser', 'detergent', 'dishwashing', 'laundry'],\n core: [\n 'bar',\n 'bars',\n 'handmade',\n 'homemade',\n 'loaf',\n 'lye',\n 'glycerin',\n 'skincare',\n 'lotion',\n 'cosmetic',\n 'spa',\n 'artisan',\n ],\n },\n shun: ['dispenser', 'dispensers'],\n },\n {\n match: [\n 'wood',\n 'woodwork',\n 'woodworking',\n 'woodworker',\n 'carpenter',\n 'carpentry',\n 'furniture',\n 'joinery',\n ],\n kin: [\n 'wood',\n 'wooden',\n 'woodwork',\n 'timber',\n 'furniture',\n 'carpentry',\n 'oak',\n 'walnut',\n ],\n broad: ['woodworking', 'wooden furniture'],\n making: ['woodworking workshop', 'carpenter at work'],\n },\n {\n match: ['bakery', 'baker', 'bread', 'pastry', 'cake', 'patisserie'],\n kin: [\n 'bakery',\n 'bread',\n 'pastry',\n 'cake',\n 'baking',\n 'baked',\n 'dough',\n 'croissant',\n ],\n broad: ['bakery', 'fresh bread'],\n making: ['baker kneading dough', 'baking bread'],\n },\n {\n match: ['coffee', 'cafe', 'café', 'roaster', 'espresso'],\n kin: [\n 'coffee',\n 'cafe',\n 'espresso',\n 'latte',\n 'cappuccino',\n 'barista',\n 'beans',\n ],\n broad: ['coffee shop', 'coffee'],\n making: ['barista making coffee'],\n },\n {\n // A caterer is named \"caterer\" and its photos \"catering\", \"buffet\",\n // \"food\": the beta.257 Copper Kettle Catering hero, held to \"caterer\"\n // alone, accepted none of forty hits (AGL-3831).\n match: ['caterer', 'catering', 'cater'],\n kin: [\n 'catering',\n 'caterer',\n 'cater',\n 'buffet',\n 'banquet',\n 'platter',\n 'food',\n 'meal',\n 'cuisine',\n ],\n broad: ['caterer', 'catering buffet'],\n making: ['chef cooking', 'catering chef'],\n // An airline's meal cart is catering too, never a caterer's: the same\n // start's search answered a plane at Düsseldorf tagged \"catering\" first.\n rivals: {\n words: ['airport', 'airplane', 'plane', 'aircraft', 'aviation', 'airline', 'airfield'],\n core: [],\n },\n },\n {\n match: ['barbecue', 'barbeque', 'bbq', 'smokehouse', 'pitmaster'],\n kin: [\n 'barbecue',\n 'barbeque',\n 'bbq',\n 'grill',\n 'grilled',\n 'brisket',\n 'smoked',\n 'smoker',\n 'ribs',\n 'meat',\n ],\n broad: ['barbecue', 'bbq meat'],\n making: ['pitmaster', 'grilling meat'],\n },\n {\n match: ['florist', 'flower', 'floral'],\n kin: ['flower', 'floral', 'bouquet', 'florist', 'bloom', 'blossom'],\n broad: ['florist', 'flower bouquet'],\n making: ['florist arranging flowers'],\n },\n {\n match: [\n 'knit',\n 'knitting',\n 'yarn',\n 'weaving',\n 'weaver',\n 'textile',\n 'textiles',\n 'quilt',\n 'quilting',\n 'sewing',\n ],\n kin: [\n 'knit',\n 'knitting',\n 'yarn',\n 'wool',\n 'weaving',\n 'textile',\n 'fabric',\n 'quilt',\n 'sewing',\n ],\n broad: ['handmade textiles', 'yarn'],\n making: ['knitting', 'weaving loom'],\n },\n {\n match: ['leather', 'leatherwork', 'leathercraft'],\n kin: ['leather', 'wallet', 'bag', 'belt', 'stitching'],\n broad: ['leather craft', 'leather goods'],\n making: ['leather crafting'],\n },\n {\n // A law practice is its people and its office: never a document, a\n // statute or a statue of justice (the beta.259 Hartwell Reyes hero).\n match: ['law', 'legal', 'lawyer', 'attorney', 'solicitor', 'barrister', 'paralegal', 'notary'],\n kin: ['law', 'legal', 'lawyer', 'attorney', 'counsel', 'office', 'client', 'consultation', 'meeting', 'advice', 'mediation'],\n broad: ['lawyer office', 'lawyer client meeting'],\n making: ['lawyer meeting client', 'lawyer office'],\n // Policing is not a family firm's; a statue of justice is a symbol, not its people.\n shun: ['police', 'policeman', 'cop', 'handcuffs', 'prisoner', 'arrest', 'crime', 'criminal', 'justitia', 'themis', 'goddess'],\n shunLead: [\n 'term',\n 'condition',\n 'paragraph',\n 'codex',\n 'regulation',\n 'statute',\n 'document',\n 'contract',\n 'typewriter',\n 'constitution',\n 'certificate',\n ],\n },\n {\n // A strength gym's photos are of lifting and training; a yoga pose on a\n // beach is tagged \"strength\" too (the beta.259 Ironline Strength Studio\n // events).\n match: ['gym', 'fitness', 'strength', 'barbell', 'crossfit', 'weightlifting', 'powerlifting', 'bodybuilding', 'kettlebell'],\n kin: [\n 'gym',\n 'fitness',\n 'workout',\n 'training',\n 'exercise',\n 'barbell',\n 'dumbbell',\n 'weight',\n 'weightlifting',\n 'deadlift',\n 'squat',\n 'kettlebell',\n 'athlete',\n 'strength',\n 'muscle',\n ],\n broad: ['gym', 'weight training'],\n making: ['coach training athlete', 'barbell training'],\n shunLead: [\n 'yoga', 'pilates', 'meditation', 'ballet', 'ballerina', 'dance', 'dancer', 'karate', 'kickboxing', 'boxing', 'boxer', 'beach', 'circus',\n // Another sport's ball, never \"medicine ball\": a basketball court covered a deadlift night (AGL-3864),\n // a cricket ball on a wooden court another (AGL-3856).\n 'basketball', 'football', 'soccer', 'baseball', 'volleyball', 'tennis', 'golf', 'rugby', 'hockey',\n 'cricket', 'squash', 'badminton', 'shuttlecock', 'bowling', 'billiards', 'snooker', 'pool', 'lacrosse', 'softball',\n 'handball', 'pingpong', 'pong',\n ],\n // A training word's other senses (AGL-3856): \"train\" is a railway's, \"lift\"\n // an elevator's or a ski lift's, \"press\" a newspaper's, \"row\" a boat's. The\n // beta.261 Synchronicity Gym's closing band, \"Ready to train\", took a\n // subway train at a station.\n shun: [\n 'railway', 'railroad', 'rail', 'locomotive', 'subway', 'metro', 'tram', 'tramway', 'commuter', 'freight',\n 'transport', 'transportation', 'traffic', 'vehicle', 'bus', 'truck', 'airplane', 'aircraft',\n 'elevator', 'escalator', 'chairlift', 'forklift', 'crane',\n 'newspaper', 'journalism', 'journalist', 'printing',\n 'boat', 'ship', 'canoe', 'kayak', 'sailboat',\n ],\n },\n {\n // A photographer's own photos are of a camera or a shoot; \"film\" is a\n // movie's word too, and \"western film\" a horse (the beta.259 Juniper and\n // Rye Photography \"Film\" card).\n match: ['photographer', 'photography', 'photo', 'photograph'],\n scenes: true,\n maker: ['photographer', 'photographers', 'camera', 'cameras', 'lens', 'lenses', 'tripod', 'dslr', 'slr', 'journalist', 'paparazzi'],\n kin: ['photographer', 'photography', 'photo', 'photograph', 'photoshoot', 'camera', 'lens'],\n broad: ['photographer camera', 'photography'],\n making: ['photographer at work', 'photographer camera'],\n rivals: {\n words: ['movie', 'cinema', 'cinematography', 'filmmaking', 'filming', 'videography', 'video', 'actor', 'projector', 'hollywood', 'western'],\n core: ['camera', 'photograph', 'photography', 'photographer', 'photo', 'photoshoot', 'analog'],\n },\n },\n // The six trades of the 2026-10-25 booth kit (AGL-4065), none of which the\n // table listed: a landscaper and a handyman widened to an office, three\n // motocross businesses took race cars, cyclists, horses and scooters, and a\n // taco trailer that also takes catering requests was read as a caterer.\n {\n // A landscaper's photos are lawns, beds and gardens at work; a zen garden\n // of raked sand is not one (Bluebonnet's irrigation section).\n match: [\n 'landscaping', 'landscaper', 'landscapers', 'lawn', 'lawns', 'xeriscape', 'xeriscaping', 'sod', 'irrigation',\n 'hardscape', 'hardscaping', 'gardening', 'gardener', 'gardeners',\n ],\n kin: [\n 'landscaping', 'landscape', 'landscaper', 'lawn', 'grass', 'garden', 'yard', 'mower', 'mowing', 'lawn mower', 'turf',\n 'hedge', 'shrub', 'mulch', 'sprinkler', 'planting', 'flowerbed', 'flower bed', 'backyard', 'gardening', 'gardener',\n 'xeriscape', 'sod', 'irrigation',\n ],\n broad: ['lawn care', 'landscaping garden', 'garden landscaping'],\n making: ['landscaper mowing lawn', 'gardener planting'],\n shunLead: ['zen', 'sand', 'office', 'business', 'desk', 'laptop', 'meeting', 'golf', 'stadium'],\n },\n {\n // A handyman's photos are tools and repairs; never an architect's house\n // with a family before it, nor a job application (Two Oaks).\n match: ['handyman', 'handymen', 'repairman', 'drywall', 'remodel', 'remodeling', 'remodeler', 'renovation', 'renovations', 'home repair'],\n kin: [\n 'handyman', 'tools', 'tool', 'tool belt', 'toolbox', 'drill', 'hammer', 'screwdriver', 'wrench', 'ladder', 'workshop',\n 'repair', 'home repair', 'carpenter', 'carpentry', 'renovation', 'remodel', 'deck', 'fence', 'door', 'wall', 'plaster',\n 'drywall', 'construction',\n ],\n broad: ['handyman tools', 'home repair', 'carpenter workshop'],\n making: ['handyman at work', 'handyman drilling'],\n shunLead: ['architecture', 'family', 'office', 'application', 'job', 'business', 'meeting', 'desk', 'laptop'],\n },\n {\n // Motocross and the motorcycle world: a dirt bike, never a bicycle, a\n // race car, a horse or a scooter (Rut Runners, Holeshot, Berm & Bolt).\n match: [\n 'motocross', 'motorcycle', 'motorcycles', 'motorbike', 'motorbikes', 'dirtbike', 'dirtbikes', 'dirt bike', 'enduro',\n 'supercross', 'moto', 'mx', 'atv', 'quad bike', 'powersports',\n ],\n kin: [\n 'motocross', 'dirt bike', 'dirtbike', 'enduro', 'supercross', 'motorbike', 'motorcycle', 'mx', 'atv', 'quad bike',\n 'motocross track', 'motocross rider', 'dirt track',\n ],\n near: ['rider', 'riders', 'helmet', 'jump', 'track', 'mud', 'dust', 'berm', 'racing', 'race', 'racer'],\n broad: ['motocross', 'dirt bike', 'motocross race', 'motocross rider'],\n making: ['motorcycle mechanic', 'motorcycle workshop'],\n rivals: {\n words: [\n 'bicycle', 'bicycles', 'cycling', 'cyclist', 'cyclists', 'cycle racing', 'bike race', 'road bike', 'mountain bike',\n 'mtb', 'downhill', 'car', 'cars', 'race car', 'formula', 'kart', 'karting', 'horse', 'horses', 'equestrian', 'scooter',\n 'moped', 'vespa', 'cruiser', 'chopper',\n ],\n core: ['motocross', 'motorcycle', 'motorbike', 'dirt bike', 'dirtbike', 'supercross', 'atv', 'quad bike'],\n },\n shunLead: ['car', 'scooter', 'moped', 'cruiser', 'chopper', 'vespa', 'bicycle', 'cyclist', 'horse', 'highway', 'asphalt', 'traffic'],\n },\n {\n // A parts shop of the motocross world: its parts, tires and riding gear,\n // never a canoe, a delivery or an industrial lathe (Berm & Bolt).\n match: ['parts', 'part', 'aftermarket', 'oem', 'spare parts'],\n of: ['motocross', 'motorcycle', 'motorbike', 'dirtbike', 'dirt bike', 'enduro', 'supercross', 'moto', 'atv', 'quad bike', 'powersports'],\n kin: ['parts', 'part', 'spare part', 'motorcycle parts', 'tire', 'tires', 'wheel', 'chain', 'sprocket', 'brake', 'exhaust', 'riding gear', 'helmet'],\n broad: ['dirt bike parts', 'motorcycle parts', 'motocross gear'],\n making: ['motorcycle mechanic', 'motorcycle workshop'],\n shunLead: ['canoe', 'river', 'delivery', 'food', 'trees', 'office', 'industry', 'industrial', 'factory'],\n },\n {\n // A taco trailer's photos are tacos and the truck, never a hotel's buffet,\n // a chef in whites or raw potatoes (Pit Row Tacos).\n match: ['taco', 'tacos', 'taqueria', 'taco truck', 'taco trailer', 'burrito', 'burritos'],\n kin: [\n 'taco', 'tacos', 'tortilla', 'tortillas', 'salsa', 'mexican', 'mexican food', 'street food', 'food truck', 'taco truck',\n 'griddle', 'burrito', 'quesadilla', 'nachos', 'guacamole', 'carnitas', 'pastor', 'asada',\n ],\n broad: ['tacos', 'street tacos', 'taco truck'],\n making: ['taco truck cooking', 'tacos on the griddle'],\n shunLead: ['buffet', 'hotel', 'fine dining', 'chef', 'indian', 'potato', 'banquet', 'cafeteria', 'wedding'],\n },\n]\n\n/** Lowercase words, letters only, without stopwords. */\nfunction contentWords(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/https?:\\/\\/\\S+|\\S+@\\S+|\\+?\\d[\\d\\s().-]{5,}\\d/g, ' ')\n .replace(/[^a-zÀ-ɏ\\s-]/g, ' ')\n .split(/\\s+/)\n .map((word) => word.replace(/^-+|-+$/g, ''))\n .filter((word) => word.length > 1 && !STOPWORDS.has(word))\n}\n\n/**\n * A word's singular, for matching only: \"bowls\" and \"bowl\", \"vases\" and\n * \"vase\", \"berries\" and \"berry\", \"dishes\" and \"dish\" meet. Both sides of a\n * comparison are reduced the same way, so an odd stem still matches itself.\n */\nexport function aiStockStem(word: string): string {\n const lower = word.toLowerCase()\n if (lower.length > 4 && lower.endsWith('ies')) return `${lower.slice(0, -3)}y`\n if (lower.length > 4 && /(?:ches|shes|sses|xes|zes)$/.test(lower))\n return lower.slice(0, -2)\n if (lower.length > 3 && lower.endsWith('s') && !/(?:ss|us|is)$/.test(lower))\n return lower.slice(0, -1)\n return lower\n}\n\n/** A text's words as stems, in order; a hyphenated word counts as its parts. */\nfunction stemList(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-zÀ-ɏ]+/)\n .filter((word) => word.length > 1)\n .map(aiStockStem)\n}\n\n/** Where a noun phrase ends: punctuation, a preposition, a conjunction. */\nconst CLAUSE_BREAK =\n /[,;:.()]|\\s[-–—]\\s|\\b(?:with|on|in|at|against|beside|next|near|under|over|by|from|for|during|while|atop|inside|across|beneath|through|into|onto|amid|among|and|of|that|which|who)\\b|&/\n\n/** One clause of a business type ({@link businessClauses}). */\ninterface AiStockClause {\n /** The word that opened it: a break's, \"|\" after a verb of making, \"\" for the first. */\n opener: string\n words: string[]\n /**\n * Where the business's own clause was a noun phrase joined to the one before\n * it by \"and\" (AGL-4065): the second, which holds the head (\"dirt bike\n * repair shop\" of \"Motorcycle and dirt bike repair shop\").\n */\n joined?: string[]\n /** Whether it says what a customer may ask of the business: \"takes quote requests\" (AGL-4065). */\n asked?: boolean\n}\n\n/** A clause's words that name the business: no site kind, no filler. */\nconst businessOf = (clause: readonly string[]) =>\n clause.filter((word) => !SITE_KINDS.has(word) && !FILLER.has(word))\n\n/**\n * A business type's clauses, each with the word that opened it. Where the\n * business's own clause is a word or two joined by \"and\" to a noun phrase\n * that ends in a place of business (\"Motorcycle and dirt bike repair shop\",\n * \"Dirt bike and ATV parts shop\"), the two are one clause (AGL-4065): the\n * Holeshot start read its business as \"motorcycle\" and lost the dirt bikes,\n * Berm & Bolt's as \"dirt bike\" and its craft as \"bike\". \"And\" before a verb\n * or a place still ends the clause. A clause that opens with what a customer\n * may ask (\"takes\", \"books\") loses that verb.\n */\nfunction businessClauses(businessType: string): AiStockClause[] {\n const text = businessType.toLowerCase().replace(DOING, ' | ')\n const clauses: AiStockClause[] = []\n const breaker = new RegExp(`${BUSINESS_BREAK.source}|\\\\|`, 'g')\n let at = 0\n let opener = ''\n const push = (raw: string) => {\n const found = contentWords(raw)\n // Never the type's first words: \"Books and coffee\" sells books.\n const asked = opener !== '' && found.length > 1 && TRANSACTION_VERBS.has(found[0] ?? '')\n clauses.push({ opener, words: asked ? found.slice(1) : found, ...(asked ? { asked: true } : {}) })\n }\n for (const match of text.matchAll(breaker)) {\n push(text.slice(at, match.index))\n opener = match[0].trim()\n at = (match.index ?? 0) + match[0].length\n }\n push(text.slice(at))\n const own = clauses.findIndex((clause) => businessOf(clause.words).length > 0)\n const first = clauses[own]\n const next = clauses[own + 1]\n if (first && next && (next.opener === 'and' || next.opener === '&')) {\n const left = businessOf(first.words)\n const right = businessOf(next.words)\n const head = right[right.length - 1] ?? ''\n if (\n left.length <= 2 &&\n left.every((word) => !VENUES.has(word) && !ROLES.has(word)) &&\n right.length >= 2 &&\n VENUES.has(head)\n )\n clauses.splice(own, 2, { opener: first.opener, words: [...first.words, ...next.words], joined: next.words })\n }\n return clauses\n}\n\n/**\n * The kind of business in a few words: the first clause of the business\n * type that says more than what kind of site it is, before a place, an\n * audience or what it makes, filler dropped, its last three words (the head\n * of an English noun phrase is at its end). \"ceramic artist\" from \"a\n * portfolio for a ceramic artist who makes stoneware bowls\"; \"candle shop\"\n * from \"a small-batch candle shop selling hand-poured soy candles online\".\n * A business named by two things joined by \"and\" is its second noun phrase\n * whole: \"dirt bike repair shop\" of \"Motorcycle and dirt bike repair shop\"\n * (AGL-4065).\n */\nexport function aiStockBusinessWords(businessType: string): string {\n for (const { words: clause, joined } of businessClauses(businessType)) {\n const named = businessOf(clause)\n if (joined) return businessOf(joined).slice(-4).join(' ')\n if (named.length) return named.slice(-3).join(' ')\n }\n return ''\n}\n\n/**\n * The business's craft in one word: the last of its words that is not the\n * place it is done in nor the person doing it, singular — \"ceramic\" from\n * \"ceramics studio\" or \"ceramic artist\", \"yoga\" from \"yoga studio\". Empty\n * when the business is only a place (\"a shop\").\n */\nexport function aiStockCraftWords(business: string): string {\n const named = business\n .split(/\\s+/)\n .filter(\n (word) =>\n word &&\n !VENUES.has(word) &&\n !ROLES.has(word) &&\n !FILLER.has(word) &&\n !SITE_KINDS.has(word),\n )\n const craft = named[named.length - 1]\n return craft ? aiStockStem(craft) : ''\n}\n\n/** What a site's photos are searched and judged by (AGL-3660). */\nexport interface AiStockSiteTerms {\n /** The kind of business, in a few words: \"ceramic artist\". */\n business: string\n /** Its craft, one singular word: \"ceramic\". */\n craft: string\n /**\n * The stems a photo of the site's world names: the business's own words,\n * what the things it makes are made of, and the craft's kin. Empty for a\n * site whose words name no world (a type left blank), and then no hit is\n * held to it.\n */\n domain: string[]\n /**\n * The business's own world (AGL-4065): the listed crafts its own clause\n * names, their names and kin, and its own words where no craft covers\n * them, as stems and stem pairs (\"dirt bike\"). What a hero's first tag and a\n * broad search's hit name. Its whole domain where no craft is listed.\n */\n lead?: string[]\n /**\n * The world a trade serves, as its type names it, where the craft is the\n * trade (\"dirt bike\" for a parts shop's craft \"part\", AGL-4065): what its\n * pictures are qualified by in place of the craft.\n */\n leadWord?: string\n /** The searches for the site's world itself, broadest last. */\n broad: string[]\n /** The searches for its maker at work, for a story of the craft (AGL-3660); empty for a craft not listed. */\n making: string[]\n /** Whether a picture naming people at a moment is searched by its scene ({@link aiStockScene}, AGL-3856). */\n scenes?: boolean\n /** Every stem of the business type or brief: what lets a sensitive topic in ({@link SENSITIVE_TOPICS}). */\n named: string[]\n /** Rival crafts' words, each with the words that must then be named too ({@link CRAFT_KIN}). */\n rivals: Array<{ words: string[]; core: string[] }>\n /**\n * The stems a photo of the craft ITSELF names, one of which a hero and a\n * product's fallbacks must name (AGL-3660): the craft and, for a listed\n * craft, its own names (\"soap\", \"soapmaker\", \"skincare\"). Empty where the\n * site names no craft.\n */\n core: string[]\n /** Words no photo of the site's craft carries unless the slot or the brief names them ({@link CRAFT_KIN}). */\n shun: string[]\n /** Words no photo of the site's craft is OF, among its first tags, unless the slot or the brief names them ({@link CRAFT_KIN}). */\n shunLead: string[]\n /** Whether the site is for adults alone, so no photo of a child is placed on it ({@link aiStockAdultsOnly}, AGL-3856). */\n adults?: boolean\n /** Where the site's own words set its pictures ({@link aiStockSetting}): a record's moment is set there where its words say nowhere (AGL-3856). */\n setting?: string\n /** The craft's maker and tools as stems, which a record of its work never leads with ({@link CRAFT_KIN}, AGL-3856). */\n maker?: string[]\n /**\n * What a craft whose pictures are people at a moment shows wherever a page\n * would show its maker ({@link aiStockWorkScenes}, AGL-3942): the scenes\n * its site's own words name, set where the site is.\n */\n work?: AiStockScene[]\n}\n\n/** A word or phrase of a group's list, as stems: what a business type and a hit are read for. */\nconst groupTerm = (word: string) => stemPhrase(word)\n\n/**\n * The site's terms, read from its business type.\n *\n * Two worlds are read (AGL-4065). Its DOMAIN is everything its words name\n * of its world, what a picture of a thing is held to. Its LEAD is the\n * business's own world: the listed crafts its own clause names (and the\n * craft's), their names and kin, and the clause's own words where no craft\n * covers them, never a word that names a world only beside another (\"race\",\n * \"team\") nor what a customer is asked to do. A hero's first tag and a broad\n * search's hit name the lead: the Rut Runners heroes, held to every word of\n * \"Amateur motocross race team: rider profiles, race schedule…\", took race\n * cars because \"race car\" named \"race\". Of the crafts its words list, the one\n * named first leads (a taco trailer that \"takes catering requests\" is a taco\n * trailer), and a craft named only in what a customer may ask for gives the\n * site no searches of its own.\n */\nexport function aiStockSiteTerms(businessType: string): AiStockSiteTerms {\n let business = aiStockBusinessWords(businessType)\n let craft = aiStockCraftWords(business)\n const domain = new Set<string>()\n /** The things it makes, by their head nouns. */\n const made = new Set<string>()\n /** Stems and stem pairs of every clause that names its world, and of those that only say what it is asked for. */\n const said = new Set<string>()\n const asked = new Set<string>()\n /** The business's own clause, as stems and stem pairs: what its lead is read from. */\n let own: string[] = []\n let ownSeen = false\n /** The last word of the first clause that names the world: \"soap\" of \"for handmade cold-process soap\". */\n let firstWorld = ''\n let named = false\n let making = false\n let place = false\n for (const { opener, words: clause, asked: isAsked } of businessClauses(businessType)) {\n if (opener === '|') making = true\n // Where it is, and who it is for, are not its world — once something has named it.\n if (named && PLACE_OR_AUDIENCE.test(opener)) {\n making = false\n place = true\n continue\n }\n // A comma goes on naming the place (AGL-3856): \"Ohio\" of \"in Columbus,\n // Ohio\" and \"North Carolina\" of \"in Asheville, North Carolina\" are not\n // the business's world.\n if (place && opener === ',') continue\n place = false\n const kept = businessOf(clause).filter(\n (word) => !VENUES.has(word) && !ROLES.has(word),\n )\n if (!ownSeen && businessOf(clause).length) {\n ownSeen = true\n own = kept.filter((word) => !LEAD_GENERIC.has(word))\n }\n if (kept.length) named = true\n // What it makes names its world by what the things are made of, never\n // the things: \"stoneware\" of \"stoneware bowls\", \"soy\" of \"soy candles\".\n // A bowl is not a ceramic world; a robin's food bowl is not pottery.\n // A set or a gift is never a world: \"gift\" of \"gift sets\" is not one.\n const world = (making ? kept.slice(0, -1) : kept).filter(\n (word) => !WRAPPERS.has(word),\n )\n for (const word of world)\n for (const stem of stemList(word)) domain.add(stem)\n for (const term of termsOf([kept.join(' ')])) (isAsked ? asked : said).add(term)\n const last = world[world.length - 1]\n if (!firstWorld && last) firstWorld = aiStockStem(last)\n if (making)\n for (const word of kept.slice(-1))\n for (const stem of stemList(word)) made.add(stem)\n }\n // A business named only by what it sells (\"a shop selling pottery\") is of that world.\n if (!domain.size) for (const stem of made) domain.add(stem)\n const typeStems = stemList(businessType)\n const typeTerms = withPairs(typeStems)\n /** Where a word or a two-word name first stands in the business type; the end where it stands nowhere. */\n const positionOf = (term: string) => {\n const [head, tail] = term.split(' ') as [string, string | undefined]\n const index = typeStems.findIndex((stem, at) => stem === head && (tail === undefined || typeStems[at + 1] === tail))\n return index >= 0 ? index : Number.MAX_SAFE_INTEGER\n }\n /** Where a group's list first meets the business type, its words in order. */\n const at = (list: readonly string[]) => Math.min(...list.map((word) => positionOf(groupTerm(word))))\n const names = (word: string) => {\n const term = groupTerm(word)\n return term.includes(' ') ? said.has(term) || asked.has(term) : domain.has(term) || made.has(term) || term === craft\n }\n const found = CRAFT_KIN.map((group, index) => ({ group, index }))\n .filter(({ group }) => group.match.some(names) && (!group.of || group.of.some(names)))\n .sort(\n (a, b) =>\n Number(Boolean(b.group.of)) - Number(Boolean(a.group.of)) || at(a.group.match) - at(b.group.match) || a.index - b.index,\n )\n const groups = found.map(({ group }) => group)\n // A craft named only in what the business is asked for (\"takes catering\n // requests\") lends its kin and its refusals, never its searches (AGL-4065).\n const major = groups.filter((group) => group.match.some((word) => said.has(groupTerm(word)) || made.has(groupTerm(word))))\n // A business that is only a place (\"an online shop for handmade\n // cold-process soap\") takes its craft from what it is for: the Saltmarsh\n // Soap Co start (2026-10-10) read its craft as nothing, so its hero searched\n // \"shop\" (a florist's bouquet) and no product was held to soap.\n if (!craft) {\n const listed = major[0]?.match\n .map(groupTerm)\n .find((stem) => !stem.includes(' ') && (domain.has(stem) || made.has(stem)))\n craft = listed || firstWorld || [...made][0] || ''\n if (craft && !stemList(business).includes(craft))\n business = `${craft} ${business}`.trim()\n } else if (major[0] && !major.some((group) => group.match.some((word) => groupTerm(word) === craft))) {\n // A word the table does not list, beside a craft it does, says what kind\n // of that craft it is (AGL-3856): \"wedding\" of \"a wedding and portrait\n // photographer\" is a photographer's subject, never a craft to search by.\n craft =\n major[0].match.map(groupTerm).find((stem) => !stem.includes(' ') && (domain.has(stem) || made.has(stem))) ?? craft\n }\n if (craft) domain.add(craft)\n const craftGroup = major.find((group) => group.match.some((word) => groupTerm(word) === craft))\n const broad: string[] = []\n const makingSearches: string[] = []\n const rivals: Array<{ words: string[]; core: string[] }> = []\n const core = new Set<string>(craft ? [craft] : [])\n const shun = new Set<string>()\n const shunLead = new Set<string>()\n for (const group of groups) {\n for (const word of group.shun ?? []) shun.add(groupTerm(word))\n for (const word of group.shunLead ?? []) shunLead.add(groupTerm(word))\n for (const word of [...group.kin, ...(group.near ?? [])]) domain.add(groupTerm(word))\n if (group.rivals)\n rivals.push({\n words: group.rivals.words.map(groupTerm),\n core: group.rivals.core.map(groupTerm),\n })\n }\n for (const group of major) {\n for (const word of group.match) core.add(groupTerm(word))\n broad.push(...group.broad)\n makingSearches.push(...group.making)\n }\n // A two-word name of a listed world names it whole: \"dirt bike\", never\n // \"bike\" (a bicycle's) where the type says it nowhere else (AGL-4065).\n for (const group of groups)\n for (const word of group.match) {\n const term = groupTerm(word)\n if (!term.includes(' ') || !typeTerms.includes(term)) continue\n domain.add(term)\n const [head, tail] = term.split(' ') as [string, string]\n const alone = (stem: string) =>\n typeStems.some((found, index) => found === stem && !(found === head ? typeStems[index + 1] === tail : typeStems[index - 1] === head))\n for (const stem of [head, tail]) if (!alone(stem)) domain.delete(stem)\n }\n // What a customer is asked to do is never a world (AGL-4065).\n for (const stem of TRANSACTION_STEMS) domain.delete(stem)\n // The business's own world: the crafts its own clause names, and the craft's.\n const ownTerms = new Set(termsOf([own.join(' ')]))\n const leading = major.filter((group) => group === craftGroup || group.match.some((word) => ownTerms.has(groupTerm(word))))\n const lead = new Set<string>()\n for (const group of leading) for (const word of [...group.match, ...group.kin]) lead.add(groupTerm(word))\n if (leading.length)\n for (const word of own)\n for (const stem of stemList(word))\n if (![...lead].some((term) => term === stem || (term.includes(' ') && term.split(' ').includes(stem) && ownTerms.has(term))))\n lead.add(stem)\n // A trade's world, named by the world it serves: \"dirt bike\" for a dirt bike parts shop.\n const served = craftGroup?.of\n ? groups\n .filter((group) => group !== craftGroup)\n .flatMap((group) => group.match)\n .filter((word) => typeTerms.includes(groupTerm(word)))\n .sort((a, b) => positionOf(groupTerm(a)) - positionOf(groupTerm(b)))[0]\n : undefined\n if (!broad.length) broad.push(business, craft)\n // A part or gear names no world on its own: a dirt bike shop's part, never a canoe's (AGL-4065).\n const ofAWorld = (term: string) => term.length > 1 && !term.split(' ').every((word) => WORLD_OBJECTS.has(word))\n return {\n business,\n craft,\n domain: [...domain].filter((stem) => stem.length > 1),\n lead: leading.length ? [...lead].filter(ofAWorld) : [...domain].filter((stem) => stem.length > 1),\n ...(served ? { leadWord: served } : {}),\n broad: [...new Set(broad.map((query) => query.trim()).filter(Boolean))],\n making: [...new Set(makingSearches)],\n ...(groups.some((group) => group.scenes) ? { scenes: true } : {}),\n ...(groups.some((group) => group.maker?.length)\n ? { maker: [...new Set(groups.flatMap((group) => group.maker ?? []).map(aiStockStem))] }\n : {}),\n named: [...new Set(typeTerms)],\n rivals,\n core: [...core].filter((term) => !craftGroup?.of || ofAWorld(term)),\n shun: [...shun],\n shunLead: [...shunLead],\n }\n}\n\n/**\n * Words that say a picture is one of a set, never what it shows (AGL-3923):\n * the beta.266 Mexicano portfolio's gallery was \"Project one\" to \"Project\n * four\", and searched \"project\" (students at a whiteboard), \"project four\"\n * (lavender) and \"four\" (a running track's lane numbers).\n */\nconst PLACEHOLDER_SUBJECTS = words(\n 'project projects piece pieces item items example examples sample samples entry entries untitled work works ' +\n 'selected recent latest ' +\n 'four five six seven eight nine ten first second third fourth fifth sixth seventh eighth ninth tenth ' +\n // When a thing is, never the thing (AGL-4065): \"Upcoming race 1 (details to be added)\" searched \"upcoming race\".\n 'upcoming past next previous future',\n)\n\n/** A phrase's content words without its filler; all filler, and nothing is left. */\nfunction subjectOf(list: readonly string[]): string[] {\n return list.filter(\n (word) => !FILLER.has(word) && !PLACEHOLDER_SUBJECTS.has(word) && !GENERIC_OBJECTS.has(word) && !SENTENCE_WORDS.has(word),\n )\n}\n\n/**\n * A picture's subject in a few words (AGL-3660): the noun phrase its alt\n * text opens with — its first clause holding more than filler, cut where a\n * preposition starts the setting, filler dropped, its last three words (the\n * head noun is the last) — else its section's name. A word or two joined by\n * \"and\" to a longer noun phrase only modify its head: the subject of \"Potato\n * and egg breakfast taco\" is \"egg breakfast taco\", never \"potato\" (AGL-4065).\n */\nexport function aiStockSubjectWords(alt: string, sectionName: string): string {\n // \"Hand-poured\", \"by hand\" and \"hands\" say how it was made, never what it shows.\n const text = withoutHands(alt)\n const breaker = new RegExp(CLAUSE_BREAK.source, 'g')\n const clauses: Array<{ words: string[]; then: string }> = []\n let at = 0\n for (const match of text.matchAll(breaker)) {\n clauses.push({ words: subjectOf(contentWords(text.slice(at, match.index))), then: match[0].trim() })\n at = (match.index ?? 0) + match[0].length\n }\n clauses.push({ words: subjectOf(contentWords(text.slice(at))), then: '' })\n for (const [index, { words: found, then }] of clauses.entries()) {\n if (!found.length) continue\n // Never where the second is one thing in a wrapper: \"Soap and Lotion Gift Set\" is a gift of both.\n const next = clauses[index + 1]?.words ?? []\n const things = next.filter((word) => !WRAPPERS.has(word))\n if ((then === 'and' || then === '&') && found.length <= 2 && things.length >= 2) return next.slice(-3).join(' ')\n return found.slice(-3).join(' ')\n }\n return subjectOf(contentWords(withoutHands(sectionName))).slice(0, 2).join(' ')\n}\n\n/**\n * The thing a subject shows, one singular word: its last word that is not\n * a set or a wrapper of it — \"bowl\" from \"nesting bowl set\", \"candle\" from\n * \"candle gift set\", \"vase\" from \"bud vase\". Its last word when every word\n * is one (\"gift set\").\n */\nexport function aiStockObjectWord(subject: string): string {\n const list = subject.split(/\\s+/).filter(Boolean)\n const object =\n [...list].reverse().find((word) => !WRAPPERS.has(word)) ??\n list[list.length - 1] ??\n ''\n return object ? aiStockStem(object) : ''\n}\n\nconst clip = (query: string) =>\n query.replace(/\\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUERY_MAX_CHARS).trim()\n\n/** The frame's orientation: a wide frame wants a landscape photo, a tall one a portrait. */\nexport function aiStockOrientation(aspect: number): StockPhotoOrientation {\n if (aspect > 1.15) return 'horizontal'\n if (aspect < 0.87) return 'vertical'\n return 'any'\n}\n\n/**\n * One search a slot tries. A `broad` one asks for the site's world and\n * takes any hit of it; any other picture of a thing takes only a hit naming\n * the thing.\n */\nexport interface AiStockSearch extends StockPhotoSearchRequest {\n broad?: boolean\n /** The words its hits are scored by, where they are not the slot's own subject (a product's searches, AGL-3676). */\n subject?: string\n /** A word every hit must name: a product's photo names the shop's category (AGL-3676). */\n requires?: string\n /**\n * Words of which a hit must name ONE, `requires` among them (AGL-3660): a\n * shop's category or the slot's own word of its world, so a soap shop's\n * body lotion is held to \"lotion\", never to \"soap\".\n */\n category?: readonly string[]\n /** The thing every hit must name, where it is not the subject's own: a product's head noun (AGL-3660). */\n object?: string\n /** Phrases that name the object where its own word is not enough: \"wax melt\" ({@link OBJECT_KIN}). */\n kin?: readonly string[]\n /** Whether the object must be among the hit's first tags, what the photo is OF (AGL-3660). */\n lead?: boolean\n /** Whether the hit's first tags must name the site's world, where the object need not lead (AGL-3660). */\n leadWorld?: boolean\n /**\n * Whether the hit's FIRST tag must name the site's world (AGL-3760): what\n * the photo is of, most of all. A hero is the site's opening picture; the\n * copper-fern-candle-co start (beta.246) took a latte with a candle behind\n * it, its tags \"coffee, mobile wallpaper 4k, latte art, …, candle\".\n */\n first?: boolean\n /** Phrases (as stems) of which one must be among the hit's first tags: a borrowed photo is OF the product's category (AGL-3660). */\n leadAny?: readonly string[]\n /** Whether its hits must name its object, whatever the slot's role: a scene's people (AGL-3856). */\n strict?: boolean\n /** Words its hits never carry, whatever the brief names: a bride in a family session ({@link aiStockScene}). */\n refuse?: readonly string[]\n /** Stems of which every hit names one, whatever else it names: a scene's people, never roses alone ({@link aiStockScene}). */\n needs?: readonly string[]\n /** Stems its own words name, which let a topic in as the brief's do: a family session's children ({@link aiStockScene}). */\n allow?: readonly string[]\n /** Stems no hit's first tags carry: a photographer or a camera on a portfolio's record, a toy frog ({@link aiStockRecordScene}, AGL-3856). */\n refuseLead?: readonly string[]\n /** Whether its hits are held to no world of the site's: a portfolio's record is of its subject, never of the craft (AGL-3856). */\n worldless?: boolean\n /** Stems of the places its hits are not set in, which none of their first tags name: a Blue Ridge couple's beach ({@link aiStockSettingAway}, AGL-3942). */\n away?: readonly string[]\n /** Whether it fills a product: no room, no scene, no fragrance bottle ({@link PRODUCT_SCENES}, AGL-3660). */\n product?: boolean\n /** Words its hits never carry unless the slot or the brief names them ({@link AiStockSiteTerms.shun}). */\n shun?: readonly string[]\n /**\n * How sure a product's search is (AGL-3660). Absent: its own photo, the\n * head noun among the first tags. `borrow`: a photo OF its category, which\n * may repeat one the job already shows. `weak`: the head noun anywhere, or\n * the category anywhere — taken only once nothing surer is left.\n */\n tier?: 'borrow' | 'weak'\n}\n\n/** A slot's part of a page, where it asks for more than its role: a collection tile or a story of the craft (AGL-3660). */\nexport type AiStockSlotPart = 'collection' | 'story'\n\n/**\n * A slot's part (AGL-3660): a tile of a collections band is product-like,\n * held to the shop's category and its own object; a picture of a story of\n * the craft, or of a thing made by hand, shows the maker at work.\n */\nexport function aiStockSlotPart(\n slot: Pick<AiLayoutPictureSlot, 'role' | 'alt'>,\n sectionName: string,\n): AiStockSlotPart | undefined {\n if (slot.role === 'hero') return undefined\n if (slot.role === 'gallery' && aiStorefrontSays('collections', sectionName))\n return 'collection'\n if (\n aiStorefrontSays('story', sectionName) ||\n saysMadeByHand(slot.alt) ||\n saysMadeByHand(sectionName)\n )\n return 'story'\n return undefined\n}\n\n/**\n * The people a picture of a moment shows (AGL-3856): what its words name, the\n * search that asks for them, the words a photo of them leads with, those of\n * which it must name one anywhere, and what it never carries unless the\n * words name it. A family session is never a bride.\n */\nconst PEOPLE_SCENES: ReadonlyArray<{\n words: readonly string[]\n query: (named: ReadonlySet<string>) => string\n subject: string\n lead: readonly string[]\n people: readonly string[]\n shun: readonly string[]\n}> = [\n {\n words: ['family', 'families', 'kid', 'kids', 'child', 'children', 'newborn', 'baby', 'parent', 'parents', 'mother', 'father'],\n query: () => 'family',\n subject: 'family',\n lead: ['family', 'families', 'child', 'children', 'kid', 'kids', 'mother', 'father', 'parents', 'mom', 'dad', 'daughter', 'son', 'baby', 'toddler'],\n people: ['family', 'child', 'children', 'kid', 'kids', 'mother', 'father', 'parent', 'parents', 'daughter', 'son', 'baby', 'toddler', 'mom', 'dad'],\n shun: ['bride', 'groom', 'bridal', 'wedding', 'newlywed', 'newlyweds', 'marriage'],\n },\n {\n words: [\n 'wedding', 'weddings', 'elopement', 'elopements', 'elope', 'eloping', 'bride', 'brides', 'bridal', 'groom', 'engagement',\n 'engaged', 'couple', 'couples', 'newlywed', 'newlyweds', 'honeymoon', 'ceremony', 'ceremonies', 'reception', 'receptions', 'vows',\n ],\n query: (named) => (['wedding', 'weddings', 'bride', 'bridal', 'groom'].some((word) => named.has(word)) ? 'wedding couple' : 'couple'),\n subject: 'couple',\n lead: ['couple', 'couples', 'bride', 'groom', 'wedding', 'newlyweds', 'lovers', 'elopement', 'bride and groom'],\n people: ['couple', 'bride', 'groom', 'newlywed', 'newlyweds', 'lovers', 'husband', 'wife', 'man', 'woman'],\n shun: [],\n },\n]\n\n/**\n * A portrait session (AGL-3856), read for a record's cover alone: \"Milestone\n * Portraits\" is a person's portrait, never a cat's. A page's \"portrait of the\n * photographer\" keeps its own words.\n */\nconst PORTRAIT_SCENE: (typeof PEOPLE_SCENES)[number] = {\n words: ['portrait', 'portraits', 'headshot', 'headshots'],\n query: () => 'portrait',\n subject: 'portrait',\n lead: ['portrait', 'woman', 'man', 'couple', 'person', 'people'],\n people: ['woman', 'women', 'man', 'men', 'couple', 'person', 'people', 'bride', 'groom', 'mother', 'father', 'family'],\n shun: [],\n}\n\n/**\n * Words a photo of a child is tagged with (AGL-3856), as stems. Pixabay tags\n * a schoolgirl \"girl\", \"schoolgirl\" or \"school girl\" far more often than\n * \"child\", so a site for adults that names a school let children in: the\n * beta.264 Brightpath Adult Learning Center's \"Meet your teachers\" showed a\n * teen graduate, a schoolgirl and kids.\n */\nconst CHILD_STEMS = [\n ...new Set(\n (\n 'child children childhood kid kids baby babies toddler toddlers infant infants newborn boy boys girl girls ' +\n 'schoolgirl schoolgirls schoolboy schoolboys schoolchild schoolchildren schoolkid schoolkids pupil pupils ' +\n 'teen teens teenager teenagers teenage preteen youth kindergarten preschool'\n )\n .split(' ')\n .map(aiStockStem),\n ),\n]\n\n/** Words of which a photo of one of the business's people names one: an adult, at work or in their role. */\nconst ADULT_PEOPLE_STEMS = [\n ...new Set(\n (\n 'man men woman women adult adults businessman businesswoman businessmen professional ' +\n 'professionals staff worker workers employee employees team colleague colleagues coworker coworkers ' +\n 'teacher teachers instructor instructors tutor tutors lecturer professor educator faculty coach coaches ' +\n 'trainer trainers chef chefs cook baker barista doctor doctors dentist nurse nurses hygienist therapist ' +\n 'physician stylist hairdresser barber artist musician photographer entrepreneur founder owner manager ' +\n 'leader speaker volunteer volunteers mechanic electrician plumber carpenter craftsman technician'\n )\n .split(' ')\n .map(aiStockStem),\n ),\n]\n\n/**\n * The roles a list of the business's people names (AGL-3856): the words that\n * name each, the words a photo of someone in it is tagged with, and the word\n * a search for them leads with, where the libraries know one. A teacher is\n * shown teaching, a coach coaching, never a student or a whistle. A team or\n * a staff is anyone at work: its words are preferred, never required.\n *\n * A role whose photos are often of someone merely tagged with it carries the\n * words of it being done, one of which the photo's first tags must name\n * (`scene`), and the words of something else being done, which none of them\n * may (`refuse`): the beta.265 Northgate Adult Learning Center's \"Meet your\n * teachers\" placed a woman painting at an easel (\"artist, teacher of\n * drawing\"), a model in a traditional dress (\"woman, model, show, teacher\")\n * and an elderly man's portrait (\"teacher, professor, man, senior\").\n */\nconst PEOPLE_ROLES: ReadonlyArray<{\n words: readonly string[]\n kin: readonly string[]\n query?: string\n loose?: boolean\n scene?: readonly string[]\n refuse?: readonly string[]\n}> = [\n {\n words: ['instructor', 'teacher', 'tutor', 'educator', 'faculty', 'professor', 'lecturer', 'mentor'],\n kin: ['teacher', 'instructor', 'tutor', 'educator', 'professor', 'lecturer', 'teaching', 'lecture', 'faculty'],\n query: 'teacher',\n scene: [\n 'teaching', 'teach', 'classroom', 'class', 'lecture', 'lesson', 'lessons', 'tutor', 'tutoring', 'blackboard', 'chalkboard',\n 'whiteboard', 'board', 'seminar', 'student', 'students', 'learner', 'learners', 'presentation',\n ],\n refuse: [\n 'model', 'modeling', 'fashion', 'pose', 'posing', 'beauty', 'glamour', 'cosplay', 'artist', 'artists', 'painter',\n 'painting', 'paint', 'easel', 'canvas', 'draw', 'draws', 'drawing', 'calligraphy',\n ],\n },\n { words: ['coach', 'trainer'], kin: ['coach', 'coaching', 'trainer', 'instructor'], query: 'coach' },\n { words: ['chef', 'cook', 'baker'], kin: ['chef', 'cook', 'cooking', 'baker', 'baking'], query: 'chef' },\n { words: ['stylist', 'barber', 'hairdresser', 'colorist'], kin: ['stylist', 'barber', 'hairdresser', 'hairstylist', 'haircut'], query: 'hairdresser' },\n {\n words: ['doctor', 'dentist', 'hygienist', 'nurse', 'therapist', 'practitioner', 'physician'],\n kin: ['doctor', 'dentist', 'hygienist', 'nurse', 'therapist', 'physician', 'medical'],\n },\n {\n words: ['staff', 'team', 'crew', 'member', 'manager', 'founder', 'owner', 'partner', 'associate', 'employee'],\n kin: ['staff', 'team', 'worker', 'employee', 'colleague', 'coworker', 'professional', 'businessman', 'businesswoman', 'owner', 'manager'],\n loose: true,\n },\n]\n\n/** A role {@link aiStockPeopleRole} reads: its kin's stems, its search word, and whether a photo must name it. */\nexport interface AiStockPeopleRole {\n kin: string[]\n query: string\n required: boolean\n /** Stems of the role being done, one of which a photo's first tags name ({@link AI_STOCK_ROLE_TAGS_READ}). */\n scene?: string[]\n /** Stems of something else being done, which none of a photo's first tags name. */\n refuse?: string[]\n}\n\n/** How many of a photo's first tags show a role being done: \"teacher, presentation, education, man, students\" (AGL-3856). */\nexport const AI_STOCK_ROLE_TAGS_READ = 6\n\n/**\n * The role a person's words say, else the first of the other texts that names\n * one (their list's name): \"Online learning coach\" of the \"Instructors\" list\n * is a coach. `null` where none names a listed role.\n */\nexport function aiStockPeopleRole(...texts: readonly string[]): AiStockPeopleRole | null {\n for (const text of texts) {\n const named = new Set(stemList(text))\n const role = PEOPLE_ROLES.find((entry) => entry.words.some((word) => named.has(aiStockStem(word))))\n if (role)\n return {\n kin: [...new Set(role.kin.map(aiStockStem))],\n query: role.query ?? '',\n required: !role.loose,\n ...(role.scene ? { scene: [...new Set(role.scene.map(aiStockStem))] } : {}),\n ...(role.refuse ? { refuse: [...new Set(role.refuse.map(aiStockStem))] } : {}),\n }\n }\n return null\n}\n\n/** A role's refusals, less what the person's own words name: a \"Drawing instructor\" may be drawing. */\nexport function aiStockRoleRefusals(role: Pick<AiStockPeopleRole, 'refuse'>, words: string): string[] {\n const named = new Set(stemList(words))\n return (role.refuse ?? []).filter((stem) => !named.has(stem))\n}\n\n/** A site's audience in its own words, when it is adults: \"Adults finishing a high school diploma\". */\nconst ADULT_AUDIENCE = /\\b(?:adults?|grown[- ]?ups?|seniors?|retirees?|older (?:adults|people)|professionals|employees|workforce|job ?seekers)\\b/i\n/** Words that say a site is for children too, whatever else it says. */\nconst YOUNG_AUDIENCE =\n /\\b(?:kids?|child(?:ren)?|teens?|teenagers?|youth|young people|famil(?:y|ies)|boys?|girls?|bab(?:y|ies)|toddlers?|k-12|elementary|middle school|preschool|kindergarten|pupils?)\\b/i\n\n/**\n * Whether a site is for adults alone (AGL-3856), as its audience, its name\n * or its business type says: \"Adults finishing a high school diploma\",\n * \"Brightpath Adult Learning Center\". Then no photo of a child is placed\n * anywhere on it, whatever else its words name (\"school\").\n */\nexport function aiStockAdultsOnly(texts: ReadonlyArray<string | undefined>): boolean {\n const said = texts.filter(Boolean).join(' . ')\n return ADULT_AUDIENCE.test(said) && !YOUNG_AUDIENCE.test(said)\n}\n\n/**\n * Words a photo by the sea is tagged with: never one set in the mountains, a\n * forest or a city (AGL-3942). Never \"palm\" or \"wave\", a hand's as often.\n */\nconst SEASIDE = [\n 'beach', 'beaches', 'sea', 'seaside', 'seashore', 'ocean', 'coast', 'coastal', 'shore', 'shoreline', 'surf', 'waves',\n 'caribbean', 'tropical', 'island', 'lagoon', 'bay', 'pier',\n]\n/** Words a photo of a desert is tagged with. */\nconst DESERT = ['desert', 'dune', 'dunes', 'cactus', 'sahara']\n/** Words a photo of a city is tagged with. */\nconst CITYSCAPE = ['city', 'urban', 'downtown', 'street', 'skyline', 'skyscraper', 'skyscrapers', 'subway', 'metro']\n\n/**\n * Where a picture of a moment is set, by the words that name it, the word a\n * search and a photo say it with, whether it is a place a photo can show on\n * its own (a landscape, not a season), and the words of the places it is\n * not, which none of a photo's first tags may name (AGL-3942): the beta.267\n * Copper Hollow Film & Portrait galleries, a Blue Ridge photographer's,\n * showed two couples on a beach, tagged \"beach, couple, nature, mountain\"\n * and \"romantic wedding couple, the beach\".\n */\nconst SCENE_SETTINGS: ReadonlyArray<{ words: readonly string[]; said: string; landscape?: boolean; away?: readonly string[] }> = [\n {\n words: ['mountain', 'mountains', 'ridgetop', 'ridge', 'summit', 'peak', 'alpine', 'overlook', 'parkway'],\n said: 'mountains',\n landscape: true,\n away: [...SEASIDE, ...DESERT, ...CITYSCAPE],\n },\n { words: ['fall', 'autumn', 'foliage'], said: 'autumn', away: ['winter', 'snow', 'snowy', 'spring', 'blossom'] },\n { words: ['winter', 'snow', 'snowy'], said: 'winter', away: [...SEASIDE, 'summer', 'tropical'] },\n { words: ['beach', 'coast', 'seaside', 'shore', 'ocean'], said: 'beach', landscape: true, away: ['snow', 'snowy', 'ski', 'skiing', ...CITYSCAPE] },\n { words: ['forest', 'woods', 'woodland'], said: 'forest', landscape: true, away: [...SEASIDE, ...DESERT, ...CITYSCAPE] },\n { words: ['spring', 'blossom', 'blossoms'], said: 'spring', away: ['winter', 'snow', 'snowy', 'autumn', 'fall'] },\n { words: ['city', 'urban', 'downtown'], said: 'city', landscape: true, away: [...SEASIDE, ...DESERT] },\n]\n\n/** The stems of the places a setting is not ({@link SCENE_SETTINGS}); none for no setting. */\nexport function aiStockSettingAway(setting: string): string[] {\n const entry = SCENE_SETTINGS.find((candidate) => candidate.said === setting)\n return entry?.away ? [...new Set(entry.away.map(aiStockStem))] : []\n}\n\n/** What a picture of a moment shows ({@link aiStockScene}). */\nexport interface AiStockScene {\n /** The searches that ask for it, the people and their setting first. */\n queries: string[]\n /** The words its photo is scored by: the people, and the setting. */\n subject: string\n /** The thing a photo of it leads with, and its kin. */\n object: string\n lead: string[]\n /** Words of which a photo of it names one. */\n people: string[]\n shun: string[]\n /** The stems of its words, which let in what they name: a family's children. */\n named: string[]\n /** Stems of the places it is not set in, which none of a photo's first tags name ({@link aiStockSettingAway}, AGL-3942). */\n away: string[]\n}\n\n/**\n * The scene a picture's words name (AGL-3856): the people at a moment, and\n * where — \"Ridgetop Elopement\" a couple in the mountains, \"Mountain Wedding\n * Day\" a wedding couple in the mountains, \"Family Session in the Fall\" a\n * family in autumn — read from every word, never only the first clause.\n * `null` where it names no people.\n */\nexport function aiStockScene(text: string, siteSetting = ''): AiStockScene | null {\n const named = sceneWords(text)\n const scene = PEOPLE_SCENES.find((entry) => entry.words.some((word) => named.has(word)))\n if (!scene) return null\n const setting = aiStockSetting(text)\n const query = scene.query(named)\n return {\n queries: [...new Set([setting ? `${query} ${setting}` : '', query].filter(Boolean))],\n subject: [scene.subject, setting].filter(Boolean).join(' '),\n object: scene.subject,\n lead: scene.lead.map((phrase) => stemList(phrase).join(' ')),\n people: scene.people.map(aiStockStem),\n shun: scene.shun.filter((word) => !named.has(word)).map(aiStockStem),\n named: [...new Set(stemList(text))],\n // Searched where its own words set it; never shown anywhere the site is not.\n away: aiStockSettingAway(setting || siteSetting),\n }\n}\n\n/** A text's lowercase words, letters only. */\nconst sceneWords = (text: string) =>\n new Set(\n text\n .toLowerCase()\n .split(/[^a-zÀ-ɏ]+/)\n .filter(Boolean),\n )\n\n/** Where a text's words set a picture ({@link SCENE_SETTINGS}): \"mountains\" of \"Couples planning mountain weddings\"; empty for none. */\nexport function aiStockSetting(text: string): string {\n const named = sceneWords(text)\n return SCENE_SETTINGS.find((entry) => entry.words.some((word) => named.has(word)))?.said ?? ''\n}\n\n/**\n * The moment a portfolio's record shows (AGL-3856): read from the record's\n * own name first, then from what it is filed under, then as a portrait, and\n * set where its name, its category or else the site's own words say. A\n * photographer's \"Getting Ready\" filed under \"Weddings and elopements\" is a\n * wedding couple in the mountains; \"Milestone Portraits\" filed under \"Family\n * portraits\" a family. Its searches end on the people alone (\"couple\"), so a\n * moment no photo shows in its setting still shows its people. `null` where\n * neither names people at a moment nor a portrait.\n */\nexport function aiStockRecordScene(name: string, category = '', siteSetting = ''): AiStockScene | null {\n const texts = [name, category].filter((text) => text.trim())\n const source =\n texts.find((text) => PEOPLE_SCENES.some((entry) => entry.words.some((word) => sceneWords(text).has(word)))) ??\n texts.find((text) => PORTRAIT_SCENE.words.some((word) => sceneWords(text).has(word)))\n if (!source) return null\n const named = sceneWords(source)\n const scene = PEOPLE_SCENES.find((entry) => entry.words.some((word) => named.has(word))) ?? PORTRAIT_SCENE\n const setting = texts.map(aiStockSetting).find(Boolean) ?? siteSetting\n const query = scene.query(named)\n const all = sceneWords(texts.join(' '))\n return {\n queries: [...new Set([setting ? `${query} ${setting}` : '', query, scene.subject].filter(Boolean))],\n subject: [scene.subject, setting].filter(Boolean).join(' '),\n object: scene.subject,\n // A record's cover leads with its people: a wedding's table decor is not \"Overlook Ceremonies\".\n lead: scene.lead.filter((phrase) => !RECORD_SCENE_UNPEOPLED.has(phrase)).map((phrase) => stemList(phrase).join(' ')),\n people: scene.people.map(aiStockStem),\n shun: scene.shun.filter((word) => !all.has(word)).map(aiStockStem),\n named: [...new Set(stemList(texts.join(' ')))],\n away: aiStockSettingAway(setting),\n }\n}\n\n/**\n * The work a craft whose pictures are people at a moment shows (AGL-3942):\n * the scenes its site's own words name, in the order they name them, each\n * set where the site is — a wedding photographer \"for couples planning\n * mountain weddings, and families\" shows a wedding couple in the mountains\n * and a family in the mountains. A family session still never shows a\n * bride, whatever else the site names. Empty where its words name no people.\n */\nexport function aiStockWorkScenes(text: string, setting = ''): AiStockScene[] {\n const list = text\n .toLowerCase()\n .split(/[^a-zÀ-ɏ]+/)\n .filter(Boolean)\n const found = PEOPLE_SCENES.map((scene) => ({ scene, at: list.findIndex((word) => scene.words.includes(word)) }))\n .filter((entry) => entry.at >= 0)\n .sort((a, b) => a.at - b.at)\n return found.map(({ scene }) => {\n const named = new Set(list.filter((word) => scene.words.includes(word)))\n const query = scene.query(named)\n return {\n queries: [...new Set([setting ? `${query} ${setting}` : '', query].filter(Boolean))],\n subject: [scene.subject, setting].filter(Boolean).join(' '),\n object: scene.subject,\n lead: scene.lead.filter((phrase) => !RECORD_SCENE_UNPEOPLED.has(phrase)).map((phrase) => stemList(phrase).join(' ')),\n people: scene.people.map(aiStockStem),\n shun: scene.shun.map(aiStockStem),\n named: [...new Set([...named].map(aiStockStem))],\n away: aiStockSettingAway(setting),\n }\n })\n}\n\n/** Whether a setting is a place a photo shows on its own, a landscape searched by its name: \"mountains\", never \"autumn\". */\nexport function aiStockSettingIsLandscape(setting: string): boolean {\n return SCENE_SETTINGS.some((entry) => entry.said === setting && entry.landscape === true)\n}\n\n/**\n * A scene's lead words a record's cover never leads with alone\n * ({@link aiStockRecordScene}): the moment with no one in it (a wedding's table\n * decor for \"Overlook Ceremonies\"), or children with no family (a ski class\n * for \"Milestone Portraits\").\n */\nconst RECORD_SCENE_UNPEOPLED = words('wedding elopement child children kid kids baby toddler')\n\n/**\n * What a portfolio's record is never OF, among its first tags, unless its own\n * words name it (AGL-3856): an animal, a toy or a figurine. The beta.265\n * Laurel Ridge \"Gallery collections\" covers were a toy frog with a camera, a\n * toy duck and a cat's portrait.\n */\nconst RECORD_ODD_LEADS = words(\n 'animal animals cat cats kitten dog dogs puppy pet pets bird birds frog frogs duck ducks horse horses cow rabbit bunny ' +\n 'toy toys figurine figurines lego doll dolls teddy puppet miniature',\n)\n\n/** An object's kin phrases as stems, or none. */\nconst kinStems = (entry: (typeof OBJECT_KIN)[number] | null): string[] =>\n entry ? [...new Set(entry.kin.map((phrase) => stemList(phrase).join(' ')))] : []\n\n/** What a product falls back to once its own searches find nothing ({@link aiStockProductSearches}). */\nexport interface AiStockProductFallback {\n /** The site's broad searches ({@link AiStockSiteTerms.broad}): \"handmade soap\". */\n broad?: readonly string[]\n /** The words a photo of the craft itself names ({@link AiStockSiteTerms.core}). */\n core?: readonly string[]\n}\n\n/**\n * A size never names a product (AGL-3660): the Tidewater start searched\n * \"soap set starter size\" for \"Bath Gift Set Starter Size\", its head noun\n * read as \"size\", and took a soap dispenser.\n */\nconst PRODUCT_SIZES =\n /\\b(?:(?:starter|travel|trial|sample|mini|full|half|family|value|jumbo|large|small|regular|standard|big)[- ])?sized?s?\\b/gi\n\n/** The wrapper words a gift is named by, searched with the craft: \"soap gift box\". */\nconst GIFT_WRAPPERS = words('gift gifts box boxes basket baskets hamper hampers')\n\n/**\n * A product's searches (AGL-3676), most specific first: each of its subjects\n * — its name's noun phrase, then its photo's — with the shop's category\n * where the phrase does not already name the shop's world (\"candle gift\n * box\"), then the category alone, a plain photo of what the shop sells. Every\n * one must find a hit naming the category — or the product's own word of the\n * shop's world, \"lotion\" in a soap shop — so no product is ever filled with a\n * lifestyle shot of something else: the beta.237 Willow Wick start put a\n * laptop and roses under \"Candle Wick Trimmer\" and an antique tea set under\n * \"Candle Gift Set\".\n *\n * And each must find a hit naming the product's own head noun among its\n * first tags (AGL-3660): the beta.239 Ember & Oak start put a bed with a book,\n * a mug and a camera (its candle a last tag) under \"Hand-Poured Soy Candle\".\n * An object whose own word is not enough ({@link OBJECT_KIN}) is searched by\n * its kin instead of the category alone, and named by them: a single taper\n * candle filled \"Wax Melt Gift Set\".\n *\n * Then, before a product is ever given a photo of something else, it falls\n * back to its own craft (AGL-3660). The Saltmarsh Soap Co start (2026-10-10)\n * found no hit naming \"bar\" or \"box\" among the first tags, and four of its\n * five products took the starter photos — a laptop and roses, a living room\n * of plants. And the beta.242 Tidewater Soap Works start (2026-10-11) showed\n * that the head noun anywhere is not enough: its own weak hits put a sauna\n * under \"Bath Gift Set\", colognes under \"Natural Body Lotion\", a bathroom\n * shelf under \"Soap Bar Trio\" and a soap dispenser under its starter size,\n * while the collection tiles beside them, searched for the category, were\n * good. So the searches are ranked by how sure they are ({@link AiStockSearch.tier}):\n *\n * 1. Its own: the head noun (or its kin) among the first tags, as above.\n * 2. `borrow`: a photo OF its category — the category alone, then the craft's\n * broad searches (\"handmade soap\", \"natural skincare\"), one of the\n * product's kin or the craft's own names among the first tags. A product\n * may repeat one the job already shows, a collection tile's photo or\n * another product's ({@link aiLayoutStockPhotoSource}): a borrowed\n * on-topic photo beats a weak specific one.\n * 3. `weak`: the same searches again, the head noun named anywhere among the\n * tags (no extra search: the page remembers its answers), a gift's own\n * wrapper with the craft (\"soap gift box\"), and the craft's broad searches,\n * any hit naming the craft itself ({@link AiStockSiteTerms.core}).\n *\n * Every one of them turns down a room or a scene, a fragrance bottle, and\n * what the product's kin shuns (a pump for a bar of soap), unless the\n * product names it. A size never names the product: \"Bath Gift Set Starter\n * Size\" is a bath gift set.\n */\nexport function aiStockProductSearches(\n slot: Pick<AiLayoutPictureSlot, 'aspect' | 'product'>,\n craft: string,\n domain: readonly string[] = [],\n fallback: AiStockProductFallback = {},\n): AiStockSearch[] {\n const orientation = aiStockOrientation(slot.aspect)\n const size = orientation === 'vertical' ? { minHeight: 900 } : { minWidth: 900 }\n const craftStems = stemList(craft)\n const world = new Set([...domain, ...craftStems])\n const subjects = (slot.product?.subjects ?? [])\n .map((raw) => aiStockSubjectWords(raw.replace(PRODUCT_SIZES, ' '), ''))\n .filter(Boolean)\n // The product's head noun is its name's: \"candle\" of \"Hand-Poured Soy Candle\".\n const own = subjects[0] ?? ''\n const object = aiStockObjectWord(own)\n const kin = object\n ? objectKin(object, [...craftStems, ...domain, ...stemList(subjects.join(' '))])\n : null\n const kinPhrases = kinStems(kin)\n // A product of the shop's world beside its category is held to either:\n // a soap shop's body lotion names \"lotion\", never \"soap\".\n const ownWorld = stemList(own).filter(\n (stem) => world.has(stem) && !WRAPPERS.has(stem) && !craftStems.includes(stem),\n )\n const category = craft && ownWorld.length ? [...craftStems, ...ownWorld] : []\n const core = [...new Set([...craftStems, ...(fallback.core ?? [])])]\n const shun = (kin?.shun ?? []).map(aiStockStem)\n type Query = {\n query: string\n subject: string\n object: string\n lead: boolean\n broad?: boolean\n tier?: 'borrow' | 'weak'\n }\n const queries: Query[] = []\n for (const subject of subjects) {\n const stems = stemList(subject)\n const qualifier = kin?.qualifier ?? ''\n const query = kin\n ? !qualifier || stems.includes(aiStockStem(qualifier))\n ? subject\n : kin.after\n ? `${subject} ${qualifier}`\n : `${qualifier} ${subject}`\n : craft && !stems.some((stem) => world.has(stem))\n ? `${craft} ${subject}`\n : subject\n queries.push({ query, subject, object, lead: true })\n }\n // The category alone stands in only for a thing that is no more than of\n // it; a thing that is its own word of the shop's world is searched by that\n // word (\"lotion\"). Its hits are still scored by the product's own words: a\n // soy candle over a taper.\n if (kin)\n for (const query of kin.queries)\n queries.push({ query, subject: own || query, object, lead: true })\n else if (object && ownWorld.includes(object))\n queries.push({ query: object, subject: own, object, lead: true })\n else if (craft)\n queries.push({ query: craft, subject: own || craft, object: craft, lead: true, tier: 'borrow' })\n const held = [...queries]\n // 2. A photo OF its category, which may be one the job already shows.\n for (const query of fallback.broad ?? [])\n queries.push({ query, subject: own, object: '', lead: true, broad: true, tier: 'borrow' })\n // 3. The head noun anywhere among the tags, by the same searches.\n for (const entry of held) queries.push({ ...entry, lead: false, tier: 'weak' })\n // A gift is its craft's: \"bath gift box\" asks for a \"soap gift box\".\n const wrapped = own\n .split(/\\s+/)\n .filter((word) => WRAPPERS.has(word) && aiStockStem(word) !== object)\n const gift = wrapped.find((word) => GIFT_WRAPPERS.has(word))\n if (craft && gift && !kin)\n queries.push({\n query: `${craft} ${wrapped.join(' ')}`,\n subject: own,\n object: aiStockStem(gift),\n lead: false,\n tier: 'weak',\n })\n // The craft's own broad searches, any hit naming the craft.\n for (const query of fallback.broad ?? [])\n queries.push({ query, subject: own, object: '', lead: false, broad: true, tier: 'weak' })\n // What a borrowed photo is OF: the product's kin, its own word of the shop's world, else the craft.\n const borrowed = kinPhrases.length ? kinPhrases : ownWorld.length ? ownWorld : core\n const seen = new Set<string>()\n const searches: AiStockSearch[] = []\n for (const entry of queries) {\n const query = clip(entry.query)\n const key = `${query}|${entry.lead}|${entry.object}|${entry.broad === true}|${entry.tier ?? ''}`\n if (!query || seen.has(key)) continue\n seen.add(key)\n const common = {\n query,\n orientation,\n ...size,\n subject: entry.subject,\n product: true,\n ...(entry.tier ? { tier: entry.tier } : {}),\n ...(shun.length ? { shun } : {}),\n }\n if (entry.broad) {\n const heldTo = [...new Set([...core, ...ownWorld])]\n searches.push({\n ...common,\n broad: true,\n ...(entry.lead\n ? {\n leadAny: borrowed,\n ...(kinPhrases.length ? { kin: kinPhrases } : {}),\n ...(heldTo.length ? { category: heldTo } : {}),\n }\n : core.length\n ? { category: core }\n : {}),\n })\n continue\n }\n searches.push({\n ...common,\n // Named anywhere, the hit's first tags are still of the shop's world:\n // a bed with a book, its candle a last tag, is not a candle's photo.\n ...(entry.lead ? { lead: true } : { leadWorld: true }),\n ...(entry.object ? { object: entry.object } : {}),\n ...(kinPhrases.length && entry.object === object ? { kin: kinPhrases } : {}),\n ...(craft ? { requires: craft } : {}),\n ...(category.length ? { category } : {}),\n })\n }\n return searches\n}\n\n/**\n * The searches a slot tries, in order, most specific first, each distinct.\n * A portrait of one of the business's people ({@link AiLayoutPictureSlot.people})\n * asks first for the role its words or its list's name (`sectionName`) say,\n * in the site's world: \"teacher classroom\" for a \"Math instructor\" (AGL-3856).\n */\nexport function aiStockSearchesFor(\n slot: Pick<AiLayoutPictureSlot, 'role' | 'alt' | 'aspect' | 'people' | 'record' | 'product'>,\n terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'domain' | 'broad'> &\n Partial<Pick<AiStockSiteTerms, 'making' | 'core' | 'scenes' | 'setting' | 'maker' | 'work' | 'leadWord'>>,\n subject: string,\n part?: AiStockSlotPart,\n sectionName = '',\n): AiStockSearch[] {\n const orientation = aiStockOrientation(slot.aspect)\n const size =\n slot.role === 'hero'\n ? { minWidth: 1600 }\n : orientation === 'vertical'\n ? { minHeight: 900 }\n : { minWidth: 900 }\n const domain = new Set(terms.domain)\n // A portfolio's record of a craft whose work is people at a moment shows the\n // moment, never the maker: the beta.265 Laurel Ridge \"Gallery collections\"\n // searched \"photographer mountain elopements\" and placed a press\n // photographer, a toy frog with a camera and a cat (AGL-3856).\n const work = aiStockShowsTheWork(slot, terms)\n // Every other picture of such a craft's site shows its work where a page\n // would show the maker (AGL-3942): the beta.267 Copper Hollow Film &\n // Portrait about page searched \"photographer at work\" and \"photographer\n // camera\", and every picture on it was a stock photographer.\n const itsWork = !work && aiStockShowsItsWork(slot, terms)\n /** Whether a query names the craft by its own name, the profession's noun: \"wedding photographer\". */\n const namesCraft = (query: string) => stemList(query).some((stem) => (terms.core ?? []).includes(stem))\n /** Whether a query names the maker, their tools or the craft: \"photographer at work\", \"photographer camera\". */\n const namesMaker = (query: string) => namesCraft(query) || stemList(query).some((stem) => (terms.maker ?? []).includes(stem))\n /** A rung of the maker's own photos, left out on a site that shows its work. */\n const shown = (query: string) => !itsWork || !namesMaker(query)\n /** A search of the slot's own words, left out on such a site only where they name the profession. */\n const said = (query: string) => !itsWork || !namesCraft(query)\n const object = aiStockObjectWord(subject)\n const subjectStems = stemList(subject)\n const kin = object ? objectKin(object, [...terms.domain, ...subjectStems]) : null\n const kinPhrases = kinStems(kin)\n // The craft qualifies a subject that does not already name the site's world.\n const namesWorld = subjectStems.some((stem) => domain.has(stem))\n // A tile of the shop's world beside its category is held to either: a soap\n // shop's \"Body care\" tile names \"body\", never \"soap\" (AGL-3660).\n const ownWorld = subjectStems.filter(\n (stem) => domain.has(stem) && !WRAPPERS.has(stem) && stem !== terms.craft,\n )\n // A hero of a craft names the craft itself: the Saltmarsh Soap Co hero\n // (2026-10-10) was a florist's bouquet tagged \"natural\" (AGL-3660).\n const core = terms.core ?? []\n // The world a trade serves qualifies its pictures where the craft is the trade: \"dirt bike\", never \"part\" (AGL-4065).\n const leadWord = terms.leadWord ?? terms.craft\n const leadStems = stemList(leadWord)\n const qualify = (phrase: string) =>\n leadWord && !namesWorld && !leadStems.every((stem) => stemList(phrase).includes(stem))\n ? `${leadWord} ${phrase}`\n : phrase\n // A part, gear, a machine, or one word of a two-word world (\"bike\" of \"dirt\n // bike\"), is never searched alone (AGL-4065): searched with the world, and\n // its photo is OF the thing and names the world. \"Parts for the ranch\"\n // searched \"parts\" and took a canoe tagged \"part\".\n const ofTheWorld =\n Boolean(leadWord) &&\n subjectStems.length > 0 &&\n subjectStems.every((stem) => WORLD_OBJECTS.has(stem) || leadStems.includes(stem)) &&\n (subjectStems.some((stem) => WORLD_OBJECTS.has(stem)) || (leadStems.length > 1 && subjectStems.length < leadStems.length))\n /** The words a photo of the world names, the world's things left out: a dirt bike's, never \"part\". */\n const worldNames = core.filter((stem) => !stem.split(' ').some((word) => WORLD_OBJECTS.has(word)))\n type Query = {\n query: string\n broad?: boolean\n people?: boolean\n held?: boolean\n category?: boolean\n /** Where the site's work is searched ({@link AiStockSiteTerms.work}). */\n work?: boolean\n /** Whether the thing must be among its photo's first tags: a record's cover, a thing of the world (AGL-4065). */\n leads?: boolean\n /** Whether its photo names the world's own words ({@link AiStockSiteTerms.core}) as well as the thing (AGL-4065). */\n ofWorld?: boolean\n }\n // A collection tile is product-like: held to the shop's category and its\n // own object among the first tags, and searched by its object's kin, never\n // the category's world alone (AGL-3660).\n const collection = part === 'collection' && Boolean(terms.craft) && !work\n const broad: Query[] = (kin && collection) || work\n ? []\n : terms.broad.filter(shown).map((query) => ({ query, broad: true, category: collection }))\n // The maker at work, held to the craft: never \"hands\" (AGL-3660).\n const makers: Query[] = (work ? [] : (terms.making ?? [])).filter(shown).map((query) => ({\n query,\n broad: true,\n category: true,\n }))\n // A portrait in its role, in the site's world, where the libraries know a word for it.\n const roleWord = slot.people ? (aiStockPeopleRole(slot.alt, sectionName)?.query ?? '') : ''\n const role = roleWord ? (stemList(terms.business).includes(roleWord) ? terms.business : `${roleWord} ${terms.business}`.trim()) : ''\n // A scene's people are read from every word of the picture's, never its first clause alone.\n const scene = work\n ? aiStockRecordScene(slot.alt, slot.record?.category ?? '', terms.setting ?? '')\n : terms.scenes && slot.role !== 'hero' && part !== 'collection'\n ? aiStockScene(slot.alt, terms.setting ?? '')\n : null\n // The site's own scenes, turned per slot so a page's pictures show each of them.\n const sceneList: AiStockScene[] = []\n if (itsWork) {\n const own = terms.work ?? []\n const turn = own.length ? aiLayoutSeedNumber(`${sectionName}|${slot.alt}`) % own.length : 0\n sceneList.push(...own.slice(turn), ...own.slice(0, turn))\n }\n // The work's own subject is never qualified by the craft: \"getting ready\", never \"photographer getting ready\".\n const own = work ? (phrase: string) => phrase : qualify\n // A record's cover is OF what it names, searched in the site's world first\n // (AGL-4065): \"handyman drywall\" before \"drywall\", which took an architect's\n // house with a family before its studs.\n const record = Boolean(slot.record) && !work && !ofTheWorld && Boolean(leadWord)\n const thing: Query[] = (\n !subject\n ? []\n : ofTheWorld\n ? [\n {\n query: `${leadWord} ${subjectStems.some((stem) => !leadStems.includes(stem)) ? subject.split(/\\s+/).filter((word) => !leadStems.includes(aiStockStem(word))).join(' ') : ''}`.trim(),\n held: true,\n leads: true,\n ofWorld: true,\n },\n ...(kin ? kin.queries.map((query) => ({ query, held: true, leads: true, ofWorld: true })) : []),\n ]\n : [\n ...(record && !leadStems.every((stem) => subjectStems.includes(stem)) ? [{ query: `${leadWord} ${subject}`, held: true, leads: true }] : []),\n { query: own(subject), held: true, ...(record ? { leads: true } : {}) },\n ...(kin\n ? kin.queries.map((query) => ({ query, held: true, ...(record ? { leads: true } : {}) }))\n : [{ query: own(object), held: true, ...(record ? { leads: true } : {}) }]),\n ]\n ).filter((query) => said(query.query))\n // Never the maker, the camera, an animal or a toy, unless the record names it.\n const recordNamed = work ? new Set(stemList(`${slot.alt} ${slot.record?.category ?? ''}`)) : null\n const refuseLead = recordNamed\n ? [...new Set([...(terms.maker ?? []), ...[...RECORD_ODD_LEADS].map(aiStockStem)])].filter((stem) => !recordNamed.has(stem))\n : []\n // Where the maker's rungs were, a site that shows its work searches its work.\n const shows: Query = { query: '', work: true }\n const making = itsWork ? [shows] : makers\n const queries: Query[] =\n slot.role === 'hero'\n ? [{ query: terms.business, broad: true }, ...broad, ...(itsWork ? [shows] : [])]\n : slot.role === 'about'\n ? [\n ...(role ? [{ query: role, broad: true, people: true }] : []),\n ...(part === 'story' ? making : []),\n ...[\n {\n query: `${terms.business} ${subject}`,\n broad: true,\n people: true,\n },\n { query: terms.business, broad: true, people: true },\n ].filter((query) => said(query.query)),\n ...(part === 'story' ? [] : making),\n ...broad,\n ]\n : [...(part === 'story' ? making : []), ...(scene ? [] : thing), ...(itsWork ? [shows] : []), ...broad]\n const seen = new Set<string>()\n const searches: AiStockSearch[] = []\n // A picture of people at a moment asks for them, and where, before anything\n // else, and takes only a photo leading with them (AGL-3856): never the\n // roses of a \"Mountain Wedding Day\", nor a bride for a family session. A\n // picture of the work never leads with the maker or a camera (AGL-3942).\n const workLead = itsWork ? (terms.maker ?? []) : []\n // The site's work is held to its own scene, never to the craft's world.\n const sceneSearch = (one: AiStockScene, query: string, ofWork: boolean): AiStockSearch => {\n const refused = [...new Set([...refuseLead, ...workLead.filter((stem) => !one.named.includes(stem))])]\n return {\n query,\n orientation,\n ...size,\n strict: true,\n subject: one.subject,\n object: one.object,\n kin: one.lead,\n lead: true,\n needs: one.people,\n allow: one.named,\n ...(one.shun.length ? { refuse: one.shun } : {}),\n ...(refused.length ? { refuseLead: refused } : {}),\n ...(one.away.length ? { away: one.away } : {}),\n ...(work || ofWork ? { worldless: true } : {}),\n }\n }\n for (const query of scene?.queries ?? []) {\n seen.add(`${query}|false`)\n searches.push(sceneSearch(scene as AiStockScene, query, false))\n }\n /** The site's own scenes, then the place itself where it is a landscape: \"mountains\". */\n const workSearches = (): AiStockSearch[] => {\n const found: AiStockSearch[] = []\n for (const one of sceneList)\n for (const query of one.queries) {\n if (seen.has(`${query}|false`)) continue\n seen.add(`${query}|false`)\n found.push(sceneSearch(one, query, true))\n }\n const place = terms.setting && aiStockSettingIsLandscape(terms.setting) ? terms.setting : ''\n if (!place || seen.has(`${place}|false`)) return found\n seen.add(`${place}|false`)\n const away = aiStockSettingAway(place)\n const stems = SCENE_SETTINGS.find((entry) => entry.said === place)?.words.map(aiStockStem) ?? []\n found.push({\n query: place,\n orientation,\n ...size,\n strict: true,\n subject: place,\n object: aiStockStem(place),\n kin: [...new Set(stems)],\n lead: true,\n ...(workLead.length ? { refuseLead: [...workLead] } : {}),\n ...(away.length ? { away } : {}),\n worldless: true,\n })\n return found\n }\n for (const raw of queries) {\n if (raw.work) {\n searches.push(...workSearches())\n continue\n }\n const query = clip(raw.query)\n const key = `${query}|${raw.people === true}`\n if (!query || seen.has(key)) continue\n seen.add(key)\n const held = raw.held === true && (collection || kinPhrases.length > 0)\n searches.push({\n query,\n orientation,\n ...size,\n ...(raw.people ? { people: true } : {}),\n ...(raw.broad ? { broad: true } : {}),\n ...(held && kinPhrases.length ? { kin: kinPhrases } : {}),\n ...((held && collection) || raw.leads ? { lead: true } : {}),\n ...(terms.craft && !raw.ofWorld && (raw.category || (raw.held && collection))\n ? {\n requires: terms.craft,\n ...(ownWorld.length ? { category: [terms.craft, ...ownWorld] } : {}),\n }\n : {}),\n ...(raw.ofWorld && worldNames.length ? { category: worldNames } : {}),\n ...(slot.role === 'hero' && core.length ? { category: core } : {}),\n // A hero is OF the site's world: its first tag names it (AGL-3760).\n ...(slot.role === 'hero' ? { first: true } : {}),\n ...(refuseLead.length ? { refuseLead } : {}),\n ...(work ? { worldless: true } : {}),\n })\n }\n return searches\n}\n\n/**\n * Whether a picture of a craft's site whose pictures are people at a moment\n * shows that work wherever a page would show the maker (AGL-3942): an about\n * picture, a story of the craft, an intro's cover. Not a record (which shows\n * its own moment, {@link aiStockShowsTheWork}), a portrait of the business's\n * people, nor a product; and only where the site's words name the work.\n */\nexport function aiStockShowsItsWork(\n slot: Pick<AiLayoutPictureSlot, 'record' | 'people' | 'product'>,\n terms: Partial<Pick<AiStockSiteTerms, 'scenes' | 'work'>>,\n): boolean {\n return Boolean(terms.scenes) && (terms.work?.length ?? 0) > 0 && !slot.record && !slot.people && !slot.product\n}\n\n/**\n * Whether a slot is a portfolio's record of a craft whose work is people at a\n * moment (AGL-3856): a photographer's \"Mountain Elopements\" shows an\n * elopement, never the photographer. Searched by the moment its words and its\n * category name, held to no world of the craft, and never led by the craft's\n * own words, an animal or a toy unless the record names them.\n */\nexport function aiStockShowsTheWork(\n slot: Pick<AiLayoutPictureSlot, 'record' | 'role' | 'people' | 'product'>,\n terms: Partial<Pick<AiStockSiteTerms, 'scenes'>>,\n): boolean {\n return Boolean(slot.record) && Boolean(terms.scenes) && slot.role !== 'hero' && !slot.people && !slot.product\n}\n\n/** What a hit is judged by. */\nexport interface AiStockJudgement {\n /** The words the picture is of; empty for a picture of the site's world. */\n subject?: string\n /** The site's domain stems ({@link AiStockSiteTerms.domain}). */\n domain?: readonly string[]\n /**\n * The business's own world ({@link AiStockSiteTerms.lead}, AGL-4065): what a\n * hero's first tag and a hit of a search that is not of a thing name. The\n * domain where absent.\n */\n world?: readonly string[]\n /**\n * Whether a hit must name the subject's object. A broad search, a hero\n * and an about picture need only name the domain.\n */\n strict?: boolean\n /** A word every hit must name: a product's photo names the shop's category (AGL-3676). */\n requires?: string\n /** Words of which a hit must name one, `requires` among them ({@link AiStockSearch.category}). */\n category?: readonly string[]\n /** The thing a hit must name, where it is not the subject's own (AGL-3660). */\n object?: string\n /** Phrases naming the object where its word is not enough; one of them is then required, and stands for the category. */\n kin?: readonly string[]\n /** Whether the object must be among the hit's first tags (AGL-3660). */\n lead?: boolean\n /** Whether the hit's first tags must name the site's world ({@link AiStockSearch.leadWorld}). */\n leadWorld?: boolean\n /** Whether the hit's first tag must name the site's world ({@link AiStockSearch.first}). */\n first?: boolean\n /** The stems of the site's business type or brief, which let a sensitive topic in ({@link AiStockSiteTerms.named}). */\n named?: readonly string[]\n /** Rival crafts: a hit naming one is rejected unless it names the site's core words ({@link AiStockSiteTerms.rivals}). */\n rivals?: ReadonlyArray<{ words: readonly string[]; core: readonly string[] }>\n /** Phrases of which one must be among the hit's first tags ({@link AiStockSearch.leadAny}). */\n leadAny?: readonly string[]\n /** Whether it judges for a product: no room, no scene, no fragrance bottle (AGL-3660). */\n product?: boolean\n /** Words a hit never carries unless the subject or the brief names them ({@link AiStockSiteTerms.shun}). */\n shun?: readonly string[]\n /** Words a hit's first tags never carry unless the subject or the brief names them ({@link AiStockSiteTerms.shunLead}). */\n shunLead?: readonly string[]\n /** Words a hit never carries, whatever the brief names ({@link AiStockSearch.refuse}). */\n refuse?: readonly string[]\n /** Stems of which a hit names one ({@link AiStockSearch.needs}). */\n needs?: readonly string[]\n /** Stems no hit's first tags carry: a child, for a portrait of one of the business's people (AGL-3856). */\n refuseLead?: readonly string[]\n /** Stems naming the role a portrait shows, which a hit is preferred for naming, most of all first (AGL-3856). */\n roles?: readonly string[]\n /** Stems of the role being done, one of which a hit's first tags must name ({@link AiStockPeopleRole.scene}). */\n roleScene?: readonly string[]\n /** Stems of something else being done, which none of a hit's first tags may name ({@link AiStockPeopleRole.refuse}). */\n roleRefuse?: readonly string[]\n /** Stems of the places the picture is not set in, which none of a hit's first tags may name ({@link AiStockSearch.away}). */\n away?: readonly string[]\n}\n\n/** The words of a photo's page address at its library, its id dropped: \"robin-bird-songbird-garden-winter\". */\nfunction pageSlug(pageUrl: string): string {\n try {\n const last = decodeURIComponent(new URL(pageUrl).pathname)\n .split('/')\n .filter(Boolean)\n .pop()\n return last?.replace(/-?\\d+$/, '') ?? ''\n } catch {\n return ''\n }\n}\n\n/** A hit's words: the first few (what it is OF), every one, and each tag's phrase. */\nfunction hitWords(photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>) {\n const slug = pageSlug(photo.pageUrl)\n const tags = (photo.tags ?? [])\n .map((tag) => tag.toLowerCase().trim())\n .filter(Boolean)\n // Each tag's words and pairs of them, read tag by tag (AGL-4065): \"race car\"\n // and \"dirt bike\" are phrases a world names; the page address is read whole.\n const lead = termsOf([...tags.slice(0, 3), slug])\n const all = termsOf([...tags, photo.alt ?? '', slug])\n const phrases = [\n ...tags.map((tag) => stemList(tag).join(' ')),\n stemList(photo.alt ?? '').join(' '),\n stemList(slug).join(' '),\n ]\n const leadPhrases = [\n ...tags.slice(0, 3).map((tag) => stemList(tag).join(' ')),\n stemList(slug).join(' '),\n ]\n /** The first tag: what the photo is most of all. */\n const firstPhrase = stemList(tags[0] ?? '').join(' ')\n const rejected = tags.some(\n (tag) =>\n REJECTED_TAGS.has(tag) ||\n tag.split(/\\s+/).some((word) => REJECTED_TAGS.has(word)),\n )\n // Whole words only, a hyphenated one kept whole: \"cross-stitch\" is not a cross.\n const words = new Set(\n [...tags, (photo.alt ?? '').toLowerCase()]\n .join(' ')\n .split(/[^a-zÀ-ɏ-]+/)\n .filter((word) => word.length > 1)\n .map(aiStockStem),\n )\n return { lead, all, phrases, leadPhrases, firstPhrase, rejected, words }\n}\n\n/** Whether a phrase is among a hit's phrases, word for word. */\nconst among = (phrases: readonly string[], phrase: string) =>\n phrases.some((found) => ` ${found} `.includes(` ${phrase} `))\n\n/**\n * Whether a hit carries a topic its site never named ({@link SENSITIVE_TOPICS}):\n * a cross, a grave, a flag, a gun, a glass of wine, a child, a mannequin.\n */\nexport function aiStockSensitive(\n photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>,\n named: readonly string[] = [],\n): boolean {\n const { words: found } = hitWords(photo)\n const site = new Set(named)\n // A maker's name, in its tags or its page address, unless the site names the maker (AGL-4065).\n const makers = aiStockMakerTerms(photo)\n if ([...MAKER_STEMS].some((maker) => makers.has(maker) && !site.has(maker))) return true\n return SENSITIVE_STEMS.some(\n (topic) =>\n [...topic.words].some((word) => found.has(word)) &&\n ![...topic.allow].some((word) => site.has(word)),\n )\n}\n\n/**\n * How well a hit shows what a slot needs (AGL-3660), or 0 when it must not\n * fill it: a mockup or a blank never; a topic the site never named never\n * ({@link aiStockSensitive}); a picture of a thing only when the hit\n * names its object AND either the site's world or the subject's own\n * two-word phrase (\"bud vase\", \"wick trimmer\"); anything else only when it\n * names the site's world (when the site names one). Among the accepted, the\n * object among the hit's first tags counts 4 (a mention among its last, 2),\n * the subject's two-word phrase 3, each of its other words 1, and the\n * site's world 1, plus a quarter when it is among the first tags.\n */\nexport function aiStockRelevance(\n photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>,\n judgement: AiStockJudgement,\n): number {\n const hit = hitWords(photo)\n if (hit.rejected) return 0\n if (aiStockSensitive(photo, judgement.named)) return 0\n // Glass art is not pottery: a rival craft's photo names this craft's own words.\n for (const rival of judgement.rivals ?? [])\n if (\n rival.words.some((word) => hit.all.has(word)) &&\n !rival.core.some((word) => hit.all.has(word))\n )\n return 0\n const subject = stemList(judgement.subject ?? '')\n // What the slot or the brief names lets a shunned word, a room or a fragrance in.\n const owned = new Set([...subject, ...(judgement.named ?? [])])\n // A dispenser is not a soapmaker's, nor a pump a bar's (AGL-3660).\n if ((judgement.shun ?? []).some((word) => hit.all.has(word) && !owned.has(word)))\n return 0\n // A family session is never a bride, however the photographer's brief names weddings.\n if ((judgement.refuse ?? []).some((word) => hit.all.has(word))) return 0\n // A teacher's portrait is never OF a child, whatever else it names.\n if ((judgement.refuseLead ?? []).some((word) => hit.lead.has(word))) return 0\n // A teacher is shown teaching: a classroom, a lecture or students among the\n // first tags, and never a model, a pose or a painting (AGL-3856).\n if (judgement.roleScene?.length || judgement.roleRefuse?.length) {\n const first = new Set(stemList((photo.tags ?? []).slice(0, AI_STOCK_ROLE_TAGS_READ).join(' ')))\n if (judgement.roleScene?.length && !judgement.roleScene.some((stem) => first.has(stem))) return 0\n const read = new Set(stemList((photo.tags ?? []).slice(0, ALT_TAGS_READ).join(' ')))\n if ((judgement.roleRefuse ?? []).some((stem) => read.has(stem))) return 0\n }\n // A Blue Ridge couple is never on a beach, however its later tags name a mountain (AGL-3942).\n if (judgement.away?.length) {\n const read = new Set(stemList((photo.tags ?? []).slice(0, ALT_TAGS_READ).join(' ')))\n if (judgement.away.some((stem) => read.has(stem))) return 0\n }\n // A wedding day shows its people: a close-up of roses tagged \"wedding\" never fills it.\n const needs = judgement.needs ?? []\n if (needs.length && !needs.some((word) => hit.all.has(word))) return 0\n // What the photo is OF: a typewriter's terms of service are not a law firm's.\n if ((judgement.shunLead ?? []).some((word) => hit.lead.has(word) && !owned.has(word)))\n return 0\n if (judgement.product) {\n // A sauna, a bathroom shelf: a room is never the product.\n for (const word of hit.lead)\n if (PRODUCT_SCENES.has(word) && !owned.has(word)) return 0\n // Colognes are not a lotion: a fragrance's bottle only for a fragrance.\n if (\n ![...FRAGRANCE_BOTTLES].some((word) => owned.has(word)) &&\n [...hit.lead].some((word) => FRAGRANCE_BOTTLES.has(word))\n )\n return 0\n }\n // A borrowed photo is OF the product's category.\n const leadAny = judgement.leadAny ?? []\n if (leadAny.length && !leadAny.some((phrase) => among(hit.leadPhrases, phrase)))\n return 0\n const kin = judgement.kin ?? []\n const kinNamed = kin.some((phrase) => among(hit.phrases, phrase))\n const kinLead = kin.some((phrase) => among(hit.leadPhrases, phrase))\n const required = stemList(judgement.requires ?? '')\n // A two-word name stays whole: \"dirt bike\", never \"bike\" (AGL-4065).\n const category = (judgement.category ?? []).map(stemPhrase).filter(Boolean)\n const anyOf = category.length ? [...new Set([...required, ...category])] : []\n const demanded = required.length > 0 || anyOf.length > 0\n const meets = anyOf.length\n ? anyOf.some((stem) => hit.all.has(stem))\n : required.every((stem) => hit.all.has(stem))\n // An object's kin stands for the category: a wax melt is the candle shop's.\n if (demanded && !kinNamed && !meets) return 0\n const object =\n judgement.object ??\n (judgement.subject ? aiStockObjectWord(judgement.subject) : '')\n const domain = (judgement.domain ?? []).filter((stem) => stem !== object)\n // The business's own world, which a picture that is not of a thing names (AGL-4065).\n const own = judgement.world?.length ? judgement.world.filter((stem) => stem !== object) : domain\n // A hit naming the word it must name is of the site's world: a product's\n // category is that world even where it is the product's own object.\n const world =\n demanded || kinNamed || domain.some((stem) => hit.all.has(stem))\n const ownWorld = demanded || kinNamed || own.some((stem) => hit.all.has(stem))\n const worldLead =\n (anyOf.length\n ? anyOf.some((stem) => hit.lead.has(stem))\n : required.length > 0 && required.every((stem) => hit.lead.has(stem))) ||\n kinLead ||\n domain.some((stem) => hit.lead.has(stem))\n if (judgement.leadWorld && !worldLead) return 0\n // The first tag alone, never the page's address: Pixabay's slug repeats a\n // late tag (\"coffee-latte-art-candle-…\"). A site whose words name no world\n // holds its hero to none.\n // The business's own world, never every word of its type (AGL-4065): \"race\n // car\" named \"race\" of \"Amateur motocross race team: … race schedule\".\n const worldStems = new Set([...anyOf, ...required, ...own])\n if (judgement.first && (worldStems.size || kin.length)) {\n const firstWorld =\n withPairs(hit.firstPhrase.split(' ').filter(Boolean)).some((stem) => worldStems.has(stem)) ||\n kin.some((phrase) => among([hit.firstPhrase], phrase))\n if (!firstWorld) return 0\n }\n // What the photo is most of all: its first tag names the object, its kin or what it must be OF.\n const firstNamed = (phrases: readonly string[]) =>\n phrases.some((phrase) => Boolean(phrase) && among([hit.firstPhrase], phrase))\n const pair = subject.length >= 2 ? subject.slice(-2).join(' ') : ''\n const phrased = Boolean(pair) && among(hit.phrases, pair)\n let score = 0\n if (judgement.strict && object) {\n // An object with kin is named only by them: \"melt\" alone is resin art.\n const named = kin.length ? kinNamed : hit.all.has(object)\n if (!named) return 0\n const leading = kin.length ? kinLead : hit.lead.has(object)\n // A lifestyle scene whose object is a last tag is not a photo OF it.\n if (judgement.lead && !leading) return 0\n if (domain.length && !world && !phrased) return 0\n score += leading ? 4 : 2\n if (kinNamed) score += 3\n if (firstNamed(kin.length ? kin : [object])) score += 1\n } else if (own.length) {\n if (!ownWorld) return 0\n }\n if (leadAny.length && firstNamed(leadAny)) score += 1\n if (phrased) score += 3\n for (const word of new Set(subject))\n if (word !== object && hit.all.has(word)) score += 1\n if (world) score += worldLead ? 1.25 : 1\n // A portrait in its role: a teacher at the board over a woman in a classroom.\n const roles = judgement.roles ?? []\n if (roles.some((word) => hit.lead.has(word))) score += 4\n else if (roles.some((word) => hit.all.has(word))) score += 2\n // A hero is most of all what its first tags say: \"law office, lawyer,\n // attorney\" over \"lawyers, personal injury, accident\" (AGL-3856): a second\n // of them naming its world says it is of that world, not of something else.\n if (judgement.first && worldStems.size) {\n const said = hit.leadPhrases.slice(0, -1).filter((phrase) => withPairs(phrase.split(' ')).some((stem) => worldStems.has(stem)))\n if (said.length >= 2) score += 0.25\n }\n return Math.max(score, 0.5)\n}\n\n/**\n * A search's acceptable hits in the order they are tried (AGL-3660): those\n * not placed yet, among the first few the library returned, those it must\n * not take dropped ({@link aiStockRelevance}), best first; the seed turns\n * the hits that score alike, so two jobs differ and one job repeats itself.\n */\nexport function aiStockRank(\n photos: readonly StockPhoto[],\n used: ReadonlySet<string>,\n seed: string,\n judgement: AiStockJudgement = {},\n): StockPhoto[] {\n const scored = photos\n .filter((photo) => !used.has(stockPhotoSourceKey(photo)))\n .slice(0, AI_LAYOUT_STOCK_PICK_WINDOW)\n .map((photo) => ({ photo, score: aiStockRelevance(photo, judgement) }))\n .filter((entry) => entry.score > 0)\n if (!scored.length) return []\n const turn = aiLayoutSeedNumber(seed)\n const ranked: StockPhoto[] = []\n for (const score of [...new Set(scored.map((entry) => entry.score))].sort(\n (a, b) => b - a,\n )) {\n const tier = scored.filter((entry) => entry.score === score)\n const start = turn % tier.length\n for (const entry of [...tier.slice(start), ...tier.slice(0, start)])\n ranked.push(entry.photo)\n }\n return ranked\n}\n\n/**\n * Whether two hits are of one shoot (AGL-3856): one contributor's photos a few\n * uploads apart, as Pixabay numbers them — the beta.265 Granite Peak Barbell\n * coaches were four of one model, 728223 to 728229 — else one page address.\n */\nexport function aiStockSameShoot(\n a: Pick<StockPhoto, 'id' | 'photographer' | 'pageUrl'>,\n b: Pick<StockPhoto, 'id' | 'photographer' | 'pageUrl'>,\n): boolean {\n const near = Number(a.id) && Number(b.id) ? Math.abs(Number(a.id) - Number(b.id)) < 100 : false\n if (a.photographer && a.photographer === b.photographer && near) return true\n const slug = pageSlug(a.pageUrl)\n return Boolean(slug) && slug === pageSlug(b.pageUrl)\n}\n\n/**\n * A search's ranked hits with those of a shoot no slot shows yet first among\n * the best (AGL-3856): a team's three cards are three people where the\n * library has them, never one model three times while another fits as well.\n * Every other order is kept.\n */\nexport function aiStockFreshShootsFirst(\n ranked: readonly StockPhoto[],\n shown: readonly StockPhoto[],\n judgement: AiStockJudgement,\n): StockPhoto[] {\n if (!shown.length || ranked.length < 2) return [...ranked]\n const best = aiStockRelevance(ranked[0] as StockPhoto, judgement)\n const top = ranked.filter((photo) => aiStockRelevance(photo, judgement) === best)\n const fresh = top.filter((photo) => !shown.some((other) => aiStockSameShoot(photo, other)))\n if (!fresh.length || fresh[0] === ranked[0]) return [...ranked]\n return [...fresh, ...ranked.filter((photo) => !fresh.includes(photo))]\n}\n\n/** The pick among a search's hits: the first {@link aiStockRank} would try, or `null`. */\nexport function aiStockPick(\n photos: readonly StockPhoto[],\n used: ReadonlySet<string>,\n seed: string,\n judgement: AiStockJudgement = {},\n): StockPhoto | null {\n return aiStockRank(photos, used, seed, judgement)[0] ?? null\n}\n\n/**\n * The library photos a stored page already shows: every `image` whose\n * source is the site's media reference. Starter photos are the platform's,\n * not the job's, and are not listed.\n */\nexport function aiStockPlacedSrcs(\n nodes: NodesMap | null | undefined,\n): string[] {\n const map = (nodes ?? {}) as unknown as Record<\n string,\n { componentId?: string; props?: Record<string, unknown> }\n >\n const out: string[] = []\n for (const node of Object.values(map)) {\n const src = node?.componentId === 'image' ? node.props?.['src'] : null\n if (typeof src === 'string' && src.startsWith('media:')) out.push(src)\n }\n return out\n}\n\n/**\n * The library photos a stored page shows, each as a slot takes it (AGL-3988):\n * its source, its size and what it shows. A photo the job placed on another\n * page is what a slot the library failed takes before any starter\n * (`aiLayoutJobPhotoPicks`). Each photo once; one without a size is left out.\n */\nexport function aiStockPlacedPhotos(nodes: NodesMap | null | undefined): AiLayoutPicturePhoto[] {\n const map = (nodes ?? {}) as unknown as Record<string, { componentId?: string; props?: Record<string, unknown> }>\n const out = new Map<string, AiLayoutPicturePhoto>()\n for (const node of Object.values(map)) {\n if (node?.componentId !== 'image') continue\n const src = node.props?.['src']\n const width = Number(node.props?.['intrinsicWidth'])\n const height = Number(node.props?.['intrinsicHeight'])\n if (typeof src !== 'string' || !src.startsWith('media:') || out.has(src)) continue\n if (!(width > 0) || !(height > 0)) continue\n const alt = typeof node.props?.['alt'] === 'string' ? (node.props['alt'] as string).trim() : ''\n out.set(src, { src, width, height, ...(alt ? { alt } : {}) })\n }\n return [...out.values()]\n}\n\n/**\n * What this process has placed for each job, by source key and asset src,\n * with the scope (the page's seed) that placed it (AGL-3660). It spans the\n * passes of one job that run here, so a page, the products or a post built\n * later does not place what an earlier one did, while a pass repeated over\n * its own page keeps its own photos. Bounded; the oldest job goes first.\n */\nconst JOB_PHOTOS = new Map<string, Map<string, string>>()\n\n/** What a job's photos map holds for a photo the media library refused for its own bytes: no page's scope (AGL-3923). */\nconst REFUSED_BY_THE_LIBRARY = '\\u0000refused'\nconst JOB_PHOTOS_MAX = 200\n\nfunction jobPhotos(key: string | null): Map<string, string> | null {\n if (!key) return null\n let placed = JOB_PHOTOS.get(key)\n if (!placed) {\n placed = new Map()\n JOB_PHOTOS.set(key, placed)\n while (JOB_PHOTOS.size > JOB_PHOTOS_MAX) {\n const oldest = JOB_PHOTOS.keys().next().value\n if (oldest === undefined) break\n JOB_PHOTOS.delete(oldest)\n }\n }\n return placed\n}\n\n/** Forgets every job's placed photos; for specs. */\nexport function aiStockForgetJobPhotos(): void {\n JOB_PHOTOS.clear()\n}\n\n/** The longest description of a photo written from the library's own words. */\nconst AI_STOCK_ALT_MAX = 160\n\n/**\n * Words a tag uses for how a photo looks or feels, never a thing it shows\n * (AGL-3856): \"extravagant\" of \"wedding dress, bride, extravagant\", \"moody\"\n * of \"forest, human, photographer\", a season or a people's name.\n */\nconst DESCRIBING = words(\n 'love romance romantic luxury luxurious fancy extravagant happiness happy beauty emotion emotions mood lifestyle ' +\n 'concept aesthetic wallpaper background retro vintage antique old young cute sexy fun funny sad positive negative healthy fit ' +\n 'strong powerful homemade tasty yummy sweet sweetness nice dark bw monochrome macro sporty active married bridal ' +\n 'female male adult good bad poc bipoc moody sunny rainy foggy misty snowy cloudy stormy dreamy shiny trendy messy ' +\n 'casual blonde blond brunette muscular athletic clever intelligent concentrated curious lonely sleepy heavy ' +\n 'nature outdoors outdoor indoors indoor scenery scenic autumn fall winter spring summer ' +\n 'physical teenage traveling ' +\n // How a photo is laid out, never a thing it shows: \"car wallpapers\" is a car (AGL-3942).\n 'wallpaper wallpapers background backgrounds backdrop backdrops texture textures ' +\n // Words a tag gives that are no noun at all: \"family, together\" is a family (AGL-3942).\n 'together alone apart away abroad ahead nearby outside inside upstairs downstairs ' +\n // Adjectives a tag gives alone, never a thing: \"students, multicultural\" (AGL-3856).\n 'multicultural multiethnic multiracial diverse international cultural traditional modern classic classical ' +\n 'domestic wild tropical rural urban ' +\n // How the photo was made, never what it shows: \"cutout, perspective\", \"men, silhouettes\".\n 'silhouette silhouettes cutout perspective bokeh closeup ' +\n // A holiday names when, never a thing: \"tet market\" is a market.\n 'tet christmas easter halloween diwali ramadan hanukkah thanksgiving ' +\n 'indian asian african american european caucasian vietnamese japanese chinese korean thai latino latina hispanic ' +\n 'japan vietnam viet nam thailand india china korea germany france italy spain england britain uk usa america ' +\n 'canada mexico brazil australia africa europe asia ' +\n // How a scene feels or looks, never a thing in it (AGL-3988): \"mountain,\n // snow, winter, cold, couple, color, landscape\" is a couple in the snow.\n 'cold warm hot chilly freezing frozen icy color colors colour colours landscape landscapes ' +\n 'panorama panoramic vista scene scenes',\n)\n\n/**\n * The sky and the light over a scene, never a thing in it (AGL-3988): \"A\n * couple with a sky at sunset\" and \"A child with clouds by a lake\" were a\n * couple at sunset and a child by a lake.\n */\nconst SCENERY = words('sky skies cloud clouds sun sunshine sunlight daylight light shadow shadows horizon')\n\n/**\n * The weather a scene is in, said as where (AGL-3988): \"A couple with a fog\n * at a wedding\" was a couple in the fog, \"A snow in the mountains\" a couple\n * in the snow.\n */\nconst WEATHER: Readonly<Record<string, string>> = {\n fog: 'in the fog',\n mist: 'in the mist',\n haze: 'in the haze',\n rain: 'in the rain',\n snow: 'in the snow',\n snowfall: 'in the snow',\n snowflakes: 'in the snow',\n wind: 'in the wind',\n}\n\n/**\n * Words a tag uses for what a person or a thing is like, said before it\n * rather than as a thing of its own (AGL-3856): \"a confident lawyer\", \"an\n * elderly couple\", \"an analog camera\", never \"a lawyer, law and a confident\".\n */\nconst QUALITIES = words(\n 'confident professional successful serious smart busy creative proud skilled experienced determined focused ' +\n 'senior junior expert friendly cheerful smiling elderly analog analogue digital mirrorless',\n)\n\n/** What a tag names that takes no article: \"chalk\" of \"board, chalk\". */\nconst MASS_NOUNS = words(\n 'food coffee tea bread wood water wax soap clay money fabric yarn wool furniture jewelry jewellery ' +\n 'pottery glass paper music art hair makeup chalk paint ink dust stone marble concrete steel metal ' +\n 'skincare equipment decor wildlife weather traffic wine beer chocolate rice sugar flour milk ' +\n 'cheese honey oil ice fire light sunlight dough sourdough pastry dessert people foliage greenery faculty staff ' +\n 'clothing bedding frosting icing flooring',\n)\n\n/** Nouns plural without an \"-s\": said without an article, \"women in a classroom\". */\nconst PLURAL_NOUNS = words('men women people children feet teeth mice geese sheep fish')\n\n/**\n * What a tag names that no photo shows as a thing of its own (AGL-3856): an\n * idea (\"law\" of \"lawyer, law\", \"feedback\" of \"board, chalk, feedback\"), a\n * doing (\"read\", \"lift\", \"fitness\", \"a workout\"), a word for the photo itself\n * (\"photo\", \"spot\"). Left out, never said with an article: \"A bookwork and a\n * read\", \"A kettlebell and fitness\", \"A board and training\" said nothing.\n */\nconst ABSTRACT_NOUNS = words(\n 'law justice advocacy business feedback review news return communication communicate discussion dialog conversation ' +\n 'success career work job satisfaction quality concept idea strategy marketing education technology health support ' +\n 'confirmation opinion rating evaluation planning project presentation optimization information internet finance ' +\n 'management leadership teamwork motivation growth strength service services help advice consulting consultation ' +\n 'marriage photography architecture travel transport transportation industry company corporate social e-business ' +\n 'fitness workout workouts exercise exercises crossfit sport sports skill skills knowledge exam exams lecture ' +\n 'session lesson course hobby leisure power energy wellness talent formation participation ' +\n 'press show day days night year years time holiday month months week weeks morning evening afternoon season seasons ' +\n 'kiss hug embrace ' +\n // A feeling, never a thing anyone holds (AGL-3988): \"A father with a care\".\n 'care worry trust hope joy peace fear faith grief pride comfort safety bliss delight passion desire feeling feelings ' +\n 'moment moments memory memories fashion style ' +\n 'photo photos picture pictures image images shot shots shoot shoots spot spots ' +\n 'read write learn study lift move remove focus relax think sit smile laugh eat swim teach enjoy celebrate explore ' +\n 'hike can',\n)\n\n/** Words ending as an idea does that are things: \"a station\", \"a city\", \"a ship\". */\nconst CONCRETE_ABSTRACT_ENDINGS = words(\n 'station mansion lotion potion ornament instrument apartment monument pavement basement garment compartment ' +\n 'equipment cement city university facility ship warship spaceship airship',\n)\n\n/** Whether a word is an idea or a doing by how it ends: \"participation\", \"unity\", \"empowerment\". */\nconst saysAnIdea = (word: string) =>\n /(?:tion|sion|ment|ness|ity|ship|ism)s?$/.test(word) && !CONCRETE_ABSTRACT_ENDINGS.has(aiStockStem(word))\n\n/**\n * Makers' names a tag gives, never what a photo shows to someone who cannot\n * see it (AGL-3856): \"A photo-camera and a sony\".\n */\nconst BRANDS = words(\n 'sony canon cannon nikon fujifilm fuji leica olympus panasonic kodak polaroid hasselblad pentax gopro dji ' +\n 'apple iphone ipad macbook imac samsung huawei android google microsoft windows dell lenovo nintendo playstation ' +\n 'xbox nike adidas puma reebok peloton bmw mercedes audi porsche ferrari lamborghini tesla ford toyota honda ' +\n 'volkswagen vw jeep chevrolet coca-cola pepsi starbucks mcdonalds ikea lego barbie disney altman ' +\n // The vehicle makers a moto site's photos are tagged with (AGL-4065).\n 'yamaha kawasaki suzuki ktm ducati harley harley-davidson husqvarna gasgas nissan subaru mazda chevy dodge reebok ' +\n 'petri zenit praktica yashica minolta mamiya rolleiflex voigtlander contax ricoh konica lomo lomography holga zeiss',\n)\n\n/** Stopwords a description still says, as the people a photo shows: \"a family\", \"a person\". */\nconst SAID_PEOPLE = words('people person family')\n\n/** Words ending in \"-ing\" that are things, and take an article: \"a wedding\", \"a ring\". */\nconst COUNTED_ING = words(\n 'wedding ring earring building painting drawing ceiling string swing king sibling wing dumpling pudding sapling',\n)\n\n/** \"-ing\" words that are things, and take no article: \"clothing\". */\nconst UNCOUNTED_ING = words('clothing bedding frosting icing flooring stuffing seasoning filling')\n\n/** People a photo shows; the generic ones give way to a role (\"man\" to \"businessman\"). */\nconst PEOPLE_NOUNS = words(\n 'man men woman women person people human humans boy boys girl girls guy guys lady ladies child children kid kids ' +\n 'baby family couple bride groom schoolgirl schoolboy teen teenager student students graduate athlete athletes ' +\n 'businessman businesswoman businessmen lawyer attorney doctor dentist nurse chef cook baker barista ' +\n 'trainer coach teacher teachers instructor lecturer professor tutor worker workers entrepreneur model ' +\n 'photographer potter artist florist mother father parent parents grandmother grandfather grandparents ' +\n 'faculty staff team participants volunteer volunteers musician dancer leader manager owner founder ' +\n 'journalist journalists reporter reporters master masters lovers newlywed newlyweds husband wife fiance fiancee spouse ' +\n // Whoever else is about (AGL-3988): \"A family with tourists\" was a family.\n 'tourist tourists traveler travelers traveller travellers hiker hikers visitor visitors friend friends crowd ' +\n // A family's people, said as a parent with a child (AGL-3988).\n 'dad dads mom moms mum mums son sons daughter daughters toddler toddlers',\n)\n/** People said by no role: a model is whoever posed (AGL-3856), \"a woman\" of \"woman, model, show, teacher\". */\nconst GENERIC_PEOPLE = words(\n 'man men woman women person people human humans guy guys lady ladies adult boy boys girl girls model models ' +\n 'tourist tourists traveler travelers traveller travellers hiker hikers visitor visitors friend friends crowd',\n)\n\n/** A parent a photo shows, said with the child beside them: \"A father with a girl\" (AGL-3988). */\nconst PARENTS = words('father mother dad mom mum parent parents grandfather grandmother grandparent grandparents')\n\n/** A child a photo shows beside a parent (AGL-3988). */\nconst CHILDREN = words('child children kid kids baby babies toddler toddlers girl girls boy boys son sons daughter daughters')\n\n/** How a family's word is said: \"a dad\" is a father (AGL-3988). */\nconst SAID_AS: Readonly<Record<string, string>> = { dad: 'father', dads: 'fathers', mom: 'mother', moms: 'mothers', mum: 'mother', mums: 'mothers' }\n\n/**\n * A body's parts, never a thing a photo is described by (AGL-3856): \"A girl\n * with a hand\" said nothing, and \"A body in a gym\" is a gym.\n */\nconst BODY_PARTS = words(\n 'hand hands finger fingers arm arms leg legs foot feet body bodies face faces eye eyes skin head heads lip lips mouth nose ' +\n 'ear ears neck shoulder shoulders knee knees',\n)\n\n/**\n * Words for a kind of thing, said only where nothing names the thing itself\n * (AGL-3856): \"A domestic cat and an animal\" is a cat.\n */\nconst KINDS_OF_THING = words('animal animals pet pets creature creatures mammal mammals object objects thing things item items')\n\n/** How many of a photo's first tags a person leads its description from, where it names a thing too: \"A camera\" of \"petri, camera, film, photography, photographer\" (AGL-3856). */\nconst ALT_PERSON_TAGS_READ = 4\n/** How many of a photo's first tags a role is said from, over a man or a woman before it: \"A man\" of \"bed, book, man, …, student\" (AGL-3856). */\nconst ALT_ROLE_TAGS_READ = 6\n\n/** What a person in a photo wears, said \"in\": \"a bride in a wedding dress\". */\nconst CLOTHING = words('dress gown suit uniform costume coat jacket robe apron')\n\n/**\n * Places a photo is set in, each with how a phrase says it is there: \"a\n * train at a station\", \"a lawyer in court\", \"a couple at a wedding\".\n */\nconst PLACES: Readonly<Record<string, string>> = {\n station: 'at',\n market: 'at',\n desk: 'at',\n table: 'at',\n counter: 'at',\n school: 'at',\n college: 'at',\n university: 'at',\n wedding: 'at',\n sunset: 'at',\n sunrise: 'at',\n dusk: 'at',\n dawn: 'at',\n beach: 'on',\n bed: 'on',\n sofa: 'on',\n couch: 'on',\n bench: 'on',\n trail: 'on',\n path: 'on',\n bridge: 'on',\n street: 'on',\n court: 'in',\n courtroom: 'in',\n office: 'in',\n kitchen: 'in',\n gym: 'in',\n studio: 'in',\n classroom: 'in',\n class: 'in',\n hall: 'in',\n room: 'in',\n garden: 'in',\n park: 'in',\n shop: 'in',\n store: 'in',\n bakery: 'in',\n cafe: 'in',\n restaurant: 'in',\n workshop: 'in',\n library: 'in',\n salon: 'in',\n clinic: 'in',\n forest: 'in',\n city: 'in',\n church: 'in',\n field: 'in',\n meadow: 'in',\n valley: 'in',\n mountain: 'in',\n hill: 'on',\n cliff: 'on',\n river: 'by',\n lake: 'by',\n lakeside: 'by',\n lakeshore: 'by',\n sea: 'by',\n ocean: 'by',\n seaside: 'by',\n coast: 'on',\n shore: 'on',\n sundown: 'at',\n waterfall: 'at',\n}\n\n/** Places that are things too, a photo's subject where nothing else is: \"a desk in a classroom\". */\nconst OBJECT_PLACES = words('desk table counter bridge bed sofa couch bench')\n\n/** Places said without an article: \"in court\", \"at sunset\". */\nconst BARE_PLACES = words('court sunset sunrise sundown dusk dawn')\n\n/** Places said in words of their own: a mountain tag is \"in the mountains\". */\nconst PLACES_SAID: Readonly<Record<string, string>> = {\n mountain: 'the mountains',\n lakeside: 'the lake',\n lakeshore: 'the lake',\n sea: 'the sea',\n ocean: 'the ocean',\n seaside: 'the sea',\n coast: 'the coast',\n shore: 'the shore',\n}\n\n/** Places that say when, said after where: \"a couple in the mountains at sunset\" (AGL-3988). */\nconst TIME_PLACES = words('sunset sunrise sundown dusk dawn')\n\n/** Places out of doors, said after a thing to sit on: \"a couple on a bench by the lake\" (AGL-3988). */\nconst OUTDOORS = words(\n 'forest field meadow valley mountain hill cliff river lake lakeside lakeshore waterfall beach park garden trail sea ocean seaside coast shore',\n)\n\n/** Words inside a tag that say one thing is where another is: \"couple on bench\" (AGL-3988). */\nconst TAG_PREPOSITIONS = words('on in at by with under near beside')\n\n/**\n * A tag that is a phrase of its own, read as its parts (AGL-3988): \"couple\n * on bench\" is a couple, and a bench they are on. The beta.270 Sugar Hollow\n * About page read it whole, as a place, and said \"A lakeside on a couple on\n * bench\".\n */\nfunction tagParts(tag: string): string[] {\n const list = tag.toLowerCase().trim().split(/\\s+/)\n const at = list.findIndex((word, index) => index > 0 && index < list.length - 1 && TAG_PREPOSITIONS.has(word))\n return at > 0 ? [list.slice(0, at).join(' '), list.slice(at + 1).join(' ')] : [tag]\n}\n\n/** How many of a photo's first tags its description reads: the things and people it is OF. */\nconst ALT_TAGS_READ = 8\n/** How far a photo's tags are read for where it is set, said last: \"in a gym\" of a kettlebell's seventh tag. */\nconst ALT_PLACE_TAGS_READ = 10\n\n/** A tag's words, a word for the photo itself taken off a compound: \"photo-camera\" is a camera. */\nfunction tagWords(tag: string): string[] {\n return tag\n .toLowerCase()\n .replace(/[^a-zÀ-ɏ\\s'-]/g, ' ')\n .replace(/\\b(?:photo|picture|image)-(?=[a-z])/g, '')\n .split(/\\s+/)\n .filter(Boolean)\n}\n\n/**\n * A tag as a phrase of an English description (AGL-3856): \"a wedding dress\",\n * \"an attorney\", \"books\", \"chalk\", \"Columbus\"; `null` for a tag that names no\n * thing (\"extravagant\", \"feedback\", \"training\", \"sony\") or is too long to be\n * one.\n */\nfunction describedTag(tag: string, proper: ReadonlySet<string>): string | null {\n const describing = (word: string) =>\n FILLER.has(word) ||\n DESCRIBING.has(word) ||\n QUALITIES.has(word) ||\n /(?:ous|ful)$/.test(word) ||\n (word.length > 4 && /[^e]ed$/.test(word))\n const all = tagWords(tag)\n // \"Beautiful flowers\" shows flowers; \"roasted\" shows nothing; \"photo model\"\n // is a model and \"traveling couples\" are couples: a word before the last\n // that is a doing says what they do, never what they are.\n const list = all.filter(\n (word, index) =>\n !describing(word) &&\n !(all.length > 1 && /^(?:photo|picture|image)$/.test(word)) &&\n !(index < all.length - 1 && index > 0 && word.endsWith('ing') && !COUNTED_ING.has(word)),\n )\n if (!list.length || all.length > 3) return null\n // A phrase of no thing (\"up close\") or a doing (\"take pictures\", \"to lift\", \"work out\") is not what it shows.\n if (list.every((word) => STOPWORDS.has(word) && !SAID_PEOPLE.has(word))) return null\n if (/^(?:to|take|taking|make|making|get|do|go|lie|in|on|at|for|with|by|of)$/.test(list[0] as string)) return null\n if (/^(?:out|up|off|down|away|on|in)$/.test(list[list.length - 1] as string)) return null\n if (list.some((word) => BRANDS.has(word))) return null\n if (list.every((word) => proper.has(word)))\n return list.map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`).join(' ')\n // Two people named side by side are both shown: \"bride groom\" is a bride and groom (AGL-3942).\n if (list.length === 2 && list.every((word) => PEOPLE_NOUNS.has(word)) && list[0] !== list[1])\n return `${articleFor(list[0] as string)} ${list[0]} and ${list[1]}`\n const last = list[list.length - 1] as string\n // An idea or a doing, never a thing: \"law\", \"feedback\", \"customer satisfaction\", \"participation\", \"weightlifting\".\n if (ABSTRACT_NOUNS.has(last) || ABSTRACT_NOUNS.has(aiStockStem(last)) || saysAnIdea(last)) return null\n const doing = last.endsWith('ing') && !COUNTED_ING.has(aiStockStem(last)) && !UNCOUNTED_ING.has(last)\n if (doing) return null\n const phrase = list.join(' ')\n const plural =\n PLURAL_NOUNS.has(last) || (aiStockStem(last) !== last && !/^(?:lens|canvas|atlas|gas|bus)$/.test(last))\n if (plural || MASS_NOUNS.has(last) || (STOPWORDS.has(list[0] as string) && !SAID_PEOPLE.has(list[0] as string)))\n return spelled(phrase)\n return `${articleFor(phrase)} ${spelled(phrase)}`\n}\n\n/** Letters said one by one, written in capitals: \"an SLR camera\", \"a DSLR\" (AGL-3942). */\nconst INITIALISMS = words('slr dslr tv dj diy bbq suv atv uv vr')\n\n/** A phrase as a description writes it, its initialisms in capitals. */\nconst spelled = (phrase: string) =>\n phrase\n .split(' ')\n .map((word) => (INITIALISMS.has(word) ? word.toUpperCase() : word))\n .join(' ')\n\n/** \"a\" or \"an\" before a phrase, an initialism by how its first letter is said: \"an SLR\", \"a DSLR\". */\nconst articleFor = (phrase: string) => {\n const first = phrase.split(' ')[0] ?? ''\n if (INITIALISMS.has(first)) return /^[aefhilmnorsx]/.test(first) ? 'an' : 'a'\n return /^(?:[aeio]|u(?!ni|s[eu]))/.test(phrase) ? 'an' : 'a'\n}\n\n/** Words a description never ends on: an article, a preposition, a conjunction. */\nconst DANGLING_END = /(?:\\s+(?:a|an|the|and|or|with|in|on|at|by|of|for|to|from|into|onto))+$/i\n\n/** One thing a photo's tags name, as {@link aiStockTagsAlt} says it. */\ninterface AiStockAltPart {\n said: string\n stems: string[]\n /** Its last word: what it is. */\n head: string\n kind: 'person' | 'place' | 'thing'\n /** The position of the tag that first named it. */\n index: number\n}\n\n/** Whether two words name one thing, one inside the other: \"law\" and \"lawyer\", \"cam\" and \"camera\". */\nfunction nearSynonyms(a: string, b: string): boolean {\n const [short, long] = a.length <= b.length ? [a, b] : [b, a]\n return short.length >= 3 && short !== long && (long.startsWith(short) || long.endsWith(short))\n}\n\n/**\n * A photo described from its own tags (AGL-3856): a short English phrase of\n * concrete things, never the library's comma-separated list: \"A train at a\n * station\", \"A confident lawyer in court\", \"A portrait of a businessman\", \"A\n * photographer with a camera on a beach\", \"A kettlebell in a gym\", \"An analog\n * camera\". It says one person at most (a role over a man or a woman, an adult\n * over a girl), what they hold or wear, or one or two things, and where:\n *\n * - an idea or a doing (\"law\", \"feedback\", \"training\", \"a read\",\n * \"participation\"), a maker's name (\"sony\"), a word for the photo itself\n * (\"photo\", \"spot\") and a look (\"moody\", \"analog\" alone, a season) are left\n * out; a quality (\"elderly\", \"analog\") is said before the one thing it\n * qualifies;\n * - of two words for one thing the first tag's stays (\"book\" over\n * \"bookwork\", \"camera\" over \"photo-camera\"), unless the later phrase holds\n * it whole (\"wedding dress\" over \"wedding\");\n * - a second thing comes only from the first two tags and where no place is\n * said, what a person holds only from the first three, where it is set\n * from the first ten;\n * - no word is said twice: never \"an elderly couple and an elderly\";\n * - the sky, the clouds and the light are no thing anyone holds, and the\n * weather is said as where it is: \"a couple in the fog at a wedding\",\n * \"a couple in the snow in the mountains\", never \"a couple with a sky at\n * sunset\" or \"a snow in the mountains\"; a feeling (\"care\", \"worry\") is no\n * thing either; whoever else is about (\"tourists\") is never said beside a\n * family; a parent beside a child is said with them (\"a father with a\n * girl\"); a tag that is a phrase of its own (\"couple on bench\") is read as\n * its parts; a time of day comes after where (\"in the mountains at\n * sunset\"), and a bench out of doors says where it stands (\"on a bench by\n * the lake\") (AGL-3988).\n *\n * `null` where no tag names a thing.\n */\nexport function aiStockTagsAlt(tags: readonly string[], proper: ReadonlySet<string> = new Set()): string | null {\n const parts: AiStockAltPart[] = []\n let quality = ''\n let portrait = false\n /** The weather it is in, said as where ({@link WEATHER}). */\n let weather = ''\n const read = tags.slice(0, ALT_PLACE_TAGS_READ).flatMap((tag, index) => tagParts(tag).map((part) => ({ tag: part, index })))\n for (const { tag, index } of read) {\n const lower = tag.toLowerCase().trim()\n const reading = index < ALT_TAGS_READ\n if (reading && (lower === 'portrait' || lower === 'portraits')) {\n portrait = true\n continue\n }\n if (QUALITIES.has(lower)) {\n if (reading) quality ||= lower\n continue\n }\n // The sky is never a thing a photo is described by; the weather is where it is.\n if (SCENERY.has(lower)) continue\n if (WEATHER[lower]) {\n if (reading) weather ||= WEATHER[lower] as string\n continue\n }\n const family = SAID_AS[lower]\n const said = family ? `${articleFor(family)} ${family}`.replace(/^an? (?=\\S+s$)/, '') : describedTag(tag, proper)\n if (!said) continue\n const bare = said.replace(/^an?\\s+/, '')\n const stems = stemList(bare)\n const head = bare.split(/\\s+/).pop()?.toLowerCase() ?? ''\n if (!head) continue\n const headStem = aiStockStem(head)\n const kind: AiStockAltPart['kind'] =\n PEOPLE_NOUNS.has(head) || PEOPLE_NOUNS.has(headStem) ? 'person' : PLACES[headStem] ? 'place' : 'thing'\n // Past the first tags only where it is set is read.\n if (!reading && kind !== 'place') continue\n // A hand or a body is never what a photo is described by.\n if (kind === 'thing' && (BODY_PARTS.has(head) || BODY_PARTS.has(headStem))) continue\n if (parts.some((part) => stems.every((stem) => part.stems.includes(stem)))) continue\n const part = { said, stems, head: headStem, kind, index }\n // A longer phrase of the same thing takes its place: \"elderly couple\" for \"couple\".\n const holds = parts.findIndex((held) => held.head === headStem && held.stems.every((stem) => stems.includes(stem)))\n if (holds >= 0) {\n parts.splice(holds, 1, { ...part, index: (parts[holds] as AiStockAltPart).index })\n continue\n }\n // Two words for one thing (\"book\" and \"bookwork\", \"cam\" and \"camera\"): the\n // first tag's stays; a person's are told apart by their role below.\n if (kind !== 'person' && parts.some((held) => held.kind !== 'person' && nearSynonyms(held.head, headStem))) continue\n parts.push(part)\n }\n // One person: a role among the first tags over a man, a woman, a girl\n // (\"businessman\" over \"man\"), else the first; a role tagged later is not\n // what the photo shows (\"bed, book, man, …, student\" is a man), nor is one\n // a model posed as (\"woman, model, show, teacher\" is a woman).\n const people = parts.filter((part) => part.kind === 'person')\n const posed = people.some((part) => part.head === 'model')\n let places = parts.filter((part) => part.kind === 'place')\n let things = parts.filter((part) => part.kind === 'thing')\n // A kind of thing only where nothing names the thing: \"a cat\", never \"a cat and an animal\".\n if (things.some((part) => !KINDS_OF_THING.has(part.head))) things = things.filter((part) => !KINDS_OF_THING.has(part.head))\n // A person tagged after the things a photo is of is not who it shows:\n // \"petri, camera, film, photography, photographer\" is a camera, and \"men,\n // silhouettes, camera, nature, photographer\" men with a camera.\n const leads = (part: AiStockAltPart) => portrait || part.index < ALT_PERSON_TAGS_READ || !things.length\n const role = posed\n ? undefined\n : people.find((part) => !GENERIC_PEOPLE.has(part.head) && part.index < ALT_ROLE_TAGS_READ && leads(part))\n // A parent beside a child is said with them (AGL-3988): \"A father with a\n // girl\", never \"a child with clouds\" of \"child, clouds, dad, dock, father\".\n const parent = people.find((part) => PARENTS.has(part.head) && part.index < ALT_ROLE_TAGS_READ)\n const child = people.find((part) => CHILDREN.has(part.head) && part.index < ALT_ROLE_TAGS_READ)\n const family = parent && child && (!role || role === parent || role === child) ? parent : undefined\n const person = family ?? role ?? people.find(leads)\n // Nothing but places: a desk is the thing in a classroom; \"a school in a classroom\" says one place.\n if (!person && !things.length && places.length > 1) {\n const object = places.find((part) => OBJECT_PLACES.has(part.head))\n if (object) {\n things = [object]\n places = places.filter((part) => part !== object)\n } else places = places.slice(0, 1)\n }\n const place = places[0]\n if (!person && !things.length && !place && !weather) return null\n /** Every word said so far, so none is said twice. */\n const said = new Set<string>()\n const fresh = (part: AiStockAltPart) => {\n const list = stemList(part.said.replace(/^an?\\s+/, ''))\n if (list.some((stem) => said.has(stem))) return false\n for (const stem of list) said.add(stem)\n return true\n }\n /** A quality before a single counted word: \"a confident lawyer\", \"an analog camera\". */\n const qualified = (part: AiStockAltPart) =>\n quality && /^an? \\S+$/.test(part.said) && !said.has(aiStockStem(quality))\n ? `${articleFor(quality)} ${quality} ${part.said.replace(/^an?\\s+/, '')}`\n : part.said\n let phrase = ''\n if (person && fresh(person)) {\n phrase = portrait ? `a portrait of ${person.said}` : qualified(person)\n const held = family && child && child !== person ? child : things.find((part) => part.index <= 2)\n if (!portrait && held && fresh(held)) phrase += ` ${CLOTHING.has(held.head) ? 'in' : 'with'} ${held.said}`\n } else if (things[0] && fresh(things[0])) {\n phrase = qualified(things[0])\n const second = things[1]\n if (second && second.index <= 1 && !place && fresh(second)) phrase += ` and ${second.said}`\n }\n /** A place as it is said alone: \"a classroom\", \"the mountains\", \"sunset\". */\n const placeOf = (part: AiStockAltPart) =>\n PLACES_SAID[part.head] ?? (BARE_PLACES.has(part.head) && /^an? \\S+$/.test(part.said) ? part.head : part.said)\n /** A place as it is said after what is there: \"in the mountains\", \"at sunset\", \"on a bench\". */\n const whereOf = (part: AiStockAltPart) => `${PLACES[part.head] ?? 'in'} ${placeOf(part)}`\n // The weather is said before where (AGL-3988): \"a couple in the fog at a\n // wedding\"; alone, it is what the photo shows: \"snow in the mountains\".\n if (weather && phrase) phrase += ` ${weather}`\n else if (weather) phrase = weather.replace(/^in the /, '')\n if (place && fresh(place)) {\n // A second place where the first is a time of day or a bench out of\n // doors: \"a couple in the mountains at sunset\", \"a couple on a bench by\n // the lake\"; never a bed in a room.\n const second = places.find(\n (part) =>\n part !== place &&\n !OBJECT_PLACES.has(part.head) &&\n !TIME_PLACES.has(part.head) &&\n (TIME_PLACES.has(place.head) || (place.head === 'bench' && OUTDOORS.has(part.head))),\n )\n const after = second && fresh(second) ? second : null\n const [first, last] = after && TIME_PLACES.has(place.head) ? [after, place] : [place, after]\n const tail = last ? ` ${whereOf(last)}` : ''\n phrase = phrase ? `${phrase} ${whereOf(first)}${tail}` : `${placeOf(first)}${tail}`\n }\n // Never a dangling article or preposition, whatever a tag left behind.\n phrase = phrase.replace(DANGLING_END, '').trim()\n if (!phrase || /^(?:a|an|the)$/i.test(phrase)) return null\n const out = `${phrase.charAt(0).toUpperCase()}${phrase.slice(1)}`\n return out.length > AI_STOCK_ALT_MAX ? out.slice(0, AI_STOCK_ALT_MAX).replace(/[\\s,]+\\S*$/, '') : out\n}\n\n/** The thing a description names: its subject's object, a trailing \"speaking calmly\" or \"dusted\" dropped. */\nfunction describedObject(text: string, sectionName: string): string {\n const list = aiStockSubjectWords(text, sectionName).split(/\\s+/).filter(Boolean)\n while (list.length > 1 && /(?:ing|ed|ly)$/.test(list[list.length - 1] as string)) list.pop()\n return aiStockObjectWord(list.join(' '))\n}\n\n/**\n * THE WORDS A PLACED STOCK PHOTO IS DESCRIBED BY (AGL-3805, AGL-3856).\n *\n * A slot's alt text is the model's, written for the picture the page asked\n * for before any photo was found, and a slot is filled by whatever the\n * library answers for its search: a hero searched by the business, a gallery\n * picture by its subject, a site in another language by English words alone.\n * Kept as written, it described a photo the page does not show: the beta.253\n * Panadería La Concha Dorada start (job eg4maZMGtN) captioned a round cake\n * dusted \"HOME MADE\" on a cloth \"Conchas recién horneadas sobre una charola en\n * el mostrador de la panadería\", and none of its nine photos showed what its\n * words said: a birthday cake with candles was \"the family kneading pan\n * dulce\", a plate of macarons the shop's display case.\n *\n * So the photo placed answers for its own words. `null` keeps the slot's: on\n * an English site whose words name the thing the photo is OF — their\n * subject's object (`aiStockSubjectWords`, a trailing \"speaking calmly\"\n * dropped) among the hit's first two tags. Any word of the subject among its\n * first three was not enough: the beta.259 Hartwell Reyes Family Law hero kept\n * \"Two attorneys speaking calmly with a client in a bright Columbus office\"\n * for a typewriter whose third tag was \"attorney\" (AGL-3856). A stand-in's\n * words ({@link AiLayoutPictureSlot.standIn}) are a search's, never a\n * description, and are never kept. Otherwise the photo is described by the\n * library's own words: its description where it writes one (a Pexels hit's\n * `alt`), else its first tags as an English phrase ({@link aiStockTagsAlt}),\n * never the library's tag list, and where no tag names a thing, the slot's\n * own subject: its words, else its section's name. The libraries write in English, and no model\n * translates them, so a site in another language takes the platform's own\n * words for an illustrative photo in its language (`aiLayoutLabel`), true of\n * any photo, as does a hit whose words name no thing.\n */\nexport function aiStockPhotoAlt(\n photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>,\n slot: Pick<AiLayoutPictureSlot, 'alt' | 'product' | 'standIn'>,\n input: { language?: string; sectionName?: string; proper?: ReadonlySet<string> } = {},\n): string | null {\n if (aiLayoutSpeaksOtherThanEnglish(input.language)) return aiLayoutLabel('illustrativePhoto', input.language)\n if (!slot.standIn) {\n const first = new Set(stemList((photo.tags ?? []).slice(0, 2).join(' ')))\n const objects = [slot.alt, ...(slot.product?.subjects ?? [])].map((text) => describedObject(text, input.sectionName ?? ''))\n if (objects.some((object) => object && first.has(object))) return null\n }\n const own = (photo.alt ?? '').replace(/\\s+/g, ' ').trim()\n if (own) return own.length > AI_STOCK_ALT_MAX ? `${own.slice(0, AI_STOCK_ALT_MAX).replace(/\\s+\\S*$/, '')}…` : own\n // No tag names a thing: the slot's own subject, as its words or its section's name say it, never a tag list.\n const subject = [slot.alt, input.sectionName ?? '']\n .map((text) => text.replace(/\\s+/g, ' ').trim())\n .find((text) => /[A-Za-zÀ-ɏ]/.test(text))\n const fallback = subject ? `${subject.charAt(0).toUpperCase()}${subject.slice(1)}`.slice(0, AI_STOCK_ALT_MAX) : ''\n return aiStockTagsAlt(photo.tags ?? [], input.proper) ?? (fallback || aiLayoutLabel('illustrativePhoto', input.language))\n}\n\n/** The names a business type writes with a capital, lowercased: \"columbus\", \"ohio\" (AGL-3856). */\nexport function aiStockProperWords(businessType: string): Set<string> {\n const found = new Set<string>()\n for (const [index, word] of businessType.split(/[^A-Za-zÀ-ɏ'-]+/).filter(Boolean).entries())\n if (index > 0 && /^[A-ZÀ-Þ]/.test(word)) found.add(word.toLowerCase())\n return found\n}\n\nconst EXTENSIONS: Record<string, string> = {\n 'image/jpeg': 'jpg',\n 'image/png': 'png',\n 'image/webp': 'webp',\n}\n\nexport interface AiLayoutStockPhotoSourceInput {\n hostId: string\n /** The member the photos are stored as: the job's creator. */\n uid: string\n /** The job's seed, as the starter photos turn by; also the scope a photo is placed under. */\n seed: string\n /** The site's business type, else the job's brief. */\n business: string\n /** The site's language, from its plan (AGL-3750); absent, English. */\n language?: string\n /**\n * The plan's photo words, in English (AGL-3760): what a site in another\n * language is searched by, in place of its business type and its alt texts,\n * unless its business type names a business listed in English\n * (`aiStockBusinessNoun`, AGL-3779), which leads.\n */\n photoWords?: string\n /**\n * The English name of the kind of site the person picked (AGL-3771): what a\n * site in another language is searched by when its business type names no\n * business listed in English (`aiStockBusinessNoun`, AGL-3779) and its plan\n * gave no photo words, rather than its business type in its own language.\n */\n kindWords?: string\n /**\n * The business's name, as the person typed it (AGL-3856): what an English\n * site is searched by when its business type names no world (\"a local\n * service business\") and its name names a craft this module lists\n * (\"Synchronicity Gym\"). Never its world otherwise.\n */\n name?: string\n /** Who the site is for, as the person typed it: searched as the name is, after it (AGL-3856). */\n audience?: string\n /**\n * The id of the kind of site the person picked (\"education\"): what a site\n * is searched by when nothing else names its world (AGL-3856).\n */\n kind?: string\n /** The page's section names, by plan index. */\n sectionNames: readonly string[]\n /**\n * The job the member started (`aiOriginJobId`), so a photo is placed once\n * across its pages. Absent, only the page itself is kept free of repeats.\n */\n jobId?: string\n /** Asset srcs or source keys the job's other pages already show. */\n avoid?: readonly string[]\n /** The most searches this source sends; a page's own bound where absent. A store's products search more (AGL-3676). */\n searches?: number\n signal?: AbortSignal\n}\n\nexport interface AiLayoutStockPhotoDeps {\n provider?: () => StockPhotoProvider | null\n ingest?: () => PluginMediaIngest | null\n budgetMs?: number\n /** The clock a refusal is dated by (AGL-3988); specs hand in a fixed one. */\n now?: () => number\n}\n\n/** A slot's choice: the accepted hits it may be filled from, best first, and the query that found them. */\ninterface AiStockChoice {\n candidates: StockPhoto[]\n query: string\n /** The search that answered them, as it was sent (AGL-3988): what the late photo pass asks again. */\n request: StockPhotoSearchRequest\n /** A photo another slot of the job already shows, reused rather than an off-topic one (AGL-3660). */\n repeat?: boolean\n}\n\n/** The words of a search that only this module reads, never sent to a library. */\nconst SEARCH_JUDGMENT_KEYS = [\n 'broad',\n 'subject',\n 'requires',\n 'object',\n 'kin',\n 'lead',\n 'leadWorld',\n 'first',\n 'category',\n 'strict',\n 'refuse',\n 'needs',\n 'allow',\n 'refuseLead',\n 'worldless',\n 'away',\n] as const\n\n/** A search as it is sent to the library: its words and size, none of how its hits are judged. */\nexport function aiStockSearchRequest(wanted: AiStockSearch): StockPhotoSearchRequest {\n const request: Record<string, unknown> = { ...wanted }\n for (const key of SEARCH_JUDGMENT_KEYS) delete request[key]\n return request as unknown as StockPhotoSearchRequest\n}\n\n/**\n * A search as a job keeps it to ask again (AGL-3988): only what a library's\n * request is made of, so asked again it is the same request, which the\n * provider's 24-hour cache answers.\n */\nexport function aiStockKeptRequest(request: StockPhotoSearchRequest): StockPhotoSearchRequest {\n return {\n query: request.query,\n ...(request.orientation ? { orientation: request.orientation } : {}),\n ...(request.minWidth ? { minWidth: request.minWidth } : {}),\n ...(request.minHeight ? { minHeight: request.minHeight } : {}),\n ...(request.people ? { people: true } : {}),\n }\n}\n\n/**\n * The library's own record of a photo copied into a site (AGL-3923, AGL-3988):\n * what the media library stores beside the bytes as `stockPhoto`, with the\n * credit its license asks for. One shape for every copy a job makes, a\n * page's and the late photo pass's.\n */\nexport function aiStockIngestRequest(\n provider: Pick<StockPhotoProvider, 'credit'>,\n input: { hostId: string; uid: string; photo: StockPhoto; bytes: { bytes: Uint8Array; contentType: string }; alt: string; query: string },\n): Parameters<PluginMediaIngest['ingest']>[0] {\n const { photo, bytes } = input\n const credit = provider.credit(photo)\n return {\n hostId: input.hostId,\n uid: input.uid,\n fileName: `${photo.provider}-${photo.id}.${EXTENSIONS[bytes.contentType] ?? 'jpg'}`,\n contentType: bytes.contentType,\n bytes: bytes.bytes,\n alt: input.alt,\n description: credit.text,\n stockPhoto: {\n key: stockPhotoSourceKey(photo),\n provider: photo.provider,\n providerLabel: credit.providerLabel,\n id: photo.id,\n pageUrl: photo.pageUrl,\n photographer: photo.photographer,\n ...(photo.photographerUrl ? { photographerUrl: photo.photographerUrl } : {}),\n license: credit.license,\n licenseUrl: credit.licenseUrl,\n attributionRequired: credit.attributionRequired,\n query: input.query,\n },\n }\n}\n\n/**\n * A job's language and English photo words (AGL-3760), the English name of\n * its kind of site (AGL-3771), and the business's name and audience as the\n * person typed them (AGL-3856), as a stock photo source takes them.\n */\nexport function aiStockPhotoWordsOf(job: {\n plan?: Pick<AiBuildPlan, 'language' | 'photoWords'> | null\n inputs?: Readonly<Record<string, unknown>> | null\n}): Pick<AiLayoutStockPhotoSourceInput, 'language' | 'photoWords' | 'kindWords' | 'name' | 'audience' | 'kind'> {\n const plan = job.plan\n const kind = job.inputs ? aiSiteKindOfInputs(job.inputs) : null\n // \"Restaurant & café\" searches as \"restaurant cafe\".\n const kindWords = kind ? kind.label.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '').replace(/&/g, ' ').replace(/\\s+/g, ' ').trim().toLowerCase() : ''\n const said = (key: string) => {\n const value = job.inputs?.[key]\n return typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim() : ''\n }\n const name = said('businessName')\n const audience = said('audience')\n return {\n ...(plan?.language ? { language: plan.language } : {}),\n ...(plan?.photoWords ? { photoWords: plan.photoWords } : {}),\n ...(kindWords ? { kindWords } : {}),\n ...(kind ? { kind: kind.id } : {}),\n ...(name ? { name } : {}),\n ...(audience ? { audience } : {}),\n }\n}\n\n/**\n * The subject a plan's photo words lead with (AGL-3769): its first word that\n * is not filler, with the place or person words that follow it — \"bakery\" of\n * \"bakery pan dulce conchas\", \"candle shop\" of \"candle shop soy candles\",\n * \"ceramic artist\" of \"ceramic artist stoneware bowls\". The words are subject\n * first, never an English noun phrase with its head last, and what follows\n * the subject may be the brief's own names in English letters: Panaderia La\n * Espiga Dorada's \"pan dulce conchas\" read as the business, made \"concha\" its\n * craft, and placed purple ceanothus flowers, tagged \"ceanothus concha\", as\n * its hero. Empty when every word is filler.\n */\nexport function aiStockPhotoWordsSubject(photoWords: string): string {\n const list = contentWords(photoWords)\n const start = list.findIndex((word) => !FILLER.has(word) && !SITE_KINDS.has(word))\n if (start < 0) return ''\n let end = start + 1\n while (end < list.length && (VENUES.has(list[end]) || ROLES.has(list[end]))) end += 1\n return list.slice(start, end).join(' ')\n}\n\n/**\n * What a source's photos are searched and judged by (AGL-3760, AGL-3769): a\n * site in another language by an English subject ({@link aiStockSourceSubject}:\n * its business named in English, else its plan's photo words' subject, else\n * its kind of site), every other site by its business type. One reading for\n * every slot of every source — hero, background, gallery, card, product,\n * post — so no slot searches by words another slot is held against. A site for\n * adults alone ({@link aiStockAdultsOnly}) is told so, whatever its world.\n */\nexport function aiStockSourceTerms(\n input: Pick<AiLayoutStockPhotoSourceInput, 'business' | 'language' | 'photoWords' | 'kindWords' | 'name' | 'audience' | 'kind'>,\n): AiStockSiteTerms {\n const terms = sourceWorldTerms(input)\n // Where the site's own words set it: a photographer \"in the Blue Ridge\" for \"mountain weddings\" (AGL-3856).\n const setting = aiStockSetting([input.business, input.audience ?? ''].join(' . '))\n // A craft whose pictures are people at a moment shows the moments its site names (AGL-3942).\n const work = terms.scenes ? aiStockWorkScenes([input.business, input.audience ?? ''].join(' . '), setting) : []\n return {\n ...terms,\n ...(aiStockAdultsOnly([input.audience, input.name, input.business]) ? { adults: true } : {}),\n ...(setting ? { setting } : {}),\n ...(work.length ? { work } : {}),\n }\n}\n\n/** What a source's photos are searched by: its world, as {@link aiStockSourceTerms} reads it. */\nfunction sourceWorldTerms(\n input: Pick<AiLayoutStockPhotoSourceInput, 'business' | 'language' | 'photoWords' | 'kindWords' | 'name' | 'audience' | 'kind'>,\n): AiStockSiteTerms {\n const english = aiStockSourceSubject(input)\n const terms = aiStockSiteTerms(english || input.business)\n if (english || (terms.domain.length && !aiStockIsAbbreviation(input.business))) return terms\n // A business type that names no world (\"a local service business\"), or\n // one the libraries do not know (\"LMS\"), is searched by the craft its\n // name, else its audience, names (AGL-3856): the beta.261 Synchronicity Gym\n // hero searched nothing at all and was left a black scrim, and its closing\n // band, held to no world, took a subway train for \"Ready to train\". Then by\n // the kind of site its name says (\"Adult Hybrid Learning Center\"), and\n // last by the kind of site the person picked: the beta.262 Adult Hybrid\n // Learning Center searched \"lms\" and shipped no photo at all.\n const craft = aiStockListedCraft(input.name ?? '') || aiStockListedCraft(input.audience ?? '')\n const kind = craft ? '' : aiStockNamedKind(input.name ?? '') || aiStockNamedKind(input.audience ?? '') || (input.kind ?? '')\n const found = craft ? aiStockSiteTerms(craft) : aiStockKindTerms(kind)\n if (!found) return terms\n return { ...found, named: [...new Set([...terms.named, ...found.named])] }\n}\n\n/**\n * Whether a business type is only an abbreviation the libraries do not know\n * (AGL-3856): \"LMS\", \"CRM\", \"B2B\". Its letters are no world to search.\n */\nexport function aiStockIsAbbreviation(businessType: string): boolean {\n const list = businessType.trim().split(/\\s+/).filter(Boolean)\n return list.length > 0 && list.length <= 2 && list.every((word) => /^[A-Z0-9&/.-]{2,6}s?$/.test(word) && /[A-Z]/.test(word))\n}\n\n/**\n * What a picture of each kind of site the guided start offers shows, where\n * nothing else says (AGL-3856): the words it is searched by, the words a\n * photo of it is tagged with, and its broad searches. A kind whose subject\n * is a craft {@link CRAFT_KIN} lists takes that craft's own.\n */\nconst KIND_SUBJECTS: Readonly<\n Record<string, { subject: string; kin?: readonly string[]; broad?: readonly string[]; shunLead?: readonly string[] }>\n> = {\n business: {\n subject: 'small business',\n kin: ['business', 'office', 'team', 'meeting', 'workplace', 'coworkers', 'entrepreneur', 'shop', 'service', 'customer'],\n broad: ['small business owner', 'team meeting office'],\n },\n trades: {\n subject: 'contractor',\n kin: ['contractor', 'construction', 'repair', 'renovation', 'tools', 'worker', 'handyman', 'plumber', 'electrician', 'house', 'roof'],\n broad: ['home repair contractor', 'construction worker tools'],\n },\n professional: {\n subject: 'consultant',\n kin: ['consultant', 'consulting', 'office', 'meeting', 'client', 'advisor', 'finance', 'accountant', 'lawyer', 'desk', 'business'],\n broad: ['consultant client meeting', 'professional office'],\n },\n wellness: {\n subject: 'wellness',\n kin: ['wellness', 'health', 'therapy', 'therapist', 'massage', 'spa', 'relaxation', 'clinic', 'healthcare'],\n broad: ['wellness therapy', 'massage therapy'],\n },\n restaurant: {\n subject: 'restaurant',\n kin: ['restaurant', 'dining', 'food', 'dish', 'chef', 'meal', 'cafe', 'cuisine', 'dinner', 'lunch'],\n broad: ['restaurant dining', 'restaurant food'],\n },\n store: {\n subject: 'boutique',\n kin: ['boutique', 'shop', 'store', 'shopping', 'retail', 'products', 'display', 'shelf'],\n broad: ['boutique shop', 'retail store display'],\n },\n portfolio: {\n subject: 'artist',\n kin: ['art', 'artist', 'design', 'creative', 'studio', 'workspace', 'painting', 'drawing'],\n broad: ['artist studio', 'creative workspace'],\n // \"Artist\" names a bee and a tattooist as often as a painter (AGL-3923):\n // the beta.266 Mexicano hero's first pick was \"artist bee, giant artist bee\".\n shunLead: ['bee', 'insect', 'insects', 'tattoo', 'makeup', 'cosmetics'],\n },\n studio: {\n subject: 'design studio',\n kin: ['design', 'designer', 'studio', 'creative', 'agency', 'team', 'workspace', 'office'],\n broad: ['design studio team', 'creative agency office'],\n },\n photography: { subject: 'photographer' },\n blog: {\n subject: 'writer',\n kin: ['writer', 'writing', 'notebook', 'laptop', 'desk', 'journal', 'reading', 'book'],\n broad: ['writer desk laptop', 'writing notebook'],\n },\n events: {\n subject: 'event',\n kin: ['event', 'celebration', 'party', 'wedding', 'venue', 'reception', 'gathering', 'decoration', 'banquet'],\n broad: ['event celebration', 'event venue decoration'],\n },\n fitness: { subject: 'gym' },\n yoga: {\n subject: 'yoga',\n kin: ['yoga', 'meditation', 'mindfulness', 'pose', 'mat', 'relaxation', 'stretching'],\n broad: ['yoga class', 'meditation'],\n },\n beauty: {\n subject: 'salon',\n kin: ['salon', 'beauty', 'hair', 'hairdresser', 'makeup', 'nails', 'manicure', 'stylist', 'spa', 'cosmetics'],\n broad: ['beauty salon', 'hair salon'],\n },\n realestate: {\n subject: 'real estate',\n kin: ['house', 'home', 'estate', 'property', 'interior', 'apartment', 'realtor', 'architecture', 'living'],\n broad: ['house exterior', 'home interior'],\n },\n education: {\n subject: 'classroom',\n kin: ['classroom', 'student', 'students', 'education', 'learning', 'e-learning', 'teacher', 'teaching', 'class', 'lecture', 'study', 'studying', 'course', 'school', 'seminar', 'training', 'book', 'books', 'laptop'],\n broad: ['adult students classroom', 'online learning', 'adult education'],\n },\n nonprofit: {\n subject: 'volunteers',\n kin: ['volunteer', 'volunteers', 'charity', 'helping', 'donation', 'nonprofit', 'team', 'people'],\n broad: ['charity volunteers', 'volunteers helping'],\n },\n music: {\n subject: 'musician',\n kin: ['music', 'musician', 'band', 'concert', 'guitar', 'stage', 'singer', 'instrument', 'piano', 'drums'],\n broad: ['live music band', 'musician guitar'],\n },\n personal: {\n subject: 'workspace',\n kin: ['workspace', 'desk', 'laptop', 'office', 'professional', 'notebook', 'coffee'],\n broad: ['workspace desk laptop', 'professional workspace'],\n },\n landing: {\n subject: 'startup team',\n kin: ['startup', 'team', 'technology', 'laptop', 'office', 'workspace', 'business', 'meeting'],\n broad: ['startup team office', 'modern workspace'],\n },\n 'coming-soon': {\n subject: 'workspace',\n kin: ['workspace', 'desk', 'laptop', 'office', 'notebook', 'coffee'],\n broad: ['modern workspace', 'workspace desk laptop'],\n },\n}\n\n/** Words a business's name or audience uses for a kind of site (AGL-3856): \"Learning Center\" is a school's. */\nconst NAMED_KINDS: ReadonlyArray<{ words: readonly string[]; kind: string }> = [\n {\n kind: 'education',\n words: ['learning', 'academy', 'school', 'tutoring', 'tutor', 'tutors', 'college', 'institute', 'university', 'courses', 'classes', 'lessons', 'education', 'students', 'learners'],\n },\n { kind: 'beauty', words: ['salon', 'barber', 'barbershop', 'nails', 'spa', 'lashes', 'brows'] },\n { kind: 'realestate', words: ['realty', 'realtor', 'realtors', 'properties', 'homes', 'estate'] },\n { kind: 'restaurant', words: ['restaurant', 'bistro', 'kitchen', 'grill', 'diner', 'eatery', 'cafe', 'café', 'tavern', 'pizzeria'] },\n { kind: 'trades', words: ['plumbing', 'roofing', 'hvac', 'electric', 'electrical', 'landscaping', 'construction', 'contracting', 'remodeling', 'painting', 'handyman'] },\n { kind: 'nonprofit', words: ['foundation', 'charity', 'church', 'ministry', 'nonprofit', 'volunteers'] },\n { kind: 'yoga', words: ['yoga', 'meditation', 'mindfulness'] },\n { kind: 'music', words: ['band', 'music', 'orchestra', 'choir', 'records'] },\n { kind: 'wellness', words: ['wellness', 'therapy', 'massage', 'clinic', 'chiropractic', 'counseling'] },\n]\n\n/** The kind of site a business's name or audience names ({@link NAMED_KINDS}), or empty. */\nexport function aiStockNamedKind(text: string): string {\n const named = new Set(text.toLowerCase().split(/[^a-zÀ-ɏ]+/).filter(Boolean))\n return NAMED_KINDS.find((entry) => entry.words.some((word) => named.has(word)))?.kind ?? ''\n}\n\n/** What a kind of site's pictures are searched and judged by ({@link KIND_SUBJECTS}); `null` for a kind not listed. */\nexport function aiStockKindTerms(kind: string): AiStockSiteTerms | null {\n const entry = KIND_SUBJECTS[kind]\n if (!entry) return null\n const base = aiStockSiteTerms(entry.subject)\n if (!entry.kin?.length) return base\n const kin = entry.kin.map(aiStockStem)\n const domain = [...new Set([...base.domain, ...kin])]\n return {\n ...base,\n domain,\n // The kind's own world is all of it: its subject and its kin (AGL-4065).\n lead: domain,\n broad: [...(entry.broad ?? base.broad)],\n // A hero names one of the kind's own words, never only the subject's.\n core: [...new Set([...base.core, ...kin])],\n ...(entry.shunLead?.length ? { shunLead: [...new Set([...base.shunLead, ...entry.shunLead.map(aiStockStem)])] } : {}),\n }\n}\n\n/**\n * The kind of site each starter is the shape of (`AiSiteKind.starter`): what\n * a picture is searched by, widened past the kind the person picked, where\n * nothing narrower found one (AGL-3923).\n */\nconst STARTER_KINDS: Readonly<Record<string, string>> = {\n business: 'business',\n 'physical-shop': 'store',\n portfolio: 'portfolio',\n landing: 'landing',\n}\n\n/** A kind's common photos ({@link KIND_GENERIC}): the words searched, and the words one of which a hit must name. */\ninterface AiStockGenericSet {\n kin: readonly string[]\n broad: readonly string[]\n}\n\nconst OFFICE: AiStockGenericSet = {\n kin: ['office', 'workspace', 'desk', 'laptop', 'computer', 'meeting', 'business', 'work', 'workplace', 'team', 'notebook', 'coffee', 'teamwork', 'conference'],\n broad: ['office workspace', 'business meeting', 'workspace desk laptop'],\n}\n\nconst WORKSPACE: AiStockGenericSet = {\n kin: ['workspace', 'desk', 'laptop', 'notebook', 'coffee', 'office', 'book', 'books', 'workplace'],\n broad: ['workspace desk laptop', 'notebook coffee desk'],\n}\n\n/**\n * The last searches a picture tries, for each kind of site the guided start\n * offers (AGL-3923): plain, common photos of where that kind's work happens,\n * which every library holds many of, held to their own words. Never a face\n * as the lead, never a child, never a product nor a rival business: a\n * restaurant's are its tables and plates, never an office. A kind with no set\n * keeps a slot nothing fits without a photo (AGL-3831).\n */\nconst KIND_GENERIC: Readonly<Record<string, AiStockGenericSet>> = {\n business: OFFICE,\n trades: {\n kin: ['tools', 'tool', 'toolbox', 'workbench', 'workshop', 'construction', 'repair', 'renovation', 'drill', 'hammer', 'wrench', 'roof', 'house', 'carpentry'],\n broad: ['tools workbench', 'home renovation', 'construction tools'],\n },\n professional: {\n kin: ['office', 'desk', 'documents', 'document', 'meeting', 'conference', 'laptop', 'workplace', 'business', 'notebook', 'paperwork', 'consulting'],\n broad: ['office desk documents', 'business meeting', 'conference room'],\n },\n wellness: {\n kin: ['spa', 'massage', 'wellness', 'relaxation', 'relax', 'towel', 'towels', 'candle', 'stones', 'therapy', 'treatment', 'aromatherapy'],\n broad: ['spa stones towel', 'massage room', 'wellness spa'],\n },\n restaurant: {\n kin: ['restaurant', 'table', 'dining', 'food', 'plate', 'dish', 'meal', 'kitchen', 'cafe', 'dinner', 'lunch', 'cuisine'],\n broad: ['restaurant interior', 'restaurant table food', 'food plate'],\n },\n store: {\n kin: ['shop', 'store', 'retail', 'shelf', 'shelves', 'display', 'interior', 'boutique', 'storefront', 'counter'],\n broad: ['shop interior', 'retail store'],\n },\n portfolio: {\n kin: ['studio', 'workspace', 'desk', 'art', 'design', 'creative', 'sketch', 'drawing', 'paint', 'painting', 'brush', 'brushes', 'canvas', 'pencil', 'pencils', 'paper'],\n broad: ['art supplies', 'creative workspace', 'art studio'],\n },\n studio: {\n kin: ['design', 'studio', 'workspace', 'desk', 'laptop', 'sketch', 'creative', 'office', 'drawing', 'pencil'],\n broad: ['design studio workspace', 'creative workspace', 'workspace desk laptop'],\n },\n photography: {\n kin: ['camera', 'cameras', 'photography', 'lens', 'photographer', 'studio', 'film', 'tripod'],\n broad: ['camera lens', 'photography studio', 'vintage camera'],\n },\n blog: {\n kin: ['notebook', 'desk', 'writing', 'laptop', 'coffee', 'journal', 'book', 'books', 'workspace', 'pen', 'typewriter'],\n broad: ['writing desk notebook', 'laptop coffee desk'],\n },\n events: {\n kin: ['event', 'venue', 'wedding', 'reception', 'party', 'celebration', 'table', 'decoration', 'banquet', 'hall', 'flowers'],\n broad: ['event venue decoration', 'banquet table', 'party decoration'],\n },\n fitness: {\n kin: ['gym', 'fitness', 'weights', 'dumbbell', 'dumbbells', 'barbell', 'kettlebell', 'workout', 'exercise', 'training'],\n broad: ['gym equipment', 'dumbbells gym', 'fitness gym'],\n },\n yoga: {\n kin: ['yoga', 'mat', 'meditation', 'studio', 'relaxation', 'candle', 'zen', 'mindfulness'],\n broad: ['yoga mat', 'yoga studio', 'meditation candle'],\n },\n beauty: {\n kin: ['salon', 'beauty', 'hair', 'makeup', 'cosmetics', 'nails', 'manicure', 'spa', 'mirror', 'brush', 'brushes'],\n broad: ['beauty salon interior', 'makeup brushes cosmetics', 'hair salon chair'],\n },\n realestate: {\n kin: ['house', 'home', 'interior', 'living', 'room', 'property', 'architecture', 'apartment', 'kitchen', 'estate'],\n broad: ['house exterior', 'home interior living room', 'modern kitchen interior'],\n },\n education: {\n kin: ['classroom', 'books', 'book', 'library', 'school', 'desk', 'education', 'learning', 'study', 'studying', 'notebook', 'chalkboard', 'blackboard', 'lecture'],\n broad: ['library books', 'classroom', 'study desk books'],\n },\n nonprofit: {\n kin: ['volunteer', 'volunteers', 'volunteering', 'charity', 'donation', 'donations', 'community', 'helping', 'help', 'hands'],\n broad: ['volunteers charity', 'donation box', 'community volunteering'],\n },\n music: {\n kin: ['music', 'guitar', 'piano', 'instrument', 'instruments', 'concert', 'stage', 'microphone', 'drums', 'studio', 'vinyl'],\n broad: ['guitar instrument', 'concert stage lights', 'music studio microphone'],\n },\n personal: WORKSPACE,\n landing: {\n kin: ['office', 'workspace', 'desk', 'laptop', 'computer', 'meeting', 'business', 'work', 'workplace', 'team', 'technology', 'startup'],\n broad: ['modern office', 'workspace desk laptop', 'business meeting'],\n },\n 'coming-soon': WORKSPACE,\n}\n\n/** The kind of site whose common photos each starter falls back to. */\nconst STARTER_GENERIC_KIND: Readonly<Record<string, string>> = {\n business: 'business',\n 'physical-shop': 'store',\n portfolio: 'portfolio',\n landing: 'landing',\n}\n\n/** Stems no common photo leads with: a face, a portrait (AGL-3923). */\nconst FACE_STEMS = ['face', 'portrait', 'selfie', 'headshot'].map(aiStockStem)\n\n/** The starter a kind of site follows ({@link STARTER_KINDS}); a kind not listed follows the business starter. */\nfunction starterOfKind(kind: string): string {\n const starter = aiSiteKind(kind)?.starter ?? 'business'\n return STARTER_KINDS[starter] ? starter : 'business'\n}\n\n/** A kind of site's common photos as a world to search and judge by ({@link KIND_GENERIC}); `null` for a kind with no set. */\nexport function aiStockKindGenericTerms(kind: string): AiStockSiteTerms | null {\n const set = KIND_GENERIC[kind]\n if (!set) return null\n const kin = [...new Set(set.kin.map(aiStockStem))]\n return {\n business: '',\n craft: '',\n domain: kin,\n broad: [...set.broad],\n making: [],\n named: [],\n rivals: [],\n core: kin,\n shun: [],\n shunLead: [],\n }\n}\n\n/**\n * Whether a site's world is only its own words (AGL-3923): no craft this\n * module lists and no kind of site named it, so its broad searches are its\n * business and its craft read back (\"freelencing\"), which a library may not\n * know at all.\n */\nexport function aiStockWorldIsUnlisted(terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'broad'>): boolean {\n const own = [...new Set([terms.business, terms.craft].map((word) => word.trim()).filter(Boolean))]\n return terms.broad.length > 0 && terms.broad.length === own.length && terms.broad.every((query, index) => query === own[index])\n}\n\n/**\n * Whether a site's world agrees with the kind of site the person picked\n * (AGL-3923): it was read from the kind, or names one of the kind's own\n * words. A gym whose owner picked Business & services does not, and is never\n * given an office.\n */\nfunction worldOfKind(terms: Pick<AiStockSiteTerms, 'craft' | 'broad' | 'domain'>, kind: string): boolean {\n const own = aiStockKindTerms(kind)\n if (!own) return false\n if (own.craft === terms.craft && own.broad.join('|') === terms.broad.join('|')) return true\n const words = new Set([...own.domain, ...(aiStockKindGenericTerms(kind)?.domain ?? [])])\n return terms.domain.some((stem) => words.has(stem))\n}\n\n/**\n * What a picture is searched by once nothing narrower found it a photo\n * (AGL-3923), widest last.\n *\n * - A site whose world is its own words alone ({@link aiStockWorldIsUnlisted})\n * widens to the kind of site the person picked, the kind its starter is the\n * shape of, and last the kind's own common photos ({@link KIND_GENERIC}),\n * else its starter's.\n * - Any other site widens only to its kind's own common photos, and only\n * where its world agrees with that kind ({@link worldOfKind}): a portfolio\n * read from its kind takes art supplies before no photo at all, and a\n * barbecue caterer whose kind says nothing of food never takes an office\n * (AGL-3831). A kind with no set keeps a slot nothing fits without a photo.\n *\n * A rung that would search what an earlier one did is left out.\n *\n * The beta.265 Kasvora Marketing Solutions start (job BK3r4I8bF1) typed its\n * business as \"Freelencing site offer services\": its world was the one word\n * \"freelencing\", which no library tags, so its cover hero searched it, found\n * nothing, and shipped a flat dark band with no photo.\n */\nexport function aiStockWiderTerms(\n terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'broad' | 'domain'> & Partial<Pick<AiStockSiteTerms, 'lead'>>,\n kind: string,\n): Array<{ rung: 'kind' | 'starter' | 'generic'; terms: AiStockSiteTerms }> {\n const rungs: Array<{ rung: 'kind' | 'starter' | 'generic'; terms: AiStockSiteTerms }> = []\n const seen = new Set<string>([JSON.stringify([terms.craft, [...terms.broad]])])\n // An outdoor or a trade world never widens to an office's photos (AGL-4065).\n const outdoor = aiStockWorldIsOutdoorOrTrade(terms)\n const add = (rung: 'kind' | 'starter' | 'generic', of: string, found: AiStockSiteTerms | null) => {\n if (!found || !found.broad.length) return\n if (outdoor && OFFICE_KINDS.has(of)) return\n const key = JSON.stringify([found.craft, found.broad])\n if (seen.has(key)) return\n seen.add(key)\n rungs.push({ rung, terms: found })\n }\n if (!aiStockWorldIsUnlisted(terms)) {\n if (kind && worldOfKind(terms, kind)) add('generic', kind, aiStockKindGenericTerms(kind))\n return rungs\n }\n const starter = starterOfKind(kind)\n const starterKind = STARTER_KINDS[starter] ?? 'business'\n if (kind) add('kind', kind, aiStockKindTerms(kind))\n add('starter', starterKind, aiStockKindTerms(starterKind))\n const generic = KIND_GENERIC[kind] ? kind : (STARTER_GENERIC_KIND[starter] ?? 'business')\n add('generic', generic, aiStockKindGenericTerms(generic))\n return rungs\n}\n\n/**\n * The kinds of site whose photos are an office, a desk or a workspace\n * (AGL-4065): what a landscaper, a roofer or a taco trailer never widens to.\n */\nconst OFFICE_KINDS: ReadonlySet<string> = new Set(['business', 'landing', 'professional', 'personal', 'coming-soon', 'studio'])\n\n/**\n * Words of a world whose work is done outdoors, on a vehicle, with tools or\n * over food (AGL-4065), as stems: such a world's pictures are never an\n * office's. The Bluebonnet Yard & Landscape start, a world the module did not\n * list, picked as Business & services, opened every page on an office.\n */\nconst OUTDOOR_AND_TRADE_STEMS: ReadonlySet<string> = new Set(\n (\n 'landscaping landscaper landscape lawn garden gardening yard roof roofing roofer fence fencing deck patio construction ' +\n 'contractor farm ranch moto motorcycle motocross bike dirt atv truck trailer tow towing auto car mechanic food ' +\n 'restaurant kitchen taco plumbing plumber electrician electrical hvac painting painter handyman carpentry carpenter ' +\n 'tree pool pest cleaning junk excavation concrete masonry welding'\n )\n .split(' ')\n .map(aiStockStem),\n)\n\n/** Whether a site's own world is outdoors, on a vehicle, with tools or over food ({@link OUTDOOR_AND_TRADE_STEMS}). */\nexport function aiStockWorldIsOutdoorOrTrade(\n terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'domain'> & Partial<Pick<AiStockSiteTerms, 'lead'>>,\n): boolean {\n const own = [...(terms.lead ?? terms.domain), ...stemList(`${terms.business} ${terms.craft}`)]\n return own.some((term) => term.split(' ').some((stem) => OUTDOOR_AND_TRADE_STEMS.has(stem)))\n}\n\n/**\n * The first word of a text that names a craft {@link CRAFT_KIN} lists, as\n * its table writes it: \"gym\" of \"Synchronicity Gym\", \"law\" of \"Hartwell\n * Reyes Family Law\". Empty where it names none, so a name that is only a\n * name (\"Hillside\") never becomes a world.\n */\nexport function aiStockListedCraft(text: string): string {\n for (const stem of stemList(text))\n for (const group of CRAFT_KIN) {\n const word = group.match.find((match) => aiStockStem(match) === stem)\n if (word) return word\n }\n return ''\n}\n\n/**\n * What a site in another language is searched by ({@link aiStockSourceTerms}),\n * in this order (AGL-3779):\n *\n * 1. The English name of the business its type names, where the curated table\n * knows it ({@link aiStockBusinessNoun}): \"florist\" for \"Una floristería en\n * Sevilla\". It leads whatever the plan's photo words say, because the words\n * are the model's and the table is not: a live plan for that florist gave\n * \"wedding bouquets event flowers\", whose subject, \"wedding\", would have\n * searched every slot, its hero included, by weddings.\n * 2. Its photo words' subject (AGL-3760, AGL-3769), for a business the table\n * does not list.\n * 3. The English name of its kind of site (AGL-3771), where the plan gave\n * none. Panaderia El Trigal's pages searched \"con pan dulce\" and placed the\n * Río Dulce; searched by its kind, a bakery's hero took a coffee mug\n * (\"restaurant cafe\"), which is why it comes last.\n *\n * The photo words' other words were never searched by (AGL-3769), so a site\n * the table names is searched by its name alone. Empty for every other site.\n */\nfunction aiStockSourceSubject(\n input: Pick<AiLayoutStockPhotoSourceInput, 'business' | 'language' | 'photoWords' | 'kindWords'>,\n): string {\n if (!aiLayoutSpeaksOtherThanEnglish(input.language)) return ''\n return (\n aiStockBusinessNoun(input.business) ||\n aiStockPhotoWordsSubject(input.photoWords ?? '') ||\n (input.kindWords ?? '').trim()\n )\n}\n\n/**\n * The source for one page, or `null` when this deployment has no stock\n * photo library or no media door, which leaves every slot to the starters.\n */\nexport function aiLayoutStockPhotoSource(\n input: AiLayoutStockPhotoSourceInput,\n deps: AiLayoutStockPhotoDeps = {},\n): AiLayoutPictureSource | null {\n const provider = (deps.provider ?? stockPhotoProvider)()\n const ingest = (deps.ingest ?? pluginMediaIngest)()\n if (!provider || !ingest || !input.hostId || !input.uid) return null\n // The libraries are tagged in English (AGL-3760). A Spanish bakery's type,\n // \"Una panadería familiar de San Antonio con pan dulce…\", read as the\n // business \"con pan dulce\", and its hero searched that and placed the Río\n // Dulce at dusk; a site in another language is searched by its plan's\n // English photo words' subject ({@link aiStockSourceTerms}), and its slots'\n // alt texts, in its own language, name no subject a search could use.\n const english = aiStockSourceSubject(input)\n const terms = aiStockSourceTerms(input)\n // Where a picture's own world finds nothing, the wider worlds it tries (AGL-3923).\n const wider = aiStockWiderTerms(terms, input.kind ?? '')\n const unlisted = aiStockWorldIsUnlisted(terms)\n const proper = aiStockProperWords(input.business)\n const now = deps.now ?? Date.now\n return async (slots, report) => {\n const timeout = AbortSignal.timeout(\n deps.budgetMs ?? AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS,\n )\n const signal = input.signal\n ? AbortSignal.any([input.signal, timeout])\n : timeout\n const scope = input.seed\n const job = jobPhotos(input.jobId ? `${input.hostId}:${input.jobId}` : null)\n const avoid = new Set(input.avoid ?? [])\n /** Placed elsewhere in the job: by another page in this process, or one the caller read. */\n const elsewhere = (key: string) =>\n avoid.has(key) || (job?.has(key) === true && job.get(key) !== scope)\n /** Source keys this page has claimed for a slot, or turned down. */\n const claimed = new Set<string>()\n /** The photos this page's slots have claimed, first choices, by slot order. */\n const shown: StockPhoto[] = []\n /** Asset srcs this page has placed. */\n const placedSrcs = new Set<string>()\n const answers = new Map<string, Promise<StockPhoto[] | null>>()\n /** The wider world a widened search is judged by (AGL-3923); a search not listed is judged by the site's. */\n const worldOf = new WeakMap<AiStockSearch, AiStockSiteTerms>()\n let searches = 0\n let storing = true\n /** Slots a photo was chosen for and could not be copied into the library (AGL-3923). */\n const uncopied = new Set<AiLayoutPictureSlot>()\n /** Each slot's picks the image hosts would not hand over, and when (AGL-3988). */\n const refusedPicks = new Map<AiLayoutPictureSlot, { keys: string[]; at: number }>()\n /** Whether the library answered any search of this page: a slot left empty then found nothing fitting. */\n let answered = false\n const remember = (sourceKey: string, src: string) => {\n placedSrcs.add(src)\n job?.set(sourceKey, scope)\n job?.set(src, scope)\n }\n /** A search's hits; the same words twice are answered from memory, and `null` once the page's searches are spent. */\n const search = (wanted: AiStockSearch): Promise<StockPhoto[] | null> => {\n const request = aiStockSearchRequest(wanted)\n const key = JSON.stringify([\n request.query,\n request.orientation,\n request.people === true,\n ])\n const known = answers.get(key)\n if (known) return known\n if (searches >= (input.searches ?? AI_LAYOUT_STOCK_SEARCHES_PER_PAGE))\n return Promise.resolve(null)\n searches += 1\n const asked = provider\n .search(request, { signal })\n .then((found) => {\n if (found) answered = true\n return found?.photos ?? []\n })\n .catch(() => [] as StockPhoto[])\n answers.set(key, asked)\n return asked\n }\n /** The photo's own words where the slot's do not describe it ({@link aiStockPhotoAlt}). */\n const altFor = (photo: StockPhoto, slot: AiLayoutPictureSlot) =>\n aiStockPhotoAlt(photo, slot, {\n ...(input.language ? { language: input.language } : {}),\n sectionName: input.sectionNames[slot.sectionIndex] ?? '',\n proper,\n })\n /** The photo placed in the site's library, a copy it holds or a new one; `null` when it cannot be placed. */\n const keep = async (\n photo: StockPhoto,\n slot: AiLayoutPictureSlot,\n query: string,\n repeat = false,\n ): Promise<AiLayoutPicturePhoto | null> => {\n const sourceKey = stockPhotoSourceKey(photo)\n const alt = altFor(photo, slot)\n const described = alt === null ? {} : { alt }\n try {\n const kept = await ingest.findStockPhoto({\n hostId: input.hostId,\n sourceKey,\n })\n if (kept) {\n // Held because a slot of this page or another page of the job shows it.\n if (!repeat && (placedSrcs.has(kept.src) || elsewhere(kept.src)))\n return null\n remember(sourceKey, kept.src)\n return {\n src: kept.src,\n width: kept.width ?? photo.width,\n height: kept.height ?? photo.height,\n ...described,\n }\n }\n // A refusal to store (the storage band, a lockdown) holds for the\n // whole page, so the rest of it reuses what it can and copies nothing.\n if (!storing || signal.aborted) return null\n const bytes = await provider.download(photo, {\n maxBytes: AI_LAYOUT_STOCK_MAX_BYTES,\n signal,\n })\n if (!bytes || signal.aborted || !storing) {\n // A copy the library would not hand over is otherwise silent (AGL-3923).\n if (!bytes && !signal.aborted) {\n uncopied.add(slot)\n // Asked for again by the late photo pass, once the burst is over (AGL-3988).\n const held = refusedPicks.get(slot) ?? { keys: [], at: 0 }\n if (!held.keys.includes(sourceKey)) held.keys.push(sourceKey)\n held.at = now()\n refusedPicks.set(slot, held)\n console.warn('ai layout pictures: a stock photo could not be downloaded', { provider: photo.provider, id: photo.id })\n }\n return null\n }\n const stored = await ingest.ingest(\n aiStockIngestRequest(provider, { hostId: input.hostId, uid: input.uid, photo, bytes, alt: alt ?? slot.alt, query }),\n )\n if (stored.ok) {\n remember(sourceKey, stored.src)\n return {\n src: stored.src,\n width: stored.width ?? photo.width,\n height: stored.height ?? photo.height,\n ...described,\n }\n }\n const refusal = stored as Extract<\n PluginMediaIngestResult,\n { ok: false }\n >\n // One photo's own bytes refused (AGL-3923): the beta.267 Brightvale\n // start's first pick, Pixabay 10157445, came labeled image/png and was\n // not PNG, and that one 415 stopped every copy on all four of its\n // pages, which then showed the starters' pottery bench and coffee\n // shop. Such a refusal is this photo's: the slot tries its next hit.\n const ofThisPhoto = AI_STOCK_PHOTO_OWN_REFUSALS.has(refusal.status)\n if (ofThisPhoto) {\n uncopied.add(slot)\n // Never tried again by this page's other slots, nor by the job's other pages.\n claimed.add(sourceKey)\n job?.set(sourceKey, REFUSED_BY_THE_LIBRARY)\n } else storing = false\n console.warn(\n 'ai layout pictures: the media library refused a stock photo',\n {\n status: refusal.status,\n reason: refusal.reason,\n provider: photo.provider,\n id: photo.id,\n holds: ofThisPhoto ? 'this photo' : 'the page',\n },\n )\n } catch (error) {\n uncopied.add(slot)\n console.warn('ai layout pictures: a stock photo could not be kept', {\n error: String(error),\n })\n }\n return null\n }\n\n /**\n * How a search's hits are judged for a slot. On a site for adults alone no\n * hit names a child; a portrait of one of the business's people names an\n * adult, never leads with a child, and is preferred in its role (AGL-3856).\n */\n const judgementFor = (\n slot: AiLayoutPictureSlot,\n request: AiStockSearch,\n subject: string,\n ): AiStockJudgement => {\n const refuse = [...(request.refuse ?? []), ...(terms.adults ? CHILD_STEMS : [])]\n const role = slot.people ? aiStockPeopleRole(slot.alt, input.sectionNames[slot.sectionIndex] ?? '') : null\n return {\n ...judgementOf(slot, request, subject, worldOf.get(request) ?? terms),\n ...(refuse.length ? { refuse: [...new Set(refuse)] } : {}),\n // An occupation is shown in it (a teacher, a coach); a team is any adult at work.\n ...(slot.people\n ? {\n needs: request.needs?.length ? request.needs : role?.required ? role.kin : ADULT_PEOPLE_STEMS,\n refuseLead: [...new Set([...CHILD_STEMS, ...(request.refuseLead ?? [])])],\n ...(role ? { roles: role.kin } : {}),\n // A teacher is shown teaching, never posing or painting (AGL-3856).\n ...(role?.scene?.length ? { roleScene: role.scene } : {}),\n ...(role?.refuse?.length ? { roleRefuse: aiStockRoleRefusals(role, slot.alt) } : {}),\n }\n : {}),\n }\n }\n /**\n * A search's own judgement, as its words set it, held to the world it was\n * asked for: the site's own, or a wider one where the site's found nothing\n * (AGL-3923). What lets a sensitive topic in is always the site's own words.\n */\n const judgementOf = (\n slot: AiLayoutPictureSlot,\n request: AiStockSearch,\n subject: string,\n world: AiStockSiteTerms,\n ): AiStockJudgement => ({\n subject: request.subject ?? (request.broad ? '' : subject),\n domain: world.domain,\n ...(world.lead?.length ? { world: world.lead } : {}),\n strict:\n (slot.role === 'gallery' && !request.broad) || !!request.requires || !!request.strict,\n named: request.allow?.length ? [...new Set([...terms.named, ...request.allow])] : terms.named,\n rivals: world.rivals,\n ...(world.shun.length || request.shun?.length\n ? { shun: [...new Set([...world.shun, ...(request.shun ?? [])])] }\n : {}),\n ...(world.shunLead.length ? { shunLead: world.shunLead } : {}),\n ...(request.product ? { product: true } : {}),\n ...(request.leadAny?.length ? { leadAny: request.leadAny } : {}),\n ...(request.requires ? { requires: request.requires } : {}),\n ...(request.category ? { category: request.category } : {}),\n ...(request.object ? { object: request.object } : {}),\n ...(request.kin ? { kin: request.kin } : {}),\n ...(request.lead ? { lead: true } : {}),\n ...(request.leadWorld ? { leadWorld: true } : {}),\n ...(request.first ? { first: true } : {}),\n ...(request.refuse?.length ? { refuse: request.refuse } : {}),\n ...(request.needs?.length ? { needs: request.needs } : {}),\n ...(request.refuseLead?.length ? { refuseLead: request.refuseLead } : {}),\n ...(request.away?.length ? { away: request.away } : {}),\n // A portfolio's record is of its own subject, never of the craft's world (AGL-3856).\n ...(request.worldless ? { domain: [], rivals: [] } : {}),\n })\n /**\n * The craft's own photos, the last thing a slot of a craft's site is\n * filled from (AGL-3660): its broad searches, any hit naming the craft\n * itself. Never a desk, a laptop or a living room for a soap shop.\n */\n const craftSearches = (slot: AiLayoutPictureSlot, world: AiStockSiteTerms = terms): AiStockSearch[] => {\n // A portfolio's record of the work is never filled by the craft's own\n // photos (AGL-3856), nor is any picture of a site that shows its work (AGL-3942).\n if (!world.core.length || aiStockShowsTheWork(slot, world) || aiStockShowsItsWork(slot, world)) return []\n const orientation = aiStockOrientation(slot.aspect)\n const size =\n slot.role === 'hero'\n ? { minWidth: 1600 }\n : orientation === 'vertical'\n ? { minHeight: 900 }\n : { minWidth: 900 }\n return world.broad.map((query) => ({\n query: clip(query),\n orientation,\n ...size,\n broad: true,\n category: world.core,\n ...(slot.role === 'hero' ? { first: true } : {}),\n ...(slot.product ? { product: true, tier: 'weak' as const } : {}),\n }))\n }\n\n /**\n * A slot's searches once its own world found it nothing (AGL-3923), in\n * order: the kind of site's world, the starter's, the slot's own words\n * alone held to no world, and last the starter's common photos. Each is\n * judged by the world it was asked for. A product, a portrait of the\n * business's people and a record's cover keep their own fallbacks.\n */\n const widerSearches = (slot: AiLayoutPictureSlot, subject: string, sectionName: string): AiStockSearch[] => {\n if (!wider.length || slot.product || slot.people || slot.record) return []\n const part = aiStockSlotPart(slot, sectionName)\n const asked: AiStockSearch[] = []\n const ask = (world: AiStockSiteTerms, requests: readonly AiStockSearch[]) => {\n for (const request of requests) {\n worldOf.set(request, world)\n asked.push(request)\n }\n }\n for (const { rung, terms: world } of wider) {\n if (rung === 'generic') continue\n ask(world, [...aiStockSearchesFor(slot, world, subject, part, sectionName), ...craftSearches(slot, world)])\n }\n const orientation = aiStockOrientation(slot.aspect)\n const size = slot.role === 'hero' ? { minWidth: 1600 } : orientation === 'vertical' ? { minHeight: 900 } : { minWidth: 900 }\n // The slot's own words, only where the site's world is its own words\n // alone, held to the kind's common world (AGL-3923), never to no world:\n // the beta.267 Brightvale closing band's \"ready talk marketing\" was\n // answered with a tin-can telephone, and its pets-and-owners answers\n // name no office either.\n const common = wider.find((rung) => rung.rung === 'generic')?.terms\n if (subject && unlisted && common) {\n const object = aiStockObjectWord(subject)\n const own = [...new Set([subject, object].map(clip).filter(Boolean))]\n ask(\n common,\n own.map((query) => ({ query, orientation, ...size, subject, strict: true })),\n )\n }\n // The kind's common photos: OF its world among their first tags, never\n // led by a face, never of a child (AGL-3923).\n for (const { rung, terms: world } of wider)\n if (rung === 'generic')\n ask(\n world,\n world.broad.map((query) => ({\n query: clip(query),\n orientation,\n ...size,\n broad: true,\n category: world.core,\n ...(slot.role === 'hero' ? { first: true } : { leadWorld: true }),\n refuse: CHILD_STEMS,\n refuseLead: FACE_STEMS,\n })),\n )\n return asked\n }\n\n // 1. Choose, slot by slot, so the page's choices never collide: each\n // slot claims its best accepted hit before the next slot looks.\n const choices: Array<AiStockChoice | null> = []\n for (const [index, slot] of slots.entries()) {\n if (signal.aborted) {\n choices.push(null)\n continue\n }\n const sectionName = input.sectionNames[slot.sectionIndex] ?? ''\n const subject = english ? '' : aiStockSubjectWords(slot.alt, sectionName)\n let choice: AiStockChoice | null = null\n const requests = [\n ...(slot.product\n ? aiStockProductSearches(slot, terms.craft, terms.domain, {\n broad: terms.broad,\n core: terms.core,\n })\n : aiStockSearchesFor(\n slot,\n terms,\n subject,\n aiStockSlotPart(slot, sectionName),\n sectionName,\n )),\n ...craftSearches(slot),\n ]\n /** Whether the library answered any of the slot's own searches with a photo at all (AGL-4065). */\n let knew = false\n /** The slot's accepted hits for a search; `null` once the page's searches are spent. */\n const accepted = async (\n request: AiStockSearch,\n repeat: boolean,\n ): Promise<StockPhoto[] | null> => {\n const found = await search(request)\n if (found === null) return null\n if (found.length && !worldOf.has(request)) knew = true\n const blocked = new Set<string>()\n if (!repeat) {\n for (const key of claimed) blocked.add(key)\n for (const hit of found) {\n const key = stockPhotoSourceKey(hit)\n if (elsewhere(key)) blocked.add(key)\n }\n }\n // A photo the library refused for its own bytes is never a repeat either (AGL-3923).\n for (const hit of found) {\n const key = stockPhotoSourceKey(hit)\n if (job?.get(key) === REFUSED_BY_THE_LIBRARY) blocked.add(key)\n }\n const judgement = judgementFor(slot, request, subject)\n const ranked = aiStockRank(found, blocked, `${input.seed}:${index}:${request.query}`, judgement)\n // A team's portraits are of different people where the hits allow (AGL-3856).\n return slot.people && !repeat ? aiStockFreshShootsFirst(ranked, shown, judgement) : ranked\n }\n /** The first of these searches with a hit to take: a new one, or one the job already shows. */\n const choose = async (\n tried: readonly AiStockSearch[],\n repeat: boolean,\n ): Promise<AiStockChoice | null> => {\n for (const request of tried) {\n if (signal.aborted) return null\n // Spent searches answer nothing; those already asked still answer from memory.\n const ranked = await accepted(request, repeat)\n if (!ranked?.length) continue\n if (!repeat) {\n claimed.add(stockPhotoSourceKey(ranked[0] as StockPhoto))\n shown.push(ranked[0] as StockPhoto)\n }\n return {\n candidates: ranked.slice(0, AI_LAYOUT_STOCK_TRIES_PER_SLOT),\n query: request.query,\n request: aiStockKeptRequest(aiStockSearchRequest(request)),\n ...(repeat ? { repeat: true } : {}),\n }\n }\n return null\n }\n // 2. Nothing new of its own: a product or a hero reuses an on-topic\n // photo another slot of the job already shows (a product may repeat\n // a collection tile's photo, or another product's) before the\n // starters' desk or living room fills it (AGL-3660). Any other\n // picture keeps \"never twice\". A product goes by how sure each\n // search is: its own and its category's photos, new and then\n // repeated, before a weak hit of its own (the Tidewater sauna).\n const repeats = Boolean(slot.product) || slot.role === 'hero'\n const sure = slot.product\n ? requests.filter((request) => request.tier !== 'weak')\n : requests\n const unsure = slot.product\n ? requests.filter((request) => request.tier === 'weak')\n : []\n // 3. Nothing of its own world at all: the wider worlds (AGL-3923), new\n // and then, for a hero, one the job already shows. A listed world\n // widens only where the library knew nothing of it (AGL-4065): one\n // it answered with photos it turned down keeps its slot without a\n // photo, never an office. A world of its own words alone still widens.\n const widened = widerSearches(slot, subject, sectionName)\n const phases: Array<[readonly AiStockSearch[], boolean, boolean]> = [\n [sure, false, false],\n ...(repeats ? [[sure, true, false] as [readonly AiStockSearch[], boolean, boolean]] : []),\n ...(unsure.length\n ? [\n [unsure, false, false] as [readonly AiStockSearch[], boolean, boolean],\n [unsure, true, false] as [readonly AiStockSearch[], boolean, boolean],\n ]\n : []),\n ...(widened.length ? [[widened, false, true] as [readonly AiStockSearch[], boolean, boolean]] : []),\n ...(widened.length && repeats ? [[widened, true, true] as [readonly AiStockSearch[], boolean, boolean]] : []),\n ]\n for (const [tried, repeat, wide] of phases) {\n if (choice || signal.aborted) break\n if (wide && knew && !unlisted) break\n choice = await choose(tried, repeat)\n }\n choices.push(choice)\n }\n\n // 3. Keep, a few at a time; a copy that fails tries the slot's next\n // accepted hit no other slot has claimed. A repeat waits for the\n // slot it repeats, so the library never holds a photo twice.\n const photos: Array<AiLayoutPicturePhoto | null> = slots.map(() => null)\n /** What this pass placed, by source key. */\n const placedByKey = new Map<string, AiLayoutPicturePhoto>()\n const fill = async (index: number) => {\n const choice = choices[index]\n const slot = slots[index]\n if (!choice || !slot) return\n for (const [rank, candidate] of choice.candidates.entries()) {\n if (signal.aborted) return\n const key = stockPhotoSourceKey(candidate)\n if (choice.repeat) {\n // Placed for another slot, it is described for this one.\n const shown = placedByKey.get(key)\n const alt = shown ? altFor(candidate, slot) : null\n const placed = shown\n ? { src: shown.src, width: shown.width, height: shown.height, ...(alt === null ? {} : { alt }) }\n : await keep(candidate, slot, choice.query, true)\n if (placed) {\n photos[index] = placed\n return\n }\n continue\n }\n if (rank > 0) {\n if (claimed.has(key)) continue\n claimed.add(key)\n }\n const placed = await keep(candidate, slot, choice.query)\n if (placed) {\n placedByKey.set(key, placed)\n photos[index] = placed\n return\n }\n }\n }\n const firsts = slots\n .map((_slot, index) => index)\n .filter((index) => !choices[index]?.repeat)\n let next = 0\n const worker = async () => {\n while (next < firsts.length) {\n const index = firsts[next] as number\n next += 1\n await fill(index)\n }\n }\n await Promise.all(\n Array.from(\n { length: Math.min(AI_LAYOUT_STOCK_COPIES_AT_ONCE, firsts.length) },\n worker,\n ),\n )\n for (const [index, choice] of choices.entries())\n if (choice?.repeat) await fill(index)\n // A slot left without a photo because its picks were refused: what they\n // were, for the late photo pass to ask for again (AGL-3988).\n for (const [index, slot] of slots.entries()) {\n const held = refusedPicks.get(slot)\n const choice = choices[index]\n if (photos[index] || !held?.keys.length || !choice) continue\n report?.refused.set(slot, { request: choice.request, keys: held.keys, at: new Date(held.at).toISOString() })\n }\n // The library answered and nothing in it fits: no photo rather than a\n // starter that shows another business (AGL-3831). A library that never\n // answered, or a site that refused to store, leaves the starters.\n // A slot whose fitting photo could not be copied was failed by the\n // library, as one that never answered is, and takes a starter rather\n // than lose its picture (AGL-3923).\n return answered && storing\n ? photos.map((photo, index) => photo ?? (uncopied.has(slots[index] as AiLayoutPictureSlot) ? null : AI_LAYOUT_NO_PHOTO))\n : photos\n }\n}\n"],"names":["pluginMediaIngest","STOCK_PHOTO_QUERY_MAX_CHARS","stockPhotoProvider","stockPhotoSourceKey","AI_LAYOUT_NO_PHOTO","aiLayoutSeedNumber","aiStorefrontSays","aiLayoutLabel","aiLayoutSpeaksOtherThanEnglish","aiSiteKind","aiSiteKindOfInputs","aiStockBusinessNoun","AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS","AI_LAYOUT_STOCK_SEARCHES_PER_PAGE","AI_LAYOUT_STOCK_PICK_WINDOW","AI_LAYOUT_STOCK_TRIES_PER_SLOT","AI_LAYOUT_STOCK_COPIES_AT_ONCE","AI_LAYOUT_STOCK_MAX_BYTES","AI_STOCK_PHOTO_OWN_REFUSALS","Set","AI_STOCK_PHOTO_PAGES_INPUT","AI_STOCK_PHOTO_AVOID_INPUT","AI_STOCK_PHOTO_JOB_PHOTOS_INPUT","AI_STOCK_PHOTO_LATE_PASS_INPUT","aiStockJobPhotosOf","value","Array","isArray","flatMap","entry","photo","src","width","Number","height","startsWith","alt","trim","words","list","split","STOPWORDS","SENTENCE_WORDS","GENERIC_OBJECTS","WORLD_OBJECTS","TRANSACTION_VERBS","TRANSACTION_STEMS","LEAD_GENERIC","FILLER","VENUES","ROLES","SITE_KINDS","DOING","BUSINESS_BREAK","PLACE_OR_AUDIENCE","WRAPPERS","REJECTED_TAGS","PRODUCT_SCENES","map","aiStockStem","FRAGRANCE_BOTTLES","SENSITIVE_TOPICS","allow","always","SENSITIVE_STEMS","topic","MAKERS","MAKER_STEMS","maker","stemList","join","withPairs","out","index","length","push","termsOf","texts","text","stemPhrase","phrase","SUITS","aiStockMakerTerms","tags","filter","tag","test","pageSlug","pageUrl","HAND_IDIOMS","withoutHands","reduce","idiom","replace","toLowerCase","saysMadeByHand","lower","some","lastIndex","found","OBJECT_KIN","objects","within","qualifier","kin","queries","shun","after","objectKin","object","world","find","word","includes","CRAFT_KIN","match","broad","rivals","core","making","shunLead","scenes","near","of","contentWords","has","endsWith","slice","CLAUSE_BREAK","businessOf","clause","businessClauses","businessType","clauses","breaker","RegExp","source","at","opener","raw","asked","matchAll","own","findIndex","first","next","right","left","head","every","splice","joined","aiStockBusinessWords","named","aiStockCraftWords","business","craft","groupTerm","aiStockSiteTerms","domain","made","said","ownSeen","firstWorld","place","isAsked","kept","stem","add","term","last","size","typeStems","typeTerms","positionOf","tail","undefined","MAX_SAFE_INTEGER","Math","min","names","group","sort","a","b","Boolean","groups","major","listed","craftGroup","makingSearches","alone","delete","ownTerms","leading","lead","served","ofAWorld","leadWord","query","PLACEHOLDER_SUBJECTS","subjectOf","aiStockSubjectWords","sectionName","then","entries","things","aiStockObjectWord","subject","reverse","clip","aiStockOrientation","aspect","aiStockSlotPart","slot","role","PEOPLE_SCENES","people","PORTRAIT_SCENE","CHILD_STEMS","ADULT_PEOPLE_STEMS","PEOPLE_ROLES","scene","refuse","loose","AI_STOCK_ROLE_TAGS_READ","aiStockPeopleRole","required","aiStockRoleRefusals","ADULT_AUDIENCE","YOUNG_AUDIENCE","aiStockAdultsOnly","SEASIDE","DESERT","CITYSCAPE","SCENE_SETTINGS","landscape","away","aiStockSettingAway","setting","candidate","aiStockScene","siteSetting","sceneWords","aiStockSetting","aiStockRecordScene","name","category","all","RECORD_SCENE_UNPEOPLED","aiStockWorkScenes","aiStockSettingIsLandscape","RECORD_ODD_LEADS","kinStems","PRODUCT_SIZES","GIFT_WRAPPERS","aiStockProductSearches","fallback","subjects","orientation","minHeight","minWidth","craftStems","product","kinPhrases","ownWorld","stems","tier","held","wrapped","gift","borrowed","seen","searches","key","common","heldTo","leadAny","leadWorld","requires","aiStockSearchesFor","terms","part","work","aiStockShowsTheWork","itsWork","aiStockShowsItsWork","namesCraft","namesMaker","shown","subjectStems","namesWorld","leadStems","qualify","ofTheWorld","worldNames","collection","makers","roleWord","record","sceneList","turn","thing","leads","ofWorld","recordNamed","refuseLead","shows","workLead","sceneSearch","one","ofWork","refused","strict","needs","worldless","workSearches","decodeURIComponent","URL","pathname","pop","hitWords","slug","phrases","leadPhrases","firstPhrase","rejected","among","aiStockSensitive","site","aiStockRelevance","judgement","hit","rival","owned","roleScene","roleRefuse","read","ALT_TAGS_READ","kinNamed","kinLead","anyOf","demanded","meets","worldLead","worldStems","firstNamed","pair","phrased","score","roles","max","aiStockRank","photos","used","seed","scored","ranked","start","aiStockSameShoot","id","abs","photographer","aiStockFreshShootsFirst","best","top","fresh","other","aiStockPick","aiStockPlacedSrcs","nodes","node","Object","values","componentId","props","aiStockPlacedPhotos","Map","set","JOB_PHOTOS","REFUSED_BY_THE_LIBRARY","JOB_PHOTOS_MAX","jobPhotos","placed","get","oldest","keys","aiStockForgetJobPhotos","clear","AI_STOCK_ALT_MAX","DESCRIBING","SCENERY","WEATHER","fog","mist","haze","rain","snow","snowfall","snowflakes","wind","QUALITIES","MASS_NOUNS","PLURAL_NOUNS","ABSTRACT_NOUNS","CONCRETE_ABSTRACT_ENDINGS","saysAnIdea","BRANDS","SAID_PEOPLE","COUNTED_ING","UNCOUNTED_ING","PEOPLE_NOUNS","GENERIC_PEOPLE","PARENTS","CHILDREN","SAID_AS","dad","dads","mom","moms","mum","mums","BODY_PARTS","KINDS_OF_THING","ALT_PERSON_TAGS_READ","ALT_ROLE_TAGS_READ","CLOTHING","PLACES","station","market","desk","table","counter","school","college","university","wedding","sunset","sunrise","dusk","dawn","beach","bed","sofa","couch","bench","trail","path","bridge","street","court","courtroom","office","kitchen","gym","studio","classroom","class","hall","room","garden","park","shop","store","bakery","cafe","restaurant","workshop","library","salon","clinic","forest","city","church","field","meadow","valley","mountain","hill","cliff","river","lake","lakeside","lakeshore","sea","ocean","seaside","coast","shore","sundown","waterfall","OBJECT_PLACES","BARE_PLACES","PLACES_SAID","TIME_PLACES","OUTDOORS","TAG_PREPOSITIONS","tagParts","ALT_PLACE_TAGS_READ","tagWords","describedTag","proper","describing","charAt","toUpperCase","articleFor","doing","plural","spelled","INITIALISMS","DANGLING_END","nearSynonyms","short","long","aiStockTagsAlt","family","parts","quality","portrait","weather","bare","reading","headStem","kind","holds","posed","places","parent","child","person","qualified","second","placeOf","whereOf","describedObject","aiStockPhotoAlt","input","language","standIn","aiStockProperWords","EXTENSIONS","SEARCH_JUDGMENT_KEYS","aiStockSearchRequest","wanted","request","aiStockKeptRequest","aiStockIngestRequest","provider","bytes","credit","hostId","uid","fileName","contentType","description","stockPhoto","providerLabel","photographerUrl","license","licenseUrl","attributionRequired","aiStockPhotoWordsOf","job","plan","inputs","kindWords","label","normalize","audience","photoWords","aiStockPhotoWordsSubject","end","aiStockSourceTerms","sourceWorldTerms","adults","english","aiStockSourceSubject","aiStockIsAbbreviation","aiStockListedCraft","aiStockNamedKind","aiStockKindTerms","KIND_SUBJECTS","trades","professional","wellness","portfolio","photography","blog","events","fitness","yoga","beauty","realestate","education","nonprofit","music","personal","landing","NAMED_KINDS","base","STARTER_KINDS","OFFICE","WORKSPACE","KIND_GENERIC","STARTER_GENERIC_KIND","FACE_STEMS","starterOfKind","starter","aiStockKindGenericTerms","aiStockWorldIsUnlisted","worldOfKind","aiStockWiderTerms","rungs","JSON","stringify","outdoor","aiStockWorldIsOutdoorOrTrade","rung","OFFICE_KINDS","starterKind","generic","OUTDOOR_AND_TRADE_STEMS","aiLayoutStockPhotoSource","deps","ingest","wider","unlisted","now","Date","slots","report","timeout","AbortSignal","budgetMs","signal","any","scope","jobId","avoid","elsewhere","claimed","placedSrcs","answers","worldOf","WeakMap","storing","uncopied","refusedPicks","answered","remember","sourceKey","search","known","Promise","resolve","catch","altFor","sectionNames","sectionIndex","keep","repeat","described","findStockPhoto","aborted","download","maxBytes","console","warn","stored","ok","refusal","ofThisPhoto","status","reason","error","String","judgementFor","judgementOf","craftSearches","widerSearches","ask","requests","choices","choice","knew","accepted","blocked","choose","tried","candidates","repeats","sure","unsure","widened","phases","wide","placedByKey","fill","rank","firsts","_slot","worker","from","toISOString"],"mappings":"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pB,iGACE;AAGJ;;;;;CAKC,GACD,MAAMmB,iBAAiB,IAAItC,IACzB;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAACuC,GAAG,CAACC;AAGR;;;;;CAKC,GACD,MAAMC,oBAAoB,IAAIzC,IAC5B;IAAC;IAAW;IAAY;IAAa;IAAW;IAAY;IAAU;IAAO;IAAY;CAAY,CAACuC,GAAG,CACvGC;AAIJ;;;;;;;;CAQC,GACD,MAAME,mBAKD;IACH;QACE,YAAY;QACZvB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDwB,OAAO;YAAC;YAAY;YAAU;YAAgB;SAAU;IAC1D;IACA;QACE,sBAAsB;QACtBxB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDwB,OAAO;YAAC;YAAW;YAAY;YAAa;YAAY;SAAY;IACtE;IACA;QACE,YAAY;QACZxB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDwB,OAAO;YAAC;YAAY;YAAY;YAAa;YAAW;SAAY;IACtE;IACA;QACE,mBAAmB;QACnBxB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDwB,OAAO;YAAC;YAAW;YAAW;YAAW;YAAW;SAAU;IAChE;IACA;QACE,kDAAkD;QAClDxB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;QACDwB,OAAO;YACL;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;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"}
|