docs-combiner 0.1.14 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/renderer.js CHANGED
@@ -100888,14 +100888,14 @@ __webpack_require__.r(__webpack_exports__);
100888
100888
  /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/CircularProgress/CircularProgress.js");
100889
100889
  /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormHelperText/FormHelperText.js");
100890
100890
  /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Alert/Alert.js");
100891
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/InputAdornment/InputAdornment.js");
100892
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Tooltip/Tooltip.js");
100893
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormControl/FormControl.js");
100894
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/InputLabel/InputLabel.js");
100895
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Select/Select.js");
100896
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/MenuItem/MenuItem.js");
100897
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormControlLabel/FormControlLabel.js");
100898
- /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Checkbox/Checkbox.js");
100891
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormControlLabel/FormControlLabel.js");
100892
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Checkbox/Checkbox.js");
100893
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/InputAdornment/InputAdornment.js");
100894
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Tooltip/Tooltip.js");
100895
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormControl/FormControl.js");
100896
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/InputLabel/InputLabel.js");
100897
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Select/Select.js");
100898
+ /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/MenuItem/MenuItem.js");
100899
100899
  /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/ToggleButtonGroup/ToggleButtonGroup.js");
100900
100900
  /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/ToggleButton/ToggleButton.js");
100901
100901
  /* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Paper/Paper.js");
@@ -100983,15 +100983,65 @@ const INSTRUCTION_ROW = [
100983
100983
  "# Обязательно | The URL for the main image of your item. Images must be in a supported format (JPG/GIF/PNG) and at least 500 x 500 pixels.",
100984
100984
  "# Обязательно | Фирменное название товара. Не более 100 символов."
100985
100985
  ];
100986
- /** Хвост ссылки для каталога: sub/utm и макросы Meta (не URL-encode — подстановка на стороне FB). */
100987
- const CATALOG_LINK_TRACKING_SUFFIX = 'sub1={{ad.id}}&sub2={{adset.id}}&sub3={{campaign.id}}&sub4={{ad.name}}&sub5={{adset.name}}&sub6={{campaign.name}}&sub7={{placement}}&sub8={{site_source_name}}&utm_source=facebook&utm_medium=paid';
100988
- /** Добавляет к URL лендинга creative_id и трекинговые параметры для строки каталога. */
100989
- function appendCreativeIdToCatalogLink(baseUrl, creativeId) {
100986
+ /** Доп. query-параметры для ссылки каталога (RedTrack / utm / макросы Meta; не URL-encode — подстановка на стороне FB). */
100987
+ const DEFAULT_CATALOG_LINK_EXTRA_MACROS = 'sub1={{ad.id}}&sub2={{adset.id}}&sub3={{campaign.id}}&sub4={{ad.name}}&sub5={{adset.name}}&sub6={{campaign.name}}&sub7={{placement}}&sub8={{site_source_name}}&utm_source=facebook&utm_medium=paid';
100988
+ const DEFAULT_CATALOG_LINK_KEITARO_MACROS = 'utm_campaign={{campaign.name}}&utm_source={{site_source_name}}&utm_placement={{placement}}&campaign_id={{campaign.id}}&adset_id={{adset.id}}&ad_id={{ad.id}}&adset_name={{adset.name}}&ad_name={{ad.name}}';
100989
+ /** 8 случайных hex-символов для уникального суффикса имени файла на Drive. */
100990
+ function randomHex8() {
100991
+ const a = new Uint8Array(4);
100992
+ crypto.getRandomValues(a);
100993
+ return Array.from(a, b => b.toString(16).padStart(2, '0')).join('');
100994
+ }
100995
+ /** Имя файла при загрузке крео: N_xxxxxxxx.png — N = номер строки подхода в UI (1–10). */
100996
+ function creativeImageUploadFilename(creoApproachUiNumber) {
100997
+ return `${creoApproachUiNumber}_${randomHex8()}.png`;
100998
+ }
100999
+ /**
101000
+ * Из имени файла картинки на Drive — номер строки подхода к крео (1–10) для каталога/трекера.
101001
+ * Формат: N_xxxxxxxx; снимаются расширение, суффиксы « (N)» от дубликатов Google.
101002
+ * Старый формат (текст_hex8) — возвращается «лейбл» после снятия hex (не только цифры).
101003
+ */
101004
+ function parseCreoApproachLabelFromImageFileName(fileName) {
101005
+ let s = fileName.replace(/\.[^/.]+$/i, '').trim();
101006
+ if (!s)
101007
+ return undefined;
101008
+ while (/\s+\(\d+\)$/.test(s)) {
101009
+ s = s.replace(/\s+\(\d+\)$/, '').trim();
101010
+ }
101011
+ const m = /^(\d+)_([0-9a-fA-F]{8})$/i.exec(s);
101012
+ if (m)
101013
+ return m[1];
101014
+ const legacy = s.replace(/_[0-9a-fA-F]{8}$/i, '').trim();
101015
+ return legacy || undefined;
101016
+ }
101017
+ const DEFAULT_CATALOG_TEXT_APPROACH_PARAM = 'sub19';
101018
+ const DEFAULT_CATALOG_CREO_APPROACH_PARAM = 'sub20';
101019
+ /** Имя query-параметра для трекера: латиница, цифры, _, - */
101020
+ function sanitizeCatalogUrlParamKey(raw, fallback) {
101021
+ const t = raw.trim();
101022
+ if (!t)
101023
+ return fallback;
101024
+ const cleaned = t.replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 64);
101025
+ return cleaned || fallback;
101026
+ }
101027
+ /** Добавляет к URL лендинга creative_id, опционально кастомные параметры подходов (имена редактируются в UI) и строку доп. макросов. */
101028
+ function appendCreativeIdToCatalogLink(baseUrl, creativeId, catalogAnalytics, extraMacrosQueryString) {
100990
101029
  const u = baseUrl.trim();
100991
101030
  if (!u)
100992
101031
  return u;
100993
101032
  const sep = u.includes('?') ? '&' : '?';
100994
- return `${u}${sep}creative_id=${encodeURIComponent(creativeId)}&${CATALOG_LINK_TRACKING_SUFFIX}`;
101033
+ const q = [`creative_id=${encodeURIComponent(creativeId)}`];
101034
+ const textKey = sanitizeCatalogUrlParamKey(catalogAnalytics?.textParamKey ?? '', DEFAULT_CATALOG_TEXT_APPROACH_PARAM);
101035
+ const creoKey = sanitizeCatalogUrlParamKey(catalogAnalytics?.creoParamKey ?? '', DEFAULT_CATALOG_CREO_APPROACH_PARAM);
101036
+ if (catalogAnalytics?.textApproach) {
101037
+ q.push(`${textKey}=${encodeURIComponent(catalogAnalytics.textApproach)}`);
101038
+ }
101039
+ if (catalogAnalytics?.creoApproach) {
101040
+ q.push(`${creoKey}=${encodeURIComponent(catalogAnalytics.creoApproach)}`);
101041
+ }
101042
+ const core = `${u}${sep}${q.join('&')}`;
101043
+ const tail = (extraMacrosQueryString ?? '').trim();
101044
+ return tail ? `${core}&${tail}` : core;
100995
101045
  }
