feat: add photos for the 34 training-catalog items that had none
The banquet menu (18 dishes) and extras/supplies/delivery items (16) in the training catalog were seeded with photo:'', which the catalog tiles render as a plain red placeholder square. Sourced a real photo for each item (mostly Pexels, free license, picked and visually reviewed one by one to avoid mismatches -- several first search hits were wrong: a live chicken for "chicken caesar salad", a person in frame, branded bottles/cups) and two AI-generated (banquet-caprese, banquet-roastbeef). Converted to square 1024x1024 WebP with sharp. Wires the paths through the actual source of truth: ops/demo/trial- banquet-data.mjs and trial-extras-data.mjs now set photo to the real path, then ops/demo/build-trial-*.mjs regenerated public/demo/*.json and the matching Supabase seed-function migrations, so the client's static JSON fetch and the server-side company-provisioning function stay in sync. Bumped the demo-catalog fetch's own cache-busting query string in training-catalog.js (and its script-tag/precache version), since it's fetched by the client with a separate version from the outer script tags -- the same stale-cache class of bug fixed earlier this session. Verified: all 34 referenced files resolve (200) and decode as real 1024x1024 images; confirmed via the actual rendered catalog tiles (#tiles img[src]) that the extras category -- where the user's red-square screenshot was taken -- now serves the real photo paths. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
39
ops/demo/image-prompts-v2.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"note": "Photos for the 34 training-catalog items that previously had none (banquet-v1 dishes, extras-v1 sets/supplies/delivery). Sourced from Pexels (free license, no attribution required) by search + manual visual review; two items (banquet-caprese, banquet-roastbeef) were AI-generated instead. Files live in public/demo/images/<file>.webp, 1024x1024, resized/converted with sharp. Regenerate the catalog JSON with ops/demo/build-trial-banquet.mjs and ops/demo/build-trial-extras.mjs after editing the *-data.mjs sources.",
|
||||
"items": [
|
||||
{"itemId": "demo-banquet-v1-caprese", "file": "banquet-caprese", "source": "ai-generated"},
|
||||
{"itemId": "demo-banquet-v1-roastbeef", "file": "banquet-roastbeef", "source": "ai-generated"},
|
||||
{"itemId": "demo-banquet-v1-salmon-roll", "file": "banquet-salmon-roll", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-hummus", "file": "banquet-hummus", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-caesar", "file": "banquet-caesar", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-olivier", "file": "banquet-olivier", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-greek", "file": "banquet-greek", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-julienne", "file": "banquet-julienne", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-stuffed-mushrooms", "file": "banquet-stuffed-mushrooms", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-chicken", "file": "banquet-chicken", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-cod", "file": "banquet-cod", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-beef-hot", "file": "banquet-beef-hot", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-mash", "file": "banquet-mash", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-rice", "file": "banquet-rice", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-berry-cream", "file": "banquet-berry-cream", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-cheese-honey", "file": "banquet-cheese-honey", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-fruit", "file": "banquet-fruit", "source": "pexels"},
|
||||
{"itemId": "demo-banquet-v1-bread", "file": "banquet-bread", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-salmon-caprese", "file": "extras-salmon-caprese", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-meat-cheese", "file": "extras-meat-cheese", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-mini-buffet", "file": "extras-mini-buffet", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-water", "file": "extras-water", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-sparkling", "file": "extras-sparkling", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-juice", "file": "extras-juice", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-mors", "file": "extras-mors", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-plate", "file": "extras-plate", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-fork", "file": "extras-fork", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-glass", "file": "extras-glass", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-napkin", "file": "extras-napkin", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-ice", "file": "extras-ice", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-tablecloth", "file": "extras-tablecloth", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-serving-kit", "file": "extras-serving-kit", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-delivery-city", "file": "extras-delivery-city", "source": "pexels"},
|
||||
{"itemId": "demo-extras-v1-delivery-outer", "file": "extras-delivery-outer", "source": "pexels"}
|
||||
]
|
||||
}
|
||||
@ -68,7 +68,7 @@ const recipes=[
|
||||
export const banquet=recipes.map(([key,name,catalogSection,price,quantities,allergens,steps,waterGrams=0],index)=>{
|
||||
const rows=quantities.map(([key,gross,net])=>{const p=products.get(key);return {productId:p.id,name:p.name,unit:p.unit,gross:gross/1000,net:net/1000,unitCost:p.cost}});
|
||||
const outputGrams=Math.round(rows.reduce((sum,r)=>sum+r.net*1000,waterGrams));
|
||||
return {id:`demo-banquet-v1-${key}`,name,category:6,catalogSection,price,weight:`${outputGrams} г`,pieces:1,photo:'',demo:true,
|
||||
return {id:`demo-banquet-v1-${key}`,name,category:6,catalogSection,price,weight:`${outputGrams} г`,pieces:1,photo:`demo/images/banquet-${key}.webp`,demo:true,
|
||||
composition:[rows.map(r=>r.name).join(', ')],ingredients:rows.map(r=>[r.name,r.gross,r.unit]),
|
||||
ttk:{number:`ДЕМО-Б${String(index+1).padStart(2,'0')}`,basis:'На 1 порцию / 1 гостя',outputGrams,waterGrams,pieces:1,rows,steps,allergens,
|
||||
ingredientCost:Math.round(rows.reduce((sum,r)=>sum+r.gross*r.unitCost,0)*100)/100,
|
||||
|
||||
@ -10,7 +10,7 @@ const premium=mixes.map(([key,name,price,pieces,sourceIds],index)=>{
|
||||
const sources=sourceIds.map(id=>boxes.find(b=>b.id===`demo-v1-${id}`)),map=new Map();
|
||||
for(const b of sources)for(const r of b.ttk.rows){const old=map.get(r.productId)||{...r,gross:0,net:0};old.gross=round(old.gross+r.gross/2);old.net=round(old.net+r.net/2);map.set(r.productId,old)}
|
||||
const rows=[...map.values()],outputGrams=Math.round(rows.filter(r=>r.unit==='кг').reduce((s,r)=>s+r.net*1000,0));
|
||||
return {id:`demo-extras-v1-${key}`,name,category:5,catalogSection:'Демонстрационные премиум-сеты',price,pieces,weight:`${outputGrams} г`,photo:'',demo:true,
|
||||
return {id:`demo-extras-v1-${key}`,name,category:5,catalogSection:'Демонстрационные премиум-сеты',price,pieces,weight:`${outputGrams} г`,photo:`demo/images/extras-${key}.webp`,demo:true,
|
||||
composition:sources.map(b=>'Половина стандартного бокса: '+b.name),ingredients:rows.map(r=>[r.name,r.gross,r.unit]),
|
||||
ttk:{number:`ДЕМО-П${index+1}`,basis:'На 1 готовый премиум-сет',outputGrams,pieces,rows,
|
||||
steps:['Приготовить две мини-подборки в половинном объёме по указанным нормам.',...sources.flatMap(b=>b.ttk.steps.map(s=>b.name+': '+s)),'Уложить обе подборки в одну общую коробку.'],
|
||||
@ -31,6 +31,6 @@ const specs=[
|
||||
['serving-kit',2,'Набор для подачи: щипцы и лопатка',190,'Демо: набор щипцы и лопатка',85,'шт.','pack','Один комплект одноразовых приборов для подачи']
|
||||
];
|
||||
const stock=specs.map(([key,category,name,price,productName,cost,unit,supplier])=>({id:`demo-extras-v1-stock-${key}`,name:productName,cost,unit,qty:0,min:unit==='кг'?1:10,supplierId:`demo-v1-supplier-${supplier}`,lastPurchaseDate:'',lastPurchasePrice:0}));
|
||||
const packaged=specs.map(([key,category,name,price,productName,cost,unit,supplier,description])=>({id:`demo-extras-v1-${key}`,name,category,catalogSection:({1:'Одноразовая посуда',2:'Для сервировки',3:'Безалкогольные напитки'})[category],price,pieces:1,weight:key==='ice'?'1 кг':'',photo:'',composition:[description],ingredients:[[productName,1,unit]],demo:true}));
|
||||
const delivery=[['city','Доставка по городу',600,'Учебный тариф за один адрес в пределах города.'],['outer','Доставка за город',1200,'Учебный тариф за один адрес в ближайшем пригороде.']].map(([key,name,price,note])=>({id:`demo-extras-v1-delivery-${key}`,name,category:4,catalogSection:'Учебные тарифы доставки',price,pieces:0,weight:'',photo:'',composition:[note],ingredients:[],demo:true}));
|
||||
const packaged=specs.map(([key,category,name,price,productName,cost,unit,supplier,description])=>({id:`demo-extras-v1-${key}`,name,category,catalogSection:({1:'Одноразовая посуда',2:'Для сервировки',3:'Безалкогольные напитки'})[category],price,pieces:1,weight:key==='ice'?'1 кг':'',photo:`demo/images/extras-${key}.webp`,composition:[description],ingredients:[[productName,1,unit]],demo:true}));
|
||||
const delivery=[['city','Доставка по городу',600,'Учебный тариф за один адрес в пределах города.'],['outer','Доставка за город',1200,'Учебный тариф за один адрес в ближайшем пригороде.']].map(([key,name,price,note])=>({id:`demo-extras-v1-delivery-${key}`,name,category:4,catalogSection:'Учебные тарифы доставки',price,pieces:0,weight:'',photo:`demo/images/extras-delivery-${key}.webp`,composition:[note],ingredients:[],demo:true}));
|
||||
export const extrasDemo={version:1,items:[...premium,...packaged,...delivery],stock};
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
const controller=new AbortController(),timeout=setTimeout(()=>controller.abort(),15000);
|
||||
try{
|
||||
const [base,banquet,extras]=await Promise.all(['catalog-v1','banquet-v1','extras-v1'].map(async name=>{
|
||||
const r=await fetch(`demo/${name}.json?v=20260920-training`,{signal:controller.signal,credentials:'same-origin'});
|
||||
const r=await fetch(`demo/${name}.json?v=20260922-training-photos`,{signal:controller.signal,credentials:'same-origin'});
|
||||
if(!r.ok)throw new Error('Не удалось загрузить учебный каталог. Проверьте интернет и повторите.');
|
||||
const value=await r.json();if(value?.version!==1)throw new Error('Неизвестная версия учебного каталога.');return value;
|
||||
}));
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"price": 290,
|
||||
"weight": "120 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-caprese.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Моцарелла мини, Томаты, Базилик, Масло оливковое"
|
||||
@ -95,7 +95,7 @@
|
||||
"price": 390,
|
||||
"weight": "100 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-roastbeef.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Ростбиф готовый, Корнишоны, Горчица, Сливки"
|
||||
@ -182,7 +182,7 @@
|
||||
"price": 350,
|
||||
"weight": "90 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-salmon-roll.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Лосось слабосолёный, Сыр сливочный, Огурцы, Укроп"
|
||||
@ -269,7 +269,7 @@
|
||||
"price": 230,
|
||||
"weight": "160 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-hummus.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Морковь, Огурцы, Перец сладкий, Хумус готовый"
|
||||
@ -355,7 +355,7 @@
|
||||
"price": 340,
|
||||
"weight": "180 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-caesar.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Филе курицы готовое, Салат листовой, Томаты черри, Хлеб тостовый, Сыр гауда, Сливки, Горчица"
|
||||
@ -483,7 +483,7 @@
|
||||
"price": 280,
|
||||
"weight": "180 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-olivier.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Картофель, Морковь, Ветчина из индейки, Яйцо куриное без скорлупы, Горошек зелёный консервированный, Корнишоны, Сливки, Горчица"
|
||||
@ -624,7 +624,7 @@
|
||||
"price": 290,
|
||||
"weight": "180 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-greek.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Томаты, Огурцы, Перец сладкий, Моцарелла мини, Маслины без косточек, Масло оливковое"
|
||||
@ -736,7 +736,7 @@
|
||||
"price": 310,
|
||||
"weight": "130 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-julienne.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Филе курицы готовое, Шампиньоны, Лук репчатый, Сливки, Сыр гауда, Масло оливковое"
|
||||
@ -849,7 +849,7 @@
|
||||
"price": 270,
|
||||
"weight": "120 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-stuffed-mushrooms.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Шампиньоны, Сыр сливочный, Сыр гауда, Укроп, Масло оливковое"
|
||||
@ -949,7 +949,7 @@
|
||||
"price": 490,
|
||||
"weight": "220 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-chicken.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Филе куриное сырое, Перец сладкий, Морковь, Сливки, Масло оливковое"
|
||||
@ -1049,7 +1049,7 @@
|
||||
"price": 590,
|
||||
"weight": "200 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-cod.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Филе трески, Томаты, Перец сладкий, Лимон, Масло оливковое"
|
||||
@ -1148,7 +1148,7 @@
|
||||
"price": 690,
|
||||
"weight": "220 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-beef-hot.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Ростбиф готовый, Шампиньоны, Лук репчатый, Сливки, Масло оливковое"
|
||||
@ -1247,7 +1247,7 @@
|
||||
"price": 160,
|
||||
"weight": "150 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-mash.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Картофель, Молоко, Масло сливочное"
|
||||
@ -1320,7 +1320,7 @@
|
||||
"price": 170,
|
||||
"weight": "150 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-rice.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Рис сухой, Морковь, Перец сладкий, Горошек зелёный консервированный, Масло оливковое"
|
||||
@ -1417,7 +1417,7 @@
|
||||
"price": 240,
|
||||
"weight": "110 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-berry-cream.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Сыр сливочный, Сливки, Крошка бисквитная, Клубника, Голубика, Пудра сахарная"
|
||||
@ -1531,7 +1531,7 @@
|
||||
"price": 310,
|
||||
"weight": "100 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-cheese-honey.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Сыр бри, Виноград, Орех грецкий очищенный, Мёд"
|
||||
@ -1618,7 +1618,7 @@
|
||||
"price": 290,
|
||||
"weight": "180 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-fruit.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Виноград, Клубника, Голубика"
|
||||
@ -1689,7 +1689,7 @@
|
||||
"price": 120,
|
||||
"weight": "60 г",
|
||||
"pieces": 1,
|
||||
"photo": "",
|
||||
"photo": "demo/images/banquet-bread.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Багет, Хлеб ржаной, Масло сливочное, Укроп"
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"price": 3500,
|
||||
"pieces": 18,
|
||||
"weight": "710 г",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-salmon-caprese.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Половина стандартного бокса: Канапе с лососем и сливочным сыром",
|
||||
@ -194,7 +194,7 @@
|
||||
"price": 3900,
|
||||
"pieces": 0,
|
||||
"weight": "750 г",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-meat-cheese.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Половина стандартного бокса: Мясное ассорти с корнишонами",
|
||||
@ -432,7 +432,7 @@
|
||||
"price": 2900,
|
||||
"pieces": 22,
|
||||
"weight": "820 г",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-mini-buffet.webp",
|
||||
"demo": true,
|
||||
"composition": [
|
||||
"Половина стандартного бокса: Брускетты с томатами и базиликом",
|
||||
@ -603,7 +603,7 @@
|
||||
"price": 90,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-water.webp",
|
||||
"composition": [
|
||||
"Одна бутылка 0,5 л"
|
||||
],
|
||||
@ -624,7 +624,7 @@
|
||||
"price": 100,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-sparkling.webp",
|
||||
"composition": [
|
||||
"Одна бутылка 0,5 л"
|
||||
],
|
||||
@ -645,7 +645,7 @@
|
||||
"price": 220,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-juice.webp",
|
||||
"composition": [
|
||||
"Одна упаковка 1 л"
|
||||
],
|
||||
@ -666,7 +666,7 @@
|
||||
"price": 280,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-mors.webp",
|
||||
"composition": [
|
||||
"Одна бутылка готового морса 1 л"
|
||||
],
|
||||
@ -687,7 +687,7 @@
|
||||
"price": 25,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-plate.webp",
|
||||
"composition": [
|
||||
"Одна сервировочная тарелка"
|
||||
],
|
||||
@ -708,7 +708,7 @@
|
||||
"price": 10,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-fork.webp",
|
||||
"composition": [
|
||||
"Одна вилка"
|
||||
],
|
||||
@ -729,7 +729,7 @@
|
||||
"price": 15,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-glass.webp",
|
||||
"composition": [
|
||||
"Один стакан"
|
||||
],
|
||||
@ -750,7 +750,7 @@
|
||||
"price": 10,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-napkin.webp",
|
||||
"composition": [
|
||||
"Одна бумажная салфетка"
|
||||
],
|
||||
@ -771,7 +771,7 @@
|
||||
"price": 180,
|
||||
"pieces": 1,
|
||||
"weight": "1 кг",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-ice.webp",
|
||||
"composition": [
|
||||
"Один пакет пищевого льда, 1 кг"
|
||||
],
|
||||
@ -792,7 +792,7 @@
|
||||
"price": 250,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-tablecloth.webp",
|
||||
"composition": [
|
||||
"Одна одноразовая скатерть 120 × 180 см"
|
||||
],
|
||||
@ -813,7 +813,7 @@
|
||||
"price": 190,
|
||||
"pieces": 1,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-serving-kit.webp",
|
||||
"composition": [
|
||||
"Один комплект одноразовых приборов для подачи"
|
||||
],
|
||||
@ -834,7 +834,7 @@
|
||||
"price": 600,
|
||||
"pieces": 0,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-delivery-city.webp",
|
||||
"composition": [
|
||||
"Учебный тариф за один адрес в пределах города."
|
||||
],
|
||||
@ -849,7 +849,7 @@
|
||||
"price": 1200,
|
||||
"pieces": 0,
|
||||
"weight": "",
|
||||
"photo": "",
|
||||
"photo": "demo/images/extras-delivery-outer.webp",
|
||||
"composition": [
|
||||
"Учебный тариф за один адрес в ближайшем пригороде."
|
||||
],
|
||||
|
||||
BIN
public/demo/images/banquet-beef-hot.webp
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
public/demo/images/banquet-berry-cream.webp
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
public/demo/images/banquet-bread.webp
Normal file
|
After Width: | Height: | Size: 190 KiB |
BIN
public/demo/images/banquet-caesar.webp
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
public/demo/images/banquet-caprese.webp
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/demo/images/banquet-cheese-honey.webp
Normal file
|
After Width: | Height: | Size: 258 KiB |
BIN
public/demo/images/banquet-chicken.webp
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
public/demo/images/banquet-cod.webp
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
public/demo/images/banquet-fruit.webp
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
public/demo/images/banquet-greek.webp
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
public/demo/images/banquet-hummus.webp
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
public/demo/images/banquet-julienne.webp
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
public/demo/images/banquet-mash.webp
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
public/demo/images/banquet-olivier.webp
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
public/demo/images/banquet-rice.webp
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
public/demo/images/banquet-roastbeef.webp
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
public/demo/images/banquet-salmon-roll.webp
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
public/demo/images/banquet-stuffed-mushrooms.webp
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
public/demo/images/extras-delivery-city.webp
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
public/demo/images/extras-delivery-outer.webp
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
public/demo/images/extras-fork.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/demo/images/extras-glass.webp
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
public/demo/images/extras-ice.webp
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
public/demo/images/extras-juice.webp
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
public/demo/images/extras-meat-cheese.webp
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
public/demo/images/extras-mini-buffet.webp
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
public/demo/images/extras-mors.webp
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
public/demo/images/extras-napkin.webp
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
public/demo/images/extras-plate.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/demo/images/extras-salmon-caprese.webp
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
public/demo/images/extras-serving-kit.webp
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
public/demo/images/extras-sparkling.webp
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
public/demo/images/extras-tablecloth.webp
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
public/demo/images/extras-water.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
@ -1,4 +1,4 @@
|
||||
<!doctype html><html lang="ru"><head><script src="core/training-catalog.js?v=20260921-training-notice"></script><link rel="stylesheet" href="core/login-signature-v1776.css?v=20260918-ui-stability"><script src="core/cloud-transport.js?v=20260918-ui-stability"></script><script src="core/banquet-menu.js?v=20260918-ui-stability-20260919-client-menu"></script><script src="core/access-policy.js?v=20260918-ui-stability"></script><style>body.sun-cloud-auth-required>header,body.sun-cloud-auth-required>.view{visibility:hidden!important;pointer-events:none!important}</style><meta charset="utf-8"><script defer src="core/import-archive.js?v=20260918-ui-stability"></script><script src="core/company-branding.js?v=20260920-employee-session"></script><script src="core/brand-theme.js?v=20260918-ui-stability"></script><script id="sun-startup-stability-guard">
|
||||
<!doctype html><html lang="ru"><head><script src="core/training-catalog.js?v=20260922-training-photos"></script><link rel="stylesheet" href="core/login-signature-v1776.css?v=20260918-ui-stability"><script src="core/cloud-transport.js?v=20260918-ui-stability"></script><script src="core/banquet-menu.js?v=20260918-ui-stability-20260919-client-menu"></script><script src="core/access-policy.js?v=20260918-ui-stability"></script><style>body.sun-cloud-auth-required>header,body.sun-cloud-auth-required>.view{visibility:hidden!important;pointer-events:none!important}</style><meta charset="utf-8"><script defer src="core/import-archive.js?v=20260918-ui-stability"></script><script src="core/company-branding.js?v=20260920-employee-session"></script><script src="core/brand-theme.js?v=20260918-ui-stability"></script><script id="sun-startup-stability-guard">
|
||||
(()=>{
|
||||
'use strict';
|
||||
const stamp=()=>new Date().toISOString().replace(/[:.]/g,'-');
|
||||
|
||||
@ -4,7 +4,7 @@ const CORE=[
|
||||
'./core/support-form.js?v=20260921-support-recipient',
|
||||
'./core/trial-promo-developer-v181.js?v=20260921-promo-entry',
|
||||
'./core/banquet-client-menu.js?v=20260920-onepage',
|
||||
'./core/training-catalog.js?v=20260920-training',
|
||||
'./core/training-catalog.js?v=20260922-training-photos',
|
||||
'./core/catalog-pricing.js?v=20260919-client-menu','./core/client-menu.css?v=20260919-client-menu',
|
||||
'./vendor/supabase-2.112.4.min.js',
|
||||
`./core/help-center.js?v=${VERSION}`,`./core/help-center.css?v=${VERSION}`,`./help/knowledge-v1.json?v=${VERSION}`,
|
||||
|
||||