100996
101046
  /** Текст ответа из OpenRouter/OpenAI chat completion (string или массив частей). */
100997
101047
  function extractChatCompletionText(choice) {
@@ -101160,6 +101210,18 @@ function extractLeadingPriceNumber(value) {
101160
101210
  return m[1].replace(',', '.');
101161
101211
  return '99';
101162
101212
  }
101213
+ /** Фон карточки крео: после 1-й переделки — светло-жёлтый, далее темнеет с каждой следующей. */
101214
+ function getRemakeHighlightBackground(remakeCount, dark) {
101215
+ if (remakeCount <= 0)
101216
+ return undefined;
101217
+ const step = Math.min(remakeCount - 1, 7);
101218
+ if (dark) {
101219
+ const opacities = [0.11, 0.16, 0.22, 0.28, 0.34, 0.42, 0.5, 0.58];
101220
+ return `rgba(255, 193, 7, ${opacities[step]})`;
101221
+ }
101222
+ const light = ['#fffde7', '#fff9c4', '#fff59d', '#ffee58', '#ffeb3b', '#fdd835', '#fbc02d', '#f9a825'];
101223
+ return light[step];
101224
+ }
101163
101225
  function App() {
101164
101226
  const [clientId, setClientId] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
101165
101227
  const [clientSecret, setClientSecret] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
@@ -101176,6 +101238,7 @@ function App() {
101176
101238
  const [translatingPairs, setTranslatingPairs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
101177
101239
  const [driveFolderUrl, setDriveFolderUrl] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
101178
101240
  const [link, setLink] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
101241
+ const linkInputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
101179
101242
  const [openaiApiKey, setOpenaiApiKey] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
101180
101243
  const [openRouterBalance, setOpenRouterBalance] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
101181
101244
  const [openRouterAccountBalance, setOpenRouterAccountBalance] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
@@ -101396,6 +101459,16 @@ function App() {
101396
101459
  // const [availability, setAvailability] = useState('in stock');
101397
101460
  // const [condition, setCondition] = useState('new');
101398
101461
  const [linkError, setLinkError] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
101462
+ /** В ссылку каталога: имя подхода к паре текстов (под трекер) */
101463
+ const [catalogUrlIncludeTextApproach, setCatalogUrlIncludeTextApproach] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
101464
+ /** В ссылку каталога: подход крео — если крео загружены из приложения (есть file id на Drive) */
101465
+ const [catalogUrlIncludeCreoApproach, setCatalogUrlIncludeCreoApproach] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
101466
+ /** Имя query-параметра для подхода к тексту (по умолчанию sub19) */
101467
+ const [catalogUrlTextApproachParam, setCatalogUrlTextApproachParam] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(DEFAULT_CATALOG_TEXT_APPROACH_PARAM);
101468
+ /** Имя query-параметра для подхода к крео (по умолчанию sub20) */
101469
+ const [catalogUrlCreoApproachParam, setCatalogUrlCreoApproachParam] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(DEFAULT_CATALOG_CREO_APPROACH_PARAM);
101470
+ /** Query-хвост после creative_id / sub19 / sub20 (редактируемый; пресет RedTrack). */
101471
+ const [catalogLinkExtraMacros, setCatalogLinkExtraMacros] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
101399
101472
  const [loading, setLoading] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
101400
101473
  const [authLoading, setAuthLoading] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
101401
101474
  const [generatedData, setGeneratedData] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
@@ -101587,7 +101660,21 @@ function App() {
101587
101660
  }
101588
101661
  }, 1000);
101589
101662
  return () => clearTimeout(timeoutId);
101590
- }, [generateProduct, generateGeo, generateAdditionalInfo, generatePriceWithCurrency, brand, link, driveFolderUrl, loadingContentFromDrive]);
101663
+ }, [
101664
+ generateProduct,
101665
+ generateGeo,
101666
+ generateAdditionalInfo,
101667
+ generatePriceWithCurrency,
101668
+ brand,
101669
+ link,
101670
+ catalogUrlIncludeTextApproach,
101671
+ catalogUrlIncludeCreoApproach,
101672
+ catalogUrlTextApproachParam,
101673
+ catalogUrlCreoApproachParam,
101674
+ catalogLinkExtraMacros,
101675
+ driveFolderUrl,
101676
+ loadingContentFromDrive
101677
+ ]);
101591
101678
  // Load generated content from Google Drive when driveFolderUrl changes
101592
101679
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
101593
101680
  if (!driveFolderUrl) {
@@ -101602,6 +101689,7 @@ function App() {
101602
101689
  setTexts(['']);
101603
101690
  setLink('');
101604
101691
  setUploadedLink('');
101692
+ setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
101605
101693
  setPairTranslations({});
101606
101694
  return;
101607
101695
  }
@@ -101618,6 +101706,7 @@ function App() {
101618
101706
  setTexts(['']);
101619
101707
  setLink('');
101620
101708
  setUploadedLink('');
101709
+ setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
101621
101710
  setPairTranslations({});
101622
101711
  return;
101623
101712
  }
@@ -101630,6 +101719,7 @@ function App() {
101630
101719
  setTexts(['']);
101631
101720
  setLink('');
101632
101721
  setUploadedLink('');
101722
+ setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
101633
101723
  setPairTranslations({});
101634
101724
  setLoadingContentFromDrive(true);
101635
101725
  setDriveFilesFound({ content: false });
@@ -104341,8 +104431,8 @@ function App() {
104341
104431
  }
104342
104432
  addLog(formatLogMessage('log', '✅ Product image found'));
104343
104433
  // Generate images with different approaches (количество по каждому подходу)
104344
- const approaches = (0,_prompts__WEBPACK_IMPORTED_MODULE_1__.getCreoApproaches)();
104345
- if (approaches.length === 0) {
104434
+ const expandedTasks = (0,_prompts__WEBPACK_IMPORTED_MODULE_1__.getCreoApproachExpandedTasks)();
104435
+ if (expandedTasks.length === 0) {
104346
104436
  addLog(formatLogMessage('error', '❌ Укажите количество изображений (хотя бы 1) в настройках подходов'));
104347
104437
  alert('Укажите количество изображений (1–4) хотя бы для одного подхода в настройках');
104348
104438
  setGeneratingImages(false);
@@ -104351,11 +104441,15 @@ function App() {
104351
104441
  // При "both" — на каждый подход генерируем и 1:1, и 2:3
104352
104442
  const useBoth = imageAspectRatio === 'both';
104353
104443
  const tasks = useBoth
104354
- ? approaches.flatMap(a => [
104355
- { approach: a, ratio: '1:1' },
104356
- { approach: a, ratio: '2:3' }
104444
+ ? expandedTasks.flatMap(t => [
104445
+ { approach: t.approach, poolIndex: t.poolIndex, ratio: '1:1' },
104446
+ { approach: t.approach, poolIndex: t.poolIndex, ratio: '2:3' }
104357
104447
  ])
104358
- : approaches.map(a => ({ approach: a, ratio: imageAspectRatio }));
104448
+ : expandedTasks.map(t => ({
104449
+ approach: t.approach,
104450
+ poolIndex: t.poolIndex,
104451
+ ratio: imageAspectRatio
104452
+ }));
104359
104453
  const additionalInfoLine = generateAdditionalInfo.trim()
104360
104454
  ? `\n📋 ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ О ПРОДУКТЕ: ${generateAdditionalInfo.trim()}`
104361
104455
  : '';
@@ -104374,6 +104468,7 @@ function App() {
104374
104468
  index: index + 1,
104375
104469
  imageUrl: undefined,
104376
104470
  approach: t.approach.name + (useBoth ? ` (${t.ratio})` : ''),
104471
+ creoApproachUiNumber: t.poolIndex + 1,
104377
104472
  aspectRatio: t.ratio,
104378
104473
  uploaded: false,
104379
104474
  checking: false,
@@ -104385,7 +104480,8 @@ function App() {
104385
104480
  regenerating: false,
104386
104481
  customRegeneratePrompt: '',
104387
104482
  failed: false,
104388
- generating: false // In sequential mode, images start queued (not generating)
104483
+ generating: false, // In sequential mode, images start queued (not generating)
104484
+ remakeCount: 0
104389
104485
  }));
104390
104486
  setGeneratedImagesData(initialPlaceholders);
104391
104487
  addLog(formatLogMessage('log', `📝 Generated prompts for ${tasks.length} images${useBoth ? ' (1:1 + 2:3 на каждый подход)' : ''}`));
@@ -104542,7 +104638,7 @@ function App() {
104542
104638
  imageUrl: null,
104543
104639
  success: false,
104544
104640
  error: new Error('Generation did not complete'),
104545
- approach: approaches[i]?.name || 'Unknown',
104641
+ approach: tasks[i]?.approach.name || 'Unknown',
104546
104642
  originalPrompt: imagePrompts[i],
104547
104643
  productImageUrl: productImage.url
104548
104644
  });
@@ -104794,7 +104890,8 @@ ${imageData.originalPrompt}
104794
104890
  checkErrors: undefined,
104795
104891
  uploaded: false, // Reset uploaded status since it's a new image
104796
104892
  customRegeneratePrompt: '', // Reset custom prompt after regeneration
104797
- failed: false // Mark as successful
104893
+ failed: false, // Mark as successful
104894
+ remakeCount: (img.remakeCount ?? 0) + 1
104798
104895
  }
104799
104896
  : img));
104800
104897
  // Run validation on the new image (skip if disabled)
@@ -104909,7 +105006,8 @@ ${imageData.originalPrompt}
104909
105006
  checkErrors: undefined,
104910
105007
  uploaded: false,
104911
105008
  customRegeneratePrompt: '',
104912
- failed: false
105009
+ failed: false,
105010
+ remakeCount: (img.remakeCount ?? 0) + 1
104913
105011
  }
104914
105012
  : img));
104915
105013
  // Validate new image (skip if disabled)
@@ -105031,11 +105129,10 @@ ${imageData.originalPrompt}
105031
105129
  logToTerminal('log', msg.replace(/\[.*?\]\s*/, ''));
105032
105130
  };
105033
105131
  try {
105034
- const filename = `${generateProduct.replace(/\s+/g, '_')}_${imageData.index}_${Date.now()}.png`;
105132
+ const filename = creativeImageUploadFilename(imageData.creoApproachUiNumber);
105035
105133
  addLog(formatLogMessage('log', `📤 Uploading image ${imageData.index} to Drive: ${filename}`));
105036
105134
  const driveUrl = await uploadImageToDrive(imageData.imageUrl, filename, folderId, addLog);
105037
105135
  addLog(formatLogMessage('log', `✅ Image ${imageData.index} uploaded: ${driveUrl}`));
105038
- // Update uploaded status
105039
105136
  setGeneratedImagesData(prev => prev.map(img => img.index === imageData.index ? { ...img, uploaded: true } : img));
105040
105137
  // (Removed legacy Generated Images links list)
105041
105138
  }
@@ -105075,9 +105172,8 @@ ${imageData.originalPrompt}
105075
105172
  : img));
105076
105173
  try {
105077
105174
  addLog(formatLogMessage('log', `📤 Uploading ${notUploaded.length} image(s) to Drive (parallel)...`));
105078
- const baseTs = Date.now();
105079
- const results = await Promise.allSettled(notUploaded.map((imageData, i) => {
105080
- const filename = `${generateProduct.replace(/\s+/g, '_')}_${imageData.index}_${baseTs}_${i}.png`;
105175
+ const results = await Promise.allSettled(notUploaded.map((imageData) => {
105176
+ const filename = creativeImageUploadFilename(imageData.creoApproachUiNumber);
105081
105177
  addLog(formatLogMessage('log', `📤 Starting upload image ${imageData.index}: ${filename}`));
105082
105178
  return uploadImageToDrive(imageData.imageUrl, filename, folderId, addLog).then(driveUrl => ({
105083
105179
  index: imageData.index,
@@ -105157,6 +105253,22 @@ ${imageData.originalPrompt}
105157
105253
  // invalid — leave as is
105158
105254
  }
105159
105255
  };
105256
+ const handleLinkPaste = (e) => {
105257
+ e.preventDefault();
105258
+ const pasted = e.clipboardData.getData('text/plain');
105259
+ const cleanedPaste = pasted.split('?')[0] ?? pasted;
105260
+ const input = e.currentTarget;
105261
+ const start = input.selectionStart ?? 0;
105262
+ const end = input.selectionEnd ?? 0;
105263
+ const newVal = link.slice(0, start) + cleanedPaste + link.slice(end);
105264
+ handleLinkChange(newVal);
105265
+ const pos = start + cleanedPaste.length;
105266
+ setTimeout(() => {
105267
+ const el = linkInputRef.current;
105268
+ if (el)
105269
+ el.setSelectionRange(pos, pos);
105270
+ }, 0);
105271
+ };
105160
105272
  const extractFolderId = (url) => {
105161
105273
  // Try to match format: /folders/([a-zA-Z0-9_-]+)
105162
105274
  const foldersMatch = url.match(/folders\/([a-zA-Z0-9_-]+)/);
@@ -105203,7 +105315,13 @@ ${imageData.originalPrompt}
105203
105315
  const name = f.name?.toLowerCase() || '';
105204
105316
  return name !== 'product.png' && name !== 'product.jpg' && name !== 'product.webp';
105205
105317
  });
105206
- return filteredFiles.map((f) => f.id ? `https://drive.google.com/file/d/${f.id}/view?usp=sharing` : '');
105318
+ return filteredFiles
105319
+ .filter((f) => f.id && f.name)
105320
+ .map((f) => ({
105321
+ fileId: f.id,
105322
+ name: f.name,
105323
+ viewUrl: `https://drive.google.com/file/d/${f.id}/view?usp=sharing`
105324
+ }));
105207
105325
  };
105208
105326
  const fetchProductImage = async (folderId) => {
105209
105327
  const validToken = await getValidAccessToken();
@@ -105336,6 +105454,11 @@ ${imageData.originalPrompt}
105336
105454
  },
105337
105455
  brand: brandValue !== undefined ? brandValue : brand || '',
105338
105456
  link: linkValue !== undefined ? linkValue : link || '',
105457
+ catalogUrlIncludeTextApproach,
105458
+ catalogUrlIncludeCreoApproach,
105459
+ catalogUrlTextApproachParam,
105460
+ catalogUrlCreoApproachParam,
105461
+ catalogLinkExtraMacros,
105339
105462
  selectedPairApproaches: (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_52__.getSelectedPairApproaches)(),
105340
105463
  imageApproachCounts: (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_52__.getImageApproachCounts)(),
105341
105464
  savedAt: new Date().toISOString()
@@ -105486,6 +105609,24 @@ ${imageData.originalPrompt}
105486
105609
  setLink(loadedData.link || '');
105487
105610
  logToTerminal('log', '[Load Content] Loaded link:', loadedData.link || '(empty)');
105488
105611
  }
105612
+ if (typeof loadedData.catalogUrlIncludeTextApproach === 'boolean') {
105613
+ setCatalogUrlIncludeTextApproach(loadedData.catalogUrlIncludeTextApproach);
105614
+ }
105615
+ if (typeof loadedData.catalogUrlIncludeCreoApproach === 'boolean') {
105616
+ setCatalogUrlIncludeCreoApproach(loadedData.catalogUrlIncludeCreoApproach);
105617
+ }
105618
+ if (typeof loadedData.catalogUrlTextApproachParam === 'string' && loadedData.catalogUrlTextApproachParam.trim()) {
105619
+ setCatalogUrlTextApproachParam(loadedData.catalogUrlTextApproachParam.trim());
105620
+ }
105621
+ if (typeof loadedData.catalogUrlCreoApproachParam === 'string' && loadedData.catalogUrlCreoApproachParam.trim()) {
105622
+ setCatalogUrlCreoApproachParam(loadedData.catalogUrlCreoApproachParam.trim());
105623
+ }
105624
+ if (typeof loadedData.catalogLinkExtraMacros === 'string') {
105625
+ setCatalogLinkExtraMacros(loadedData.catalogLinkExtraMacros);
105626
+ }
105627
+ else {
105628
+ setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
105629
+ }
105489
105630
  const mergedApproaches = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_52__.mergePromptApproachesFromDriveFile)(loadedData);
105490
105631
  if (mergedApproaches) {
105491
105632
  logToTerminal('log', '[Load Content] Applied text + image approach settings from Drive JSON');
@@ -105574,9 +105715,17 @@ ${imageData.originalPrompt}
105574
105715
  for (let i = 0; i < pairCount; i++) {
105575
105716
  const title = titleList[i];
105576
105717
  const text = textList[i];
105718
+ const pairApproachIdx = lastUsedApproachIndices[i] ?? i;
105719
+ const textApproachUiNumber = String(pairApproachIdx + 1);
105577
105720
  for (const image of images) {
105578
105721
  const id = `${brand}${idCounter++}`;
105579
- const rowLink = appendCreativeIdToCatalogLink(link, id);
105722
+ const creoFromFileName = parseCreoApproachLabelFromImageFileName(image.name);
105723
+ const rowLink = appendCreativeIdToCatalogLink(link, id, {
105724
+ textApproach: catalogUrlIncludeTextApproach ? textApproachUiNumber : undefined,
105725
+ creoApproach: catalogUrlIncludeCreoApproach && creoFromFileName ? creoFromFileName : undefined,
105726
+ textParamKey: catalogUrlTextApproachParam,
105727
+ creoParamKey: catalogUrlCreoApproachParam
105728
+ }, catalogLinkExtraMacros);
105580
105729
  rows.push([
105581
105730
  id,
105582
105731
  title,
@@ -105585,7 +105734,7 @@ ${imageData.originalPrompt}
105585
105734
  'new',
105586
105735
  '10,00 USD',
105587
105736
  rowLink,
105588
- image,
105737
+ image.viewUrl,
105589
105738
  brand
105590
105739
  ]);
105591
105740
  }
@@ -105921,7 +106070,23 @@ ${imageData.originalPrompt}
105921
106070
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2 },
105922
106071
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "Brand (Short ID)", variant: "outlined", sx: { flex: '0 0 320px', minWidth: 280 }, value: brand, InputProps: { readOnly: true }, placeholder: "\u0410\u0432\u0442\u043E: \u0442\u043E\u0432\u0430\u0440-\u0433\u0435\u043E-\u0446\u0435\u043D\u0430", helperText: "\u0410\u0432\u0442\u043E\u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u0438\u0437 \u0442\u043E\u0432\u0430\u0440\u0430, \u0433\u0435\u043E \u0438 \u0446\u0435\u043D\u044B" }),
105923
106072
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { flex: 1, minWidth: 0 } },
105924
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "Link", variant: "outlined", fullWidth: true, value: link, onChange: (e) => handleLinkChange(e.target.value), onBlur: handleLinkBlur, error: !!linkError, helperText: linkError, placeholder: "https://example.com/product/" }))),
106073
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "Link", variant: "outlined", fullWidth: true, value: link, onChange: (e) => handleLinkChange(e.target.value), onBlur: handleLinkBlur, error: !!linkError, helperText: linkError, placeholder: "https://example.com/product/", inputRef: linkInputRef, InputProps: { onPaste: handleLinkPaste } }))),
106074
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', gap: 1, alignItems: 'flex-start', mt: 1.5 } },
106075
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "\u0414\u043E\u043F. \u043C\u0430\u043A\u0440\u043E\u0441\u044B (\u043A\u0430\u0442\u0430\u043B\u043E\u0433)", variant: "outlined", size: "small", fullWidth: true, multiline: true, minRows: 2, value: catalogLinkExtraMacros, onChange: (e) => setCatalogLinkExtraMacros(e.target.value), placeholder: DEFAULT_CATALOG_LINK_EXTRA_MACROS, helperText: "\u0414\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u043F\u043E\u0441\u043B\u0435 creative_id \u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043E\u0432 \u043F\u043E\u0434\u0445\u043E\u0434\u043E\u0432. \u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442\u0441\u044F \u0432 JSON \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u043F\u0430\u043F\u043A\u0438.", sx: { '& .MuiInputBase-input': { fontFamily: 'monospace', fontSize: 12 } } }),
106076
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 0.5, sx: { flexShrink: 0, mt: 0.5 } },
106077
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], { size: "small", variant: "outlined", onClick: () => setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS), sx: { textTransform: 'none', whiteSpace: 'nowrap' } }, "redtrack"),
106078
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], { size: "small", variant: "outlined", onClick: () => setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_KEITARO_MACROS), sx: { textTransform: 'none', whiteSpace: 'nowrap' } }, "keitaro"))),
106079
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 1.5, sx: { mt: 1 } },
106080
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2, alignItems: { xs: 'stretch', sm: 'flex-start' } },
106081
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_21__["default"], { control: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { checked: catalogUrlIncludeTextApproach, onChange: e => setCatalogUrlIncludeTextApproach(e.target.checked), size: "small" }), label: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
106082
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2" }, "\u041F\u043E\u0434\u0445\u043E\u0434 \u043A \u0442\u0435\u043A\u0441\u0442\u0443 \u0432 URL \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430"),
106083
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary" }, "\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u2014 \u043D\u043E\u043C\u0435\u0440 \u0441\u0442\u0440\u043E\u043A\u0438 \u043F\u043E\u0434\u0445\u043E\u0434\u0430 \u0434\u043B\u044F \u043F\u0430\u0440 \u0432 \u0442\u0430\u0431\u043B\u0438\u0446\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A (1\u201310)")), sx: { alignItems: 'flex-start', mr: 0, flex: { sm: '1 1 200px' }, minWidth: 0 } }),
106084
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 \u0434\u043B\u044F \u0442\u0435\u043A\u0441\u0442\u0430", size: "small", value: catalogUrlTextApproachParam, onChange: e => setCatalogUrlTextApproachParam(e.target.value), placeholder: DEFAULT_CATALOG_TEXT_APPROACH_PARAM, sx: { width: { xs: '100%', sm: 200 }, flexShrink: 0 }, helperText: `По умолчанию: ${DEFAULT_CATALOG_TEXT_APPROACH_PARAM}` })),
106085
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2, alignItems: { xs: 'stretch', sm: 'flex-start' } },
106086
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_21__["default"], { control: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { checked: catalogUrlIncludeCreoApproach, onChange: e => setCatalogUrlIncludeCreoApproach(e.target.checked), size: "small" }), label: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
106087
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2" }, "\u041F\u043E\u0434\u0445\u043E\u0434 \u043A \u043A\u0440\u0435\u043E \u0432 URL \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430"),
106088
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary" }, "\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u2014 \u043D\u043E\u043C\u0435\u0440 N \u0438\u0437 \u0438\u043C\u0435\u043D\u0438 \u0444\u0430\u0439\u043B\u0430 N_xxxxxxxx.png \u043D\u0430 Drive (N = \u0441\u0442\u0440\u043E\u043A\u0430 \u043F\u043E\u0434\u0445\u043E\u0434\u0430 \u043A \u043A\u0440\u0435\u043E, 1\u201310); \u00AB (1)\u00BB \u043E\u0442 \u0434\u0443\u0431\u043B\u0438\u043A\u0430\u0442\u0430 Google \u0441\u043D\u0438\u043C\u0430\u0435\u0442\u0441\u044F")), sx: { alignItems: 'flex-start', mr: 0, flex: { sm: '1 1 200px' }, minWidth: 0 } }),
106089
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 \u0434\u043B\u044F \u043A\u0440\u0435\u043E", size: "small", value: catalogUrlCreoApproachParam, onChange: e => setCatalogUrlCreoApproachParam(e.target.value), placeholder: DEFAULT_CATALOG_CREO_APPROACH_PARAM, sx: { width: { xs: '100%', sm: 200 }, flexShrink: 0 }, helperText: `По умолчанию: ${DEFAULT_CATALOG_CREO_APPROACH_PARAM}` }))),
105925
106090
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], { sx: { my: 2 } }),
105926
106091
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "h6", gutterBottom: true }, "AI Generation Settings"),
105927
106092
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
@@ -105929,20 +106094,20 @@ ${imageData.originalPrompt}
105929
106094
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
105930
106095
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "\u0413\u0435\u043E", variant: "outlined", fullWidth: true, value: generateGeo, onChange: (e) => setGenerateGeo(e.target.value), placeholder: "\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: \u0420\u0443\u043C\u044B\u043D\u0438\u044F" }),
105931
106096
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "\u0426\u0435\u043D\u0430 \u0438 \u0432\u0430\u043B\u044E\u0442\u0430", variant: "outlined", fullWidth: true, value: generatePriceWithCurrency, onChange: (e) => setGeneratePriceWithCurrency(e.target.value), placeholder: "\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: 29 euro, 11400 HUF, 149 RON \u0438\u043B\u0438 \u043B\u044E\u0431\u043E\u0439 \u0434\u0440\u0443\u0433\u043E\u0439 \u0444\u043E\u0440\u043C\u0430\u0442", helperText: "\u041B\u044E\u0431\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0434\u043B\u044F \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F \u0432 \u043F\u0440\u043E\u043C\u043F\u0442\u0435 \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439. \u041A\u043D\u043E\u043F\u043A\u0438 \u0441\u043F\u0440\u0430\u0432\u0430 \u043F\u043E\u0434\u0441\u0442\u0430\u0432\u043B\u044F\u044E\u0442 \u0441\u0438\u043C\u0432\u043E\u043B \u0432\u0430\u043B\u044E\u0442\u044B, \u0446\u0438\u0444\u0440\u0443 \u0431\u0435\u0440\u0443\u0442 \u0438\u0437 \u043F\u043E\u043B\u044F (\u0438\u043B\u0438 99).", InputProps: {
105932
- endAdornment: (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_21__["default"], { position: "end" },
106097
+ endAdornment: (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_23__["default"], { position: "end" },
105933
106098
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 0.25, mr: -0.5 } },
105934
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: "\u041F\u043E\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C $ (\u0446\u0438\u0444\u0440\u0430 \u0438\u0437 \u043F\u043E\u043B\u044F \u0438\u043B\u0438 99)" },
106099
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: "\u041F\u043E\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C $ (\u0446\u0438\u0444\u0440\u0430 \u0438\u0437 \u043F\u043E\u043B\u044F \u0438\u043B\u0438 99)" },
105935
106100
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", "aria-label": "\u0411\u044B\u0441\u0442\u0440\u043E \u0434\u043E\u043B\u043B\u0430\u0440", onClick: () => {
105936
106101
  const n = extractLeadingPriceNumber(generatePriceWithCurrency);
105937
106102
  setGeneratePriceWithCurrency(`$${n}`);
105938
106103
  }, edge: "end" },
105939
106104
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_35__["default"], { sx: { fontSize: 20 } }))),
105940
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: "\u041F\u043E\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u20AC (\u0446\u0438\u0444\u0440\u0430 \u0438\u0437 \u043F\u043E\u043B\u044F \u0438\u043B\u0438 99)" },
106105
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: "\u041F\u043E\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u20AC (\u0446\u0438\u0444\u0440\u0430 \u0438\u0437 \u043F\u043E\u043B\u044F \u0438\u043B\u0438 99)" },
105941
106106
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", "aria-label": "\u0411\u044B\u0441\u0442\u0440\u043E \u0435\u0432\u0440\u043E", onClick: () => {
105942
106107
  const n = extractLeadingPriceNumber(generatePriceWithCurrency);
105943
106108
  setGeneratePriceWithCurrency(`€${n}`);
105944
106109
  }, edge: "end", sx: { minWidth: 34, fontSize: '1rem', fontWeight: 700 } }, "\u20AC")),
105945
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: "\u041F\u043E\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C z\u0142 (\u0446\u0438\u0444\u0440\u0430 \u0438\u0437 \u043F\u043E\u043B\u044F \u0438\u043B\u0438 99)" },
106110
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: "\u041F\u043E\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C z\u0142 (\u0446\u0438\u0444\u0440\u0430 \u0438\u0437 \u043F\u043E\u043B\u044F \u0438\u043B\u0438 99)" },
105946
106111
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", "aria-label": "\u0411\u044B\u0441\u0442\u0440\u043E \u0437\u043B\u043E\u0442\u044B\u0435", onClick: () => {
105947
106112
  const n = extractLeadingPriceNumber(generatePriceWithCurrency);
105948
106113
  setGeneratePriceWithCurrency(`${n} zł`);
@@ -105951,29 +106116,29 @@ ${imageData.originalPrompt}
105951
106116
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
105952
106117
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { label: "\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F (\u043D\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E)", variant: "outlined", fullWidth: true, multiline: true, minRows: 3, value: generateAdditionalInfo, onChange: (e) => setGenerateAdditionalInfo(e.target.value), placeholder: "\u0418\u043D\u0433\u0440\u0435\u0434\u0438\u0435\u043D\u0442\u044B, \u0443\u0442\u043E\u0447\u043D\u0435\u043D\u0438\u044F \u043A \u043F\u0440\u043E\u043C\u043F\u0442\u0443 \u0438 \u0442.\u0434.", sx: { mb: 2 } })),
105953
106118
  openaiApiKey && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
105954
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_23__["default"], { fullWidth: true, variant: "outlined" },
105955
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], null, "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439"),
105956
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_25__["default"], { value: selectedImageModel, onChange: (e) => handleImageModelChange(e.target.value), label: "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439", disabled: loadingImageModels || imageModels.length === 0 }, loadingImageModels ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], { disabled: true },
106119
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_25__["default"], { fullWidth: true, variant: "outlined" },
106120
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], null, "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439"),
106121
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_27__["default"], { value: selectedImageModel, onChange: (e) => handleImageModelChange(e.target.value), label: "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439", disabled: loadingImageModels || imageModels.length === 0 }, loadingImageModels ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { disabled: true },
105957
106122
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
105958
106123
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_18__["default"], { size: 16 }),
105959
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u043C\u043E\u0434\u0435\u043B\u0435\u0439...")))) : imageModels.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], { disabled: true }, "\u041D\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u043C\u043E\u0434\u0435\u043B\u0435\u0439")) : (imageModels.map((model) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], { key: model.id, value: model.id }, model.name))))),
106124
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u043C\u043E\u0434\u0435\u043B\u0435\u0439...")))) : imageModels.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { disabled: true }, "\u041D\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u043C\u043E\u0434\u0435\u043B\u0435\u0439")) : (imageModels.map((model) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { key: model.id, value: model.id }, model.name))))),
105960
106125
  !loadingImageModels && imageModels.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_19__["default"], null, selectedImageModel === _models__WEBPACK_IMPORTED_MODULE_2__.MODELS.imageGeneration
105961
106126
  ? 'Используется модель по умолчанию'
105962
106127
  : 'Выбрана модель: ' + (imageModels.find(m => m.id === selectedImageModel)?.name || selectedImageModel)))),
105963
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_23__["default"], { fullWidth: true, variant: "outlined" },
105964
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], null, "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u043A\u0440\u0435\u0430\u0442\u0438\u0432\u043E\u0432"),
105965
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_25__["default"], { value: selectedValidationModel, onChange: (e) => handleValidationModelChange(e.target.value), label: "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u043A\u0440\u0435\u0430\u0442\u0438\u0432\u043E\u0432", disabled: loadingValidationModels || validationModels.length === 0 }, loadingValidationModels ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], { disabled: true },
106128
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_25__["default"], { fullWidth: true, variant: "outlined" },
106129
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], null, "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u043A\u0440\u0435\u0430\u0442\u0438\u0432\u043E\u0432"),
106130
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_27__["default"], { value: selectedValidationModel, onChange: (e) => handleValidationModelChange(e.target.value), label: "\u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u043A\u0440\u0435\u0430\u0442\u0438\u0432\u043E\u0432", disabled: loadingValidationModels || validationModels.length === 0 }, loadingValidationModels ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { disabled: true },
105966
106131
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
105967
106132
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_18__["default"], { size: 16 }),
105968
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u043C\u043E\u0434\u0435\u043B\u0435\u0439...")))) : validationModels.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], { disabled: true }, "\u041D\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u043C\u043E\u0434\u0435\u043B\u0435\u0439")) : (validationModels.map((model) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_26__["default"], { key: model.id, value: model.id }, model.name))))),
106133
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u043C\u043E\u0434\u0435\u043B\u0435\u0439...")))) : validationModels.length === 0 ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { disabled: true }, "\u041D\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u043C\u043E\u0434\u0435\u043B\u0435\u0439")) : (validationModels.map((model) => (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { key: model.id, value: model.id }, model.name))))),
105969
106134
  !loadingValidationModels && validationModels.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_19__["default"], null, selectedValidationModel === _models__WEBPACK_IMPORTED_MODULE_2__.MODELS.creativeValidation
105970
106135
  ? 'Используется модель по умолчанию'
105971
106136
  : 'Выбрана модель: ' + (validationModels.find(m => m.id === selectedValidationModel)?.name || selectedValidationModel))),
105972
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_27__["default"], { control: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_28__["default"], { checked: validationDisabled, onChange: (e) => handleValidationDisabledChange(e.target.checked), color: "primary" }), label: "\u041E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443", sx: { mt: 1 } })))),
106137
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_21__["default"], { control: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { checked: validationDisabled, onChange: (e) => handleValidationDisabledChange(e.target.checked), color: "primary" }), label: "\u041E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443", sx: { mt: 1 } })))),
105973
106138
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
105974
106139
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], { variant: "contained", color: "primary", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_36__["default"], null), onClick: handleGenerateContent, disabled: generating || loadingContentFromDrive || !openaiApiKey || !generateProduct.trim() || !generateGeo.trim(), sx: { flexGrow: 1 }, size: "large" }, generating ? 'Generating...' : 'Generate Titles & Descriptions'),
105975
106140
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 1, alignItems: "center", sx: { flexGrow: 1 } },
105976
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: imageAspectRatio === '1:1'
106141
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: imageAspectRatio === '1:1'
105977
106142
  ? '1:1 — квадрат (1024×1024 px)'
105978
106143
  : imageAspectRatio === '2:3'
105979
106144
  ? '2:3 — портрет (1024×1536 px)'
@@ -106065,8 +106230,20 @@ ${imageData.originalPrompt}
106065
106230
  } }, generatedImagesData.map((imageData) => {
106066
106231
  const imgRatio = imageData.aspectRatio ?? (imageAspectRatio === 'both' ? '1:1' : imageAspectRatio);
106067
106232
  const aspectRatioCss = imgRatio === '2:3' ? '2 / 3' : '1 / 1';
106068
- return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { key: imageData.index, sx: { position: 'relative' } },
106069
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043A\u0440\u0435\u0430\u0442\u0438\u0432" },
106233
+ const remakeN = imageData.remakeCount ?? 0;
106234
+ const remakeBg = getRemakeHighlightBackground(remakeN, darkMode);
106235
+ return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { key: imageData.index, sx: {
106236
+ position: 'relative',
106237
+ ...(remakeBg
106238
+ ? {
106239
+ p: 1,
106240
+ borderRadius: 1,
106241
+ bgcolor: remakeBg,
106242
+ boxSizing: 'border-box'
106243
+ }
106244
+ : {})
106245
+ } },
106246
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043A\u0440\u0435\u0430\u0442\u0438\u0432" },
106070
106247
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null,
106071
106248
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", "aria-label": "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043A\u0440\u0435\u0430\u0442\u0438\u0432", sx: {
106072
106249
  position: 'absolute',
@@ -106282,7 +106459,7 @@ ${imageData.originalPrompt}
106282
106459
  "/",
106283
106460
  Math.max(generatedTitlesData.length, generatedTextsData.length),
106284
106461
  ")"),
106285
- (generatedTitlesData.length > 0 || generatedTextsData.length > 0) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: pairsJsonCopied ? 'Скопировано' : 'Скопировать все пары как JSON-массив' },
106462
+ (generatedTitlesData.length > 0 || generatedTextsData.length > 0) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: pairsJsonCopied ? 'Скопировано' : 'Скопировать все пары как JSON-массив' },
106286
106463
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", "aria-label": "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0430\u0440\u044B \u043A\u0430\u043A JSON", onClick: () => void copyGeneratedPairsAsJson(), disabled: generating, sx: {
106287
106464
  opacity: 0.28,
106288
106465
  p: 0.35,
@@ -106345,11 +106522,11 @@ ${imageData.originalPrompt}
106345
106522
  i + 1),
106346
106523
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary" }, pairLabel),
106347
106524
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { flexGrow: 1, minWidth: 8 } }),
106348
- react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0430\u0440\u0443" },
106525
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0430\u0440\u0443" },
106349
106526
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null,
106350
106527
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", color: "error", "aria-label": "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0430\u0440\u0443", onClick: () => handleDeleteGeneratedPair(i), disabled: pairGenerating || generating },
106351
106528
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_42__["default"], { fontSize: "small" })))),
106352
- translatingPairs && !pairTranslations[i] ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_18__["default"], { size: 13, sx: { color: 'text.disabled', ml: 0.5 } })) : pairTranslations[i] ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_22__["default"], { title: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
106529
+ translatingPairs && !pairTranslations[i] ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_18__["default"], { size: 13, sx: { color: 'text.disabled', ml: 0.5 } })) : pairTranslations[i] ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
106353
106530
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { fontWeight: 700, display: 'block', mb: 0.5 } }, "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A:"),
106354
106531
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { display: 'block', mb: 1 } }, pairTranslations[i].titleRu),
106355
106532
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { fontWeight: 700, display: 'block', mb: 0.5 } }, "\u0422\u0435\u043A\u0441\u0442:"),
@@ -107259,7 +107436,14 @@ function PromptManagerDialog({ open, onClose }) {
107259
107436
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { type: "number", size: "small", value: count, onChange: (e) => {
107260
107437
  const v = parseInt(e.target.value, 10);
107261
107438
  handleImageApproachCountChange(i, isNaN(v) ? 0 : v);
107262
- }, onBlur: handleImageCountBlur, inputProps: { min: 0, max: 4, step: 1 }, sx: { width: 56, '& .MuiInputBase-input': { textAlign: 'center', py: 0.5 } } })),
107439
+ }, onBlur: handleImageCountBlur, inputProps: {
107440
+ min: 0,
107441
+ max: 4,
107442
+ step: 1,
107443
+ onWheel: (e) => {
107444
+ e.preventDefault();
107445
+ },
107446
+ }, sx: { width: 56, '& .MuiInputBase-input': { textAlign: 'center', py: 0.5 } } })),
107263
107447
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", { style: { padding: '4px 8px', fontWeight: 500, whiteSpace: 'nowrap' } }, approach.name),
107264
107448
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", { style: { padding: '4px 8px', color: '#777' } }, approach.prompt.split('\n')[0])));
107265
107449
  }))))),
@@ -107873,6 +108057,7 @@ __webpack_require__.r(__webpack_exports__);
107873
108057
  /* harmony export */ PAIR_APPROACH_POOL: () => (/* binding */ PAIR_APPROACH_POOL),
107874
108058
  /* harmony export */ TEXTS_APPROACH_POOL: () => (/* binding */ TEXTS_APPROACH_POOL),
107875
108059
  /* harmony export */ TITLES_APPROACH_POOL: () => (/* binding */ TITLES_APPROACH_POOL),
108060
+ /* harmony export */ getCreoApproachExpandedTasks: () => (/* binding */ getCreoApproachExpandedTasks),
107876
108061
  /* harmony export */ getCreoApproaches: () => (/* binding */ getCreoApproaches),
107877
108062
  /* harmony export */ getImageCheckPrompt: () => (/* binding */ getImageCheckPrompt),
107878
108063
  /* harmony export */ getImageGenerationBasePrompt: () => (/* binding */ getImageGenerationBasePrompt),
@@ -108595,10 +108780,10 @@ AUTO-CHECK (перед финалом):
108595
108780
  ВАЖНО: Твой ответ — это ИЗОБРАЖЕНИЕ, не текст. Не пиши план, не перечисляй элементы текстом, не рассуждай, не вызывай tools. Сразу генерируй визуальный креатив как картинку.`;
108596
108781
  }
108597
108782
  /**
108598
- * Получить подходы с учетом количества и оверрайдов.
108599
- * Каждый подход повторяется N раз (0–4), где N = imageApproachCounts[i].
108783
+ * Развёрнутый список задач крео: каждый подход повторяется N раз (0–4), N = imageApproachCounts[i].
108784
+ * poolIndex индекс строки в CREO_APPROACHES (0-based); в UI таблице это номер строки poolIndex + 1 (1–10).
108600
108785
  */
108601
- function getCreoApproaches() {
108786
+ function getCreoApproachExpandedTasks() {
108602
108787
  const counts = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_0__.getImageApproachCounts)();
108603
108788
  const result = [];
108604
108789
  for (let i = 0; i < CREO_APPROACHES.length && i < counts.length; i++) {
@@ -108618,11 +108803,15 @@ function getCreoApproaches() {
108618
108803
  _debugLog(`✅ Using CUSTOM approach: ${approach.name}`, `hasPrompt=${!!override.customPrompt}`, `hasHeadline=${!!override.customHeadlineAngle}`, `hasBullets=${!!override.customBulletsFocus}`);
108619
108804
  }
108620
108805
  for (let k = 0; k < counts[i]; k++) {
108621
- result.push(resolved);
108806
+ result.push({ approach: resolved, poolIndex: i });
108622
108807
  }
108623
108808
  }
108624
108809
  return result;
108625
108810
  }
108811
+ /** Плоский список подходов (без индекса строки) — для обратной совместимости. */
108812
+ function getCreoApproaches() {
108813
+ return getCreoApproachExpandedTasks().map(t => t.approach);
108814
+ }
108626
108815
  const CREO_APPROACHES = [
108627
108816
  {
108628
108817
  name: 'Эксперт / Авторитет',