docs-combiner 0.1.15 → 0.1.16
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 +726 -344
- package/dist/renderer.js.map +1 -1
- package/package.json +1 -1
package/dist/renderer.js
CHANGED
|
@@ -3056,29 +3056,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
3056
3056
|
|
|
3057
3057
|
/***/ }),
|
|
3058
3058
|
|
|
3059
|
-
/***/ "./node_modules/@mui/icons-material/esm/InfoOutlined.js":
|
|
3060
|
-
/*!**************************************************************!*\
|
|
3061
|
-
!*** ./node_modules/@mui/icons-material/esm/InfoOutlined.js ***!
|
|
3062
|
-
\**************************************************************/
|
|
3063
|
-
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
3064
|
-
|
|
3065
|
-
"use strict";
|
|
3066
|
-
__webpack_require__.r(__webpack_exports__);
|
|
3067
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
3068
|
-
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
3069
|
-
/* harmony export */ });
|
|
3070
|
-
/* harmony import */ var _utils_createSvgIcon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/createSvgIcon.js */ "./node_modules/@mui/material/esm/utils/createSvgIcon.js");
|
|
3071
|
-
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react/jsx-runtime */ "./node_modules/react/jsx-runtime.js");
|
|
3072
|
-
"use client";
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,_utils_createSvgIcon_js__WEBPACK_IMPORTED_MODULE_0__["default"])(/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("path", {
|
|
3077
|
-
d: "M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8"
|
|
3078
|
-
}), 'InfoOutlined'));
|
|
3079
|
-
|
|
3080
|
-
/***/ }),
|
|
3081
|
-
|
|
3082
3059
|
/***/ "./node_modules/@mui/icons-material/esm/KeyboardArrowDown.js":
|
|
3083
3060
|
/*!*******************************************************************!*\
|
|
3084
3061
|
!*** ./node_modules/@mui/icons-material/esm/KeyboardArrowDown.js ***!
|
|
@@ -100879,15 +100856,15 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
100879
100856
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Card/Card.js");
|
|
100880
100857
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/CardContent/CardContent.js");
|
|
100881
100858
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Stack/Stack.js");
|
|
100882
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100883
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100884
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100885
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100859
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/TextField/TextField.js");
|
|
100860
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormHelperText/FormHelperText.js");
|
|
100861
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/CircularProgress/CircularProgress.js");
|
|
100862
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Alert/Alert.js");
|
|
100886
100863
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Divider/Divider.js");
|
|
100887
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100888
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100889
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100890
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100864
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Accordion/Accordion.js");
|
|
100865
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/AccordionSummary/AccordionSummary.js");
|
|
100866
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/AccordionDetails/AccordionDetails.js");
|
|
100867
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Button/Button.js");
|
|
100891
100868
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/FormControlLabel/FormControlLabel.js");
|
|
100892
100869
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Checkbox/Checkbox.js");
|
|
100893
100870
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/InputAdornment/InputAdornment.js");
|
|
@@ -100899,30 +100876,33 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
100899
100876
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/ToggleButtonGroup/ToggleButtonGroup.js");
|
|
100900
100877
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/ToggleButton/ToggleButton.js");
|
|
100901
100878
|
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Paper/Paper.js");
|
|
100902
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100903
|
-
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/
|
|
100904
|
-
/* harmony import */ var
|
|
100905
|
-
/* harmony import */ var
|
|
100906
|
-
/* harmony import */ var
|
|
100907
|
-
/* harmony import */ var
|
|
100908
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100909
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100910
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100911
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100912
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100913
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100914
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100915
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100916
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100917
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100918
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100919
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100920
|
-
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/
|
|
100921
|
-
/* harmony import */ var
|
|
100922
|
-
/* harmony import */ var
|
|
100923
|
-
/* harmony import */ var
|
|
100924
|
-
/* harmony import */ var
|
|
100925
|
-
/* harmony import */ var
|
|
100879
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/Dialog/Dialog.js");
|
|
100880
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/DialogTitle/DialogTitle.js");
|
|
100881
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/DialogContent/DialogContent.js");
|
|
100882
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/DialogActions/DialogActions.js");
|
|
100883
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/styles/createTheme.js");
|
|
100884
|
+
/* harmony import */ var _mui_material__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! @mui/material */ "./node_modules/@mui/material/esm/styles/ThemeProvider.js");
|
|
100885
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/AccountBalance.js");
|
|
100886
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/AttachMoney.js");
|
|
100887
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/AutoAwesome.js");
|
|
100888
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Brightness4.js");
|
|
100889
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Brightness7.js");
|
|
100890
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/CheckCircle.js");
|
|
100891
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/CloudDownload.js");
|
|
100892
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/ContentCopy.js");
|
|
100893
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/DeleteOutline.js");
|
|
100894
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/ExpandMore.js");
|
|
100895
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Login.js");
|
|
100896
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Logout.js");
|
|
100897
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/NoteAdd.js");
|
|
100898
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Replay.js");
|
|
100899
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Settings.js");
|
|
100900
|
+
/* harmony import */ var _mui_icons_material__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(/*! @mui/icons-material */ "./node_modules/@mui/icons-material/esm/Visibility.js");
|
|
100901
|
+
/* harmony import */ var _PromptManagerDialog__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(/*! ./PromptManagerDialog */ "./src/PromptManagerDialog.tsx");
|
|
100902
|
+
/* harmony import */ var _promptOverrides__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(/*! ./promptOverrides */ "./src/promptOverrides.ts");
|
|
100903
|
+
/* harmony import */ var xlsx__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(/*! xlsx */ "./node_modules/xlsx/xlsx.mjs");
|
|
100904
|
+
/* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(/*! jszip */ "./node_modules/jszip/dist/jszip.min.js");
|
|
100905
|
+
/* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_57___default = /*#__PURE__*/__webpack_require__.n(jszip__WEBPACK_IMPORTED_MODULE_57__);
|
|
100926
100906
|
|
|
100927
100907
|
|
|
100928
100908
|
|
|
@@ -101222,6 +101202,70 @@ function getRemakeHighlightBackground(remakeCount, dark) {
|
|
|
101222
101202
|
const light = ['#fffde7', '#fff9c4', '#fff59d', '#ffee58', '#ffeb3b', '#fdd835', '#fbc02d', '#f9a825'];
|
|
101223
101203
|
return light[step];
|
|
101224
101204
|
}
|
|
101205
|
+
function sortedPairIndicesEqual(a, b) {
|
|
101206
|
+
const sa = [...a].sort((x, y) => x - y);
|
|
101207
|
+
const sb = [...b].sort((x, y) => x - y);
|
|
101208
|
+
if (sa.length !== sb.length)
|
|
101209
|
+
return false;
|
|
101210
|
+
return sa.every((v, i) => v === sb[i]);
|
|
101211
|
+
}
|
|
101212
|
+
function imageApproachCountsEqual(a, b) {
|
|
101213
|
+
if (a.length !== b.length)
|
|
101214
|
+
return false;
|
|
101215
|
+
return a.every((v, i) => v === b[i]);
|
|
101216
|
+
}
|
|
101217
|
+
function formatPairApproachesForDisplay(indices) {
|
|
101218
|
+
return [...indices]
|
|
101219
|
+
.sort((x, y) => x - y)
|
|
101220
|
+
.map(i => {
|
|
101221
|
+
const p = _prompts__WEBPACK_IMPORTED_MODULE_1__.PAIR_APPROACH_POOL[i];
|
|
101222
|
+
const label = p?.name ?? '?';
|
|
101223
|
+
return `${i + 1}. ${label}`;
|
|
101224
|
+
})
|
|
101225
|
+
.join('\n');
|
|
101226
|
+
}
|
|
101227
|
+
function formatImageCountsForDisplay(counts) {
|
|
101228
|
+
const lines = counts
|
|
101229
|
+
.map((c, i) => (c > 0 ? `${_prompts__WEBPACK_IMPORTED_MODULE_1__.CREO_APPROACHES[i]?.name ?? `№${i + 1}`}: ×${c}` : null))
|
|
101230
|
+
.filter((x) => x != null);
|
|
101231
|
+
return lines.length > 0 ? lines.join('\n') : 'ни один подход (все 0)';
|
|
101232
|
+
}
|
|
101233
|
+
/** Один раз прошли экран «Application Error» — больше не показывать (localStorage + Electron config). */
|
|
101234
|
+
const SECRET_UNLOCK_STORAGE_KEY = 'docs_combiner_secret_unlocked';
|
|
101235
|
+
async function fetchDriveFilePermissions(token, fileId) {
|
|
101236
|
+
const permissionsUrl = `https://www.googleapis.com/drive/v3/files/${fileId}?fields=permissions(id,type,role)&supportsAllDrives=true`;
|
|
101237
|
+
const permissionsResponse = await fetch(permissionsUrl, {
|
|
101238
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
101239
|
+
});
|
|
101240
|
+
if (!permissionsResponse.ok) {
|
|
101241
|
+
return { ok: false, errorText: await permissionsResponse.text() };
|
|
101242
|
+
}
|
|
101243
|
+
const permissionsData = await permissionsResponse.json();
|
|
101244
|
+
return { ok: true, permissions: permissionsData.permissions || [] };
|
|
101245
|
+
}
|
|
101246
|
+
/** Доступ «любой по ссылке» / публичный читатель — нужен для скачивания референса по URL без OAuth. */
|
|
101247
|
+
function permissionsIncludeAnyoneLink(permissions) {
|
|
101248
|
+
return permissions.some(p => p.type === 'anyone');
|
|
101249
|
+
}
|
|
101250
|
+
async function verifyOfferFolderHasAnyoneLinkForImageGen(token, folderId) {
|
|
101251
|
+
const offerPermResult = await fetchDriveFilePermissions(token, folderId);
|
|
101252
|
+
if (!offerPermResult.ok) {
|
|
101253
|
+
return {
|
|
101254
|
+
ok: false,
|
|
101255
|
+
message: 'Не удалось проверить доступ к папке оффера в Google Диске.\n\n' +
|
|
101256
|
+
'Генерация изображений с референсом может не работать без доступа по ссылке.\n\n' +
|
|
101257
|
+
(offerPermResult.errorText.trim().slice(0, 280) || 'Ошибка API')
|
|
101258
|
+
};
|
|
101259
|
+
}
|
|
101260
|
+
if (!permissionsIncludeAnyoneLink(offerPermResult.permissions)) {
|
|
101261
|
+
return {
|
|
101262
|
+
ok: false,
|
|
101263
|
+
message: 'Папка оффера закрыта для доступа по ссылке: нет права «Все, у кого есть ссылка» (тип anyone).\n\n' +
|
|
101264
|
+
'Сервисы генерации скачивают product.png по публичному URL. Включите в Google Диске общий доступ с ролью «Читатель» для этой папки (или согласитесь, когда приложение предложит сделать это автоматически).'
|
|
101265
|
+
};
|
|
101266
|
+
}
|
|
101267
|
+
return { ok: true };
|
|
101268
|
+
}
|
|
101225
101269
|
function App() {
|
|
101226
101270
|
const [clientId, setClientId] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
|
|
101227
101271
|
const [clientSecret, setClientSecret] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
|
|
@@ -101236,7 +101280,10 @@ function App() {
|
|
|
101236
101280
|
// Переводы сгенерированных пар на русский: ключ = 0-based индекс пары
|
|
101237
101281
|
const [pairTranslations, setPairTranslations] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({});
|
|
101238
101282
|
const [translatingPairs, setTranslatingPairs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101283
|
+
/** Папка оффера: загрузка/сохранение контента и крео (как раньше) */
|
|
101239
101284
|
const [driveFolderUrl, setDriveFolderUrl] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
|
|
101285
|
+
/** Корневая папка: только поле + проверка общего доступа и подпапки OFFERS (отдельно от папки оффера) */
|
|
101286
|
+
const [rootDriveFolderUrl, setRootDriveFolderUrl] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
|
|
101240
101287
|
const [link, setLink] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
|
|
101241
101288
|
const linkInputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
101242
101289
|
const [openaiApiKey, setOpenaiApiKey] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)('');
|
|
@@ -101441,10 +101488,17 @@ function App() {
|
|
|
101441
101488
|
const [uploadingImages, setUploadingImages] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101442
101489
|
const [uploadingProduct, setUploadingProduct] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101443
101490
|
const [folderFilesInfo, setFolderFilesInfo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
101491
|
+
const [rootFolderInfo, setRootFolderInfo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
101444
101492
|
const productFileInputRef = react__WEBPACK_IMPORTED_MODULE_0___default().useRef(null);
|
|
101445
101493
|
const [checkingFolderFiles, setCheckingFolderFiles] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101494
|
+
const [checkingRootFolder, setCheckingRootFolder] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101495
|
+
const [drivePublicAccessWarning, setDrivePublicAccessWarning] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101496
|
+
/** Уже обработали запрос доступа по ссылке для корневой папки (OFFERS) */
|
|
101446
101497
|
const permissionCheckedFoldersRef = react__WEBPACK_IMPORTED_MODULE_0___default().useRef(new Set());
|
|
101498
|
+
/** Уже спрашивали про доступ по ссылке для папки оффера (нужен OpenRouter по uc?export=view) */
|
|
101499
|
+
const driveFolderPublicLinkPromptedRef = react__WEBPACK_IMPORTED_MODULE_0___default().useRef(new Set());
|
|
101447
101500
|
const folderCheckRunningRef = react__WEBPACK_IMPORTED_MODULE_0___default().useRef(false);
|
|
101501
|
+
const rootFolderCheckRunningRef = react__WEBPACK_IMPORTED_MODULE_0___default().useRef(false);
|
|
101448
101502
|
const [imagesProcessStartTime, setImagesProcessStartTime] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
101449
101503
|
const [contentProcessStartTime, setContentProcessStartTime] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
101450
101504
|
const [contentGenerationLogs, setContentGenerationLogs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
|
|
@@ -101485,9 +101539,36 @@ function App() {
|
|
|
101485
101539
|
const saved = localStorage.getItem('themeMode');
|
|
101486
101540
|
return saved === 'dark';
|
|
101487
101541
|
});
|
|
101488
|
-
// Secret unlock state
|
|
101489
|
-
const [unlocked, setUnlocked] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(
|
|
101542
|
+
// Secret unlock state — восстанавливаем из localStorage; при старте Electron подмешивает config.secretUnlockPassed
|
|
101543
|
+
const [unlocked, setUnlocked] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
|
|
101544
|
+
try {
|
|
101545
|
+
return localStorage.getItem(SECRET_UNLOCK_STORAGE_KEY) === '1';
|
|
101546
|
+
}
|
|
101547
|
+
catch {
|
|
101548
|
+
return false;
|
|
101549
|
+
}
|
|
101550
|
+
});
|
|
101490
101551
|
const [clickSequence, setClickSequence] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
|
|
101552
|
+
const persistSecretUnlockPassed = () => {
|
|
101553
|
+
try {
|
|
101554
|
+
localStorage.setItem(SECRET_UNLOCK_STORAGE_KEY, '1');
|
|
101555
|
+
}
|
|
101556
|
+
catch {
|
|
101557
|
+
// ignore
|
|
101558
|
+
}
|
|
101559
|
+
void (async () => {
|
|
101560
|
+
try {
|
|
101561
|
+
const api = getElectronAPI();
|
|
101562
|
+
if (api) {
|
|
101563
|
+
const current = await api.loadConfig();
|
|
101564
|
+
await api.saveConfig({ ...current, secretUnlockPassed: true });
|
|
101565
|
+
}
|
|
101566
|
+
}
|
|
101567
|
+
catch {
|
|
101568
|
+
// ignore
|
|
101569
|
+
}
|
|
101570
|
+
})();
|
|
101571
|
+
};
|
|
101491
101572
|
// Handle secret unlock clicks - simplified to left then right
|
|
101492
101573
|
const handleSecretClick = (e) => {
|
|
101493
101574
|
if (unlocked)
|
|
@@ -101512,6 +101593,7 @@ function App() {
|
|
|
101512
101593
|
// Second click: right side (after left)
|
|
101513
101594
|
setUnlocked(true);
|
|
101514
101595
|
setClickSequence([]);
|
|
101596
|
+
persistSecretUnlockPassed();
|
|
101515
101597
|
}
|
|
101516
101598
|
else {
|
|
101517
101599
|
// Wrong click or wrong sequence, reset
|
|
@@ -101526,7 +101608,7 @@ function App() {
|
|
|
101526
101608
|
}
|
|
101527
101609
|
};
|
|
101528
101610
|
// Create theme based on mode
|
|
101529
|
-
const theme = react__WEBPACK_IMPORTED_MODULE_0___default().useMemo(() => (0,
|
|
101611
|
+
const theme = react__WEBPACK_IMPORTED_MODULE_0___default().useMemo(() => (0,_mui_material__WEBPACK_IMPORTED_MODULE_36__["default"])({
|
|
101530
101612
|
palette: {
|
|
101531
101613
|
mode: darkMode ? 'dark' : 'light',
|
|
101532
101614
|
...(darkMode
|
|
@@ -101581,6 +101663,8 @@ function App() {
|
|
|
101581
101663
|
applyThemeStyles(darkMode);
|
|
101582
101664
|
}, [darkMode]);
|
|
101583
101665
|
const [promptManagerOpen, setPromptManagerOpen] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
|
101666
|
+
/** После загрузки project-settings.json: спросить, подставить подходы из файла или оставить локальные. */
|
|
101667
|
+
const [approachLoadChoice, setApproachLoadChoice] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
|
|
101584
101668
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
101585
101669
|
// Load config on mount
|
|
101586
101670
|
const loadKey = async () => {
|
|
@@ -101601,6 +101685,15 @@ function App() {
|
|
|
101601
101685
|
setOpenaiApiKey(config.openaiApiKey);
|
|
101602
101686
|
// Balance will be fetched automatically by useEffect when openaiApiKey changes
|
|
101603
101687
|
}
|
|
101688
|
+
if (config.secretUnlockPassed === true) {
|
|
101689
|
+
setUnlocked(true);
|
|
101690
|
+
try {
|
|
101691
|
+
localStorage.setItem(SECRET_UNLOCK_STORAGE_KEY, '1');
|
|
101692
|
+
}
|
|
101693
|
+
catch {
|
|
101694
|
+
// ignore
|
|
101695
|
+
}
|
|
101696
|
+
}
|
|
101604
101697
|
}
|
|
101605
101698
|
catch (err) {
|
|
101606
101699
|
// Silent fail
|
|
@@ -101609,8 +101702,11 @@ function App() {
|
|
|
101609
101702
|
// effect (which depends on [driveFolderUrl]) will have valid tokens available
|
|
101610
101703
|
try {
|
|
101611
101704
|
const cachedDriveFolderUrl = localStorage.getItem('cached_driveFolderUrl');
|
|
101705
|
+
const cachedRootDriveFolderUrl = localStorage.getItem('cached_rootDriveFolderUrl');
|
|
101612
101706
|
if (cachedDriveFolderUrl)
|
|
101613
101707
|
setDriveFolderUrl(cachedDriveFolderUrl);
|
|
101708
|
+
if (cachedRootDriveFolderUrl)
|
|
101709
|
+
setRootDriveFolderUrl(cachedRootDriveFolderUrl);
|
|
101614
101710
|
}
|
|
101615
101711
|
catch (err) {
|
|
101616
101712
|
// Silent fail
|
|
@@ -101618,7 +101714,7 @@ function App() {
|
|
|
101618
101714
|
};
|
|
101619
101715
|
loadKey();
|
|
101620
101716
|
// Load prompt overrides from Electron config
|
|
101621
|
-
(0,
|
|
101717
|
+
(0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.loadOverridesFromElectron)();
|
|
101622
101718
|
}, []);
|
|
101623
101719
|
// Save form fields to localStorage whenever they change
|
|
101624
101720
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
@@ -101631,6 +101727,22 @@ function App() {
|
|
|
101631
101727
|
// Silent fail
|
|
101632
101728
|
}
|
|
101633
101729
|
}, [driveFolderUrl]);
|
|
101730
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
101731
|
+
try {
|
|
101732
|
+
if (rootDriveFolderUrl) {
|
|
101733
|
+
localStorage.setItem('cached_rootDriveFolderUrl', rootDriveFolderUrl);
|
|
101734
|
+
}
|
|
101735
|
+
else {
|
|
101736
|
+
localStorage.removeItem('cached_rootDriveFolderUrl');
|
|
101737
|
+
}
|
|
101738
|
+
}
|
|
101739
|
+
catch (err) {
|
|
101740
|
+
// Silent fail
|
|
101741
|
+
}
|
|
101742
|
+
}, [rootDriveFolderUrl]);
|
|
101743
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
101744
|
+
setDrivePublicAccessWarning(false);
|
|
101745
|
+
}, [rootDriveFolderUrl]);
|
|
101634
101746
|
// Auto-save AI Generation Settings, brand and link to Google Drive when they change
|
|
101635
101747
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
101636
101748
|
if (!driveFolderUrl)
|
|
@@ -101691,6 +101803,7 @@ function App() {
|
|
|
101691
101803
|
setUploadedLink('');
|
|
101692
101804
|
setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
|
|
101693
101805
|
setPairTranslations({});
|
|
101806
|
+
setApproachLoadChoice(null);
|
|
101694
101807
|
return;
|
|
101695
101808
|
}
|
|
101696
101809
|
const folderId = extractFolderId(driveFolderUrl);
|
|
@@ -101708,6 +101821,7 @@ function App() {
|
|
|
101708
101821
|
setUploadedLink('');
|
|
101709
101822
|
setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
|
|
101710
101823
|
setPairTranslations({});
|
|
101824
|
+
setApproachLoadChoice(null);
|
|
101711
101825
|
return;
|
|
101712
101826
|
}
|
|
101713
101827
|
logToTerminal('log', '[Load] driveFolderUrl changed, clearing old data and loading from folderId:', folderId);
|
|
@@ -101721,6 +101835,7 @@ function App() {
|
|
|
101721
101835
|
setUploadedLink('');
|
|
101722
101836
|
setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
|
|
101723
101837
|
setPairTranslations({});
|
|
101838
|
+
setApproachLoadChoice(null);
|
|
101724
101839
|
setLoadingContentFromDrive(true);
|
|
101725
101840
|
setDriveFilesFound({ content: false });
|
|
101726
101841
|
// Load content from Google Drive
|
|
@@ -101877,11 +101992,132 @@ function App() {
|
|
|
101877
101992
|
fetchValidationModels();
|
|
101878
101993
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
101879
101994
|
}, [openaiApiKey]);
|
|
101880
|
-
//
|
|
101995
|
+
// Корневая папка: общий доступ и подпапка OFFERS
|
|
101996
|
+
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
101997
|
+
let cancelled = false;
|
|
101998
|
+
const checkRootFolder = async () => {
|
|
101999
|
+
if (rootFolderCheckRunningRef.current)
|
|
102000
|
+
return;
|
|
102001
|
+
if (!rootDriveFolderUrl.trim()) {
|
|
102002
|
+
setRootFolderInfo(null);
|
|
102003
|
+
setDrivePublicAccessWarning(false);
|
|
102004
|
+
return;
|
|
102005
|
+
}
|
|
102006
|
+
const validToken = await getValidAccessToken();
|
|
102007
|
+
if (!validToken || cancelled) {
|
|
102008
|
+
if (!cancelled)
|
|
102009
|
+
setRootFolderInfo(null);
|
|
102010
|
+
return;
|
|
102011
|
+
}
|
|
102012
|
+
const rootFolderId = extractFolderId(rootDriveFolderUrl);
|
|
102013
|
+
if (!rootFolderId || cancelled) {
|
|
102014
|
+
if (!cancelled)
|
|
102015
|
+
setRootFolderInfo(null);
|
|
102016
|
+
return;
|
|
102017
|
+
}
|
|
102018
|
+
rootFolderCheckRunningRef.current = true;
|
|
102019
|
+
setCheckingRootFolder(true);
|
|
102020
|
+
try {
|
|
102021
|
+
if (!permissionCheckedFoldersRef.current.has(rootFolderId)) {
|
|
102022
|
+
const permissionsUrl = `https://www.googleapis.com/drive/v3/files/${rootFolderId}?fields=permissions(id,type,role)&supportsAllDrives=true`;
|
|
102023
|
+
const permissionsResponse = await fetch(permissionsUrl, {
|
|
102024
|
+
headers: {
|
|
102025
|
+
'Authorization': `Bearer ${validToken}`
|
|
102026
|
+
}
|
|
102027
|
+
});
|
|
102028
|
+
if (cancelled)
|
|
102029
|
+
return;
|
|
102030
|
+
permissionCheckedFoldersRef.current.add(rootFolderId);
|
|
102031
|
+
if (permissionsResponse.ok) {
|
|
102032
|
+
const permissionsData = await permissionsResponse.json();
|
|
102033
|
+
const anyonePerms = (permissionsData.permissions || []).filter((p) => p.type === 'anyone' && p.id);
|
|
102034
|
+
if (anyonePerms.length > 0) {
|
|
102035
|
+
if (cancelled)
|
|
102036
|
+
return;
|
|
102037
|
+
const revoke = window.confirm('У этой папки включён общий доступ по ссылке («Все, у кого есть ссылка» или публично в интернете).\n\n' +
|
|
102038
|
+
'Приложение использует ваш аккаунт Google — открывать папку всем не обязательно.\n\n' +
|
|
102039
|
+
'Убрать общий доступ для этой папки автоматически?');
|
|
102040
|
+
if (cancelled)
|
|
102041
|
+
return;
|
|
102042
|
+
if (revoke) {
|
|
102043
|
+
const tok = await getValidAccessToken();
|
|
102044
|
+
if (!tok || cancelled) {
|
|
102045
|
+
if (!cancelled)
|
|
102046
|
+
setRootFolderInfo(null);
|
|
102047
|
+
return;
|
|
102048
|
+
}
|
|
102049
|
+
for (const p of anyonePerms) {
|
|
102050
|
+
if (cancelled)
|
|
102051
|
+
break;
|
|
102052
|
+
const delUrl = `https://www.googleapis.com/drive/v3/files/${rootFolderId}/permissions/${p.id}?supportsAllDrives=true`;
|
|
102053
|
+
const delRes = await fetch(delUrl, {
|
|
102054
|
+
method: 'DELETE',
|
|
102055
|
+
headers: { 'Authorization': `Bearer ${tok}` }
|
|
102056
|
+
});
|
|
102057
|
+
if (!delRes.ok) {
|
|
102058
|
+
const errText = await delRes.text();
|
|
102059
|
+
logToTerminal('error', 'Failed to remove Drive permission:', errText);
|
|
102060
|
+
}
|
|
102061
|
+
}
|
|
102062
|
+
if (!cancelled)
|
|
102063
|
+
setDrivePublicAccessWarning(false);
|
|
102064
|
+
}
|
|
102065
|
+
else if (!cancelled) {
|
|
102066
|
+
setDrivePublicAccessWarning(true);
|
|
102067
|
+
}
|
|
102068
|
+
}
|
|
102069
|
+
else if (!cancelled) {
|
|
102070
|
+
setDrivePublicAccessWarning(false);
|
|
102071
|
+
}
|
|
102072
|
+
}
|
|
102073
|
+
}
|
|
102074
|
+
if (cancelled)
|
|
102075
|
+
return;
|
|
102076
|
+
const currentToken = await getValidAccessToken();
|
|
102077
|
+
if (!currentToken || cancelled) {
|
|
102078
|
+
if (!cancelled)
|
|
102079
|
+
setRootFolderInfo(null);
|
|
102080
|
+
return;
|
|
102081
|
+
}
|
|
102082
|
+
const fields = 'files(id, name)';
|
|
102083
|
+
const qOffers = `'${rootFolderId}' in parents and trashed = false and mimeType = 'application/vnd.google-apps.folder'`;
|
|
102084
|
+
const offersUrl = `https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(qOffers)}&fields=${encodeURIComponent(fields)}&supportsAllDrives=true`;
|
|
102085
|
+
const offersResponse = await fetch(offersUrl, {
|
|
102086
|
+
headers: { 'Authorization': `Bearer ${currentToken}` }
|
|
102087
|
+
});
|
|
102088
|
+
if (cancelled)
|
|
102089
|
+
return;
|
|
102090
|
+
let hasOffersFolder = false;
|
|
102091
|
+
if (offersResponse.ok) {
|
|
102092
|
+
const offersData = await offersResponse.json();
|
|
102093
|
+
hasOffersFolder = (offersData.files || []).some((f) => (f.name || '').toUpperCase() === 'OFFERS');
|
|
102094
|
+
}
|
|
102095
|
+
if (!cancelled) {
|
|
102096
|
+
setRootFolderInfo({ hasOffersFolder });
|
|
102097
|
+
}
|
|
102098
|
+
}
|
|
102099
|
+
catch (err) {
|
|
102100
|
+
if (!cancelled)
|
|
102101
|
+
setRootFolderInfo(null);
|
|
102102
|
+
}
|
|
102103
|
+
finally {
|
|
102104
|
+
rootFolderCheckRunningRef.current = false;
|
|
102105
|
+
if (!cancelled)
|
|
102106
|
+
setCheckingRootFolder(false);
|
|
102107
|
+
}
|
|
102108
|
+
};
|
|
102109
|
+
const timeoutId = setTimeout(() => {
|
|
102110
|
+
checkRootFolder();
|
|
102111
|
+
}, 500);
|
|
102112
|
+
return () => {
|
|
102113
|
+
cancelled = true;
|
|
102114
|
+
clearTimeout(timeoutId);
|
|
102115
|
+
};
|
|
102116
|
+
}, [rootDriveFolderUrl, accessToken, refreshToken]);
|
|
102117
|
+
// Рабочая папка Google Drive: product и крео-изображения
|
|
101881
102118
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
101882
102119
|
let cancelled = false;
|
|
101883
102120
|
const checkFolderFiles = async () => {
|
|
101884
|
-
// Prevent concurrent runs (e.g. if token refresh re-triggers the effect while a check is in progress)
|
|
101885
102121
|
if (folderCheckRunningRef.current)
|
|
101886
102122
|
return;
|
|
101887
102123
|
if (!driveFolderUrl.trim()) {
|
|
@@ -101903,47 +102139,38 @@ function App() {
|
|
|
101903
102139
|
folderCheckRunningRef.current = true;
|
|
101904
102140
|
setCheckingFolderFiles(true);
|
|
101905
102141
|
try {
|
|
101906
|
-
|
|
101907
|
-
|
|
101908
|
-
const permissionsUrl = `https://www.googleapis.com/drive/v3/files/${folderId}?fields=permissions(id,type,role)`;
|
|
101909
|
-
const permissionsResponse = await fetch(permissionsUrl, {
|
|
101910
|
-
headers: {
|
|
101911
|
-
'Authorization': `Bearer ${validToken}`
|
|
101912
|
-
}
|
|
101913
|
-
});
|
|
102142
|
+
if (!driveFolderPublicLinkPromptedRef.current.has(folderId)) {
|
|
102143
|
+
const permResult = await fetchDriveFilePermissions(validToken, folderId);
|
|
101914
102144
|
if (cancelled)
|
|
101915
102145
|
return;
|
|
101916
|
-
if (
|
|
101917
|
-
|
|
101918
|
-
|
|
102146
|
+
if (!permResult.ok) {
|
|
102147
|
+
logToTerminal('warn', 'Could not read offer folder permissions (will retry on next check):', permResult.errorText);
|
|
102148
|
+
}
|
|
102149
|
+
else {
|
|
102150
|
+
const hasPublicLinkAccess = permissionsIncludeAnyoneLink(permResult.permissions);
|
|
101919
102151
|
if (hasPublicLinkAccess) {
|
|
101920
|
-
|
|
101921
|
-
permissionCheckedFoldersRef.current.add(folderId);
|
|
102152
|
+
driveFolderPublicLinkPromptedRef.current.add(folderId);
|
|
101922
102153
|
}
|
|
101923
102154
|
else {
|
|
101924
|
-
// Mark as checked BEFORE showing confirm to prevent duplicate prompts
|
|
101925
|
-
permissionCheckedFoldersRef.current.add(folderId);
|
|
101926
102155
|
if (cancelled)
|
|
101927
102156
|
return;
|
|
101928
|
-
|
|
101929
|
-
|
|
101930
|
-
'
|
|
101931
|
-
'Разрешить автоматически включить доступ по ссылке для этой папки?');
|
|
102157
|
+
const userConsent = window.confirm('⚠️ Папка оффера на Google Диске не открыта для всех по ссылке.\n\n' +
|
|
102158
|
+
'Сервисы генерации изображений (OpenRouter) скачивают картинки по публичному URL — без доступа по ссылке запросы могут падать с ошибкой.\n\n' +
|
|
102159
|
+
'Включить доступ по ссылке для этой папки (читатель) автоматически?');
|
|
101932
102160
|
if (cancelled)
|
|
101933
102161
|
return;
|
|
101934
102162
|
if (userConsent) {
|
|
101935
|
-
|
|
101936
|
-
|
|
101937
|
-
if (!currentToken || cancelled) {
|
|
102163
|
+
const tok = await getValidAccessToken();
|
|
102164
|
+
if (!tok || cancelled) {
|
|
101938
102165
|
if (!cancelled)
|
|
101939
102166
|
setFolderFilesInfo(null);
|
|
101940
102167
|
return;
|
|
101941
102168
|
}
|
|
101942
|
-
const createPermissionUrl = `https://www.googleapis.com/drive/v3/files/${folderId}/permissions`;
|
|
102169
|
+
const createPermissionUrl = `https://www.googleapis.com/drive/v3/files/${folderId}/permissions?supportsAllDrives=true`;
|
|
101943
102170
|
const createPermissionResponse = await fetch(createPermissionUrl, {
|
|
101944
102171
|
method: 'POST',
|
|
101945
102172
|
headers: {
|
|
101946
|
-
'Authorization': `Bearer ${
|
|
102173
|
+
'Authorization': `Bearer ${tok}`,
|
|
101947
102174
|
'Content-Type': 'application/json'
|
|
101948
102175
|
},
|
|
101949
102176
|
body: JSON.stringify({
|
|
@@ -101955,22 +102182,34 @@ function App() {
|
|
|
101955
102182
|
return;
|
|
101956
102183
|
if (!createPermissionResponse.ok) {
|
|
101957
102184
|
const errorText = await createPermissionResponse.text();
|
|
101958
|
-
logToTerminal('error', 'Failed to enable public link access:', errorText);
|
|
101959
|
-
alert('⚠️ Не удалось автоматически включить доступ по
|
|
102185
|
+
logToTerminal('error', 'Failed to enable public link access for offer folder:', errorText);
|
|
102186
|
+
window.alert('⚠️ Не удалось автоматически включить доступ по ссылке.\n\n' +
|
|
102187
|
+
'Сделайте папку доступной по ссылке вручную в Google Диске (роль «Читатель»).');
|
|
102188
|
+
// Не помечаем folderId — при следующей проверке снова предложим / повторим
|
|
101960
102189
|
}
|
|
101961
102190
|
else {
|
|
101962
|
-
|
|
102191
|
+
const verify = await fetchDriveFilePermissions(tok, folderId);
|
|
102192
|
+
if (verify.ok && permissionsIncludeAnyoneLink(verify.permissions)) {
|
|
102193
|
+
driveFolderPublicLinkPromptedRef.current.add(folderId);
|
|
102194
|
+
logToTerminal('log', '✅ Public link access enabled for offer folder (verified)');
|
|
102195
|
+
}
|
|
102196
|
+
else {
|
|
102197
|
+
logToTerminal('warn', 'Permission API succeeded but anyone-link not visible on re-fetch; user should verify in Drive UI');
|
|
102198
|
+
window.alert('⚠️ Запрос на доступ отправлен, но повторная проверка не увидела права «для всех по ссылке».\n\n' +
|
|
102199
|
+
'Проверьте папку в Google Диске вручную: общий доступ → «Все, у кого есть ссылка» → Читатель.');
|
|
102200
|
+
}
|
|
101963
102201
|
}
|
|
101964
102202
|
}
|
|
101965
102203
|
else {
|
|
101966
|
-
|
|
102204
|
+
driveFolderPublicLinkPromptedRef.current.add(folderId);
|
|
102205
|
+
window.alert('⚠️ Без доступа по ссылке генерация с референсами из этой папки может не работать.\n\n' +
|
|
102206
|
+
'Включите вручную: Настройки доступа → «Все, у кого есть ссылка» → Читатель.');
|
|
101967
102207
|
}
|
|
101968
102208
|
}
|
|
101969
102209
|
}
|
|
101970
102210
|
}
|
|
101971
102211
|
if (cancelled)
|
|
101972
102212
|
return;
|
|
101973
|
-
// Then check folder files
|
|
101974
102213
|
const currentToken = await getValidAccessToken();
|
|
101975
102214
|
if (!currentToken || cancelled) {
|
|
101976
102215
|
if (!cancelled)
|
|
@@ -101979,7 +102218,7 @@ function App() {
|
|
|
101979
102218
|
}
|
|
101980
102219
|
const q = `'${folderId}' in parents and trashed = false and mimeType contains 'image/'`;
|
|
101981
102220
|
const fields = 'files(id, name)';
|
|
101982
|
-
const url = `https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(q)}&fields=${encodeURIComponent(fields)}`;
|
|
102221
|
+
const url = `https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(q)}&fields=${encodeURIComponent(fields)}&supportsAllDrives=true`;
|
|
101983
102222
|
const response = await fetch(url, {
|
|
101984
102223
|
headers: {
|
|
101985
102224
|
'Authorization': `Bearer ${currentToken}`
|
|
@@ -101987,30 +102226,28 @@ function App() {
|
|
|
101987
102226
|
});
|
|
101988
102227
|
if (cancelled)
|
|
101989
102228
|
return;
|
|
101990
|
-
if (response.ok) {
|
|
101991
|
-
const data = await response.json();
|
|
101992
|
-
const hasProduct = data.files.some((f) => {
|
|
101993
|
-
const name = f.name?.toLowerCase() || '';
|
|
101994
|
-
return name === 'product.png' || name === 'product.jpg' || name === 'product.webp';
|
|
101995
|
-
});
|
|
101996
|
-
const hasCreativeImages = data.files.some((f) => {
|
|
101997
|
-
const name = f.name?.toLowerCase() || '';
|
|
101998
|
-
return name !== 'product.png' && name !== 'product.jpg' && name !== 'product.webp';
|
|
101999
|
-
});
|
|
102000
|
-
if (!cancelled) {
|
|
102001
|
-
setFolderFilesInfo({ hasProduct, hasCreativeImages });
|
|
102002
|
-
// If product not found, poll every 10 seconds until found
|
|
102003
|
-
if (!hasProduct) {
|
|
102004
|
-
pollTimeoutId = setTimeout(() => {
|
|
102005
|
-
if (!cancelled)
|
|
102006
|
-
checkFolderFiles();
|
|
102007
|
-
}, 10_000);
|
|
102008
|
-
}
|
|
102009
|
-
}
|
|
102010
|
-
}
|
|
102011
|
-
else {
|
|
102229
|
+
if (!response.ok) {
|
|
102012
102230
|
if (!cancelled)
|
|
102013
102231
|
setFolderFilesInfo(null);
|
|
102232
|
+
return;
|
|
102233
|
+
}
|
|
102234
|
+
const data = await response.json();
|
|
102235
|
+
const hasProduct = data.files.some((f) => {
|
|
102236
|
+
const name = f.name?.toLowerCase() || '';
|
|
102237
|
+
return name === 'product.png' || name === 'product.jpg' || name === 'product.webp';
|
|
102238
|
+
});
|
|
102239
|
+
const hasCreativeImages = data.files.some((f) => {
|
|
102240
|
+
const name = f.name?.toLowerCase() || '';
|
|
102241
|
+
return name !== 'product.png' && name !== 'product.jpg' && name !== 'product.webp';
|
|
102242
|
+
});
|
|
102243
|
+
if (!cancelled) {
|
|
102244
|
+
setFolderFilesInfo({ hasProduct, hasCreativeImages });
|
|
102245
|
+
if (!hasProduct) {
|
|
102246
|
+
pollTimeoutId = setTimeout(() => {
|
|
102247
|
+
if (!cancelled)
|
|
102248
|
+
checkFolderFiles();
|
|
102249
|
+
}, 10_000);
|
|
102250
|
+
}
|
|
102014
102251
|
}
|
|
102015
102252
|
}
|
|
102016
102253
|
catch (err) {
|
|
@@ -102024,7 +102261,6 @@ function App() {
|
|
|
102024
102261
|
}
|
|
102025
102262
|
};
|
|
102026
102263
|
let pollTimeoutId = null;
|
|
102027
|
-
// Debounce check
|
|
102028
102264
|
const timeoutId = setTimeout(() => {
|
|
102029
102265
|
checkFolderFiles();
|
|
102030
102266
|
}, 500);
|
|
@@ -103131,7 +103367,7 @@ function App() {
|
|
|
103131
103367
|
setTexts(['']);
|
|
103132
103368
|
setPairTranslations({});
|
|
103133
103369
|
// Read pairs count from settings (3–10, default 3)
|
|
103134
|
-
const pairsCountInit = (0,
|
|
103370
|
+
const pairsCountInit = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.getPairsCount)();
|
|
103135
103371
|
// Initialize placeholders
|
|
103136
103372
|
const initialTitles = Array.from({ length: pairsCountInit }, (_, index) => ({
|
|
103137
103373
|
index: index + 1,
|
|
@@ -103160,7 +103396,7 @@ function App() {
|
|
|
103160
103396
|
}
|
|
103161
103397
|
// Generate all pairs (title + text) in a single request
|
|
103162
103398
|
addLog(formatLogMessage('log', '📋 Generating title+text pairs in a single request...'));
|
|
103163
|
-
const selectedIndices = (0,
|
|
103399
|
+
const selectedIndices = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.getSelectedPairApproaches)();
|
|
103164
103400
|
setLastUsedApproachIndices(selectedIndices);
|
|
103165
103401
|
const pairsCount = selectedIndices.length;
|
|
103166
103402
|
addLog(formatLogMessage('log', `⚙️ Generating ${pairsCount} pairs (approaches: ${selectedIndices.join(', ')})`));
|
|
@@ -104099,7 +104335,7 @@ function App() {
|
|
|
104099
104335
|
addLog(formatLogMessage(level, ...args));
|
|
104100
104336
|
};
|
|
104101
104337
|
logMsg('log', '📦 Creating ZIP archive with HTML and product image...');
|
|
104102
|
-
const zip = new (
|
|
104338
|
+
const zip = new (jszip__WEBPACK_IMPORTED_MODULE_57___default())();
|
|
104103
104339
|
// Replace product image path in HTML to match actual filename (png/jpg/webp)
|
|
104104
104340
|
const htmlWithProductPath = htmlContent.replace(/src=["']product\.(png|jpe?g|webp)["']/gi, `src="${productImageName}"`);
|
|
104105
104341
|
zip.file('index.html', htmlWithProductPath);
|
|
@@ -104421,6 +104657,15 @@ function App() {
|
|
|
104421
104657
|
throw new Error(errorMsg);
|
|
104422
104658
|
}
|
|
104423
104659
|
addLog(formatLogMessage('log', '✅ Folder ID extracted:', folderId));
|
|
104660
|
+
addLog(formatLogMessage('log', '🔒 Проверка доступа по ссылке к папке оффера (нужен для референса)...'));
|
|
104661
|
+
const pubGate = await verifyOfferFolderHasAnyoneLinkForImageGen(validToken, folderId);
|
|
104662
|
+
if (!pubGate.ok) {
|
|
104663
|
+
addLog(formatLogMessage('error', '❌ ' + pubGate.message));
|
|
104664
|
+
alert(pubGate.message);
|
|
104665
|
+
setGeneratingImages(false);
|
|
104666
|
+
return;
|
|
104667
|
+
}
|
|
104668
|
+
addLog(formatLogMessage('log', '✅ Доступ по ссылке к папке оффера подтверждён'));
|
|
104424
104669
|
// Check for product image (png/jpg/webp)
|
|
104425
104670
|
addLog(formatLogMessage('log', '🔍 Checking for product image...'));
|
|
104426
104671
|
const productImage = await fetchProductImage(folderId);
|
|
@@ -104731,11 +104976,26 @@ function App() {
|
|
|
104731
104976
|
alert('Не удалось найти оригинальный промпт или изображение продукта для переделки');
|
|
104732
104977
|
return;
|
|
104733
104978
|
}
|
|
104979
|
+
const regenFolderId = extractFolderId(driveFolderUrl);
|
|
104980
|
+
if (!regenFolderId) {
|
|
104981
|
+
alert('Укажите корректный URL папки оффера на Google Drive');
|
|
104982
|
+
return;
|
|
104983
|
+
}
|
|
104734
104984
|
const addLog = (msg) => {
|
|
104735
104985
|
setImagesGenerationLogs(prev => [...prev, msg]);
|
|
104736
104986
|
logToTerminal('log', msg.replace(/\[.*?\]\s*/, ''));
|
|
104737
104987
|
};
|
|
104738
104988
|
try {
|
|
104989
|
+
const regenTok = await getValidAccessToken();
|
|
104990
|
+
if (!regenTok) {
|
|
104991
|
+
alert('Please log in with Google first');
|
|
104992
|
+
return;
|
|
104993
|
+
}
|
|
104994
|
+
const regenPub = await verifyOfferFolderHasAnyoneLinkForImageGen(regenTok, regenFolderId);
|
|
104995
|
+
if (!regenPub.ok) {
|
|
104996
|
+
alert(regenPub.message);
|
|
104997
|
+
return;
|
|
104998
|
+
}
|
|
104739
104999
|
// Get current customRegeneratePrompt from state
|
|
104740
105000
|
const currentImageData = generatedImagesData.find(img => img.index === imageData.index);
|
|
104741
105001
|
const customPrompt = currentImageData?.customRegeneratePrompt?.trim() || '';
|
|
@@ -104956,11 +105216,26 @@ ${imageData.originalPrompt}
|
|
|
104956
105216
|
alert('Не удалось найти оригинальный промпт или изображение продукта для переделки');
|
|
104957
105217
|
return;
|
|
104958
105218
|
}
|
|
105219
|
+
const freshFolderId = extractFolderId(driveFolderUrl);
|
|
105220
|
+
if (!freshFolderId) {
|
|
105221
|
+
alert('Укажите корректный URL папки оффера на Google Drive');
|
|
105222
|
+
return;
|
|
105223
|
+
}
|
|
104959
105224
|
const addLog = (msg) => {
|
|
104960
105225
|
setImagesGenerationLogs(prev => [...prev, msg]);
|
|
104961
105226
|
logToTerminal('log', msg.replace(/\[.*?\]\s*/, ''));
|
|
104962
105227
|
};
|
|
104963
105228
|
try {
|
|
105229
|
+
const freshTok = await getValidAccessToken();
|
|
105230
|
+
if (!freshTok) {
|
|
105231
|
+
alert('Please log in with Google first');
|
|
105232
|
+
return;
|
|
105233
|
+
}
|
|
105234
|
+
const freshPub = await verifyOfferFolderHasAnyoneLinkForImageGen(freshTok, freshFolderId);
|
|
105235
|
+
if (!freshPub.ok) {
|
|
105236
|
+
alert(freshPub.message);
|
|
105237
|
+
return;
|
|
105238
|
+
}
|
|
104964
105239
|
// Mark as regenerating (show overlay timer) - clear old image URL immediately to force re-render
|
|
104965
105240
|
setGeneratedImagesData(prev => prev.map(img => img.index === imageData.index
|
|
104966
105241
|
? {
|
|
@@ -105459,8 +105734,8 @@ ${imageData.originalPrompt}
|
|
|
105459
105734
|
catalogUrlTextApproachParam,
|
|
105460
105735
|
catalogUrlCreoApproachParam,
|
|
105461
105736
|
catalogLinkExtraMacros,
|
|
105462
|
-
selectedPairApproaches: (0,
|
|
105463
|
-
imageApproachCounts: (0,
|
|
105737
|
+
selectedPairApproaches: (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.getSelectedPairApproaches)(),
|
|
105738
|
+
imageApproachCounts: (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.getImageApproachCounts)(),
|
|
105464
105739
|
savedAt: new Date().toISOString()
|
|
105465
105740
|
};
|
|
105466
105741
|
const jsonContent = JSON.stringify(dataToSave, null, 2);
|
|
@@ -105627,9 +105902,23 @@ ${imageData.originalPrompt}
|
|
|
105627
105902
|
else {
|
|
105628
105903
|
setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS);
|
|
105629
105904
|
}
|
|
105630
|
-
const
|
|
105631
|
-
|
|
105632
|
-
|
|
105905
|
+
const parsedApproaches = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.parseApproachesFromDriveData)(loadedData);
|
|
105906
|
+
const currentPairs = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.getSelectedPairApproaches)();
|
|
105907
|
+
const currentCounts = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.getImageApproachCounts)();
|
|
105908
|
+
const hasDrivePairs = parsedApproaches.pairs !== null;
|
|
105909
|
+
const hasDriveCounts = parsedApproaches.counts !== null;
|
|
105910
|
+
if (hasDrivePairs || hasDriveCounts) {
|
|
105911
|
+
const pairsDiffer = hasDrivePairs && !sortedPairIndicesEqual(parsedApproaches.pairs, currentPairs);
|
|
105912
|
+
const countsDiffer = hasDriveCounts && !imageApproachCountsEqual(parsedApproaches.counts, currentCounts);
|
|
105913
|
+
if (pairsDiffer || countsDiffer) {
|
|
105914
|
+
setApproachLoadChoice({
|
|
105915
|
+
savedPairs: parsedApproaches.pairs,
|
|
105916
|
+
savedCounts: parsedApproaches.counts,
|
|
105917
|
+
currentPairs,
|
|
105918
|
+
currentCounts,
|
|
105919
|
+
});
|
|
105920
|
+
logToTerminal('log', '[Load Content] Offer file contains approach settings — asking user to apply or keep current');
|
|
105921
|
+
}
|
|
105633
105922
|
}
|
|
105634
105923
|
logToTerminal('log', '[Load Content] Successfully loaded content');
|
|
105635
105924
|
setDriveFilesFound(prev => ({ ...prev, content: false }));
|
|
@@ -105641,6 +105930,19 @@ ${imageData.originalPrompt}
|
|
|
105641
105930
|
return { found: false };
|
|
105642
105931
|
}
|
|
105643
105932
|
};
|
|
105933
|
+
const handleApproachLoadApplyFromFile = () => {
|
|
105934
|
+
if (!approachLoadChoice)
|
|
105935
|
+
return;
|
|
105936
|
+
const applied = (0,_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.applyParsedApproachesFromDrive)(approachLoadChoice.savedPairs, approachLoadChoice.savedCounts);
|
|
105937
|
+
if (applied) {
|
|
105938
|
+
logToTerminal('log', '[Load Content] Applied approach settings from offer file (user choice)');
|
|
105939
|
+
}
|
|
105940
|
+
setApproachLoadChoice(null);
|
|
105941
|
+
};
|
|
105942
|
+
const handleApproachLoadKeepCurrent = () => {
|
|
105943
|
+
logToTerminal('log', '[Load Content] Kept local approach settings (user choice)');
|
|
105944
|
+
setApproachLoadChoice(null);
|
|
105945
|
+
};
|
|
105644
105946
|
syncDriveAfterPromptSaveRef.current = () => {
|
|
105645
105947
|
if (!driveFolderUrl || loadingContentFromDrive)
|
|
105646
105948
|
return;
|
|
@@ -105659,8 +105961,8 @@ ${imageData.originalPrompt}
|
|
|
105659
105961
|
};
|
|
105660
105962
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
|
105661
105963
|
const listener = () => syncDriveAfterPromptSaveRef.current();
|
|
105662
|
-
window.addEventListener(
|
|
105663
|
-
return () => window.removeEventListener(
|
|
105964
|
+
window.addEventListener(_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.PROMPT_OVERRIDES_SAVED_EVENT, listener);
|
|
105965
|
+
return () => window.removeEventListener(_promptOverrides__WEBPACK_IMPORTED_MODULE_55__.PROMPT_OVERRIDES_SAVED_EVENT, listener);
|
|
105664
105966
|
}, []);
|
|
105665
105967
|
const handleGenerate = async () => {
|
|
105666
105968
|
if (!driveFolderUrl || !brand || !link) {
|
|
@@ -105741,8 +106043,8 @@ ${imageData.originalPrompt}
|
|
|
105741
106043
|
}
|
|
105742
106044
|
setGeneratedData(rows);
|
|
105743
106045
|
// Create workbook
|
|
105744
|
-
const wb =
|
|
105745
|
-
const ws =
|
|
106046
|
+
const wb = xlsx__WEBPACK_IMPORTED_MODULE_56__.utils.book_new();
|
|
106047
|
+
const ws = xlsx__WEBPACK_IMPORTED_MODULE_56__.utils.aoa_to_sheet(rows);
|
|
105746
106048
|
// Set column widths (approximate pixel width / 7)
|
|
105747
106049
|
ws['!cols'] = [
|
|
105748
106050
|
{ wch: 20 }, // id
|
|
@@ -105755,9 +106057,9 @@ ${imageData.originalPrompt}
|
|
|
105755
106057
|
{ wch: 40 }, // image_link
|
|
105756
106058
|
{ wch: 20 } // brand
|
|
105757
106059
|
];
|
|
105758
|
-
|
|
106060
|
+
xlsx__WEBPACK_IMPORTED_MODULE_56__.utils.book_append_sheet(wb, ws, "Products");
|
|
105759
106061
|
// Generate buffer
|
|
105760
|
-
const wbout =
|
|
106062
|
+
const wbout = xlsx__WEBPACK_IMPORTED_MODULE_56__.write(wb, { bookType: 'xlsx', type: 'array' });
|
|
105761
106063
|
// Upload to Drive (имя файла по бренду)
|
|
105762
106064
|
const dateStr = new Date().toISOString().split('T')[0];
|
|
105763
106065
|
const fileName = `${brand}-${dateStr}.xlsx`;
|
|
@@ -105879,13 +106181,13 @@ ${imageData.originalPrompt}
|
|
|
105879
106181
|
setTestLoading(true);
|
|
105880
106182
|
try {
|
|
105881
106183
|
// Create simple test workbook with structure
|
|
105882
|
-
const wb =
|
|
106184
|
+
const wb = xlsx__WEBPACK_IMPORTED_MODULE_56__.utils.book_new();
|
|
105883
106185
|
const rows = [
|
|
105884
106186
|
INSTRUCTION_ROW,
|
|
105885
106187
|
['id', 'title', 'description', 'availability', 'condition', 'price', 'link', 'image_link', 'brand'],
|
|
105886
106188
|
['test1', 'Test Title', 'Test Description', 'in stock', 'new', '10.00 USD', 'http://test.com', 'http://test.com/img.jpg', 'TestBrand']
|
|
105887
106189
|
];
|
|
105888
|
-
const ws =
|
|
106190
|
+
const ws = xlsx__WEBPACK_IMPORTED_MODULE_56__.utils.aoa_to_sheet(rows);
|
|
105889
106191
|
// Set column widths
|
|
105890
106192
|
ws['!cols'] = [
|
|
105891
106193
|
{ wch: 20 }, // id
|
|
@@ -105898,8 +106200,8 @@ ${imageData.originalPrompt}
|
|
|
105898
106200
|
{ wch: 40 }, // image_link
|
|
105899
106201
|
{ wch: 20 } // brand
|
|
105900
106202
|
];
|
|
105901
|
-
|
|
105902
|
-
const wbout =
|
|
106203
|
+
xlsx__WEBPACK_IMPORTED_MODULE_56__.utils.book_append_sheet(wb, ws, "Test");
|
|
106204
|
+
const wbout = xlsx__WEBPACK_IMPORTED_MODULE_56__.write(wb, { bookType: 'xlsx', type: 'array' });
|
|
105903
106205
|
// Try to extract folder ID if available, otherwise upload to root
|
|
105904
106206
|
const folderId = driveFolderUrl ? extractFolderId(driveFolderUrl) : undefined;
|
|
105905
106207
|
const result = await uploadFileToDrive(wbout, 'test_table.xlsx', folderId || undefined);
|
|
@@ -105951,7 +106253,7 @@ ${imageData.originalPrompt}
|
|
|
105951
106253
|
};
|
|
105952
106254
|
// Show lock screen if not unlocked
|
|
105953
106255
|
if (!unlocked) {
|
|
105954
|
-
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106256
|
+
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_37__["default"], { theme: theme },
|
|
105955
106257
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_4__["default"], null),
|
|
105956
106258
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { onClick: handleSecretClick, sx: {
|
|
105957
106259
|
width: '100vw',
|
|
@@ -105991,35 +106293,49 @@ ${imageData.originalPrompt}
|
|
|
105991
106293
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("br", null),
|
|
105992
106294
|
"Please contact system administrator"))));
|
|
105993
106295
|
}
|
|
105994
|
-
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106296
|
+
return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_37__["default"], { theme: theme },
|
|
105995
106297
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_4__["default"], null),
|
|
105996
106298
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_7__["default"], { maxWidth: "lg", sx: { py: 4 } },
|
|
105997
106299
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 } },
|
|
105998
106300
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "h4", component: "h1", sx: { fontWeight: 'bold', color: 'primary.main' } }, "Docs Combiner"),
|
|
105999
106301
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
|
|
106000
106302
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { onClick: () => setPromptManagerOpen(true), color: "inherit", "aria-label": "manage prompts", sx: { mr: 1 } },
|
|
106001
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106002
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { onClick: toggleTheme, color: "inherit", "aria-label": "toggle theme" }, darkMode ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106303
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_52__["default"], null)),
|
|
106304
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { onClick: toggleTheme, color: "inherit", "aria-label": "toggle theme" }, darkMode ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_42__["default"], null) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_41__["default"], null)))),
|
|
106003
106305
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_9__["default"], { variant: "outlined", sx: { mb: 4 } },
|
|
106004
106306
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_10__["default"], null,
|
|
106005
106307
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 3 },
|
|
106006
106308
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
|
|
106007
106309
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "h6", gutterBottom: true }, "Google Drive Authentication"),
|
|
106008
|
-
|
|
106009
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106310
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { mb: 2 } },
|
|
106311
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "subtitle2", color: "text.secondary", gutterBottom: true }, "\u041A\u043E\u0440\u043D\u0435\u0432\u0430\u044F \u043F\u0430\u043F\u043A\u0430 \u043F\u0440\u043E\u0435\u043A\u0442\u0430"),
|
|
106312
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary", display: "block", sx: { mb: 1 } }, "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u043A\u043E\u0440\u043D\u0435\u0432\u0443\u044E \u043F\u0430\u043F\u043A\u0443 \u043D\u0430 Google \u0414\u0438\u0441\u043A\u0435 (\u0432\u043D\u0443\u0442\u0440\u0438 \u043D\u0435\u0451 \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u043F\u0430\u043F\u043A\u0430 OFFERS)."),
|
|
106313
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "URL \u043A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u043F\u0430\u043F\u043A\u0438 Google Drive", variant: "outlined", fullWidth: true, value: rootDriveFolderUrl, onChange: (e) => setRootDriveFolderUrl(e.target.value), placeholder: "https://drive.google.com/drive/folders/...", sx: { mb: 1 } }),
|
|
106314
|
+
checkingRootFolder && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null,
|
|
106315
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { component: "span", sx: { display: 'inline-flex', alignItems: 'center', gap: 1 } },
|
|
106316
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 14 }),
|
|
106317
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u043F\u0430\u043F\u043A\u0438 (OFFERS, \u0434\u043E\u0441\u0442\u0443\u043F)...")))),
|
|
106318
|
+
drivePublicAccessWarning && extractFolderId(rootDriveFolderUrl) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "warning", sx: { mt: 1 } }, "\u041E\u0431\u0449\u0438\u0439 \u0434\u043E\u0441\u0442\u0443\u043F \u043F\u043E \u0441\u0441\u044B\u043B\u043A\u0435 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0432\u043A\u043B\u044E\u0447\u0451\u043D. \u0417\u0430\u043A\u0440\u043E\u0439\u0442\u0435 \u0435\u0433\u043E \u0432\u0440\u0443\u0447\u043D\u0443\u044E \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u0434\u043E\u0441\u0442\u0443\u043F\u0430 Google \u0414\u0438\u0441\u043A\u0430 \u0438\u043B\u0438 \u0441\u043C\u0435\u043D\u0438\u0442\u0435 \u043F\u0430\u043F\u043A\u0443 \u0438 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0442\u0435\u0441\u044C \u0443\u0431\u0440\u0430\u0442\u044C \u0434\u043E\u0441\u0442\u0443\u043F \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438.")),
|
|
106319
|
+
!checkingRootFolder && rootFolderInfo && !rootFolderInfo.hasOffersFolder && extractFolderId(rootDriveFolderUrl) && (accessToken || refreshToken) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "error", sx: { mt: 1 } }, "\u0412 \u043A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u043F\u0430\u043F\u043A\u0435 \u043D\u0435\u0442 \u043F\u043E\u0434\u043F\u0430\u043F\u043A\u0438 OFFERS. \u0421\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u043F\u0430\u043F\u043A\u0443 \u0441 \u0438\u043C\u0435\u043D\u0435\u043C OFFERS (\u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u043D\u0435 \u0432\u0430\u0436\u0435\u043D) \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443.")),
|
|
106320
|
+
!checkingRootFolder && !rootFolderInfo && rootDriveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null, (accessToken || refreshToken)
|
|
106321
|
+
? 'Введите корректную ссылку на корневую папку Google Drive'
|
|
106322
|
+
: 'Войдите в Google, чтобы проверить корневую папку и подпапку OFFERS'))),
|
|
106323
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], { sx: { my: 2 } }),
|
|
106324
|
+
accessToken ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], null,
|
|
106325
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_18__["default"], { expandIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_47__["default"], null) },
|
|
106010
106326
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { sx: { display: 'flex', alignItems: 'center', color: 'success.main' } },
|
|
106011
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106327
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_43__["default"], { sx: { mr: 1 } }),
|
|
106012
106328
|
" Logged In (Credentials Hidden)")),
|
|
106013
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106329
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_19__["default"], null,
|
|
106014
106330
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 2 },
|
|
106015
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106016
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106331
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "Client ID", variant: "outlined", fullWidth: true, value: clientId, onChange: (e) => handleClientIdChange(e.target.value), helperText: "From Google Cloud Console (OAuth 2.0 Client ID)" }),
|
|
106332
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "Client Secret", variant: "outlined", fullWidth: true, value: clientSecret, onChange: (e) => handleClientSecretChange(e.target.value) }),
|
|
106017
106333
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], null),
|
|
106018
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106019
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106020
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106334
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "OpenRouter API Key", variant: "outlined", fullWidth: true, value: openaiApiKey, onChange: (e) => handleOpenaiApiKeyChange(e.target.value), helperText: "Required for AI generation (images and text). Your key is stored locally. Get your key at openrouter.ai" }))))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 2 },
|
|
106335
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "Client ID", variant: "outlined", fullWidth: true, value: clientId, onChange: (e) => handleClientIdChange(e.target.value), helperText: "From Google Cloud Console (OAuth 2.0 Client ID)" }),
|
|
106336
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "Client Secret", variant: "outlined", fullWidth: true, value: clientSecret, onChange: (e) => handleClientSecretChange(e.target.value) }))),
|
|
106021
106337
|
openaiApiKey && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 2, mt: 2 } },
|
|
106022
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106338
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_38__["default"], { color: openRouterAccountBalance !== null ? 'primary' : 'disabled' }),
|
|
106023
106339
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", color: openRouterAccountBalance !== null ? 'text.primary' : 'text.secondary' },
|
|
106024
106340
|
"\u0411\u0430\u043B\u0430\u043D\u0441: ",
|
|
106025
106341
|
openRouterBalanceLoading ? 'Loading...' : (openRouterAccountBalance !== null ? `$${openRouterAccountBalance.toFixed(2)}` : 'N/A')),
|
|
@@ -106028,28 +106344,30 @@ ${imageData.originalPrompt}
|
|
|
106028
106344
|
"\u041B\u0438\u043C\u0438\u0442 \u043A\u043B\u044E\u0447\u0430: ",
|
|
106029
106345
|
openRouterBalanceLoading ? 'Loading...' : (openRouterBalance === -1 ? 'Без лимита' : (openRouterBalance !== null ? `${openRouterBalance.toFixed(4)}` : 'N/A'))))),
|
|
106030
106346
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, alignItems: "center", sx: { mt: 2 } },
|
|
106031
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106032
|
-
accessToken && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106347
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: accessToken ? "success" : "primary", onClick: handleLogin, disabled: authLoading || !clientId || !clientSecret, startIcon: authLoading ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20, color: "inherit" }) : (accessToken ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_43__["default"], null) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_48__["default"], null)), sx: { flexGrow: 1 } }, authLoading ? 'Logging in...' : (accessToken ? 'Logged In' : 'Login with Google')),
|
|
106348
|
+
accessToken && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "outlined", color: "error", onClick: handleLogout, startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_49__["default"], null) }, "Logout")))),
|
|
106033
106349
|
!accessToken && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106034
106350
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], null),
|
|
106035
106351
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
|
|
106036
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106352
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "OpenRouter API Key", variant: "outlined", fullWidth: true, value: openaiApiKey, onChange: (e) => handleOpenaiApiKeyChange(e.target.value), helperText: "Required for AI generation (images and text). Your key is stored locally. Get your key at openrouter.ai", sx: { mb: 2 } })))),
|
|
106037
106353
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], { sx: { my: 2 } }),
|
|
106038
106354
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
|
|
106039
106355
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "h6", gutterBottom: true }, "Google Drive Folder"),
|
|
106040
106356
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2 },
|
|
106041
106357
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { flexGrow: 1 } },
|
|
106042
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106043
|
-
checkingFolderFiles && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106358
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "Google Drive Folder URL", variant: "outlined", fullWidth: true, value: driveFolderUrl, onChange: (e) => setDriveFolderUrl(e.target.value), placeholder: "https://drive.google.com/drive/folders/..." }),
|
|
106359
|
+
checkingFolderFiles && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null,
|
|
106044
106360
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { component: "span", sx: { display: 'inline-flex', alignItems: 'center', gap: 1 } },
|
|
106045
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106046
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0444\u0430\u0439\u043B\u043E\u0432...")))),
|
|
106047
|
-
!checkingFolderFiles && folderFilesInfo && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106361
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 14 }),
|
|
106362
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0444\u0430\u0439\u043B\u043E\u0432 \u0432 \u043F\u0430\u043F\u043A\u0435...")))),
|
|
106363
|
+
!checkingFolderFiles && folderFilesInfo && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null,
|
|
106048
106364
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { component: "span", sx: { display: 'block' } }, folderFilesInfo.hasProduct ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { component: "span", sx: { color: 'success.main' } }, "\u2713 product.png/jpg/webp \u043D\u0430\u0439\u0434\u0435\u043D")) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { component: "span", sx: { color: 'info.main' } }, "\u2139 product.png/jpg/webp \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0447\u0435\u0440\u0435\u0437 \u043A\u043D\u043E\u043F\u043A\u0443 \u043D\u0438\u0436\u0435"))))),
|
|
106049
|
-
!checkingFolderFiles && !folderFilesInfo && driveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106050
|
-
|
|
106365
|
+
!checkingFolderFiles && !folderFilesInfo && driveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null, (accessToken || refreshToken)
|
|
106366
|
+
? 'Введите корректную ссылку на папку Google Drive'
|
|
106367
|
+
: 'Войдите в Google, чтобы проверить файлы в папке'))))),
|
|
106368
|
+
!driveFolderUrl.trim() ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "info", sx: { mt: 2 } },
|
|
106051
106369
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body1", sx: { fontWeight: 'bold', mb: 1 } }, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0430\u043F\u043A\u0443 Google Drive \u0434\u043B\u044F \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u044F"),
|
|
106052
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2" }, "\u0414\u043B\u044F \u0440\u0430\u0431\u043E\u0442\u044B \u0441 \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043A\u043E\u043D\u0442\u0435\u043D\u0442\u0430 \u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0443\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443 Google Drive.
|
|
106370
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2" }, "\u0414\u043B\u044F \u0440\u0430\u0431\u043E\u0442\u044B \u0441 \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043A\u043E\u043D\u0442\u0435\u043D\u0442\u0430 \u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0443\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443 Google Drive."))) : !extractFolderId(driveFolderUrl) ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "warning", sx: { mt: 2 } },
|
|
106053
106371
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body1", sx: { fontWeight: 'bold', mb: 1 } }, "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u0443\u044E \u0441\u0441\u044B\u043B\u043A\u0443 \u043D\u0430 \u043F\u0430\u043F\u043A\u0443"),
|
|
106054
106372
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2" }, "\u0421\u0441\u044B\u043B\u043A\u0430 \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0435: https://drive.google.com/drive/folders/..."))) : loadingContentFromDrive ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: {
|
|
106055
106373
|
display: 'flex',
|
|
@@ -106065,35 +106383,35 @@ ${imageData.originalPrompt}
|
|
|
106065
106383
|
? 'rgba(25, 118, 210, 0.1)'
|
|
106066
106384
|
: 'rgba(25, 118, 210, 0.05)'
|
|
106067
106385
|
} },
|
|
106068
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106386
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 40, sx: { color: 'primary.main' } }),
|
|
106069
106387
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body1", sx: { color: 'text.secondary', fontWeight: 'bold' } }, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0434\u0430\u043D\u043D\u044B\u0445 \u0438\u0437 \u043F\u0430\u043F\u043A\u0438..."))) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106070
106388
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2 },
|
|
106071
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106389
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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" }),
|
|
106072
106390
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { flex: 1, minWidth: 0 } },
|
|
106073
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106391
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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
106392
|
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(
|
|
106393
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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
106394
|
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(
|
|
106078
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106395
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { size: "small", variant: "outlined", onClick: () => setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_EXTRA_MACROS), sx: { textTransform: 'none', whiteSpace: 'nowrap' } }, "redtrack"),
|
|
106396
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { size: "small", variant: "outlined", onClick: () => setCatalogLinkExtraMacros(DEFAULT_CATALOG_LINK_KEITARO_MACROS), sx: { textTransform: 'none', whiteSpace: 'nowrap' } }, "keitaro"))),
|
|
106079
106397
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 1.5, sx: { mt: 1 } },
|
|
106080
106398
|
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
106399
|
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
106400
|
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
106401
|
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(
|
|
106402
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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
106403
|
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
106404
|
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
106405
|
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
106406
|
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(
|
|
106407
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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}` }))),
|
|
106090
106408
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], { sx: { my: 2 } }),
|
|
106091
106409
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "h6", gutterBottom: true }, "AI Generation Settings"),
|
|
106092
106410
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
|
|
106093
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106411
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: "\u0422\u043E\u0432\u0430\u0440", variant: "outlined", fullWidth: true, value: generateProduct, onChange: (e) => setGenerateProduct(e.target.value), placeholder: "\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: \u043A\u0430\u043F\u043B\u0438 \u043E\u0442 \u043F\u0430\u0440\u0430\u0437\u0438\u0442\u043E\u0432 Detoxil Water", sx: { mb: 2 } })),
|
|
106094
106412
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
|
|
106095
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106096
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106413
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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" }),
|
|
106414
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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: {
|
|
106097
106415
|
endAdornment: (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_23__["default"], { position: "end" },
|
|
106098
106416
|
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 } },
|
|
106099
106417
|
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)" },
|
|
@@ -106101,7 +106419,7 @@ ${imageData.originalPrompt}
|
|
|
106101
106419
|
const n = extractLeadingPriceNumber(generatePriceWithCurrency);
|
|
106102
106420
|
setGeneratePriceWithCurrency(`$${n}`);
|
|
106103
106421
|
}, edge: "end" },
|
|
106104
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106422
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_39__["default"], { sx: { fontSize: 20 } }))),
|
|
106105
106423
|
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)" },
|
|
106106
106424
|
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: () => {
|
|
106107
106425
|
const n = extractLeadingPriceNumber(generatePriceWithCurrency);
|
|
@@ -106114,29 +106432,29 @@ ${imageData.originalPrompt}
|
|
|
106114
106432
|
}, edge: "end", sx: { minWidth: 36, fontSize: '0.8rem', fontWeight: 700, letterSpacing: -0.3 } }, "z\u0142"))))),
|
|
106115
106433
|
} })),
|
|
106116
106434
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], null,
|
|
106117
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106435
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["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 } })),
|
|
106118
106436
|
openaiApiKey && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
|
|
106119
106437
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_25__["default"], { fullWidth: true, variant: "outlined" },
|
|
106120
106438
|
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
106439
|
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 },
|
|
106122
106440
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
|
|
106123
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106441
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16 }),
|
|
106124
106442
|
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))))),
|
|
106125
|
-
!loadingImageModels && imageModels.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106443
|
+
!loadingImageModels && imageModels.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null, selectedImageModel === _models__WEBPACK_IMPORTED_MODULE_2__.MODELS.imageGeneration
|
|
106126
106444
|
? 'Используется модель по умолчанию'
|
|
106127
106445
|
: 'Выбрана модель: ' + (imageModels.find(m => m.id === selectedImageModel)?.name || selectedImageModel)))),
|
|
106128
106446
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_25__["default"], { fullWidth: true, variant: "outlined" },
|
|
106129
106447
|
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
106448
|
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 },
|
|
106131
106449
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
|
|
106132
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106450
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16 }),
|
|
106133
106451
|
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))))),
|
|
106134
|
-
!loadingValidationModels && validationModels.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106452
|
+
!loadingValidationModels && validationModels.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_13__["default"], null, selectedValidationModel === _models__WEBPACK_IMPORTED_MODULE_2__.MODELS.creativeValidation
|
|
106135
106453
|
? 'Используется модель по умолчанию'
|
|
106136
106454
|
: 'Выбрана модель: ' + (validationModels.find(m => m.id === selectedValidationModel)?.name || selectedValidationModel))),
|
|
106137
106455
|
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 } })))),
|
|
106138
106456
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
|
|
106139
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106457
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "primary", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_40__["default"], null), onClick: handleGenerateContent, disabled: generating || loadingContentFromDrive || !openaiApiKey || !generateProduct.trim() || !generateGeo.trim(), sx: { flexGrow: 1 }, size: "large" }, generating ? 'Generating...' : 'Generate Titles & Descriptions'),
|
|
106140
106458
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 1, alignItems: "center", sx: { flexGrow: 1 } },
|
|
106141
106459
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_24__["default"], { title: imageAspectRatio === '1:1'
|
|
106142
106460
|
? '1:1 — квадрат (1024×1024 px)'
|
|
@@ -106163,7 +106481,7 @@ ${imageData.originalPrompt}
|
|
|
106163
106481
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_30__["default"], { value: "1:1", sx: { px: 1.5, fontWeight: 600, fontSize: '0.8rem' } }, "1:1"),
|
|
106164
106482
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_30__["default"], { value: "2:3", sx: { px: 1.5, fontWeight: 600, fontSize: '0.8rem' } }, "2:3"),
|
|
106165
106483
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_30__["default"], { value: "both", sx: { px: 1.5, fontWeight: 600, fontSize: '0.8rem' } }, "\u041E\u0431\u0430")))),
|
|
106166
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106484
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "secondary", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_40__["default"], null), onClick: handleGenerateImages, disabled: generatingImages ||
|
|
106167
106485
|
!openaiApiKey ||
|
|
106168
106486
|
(!accessToken && !refreshToken) ||
|
|
106169
106487
|
!generateProduct.trim() ||
|
|
@@ -106181,9 +106499,9 @@ ${imageData.originalPrompt}
|
|
|
106181
106499
|
: !driveFolderUrl.trim()
|
|
106182
106500
|
? 'Заполните URL папки Google Drive'
|
|
106183
106501
|
: undefined }, generatingImages ? 'Generating Images...' : 'Generate Images')),
|
|
106184
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106185
|
-
uploadedLink && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106186
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106502
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "success", size: "large", onClick: handleGenerate, disabled: loading, startIcon: loading ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20, color: "inherit" }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_44__["default"], null), sx: { py: 1.5, fontSize: '1.1rem', flexGrow: 1 } }, loading ? 'Generating...' : 'Generate Catalog'),
|
|
106503
|
+
uploadedLink && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "success", sx: { flexGrow: 1, minWidth: 0 }, action: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { "aria-label": "copy link", color: "inherit", size: "small", onClick: handleCopyLink, sx: { ml: 1 } },
|
|
106504
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_45__["default"], { fontSize: "small" })) },
|
|
106187
106505
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' } },
|
|
106188
106506
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null,
|
|
106189
106507
|
"\u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D!",
|
|
@@ -106193,17 +106511,17 @@ ${imageData.originalPrompt}
|
|
|
106193
106511
|
getElectronAPI().openExternal(uploadedLink);
|
|
106194
106512
|
}, style: { cursor: 'pointer', textDecoration: 'underline', color: 'inherit' } }, "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432 Google Drive")),
|
|
106195
106513
|
linkCopied && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'success.dark', fontWeight: 'bold' } }, "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D\u043E!"))))),
|
|
106196
|
-
folderFilesInfo !== null && !folderFilesInfo.hasProduct && driveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106514
|
+
folderFilesInfo !== null && !folderFilesInfo.hasProduct && driveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "warning", sx: { mt: 1 } }, "\u0414\u043B\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0439 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F product.png/jpg/webp. \u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043E \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E \u043A\u043D\u043E\u043F\u043A\u0438 \"Generate Product from Banka\".")),
|
|
106197
106515
|
!generatingImages && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106198
|
-
!openaiApiKey && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106199
|
-
openaiApiKey && (!accessToken && !refreshToken) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106200
|
-
openaiApiKey && (accessToken || refreshToken) && !generateProduct.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106201
|
-
openaiApiKey && (accessToken || refreshToken) && generateProduct.trim() && !generateGeo.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106202
|
-
openaiApiKey && (accessToken || refreshToken) && generateProduct.trim() && generateGeo.trim() && !driveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106516
|
+
!openaiApiKey && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "error", sx: { mt: 1 } }, "\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 OpenRouter API Key")),
|
|
106517
|
+
openaiApiKey && (!accessToken && !refreshToken) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "error", sx: { mt: 1 } }, "\u0412\u043E\u0439\u0434\u0438\u0442\u0435 \u0432 Google Drive")),
|
|
106518
|
+
openaiApiKey && (accessToken || refreshToken) && !generateProduct.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "error", sx: { mt: 1 } }, "\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u043F\u043E\u043B\u0435 \u0422\u043E\u0432\u0430\u0440")),
|
|
106519
|
+
openaiApiKey && (accessToken || refreshToken) && generateProduct.trim() && !generateGeo.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "error", sx: { mt: 1 } }, "\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u043F\u043E\u043B\u0435 \u0413\u0435\u043E")),
|
|
106520
|
+
openaiApiKey && (accessToken || refreshToken) && generateProduct.trim() && generateGeo.trim() && !driveFolderUrl.trim() && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_15__["default"], { severity: "error", sx: { mt: 1 } }, "\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 URL \u043F\u0430\u043F\u043A\u0438 Google Drive"))))),
|
|
106203
106521
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { type: "file", ref: productFileInputRef, accept: "image/png,image/jpeg,image/jpg,image/webp", style: { display: 'none' }, onChange: handleProductFileSelected }),
|
|
106204
106522
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 2, sx: { mb: 2 } },
|
|
106205
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106206
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106523
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "success", startIcon: uploadingProduct ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20, color: "inherit" }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_44__["default"], null), onClick: handleUploadProductFile, disabled: uploadingProduct || !accessToken || !driveFolderUrl.trim(), sx: { flexGrow: 1 }, size: "large" }, uploadingProduct ? 'Загрузка...' : 'Загрузить product.png/jpg/webp'),
|
|
106524
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "info", startIcon: generatingLanding ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20, color: "inherit" }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_50__["default"], null), onClick: handleCreateLanding, disabled: generatingLanding ||
|
|
106207
106525
|
!openaiApiKey ||
|
|
106208
106526
|
!accessToken ||
|
|
106209
106527
|
!driveFolderUrl.trim() ||
|
|
@@ -106218,10 +106536,10 @@ ${imageData.originalPrompt}
|
|
|
106218
106536
|
generatedImagesData.length,
|
|
106219
106537
|
")"),
|
|
106220
106538
|
checkingImages && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 2 } },
|
|
106221
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106539
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16 }),
|
|
106222
106540
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'text.secondary' } }, "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043A\u0430\u0447\u0435\u0441\u0442\u0432\u0430..."))),
|
|
106223
106541
|
generatedImagesData.length > 0 && generatedImagesData.some(img => !img.uploaded && img.imageUrl) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { mb: 2 } },
|
|
106224
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106542
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "primary", onClick: handleUploadAllImages, disabled: uploadingImages || generatingImages || !driveFolderUrl.trim(), startIcon: uploadingImages ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20 }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_44__["default"], null), fullWidth: true }, uploadingImages ? 'Загрузка...' : `Загрузить все (${generatedImagesData.filter(img => !img.uploaded && img.imageUrl).length})`))),
|
|
106225
106543
|
generatedImagesData.length > 0 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: {
|
|
106226
106544
|
display: 'grid',
|
|
106227
106545
|
gridTemplateColumns: { xs: '1fr', sm: 'repeat(2, 1fr)', md: 'repeat(3, 1fr)' },
|
|
@@ -106270,7 +106588,7 @@ ${imageData.originalPrompt}
|
|
|
106270
106588
|
imageData.generating ||
|
|
106271
106589
|
!!imageData.regenerating ||
|
|
106272
106590
|
!!imageData.uploading },
|
|
106273
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106591
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_46__["default"], { fontSize: "small" })))),
|
|
106274
106592
|
imageData.generating ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: {
|
|
106275
106593
|
width: '100%',
|
|
106276
106594
|
aspectRatio: aspectRatioCss,
|
|
@@ -106286,7 +106604,7 @@ ${imageData.originalPrompt}
|
|
|
106286
106604
|
gap: 2,
|
|
106287
106605
|
p: 3
|
|
106288
106606
|
} },
|
|
106289
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106607
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 40, sx: { color: 'primary.main' } }),
|
|
106290
106608
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", sx: { color: 'text.secondary', textAlign: 'center', fontWeight: 'bold' } }, "\u0413\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F..."),
|
|
106291
106609
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'text.secondary', textAlign: 'center' } }, imageData.approach),
|
|
106292
106610
|
generatingImages && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'text.secondary', textAlign: 'center' } },
|
|
@@ -106306,7 +106624,7 @@ ${imageData.originalPrompt}
|
|
|
106306
106624
|
gap: 2,
|
|
106307
106625
|
p: 3
|
|
106308
106626
|
} },
|
|
106309
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106627
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 40, sx: { color: 'primary.main' } }),
|
|
106310
106628
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", sx: { color: 'text.secondary', textAlign: 'center', fontWeight: 'bold' } }, "\u041F\u0435\u0440\u0435\u0434\u0435\u043B\u043A\u0430..."),
|
|
106311
106629
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'text.secondary', textAlign: 'center' } }, imageData.approach))) : imageData.imageUrl ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106312
106630
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { component: "img", src: imageData.imageUrl, alt: `Generated Image ${imageData.index}`, sx: {
|
|
@@ -106341,7 +106659,7 @@ ${imageData.originalPrompt}
|
|
|
106341
106659
|
alignItems: 'center',
|
|
106342
106660
|
gap: 1
|
|
106343
106661
|
} },
|
|
106344
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106662
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 40, sx: { color: 'primary.main' } }),
|
|
106345
106663
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'white', fontWeight: 'bold', textShadow: '1px 1px 2px rgba(0,0,0,0.8)' } }, "\u041F\u0435\u0440\u0435\u0434\u0435\u043B\u043A\u0430..."))))) : imageData.failed ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: {
|
|
106346
106664
|
width: '100%',
|
|
106347
106665
|
aspectRatio: aspectRatioCss,
|
|
@@ -106402,14 +106720,13 @@ ${imageData.originalPrompt}
|
|
|
106402
106720
|
imageData.checkErrors.length > 2 && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'text.secondary', fontSize: '0.7rem' } },
|
|
106403
106721
|
"+",
|
|
106404
106722
|
imageData.checkErrors.length - 2,
|
|
106405
|
-
" \u0435\u0449\u0451")))),
|
|
106406
|
-
imageData.checkFailed && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], { size: "small", variant: "outlined", color: "warning", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_48__["default"], null), onClick: () => handleRetryCheck(imageData), disabled: imageData.checking, sx: { mt: 0.5, fontSize: '0.7rem', py: 0.25, px: 1 } }, "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443")))),
|
|
106723
|
+
" \u0435\u0449\u0451")))))),
|
|
106407
106724
|
imageData.checkStatus === 'checking' && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'warning.main', display: 'block' } }, "\uD83D\uDD0D \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442\u0441\u044F...")),
|
|
106408
106725
|
imageData.checkStatus === 'pending' && !imageData.failed && !imageData.generating && imageData.imageUrl && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'text.secondary', display: 'block' } }, "\u23F3 \u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438")),
|
|
106409
106726
|
imageData.failed && !imageData.generating && !imageData.imageUrl && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'error.main', display: 'block', fontWeight: 'bold' } }, "\u274C \u0413\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u043D\u0435 \u0443\u0434\u0430\u043B\u0430\u0441\u044C")),
|
|
106410
106727
|
imageData.uploaded && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { color: 'success.main', display: 'block', mt: 0.5 } }, "\u2713 \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E"))),
|
|
106411
106728
|
!imageData.generating && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', gap: 1, flexDirection: 'column', mt: 1 } },
|
|
106412
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106729
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { size: "small", multiline: true, minRows: 2, maxRows: 4, fullWidth: true, placeholder: "\u0423\u0442\u043E\u0447\u043D\u0435\u043D\u0438\u044F \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u0434\u0435\u043B\u043A\u0438 (\u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043E \u043F\u0440\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430\u0445)", value: imageData.customRegeneratePrompt || '', onChange: (e) => {
|
|
106413
106730
|
setGeneratedImagesData(prev => prev.map(img => img.index === imageData.index
|
|
106414
106731
|
? { ...img, customRegeneratePrompt: e.target.value }
|
|
106415
106732
|
: img));
|
|
@@ -106426,22 +106743,27 @@ ${imageData.originalPrompt}
|
|
|
106426
106743
|
: 'transparent'
|
|
106427
106744
|
}
|
|
106428
106745
|
} }),
|
|
106429
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106746
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: "row", spacing: 1, sx: { width: '100%', alignItems: 'stretch' } },
|
|
106747
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { size: "small", variant: "contained", color: imageData.failed ? 'error' : imageData.checkStatus === 'needs_rebuild' ? 'warning' : 'primary', startIcon: imageData.regenerating ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16 }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_40__["default"], null), onClick: () => handleRegenerateImage(imageData), disabled: imageData.regenerating ||
|
|
106748
|
+
imageData.uploading ||
|
|
106749
|
+
imageData.checkStatus === 'checking' ||
|
|
106750
|
+
!imageData.originalPrompt ||
|
|
106751
|
+
!imageData.productImageUrl ||
|
|
106752
|
+
(generatingImages && !imageData.imageUrl && !imageData.failed && !imageData.generating), sx: { flex: 1, minWidth: 0, py: 1, lineHeight: 1.2, whiteSpace: 'normal' } }, imageData.regenerating
|
|
106753
|
+
? (imageData.failed ? 'Генерация...' : 'Переделка...')
|
|
106754
|
+
: ((generatingImages && !imageData.imageUrl && !imageData.failed && !imageData.generating)
|
|
106755
|
+
? 'В очереди'
|
|
106756
|
+
: (!imageData.imageUrl ? 'Сгенерировать' : 'Переделать'))),
|
|
106757
|
+
imageData.imageUrl ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { size: "small", variant: "outlined", color: "secondary", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_51__["default"], null), onClick: () => handleRegenerateImageFresh(imageData), disabled: imageData.regenerating ||
|
|
106758
|
+
imageData.uploading ||
|
|
106759
|
+
imageData.checkStatus === 'checking' ||
|
|
106760
|
+
!imageData.originalPrompt ||
|
|
106761
|
+
!imageData.productImageUrl, sx: { flex: 1, minWidth: 0, py: 1, lineHeight: 1.2, whiteSpace: 'normal' } }, "\u041F\u0435\u0440\u0435\u0434\u0435\u043B\u0430\u0442\u044C \u0437\u0430\u043D\u043E\u0432\u043E")) : null),
|
|
106762
|
+
imageData.imageUrl && !validationDisabled && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { size: "small", variant: "outlined", color: "warning", startIcon: imageData.checkStatus === 'checking' ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16, color: "inherit" })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_51__["default"], null)), onClick: () => handleRetryCheck(imageData), disabled: imageData.regenerating ||
|
|
106430
106763
|
imageData.uploading ||
|
|
106431
|
-
imageData.
|
|
106432
|
-
|
|
106433
|
-
|
|
106434
|
-
(generatingImages && !imageData.imageUrl && !imageData.failed && !imageData.generating), fullWidth: true }, imageData.regenerating
|
|
106435
|
-
? (imageData.failed ? 'Генерация...' : 'Переделка...')
|
|
106436
|
-
: ((generatingImages && !imageData.imageUrl && !imageData.failed && !imageData.generating)
|
|
106437
|
-
? 'В очереди'
|
|
106438
|
-
: (!imageData.imageUrl ? 'Сгенерировать' : 'Переделать'))),
|
|
106439
|
-
imageData.imageUrl && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], { size: "small", variant: "outlined", color: "secondary", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_48__["default"], null), onClick: () => handleRegenerateImageFresh(imageData), disabled: imageData.regenerating ||
|
|
106440
|
-
imageData.uploading ||
|
|
106441
|
-
imageData.checkStatus === 'checking' ||
|
|
106442
|
-
!imageData.originalPrompt ||
|
|
106443
|
-
!imageData.productImageUrl, fullWidth: true }, "\u041F\u0435\u0440\u0435\u0434\u0435\u043B\u0430\u0442\u044C \u0437\u0430\u043D\u043E\u0432\u043E")),
|
|
106444
|
-
!imageData.uploaded && imageData.imageUrl && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_17__["default"], { size: "small", variant: "outlined", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_40__["default"], null), onClick: () => {
|
|
106764
|
+
imageData.generating ||
|
|
106765
|
+
imageData.checkStatus === 'checking', fullWidth: true }, imageData.checkStatus === 'checking' ? 'Проверка…' : 'Перепроверить')),
|
|
106766
|
+
!imageData.uploaded && imageData.imageUrl && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { size: "small", variant: "outlined", startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_44__["default"], null), onClick: () => {
|
|
106445
106767
|
const folderId = extractFolderId(driveFolderUrl);
|
|
106446
106768
|
if (folderId) {
|
|
106447
106769
|
handleUploadImage(imageData, folderId);
|
|
@@ -106449,7 +106771,7 @@ ${imageData.originalPrompt}
|
|
|
106449
106771
|
}, disabled: imageData.uploading || imageData.regenerating || !driveFolderUrl.trim(), fullWidth: true }, imageData.uploading ? 'Загрузка...' : 'Загрузить'))))));
|
|
106450
106772
|
}))),
|
|
106451
106773
|
generatedImagesData.length > 0 && generatedImagesData.some(img => !img.uploaded && img.imageUrl) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { mt: 2 } },
|
|
106452
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106774
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", color: "primary", onClick: handleUploadAllImages, disabled: uploadingImages || generatingImages || !driveFolderUrl.trim(), startIcon: uploadingImages ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20 }) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_44__["default"], null), fullWidth: true }, uploadingImages ? 'Загрузка...' : `Загрузить все (${generatedImagesData.filter(img => !img.uploaded && img.imageUrl).length})`))))),
|
|
106453
106775
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_16__["default"], { sx: { my: 2 } }),
|
|
106454
106776
|
(generatedTitlesData.length > 0 || generatedTextsData.length > 0 || loadingContentFromDrive) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { mb: 2 } },
|
|
106455
106777
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 1, mb: 1 } },
|
|
@@ -106466,7 +106788,7 @@ ${imageData.originalPrompt}
|
|
|
106466
106788
|
color: 'text.secondary',
|
|
106467
106789
|
'&:hover': { opacity: 0.75, color: 'text.primary' },
|
|
106468
106790
|
} },
|
|
106469
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106791
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_45__["default"], { sx: { fontSize: 16 } }))))),
|
|
106470
106792
|
loadingContentFromDrive && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: {
|
|
106471
106793
|
display: 'flex',
|
|
106472
106794
|
flexDirection: 'column',
|
|
@@ -106481,7 +106803,7 @@ ${imageData.originalPrompt}
|
|
|
106481
106803
|
: 'rgba(25, 118, 210, 0.05)',
|
|
106482
106804
|
mb: 2
|
|
106483
106805
|
} },
|
|
106484
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106806
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 40, sx: { color: 'primary.main' } }),
|
|
106485
106807
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body1", sx: { color: 'text.secondary', fontWeight: 'bold' } }, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u043D\u0442\u0430 \u0438\u0437 Google Drive..."))),
|
|
106486
106808
|
(generatedTitlesData.length > 0 || generatedTextsData.length > 0) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 2 }, Array.from({
|
|
106487
106809
|
length: Math.max(generatedTitlesData.length, generatedTextsData.length)
|
|
@@ -106525,79 +106847,93 @@ ${imageData.originalPrompt}
|
|
|
106525
106847
|
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" },
|
|
106526
106848
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null,
|
|
106527
106849
|
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 },
|
|
106528
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106529
|
-
translatingPairs && !pairTranslations[i] ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
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:"),
|
|
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),
|
|
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:"),
|
|
106533
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", sx: { display: 'block' } }, pairTranslations[i].textRu)), placement: "right", arrow: true, componentsProps: {
|
|
106534
|
-
tooltip: { sx: { maxWidth: 360, fontSize: 12, lineHeight: 1.6, p: '10px 14px' } },
|
|
106535
|
-
} },
|
|
106536
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_8__["default"], { size: "small", sx: { p: 0.25, color: 'text.disabled', '&:hover': { color: 'primary.main' } } },
|
|
106537
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_44__["default"], { sx: { fontSize: 14 } })))) : null),
|
|
106850
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_46__["default"], { fontSize: "small" })))),
|
|
106851
|
+
translatingPairs && !pairTranslations[i] ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 13, sx: { color: 'text.disabled', ml: 0.5 } })) : null),
|
|
106538
106852
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 1.5 },
|
|
106539
|
-
titleData && (
|
|
106540
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106541
|
-
|
|
106542
|
-
|
|
106543
|
-
|
|
106544
|
-
|
|
106545
|
-
|
|
106546
|
-
|
|
106547
|
-
|
|
106548
|
-
|
|
106549
|
-
|
|
106550
|
-
|
|
106551
|
-
|
|
106552
|
-
|
|
106553
|
-
|
|
106554
|
-
|
|
106555
|
-
|
|
106556
|
-
|
|
106557
|
-
|
|
106558
|
-
|
|
106559
|
-
|
|
106560
|
-
|
|
106561
|
-
|
|
106562
|
-
|
|
106563
|
-
|
|
106564
|
-
|
|
106565
|
-
|
|
106566
|
-
|
|
106567
|
-
|
|
106568
|
-
|
|
106569
|
-
|
|
106570
|
-
|
|
106571
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106572
|
-
|
|
106573
|
-
|
|
106574
|
-
|
|
106575
|
-
|
|
106576
|
-
|
|
106577
|
-
|
|
106578
|
-
|
|
106579
|
-
|
|
106580
|
-
|
|
106581
|
-
|
|
106582
|
-
'
|
|
106583
|
-
|
|
106584
|
-
|
|
106585
|
-
|
|
106586
|
-
|
|
106587
|
-
|
|
106588
|
-
|
|
106589
|
-
|
|
106590
|
-
|
|
106591
|
-
|
|
106592
|
-
|
|
106593
|
-
|
|
106594
|
-
|
|
106595
|
-
|
|
106596
|
-
|
|
106597
|
-
|
|
106598
|
-
|
|
106599
|
-
|
|
106600
|
-
|
|
106853
|
+
titleData && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106854
|
+
titleData.generating ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
|
|
106855
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16, sx: { color: 'primary.main' } }),
|
|
106856
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", color: "text.secondary" }, "\u0413\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u2026"))) : titleData.failed ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: `Заголовок ${i + 1}`, variant: "outlined", fullWidth: true, size: "small", value: titleData.title, placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0432\u0440\u0443\u0447\u043D\u0443\u044E", helperText: titleData.errorMessage ? `Не сгенерирован: ${titleData.errorMessage}` : 'Можно ввести или исправить заголовок вручную', error: !!titleData.errorMessage, onChange: (e) => {
|
|
106857
|
+
const newValue = e.target.value;
|
|
106858
|
+
setGeneratedTitlesData(prev => {
|
|
106859
|
+
const updated = prev.map(t => t.index === titleData.index
|
|
106860
|
+
? { ...t, title: newValue, failed: false, errorMessage: undefined }
|
|
106861
|
+
: t);
|
|
106862
|
+
setTitles(updated.map(t => t.title).filter(Boolean).join('\n'));
|
|
106863
|
+
return updated;
|
|
106864
|
+
});
|
|
106865
|
+
}, sx: {
|
|
106866
|
+
'& .MuiInputBase-root': {
|
|
106867
|
+
backgroundColor: (theme) => theme.palette.mode === 'dark'
|
|
106868
|
+
? 'rgba(244,67,54,0.08)'
|
|
106869
|
+
: 'rgba(244,67,54,0.04)'
|
|
106870
|
+
}
|
|
106871
|
+
} })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: `Заголовок ${i + 1}`, variant: "outlined", fullWidth: true, size: "small", value: titleData.title, onChange: (e) => {
|
|
106872
|
+
const newValue = e.target.value;
|
|
106873
|
+
setGeneratedTitlesData(prev => {
|
|
106874
|
+
const updated = prev.map(t => t.index === titleData.index ? { ...t, title: newValue } : t);
|
|
106875
|
+
setTitles(updated.map(t => t.title).filter(Boolean).join('\n'));
|
|
106876
|
+
return updated;
|
|
106877
|
+
});
|
|
106878
|
+
}, sx: {
|
|
106879
|
+
'& .MuiInputBase-root': {
|
|
106880
|
+
backgroundColor: (theme) => theme.palette.mode === 'dark'
|
|
106881
|
+
? 'rgba(76,175,80,0.08)'
|
|
106882
|
+
: 'rgba(76,175,80,0.04)'
|
|
106883
|
+
}
|
|
106884
|
+
} })),
|
|
106885
|
+
!titleData.generating && pairTranslations[i]?.titleRu?.trim() ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { component: "div", variant: "caption", sx: {
|
|
106886
|
+
mt: -0.5,
|
|
106887
|
+
pl: 1.5,
|
|
106888
|
+
pr: 1,
|
|
106889
|
+
fontSize: '0.7rem',
|
|
106890
|
+
lineHeight: 1.45,
|
|
106891
|
+
color: 'text.secondary',
|
|
106892
|
+
opacity: 0.92,
|
|
106893
|
+
} }, pairTranslations[i].titleRu)) : null)),
|
|
106894
|
+
textData && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106895
|
+
textData.generating ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
|
|
106896
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 16, sx: { color: 'primary.main' } }),
|
|
106897
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", color: "text.secondary" }, "\u0413\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u0442\u0435\u043A\u0441\u0442\u0430\u2026"))) : textData.failed ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: `Текст ${i + 1}`, variant: "outlined", fullWidth: true, multiline: true, minRows: 3, value: textData.text, placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0435\u043A\u0441\u0442 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0438\u044F \u0432\u0440\u0443\u0447\u043D\u0443\u044E", helperText: textData.errorMessage ? `Не сгенерирован: ${textData.errorMessage}` : 'Можно ввести или исправить текст вручную', error: !!textData.errorMessage, onChange: (e) => {
|
|
106898
|
+
const newValue = e.target.value;
|
|
106899
|
+
setGeneratedTextsData(prev => {
|
|
106900
|
+
const updated = prev.map(t => t.index === textData.index
|
|
106901
|
+
? { ...t, text: newValue, failed: false, errorMessage: undefined }
|
|
106902
|
+
: t);
|
|
106903
|
+
setTexts(updated.map(t => t.text));
|
|
106904
|
+
return updated;
|
|
106905
|
+
});
|
|
106906
|
+
}, sx: {
|
|
106907
|
+
'& .MuiInputBase-root': {
|
|
106908
|
+
backgroundColor: (theme) => theme.palette.mode === 'dark'
|
|
106909
|
+
? 'rgba(244,67,54,0.08)'
|
|
106910
|
+
: 'rgba(244,67,54,0.04)'
|
|
106911
|
+
}
|
|
106912
|
+
} })) : (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_12__["default"], { label: `Текст ${i + 1}`, variant: "outlined", fullWidth: true, multiline: true, minRows: 3, value: textData.text, onChange: (e) => {
|
|
106913
|
+
const newValue = e.target.value;
|
|
106914
|
+
setGeneratedTextsData(prev => {
|
|
106915
|
+
const updated = prev.map(t => t.index === textData.index ? { ...t, text: newValue } : t);
|
|
106916
|
+
setTexts(updated.map(t => t.text).filter(Boolean));
|
|
106917
|
+
return updated;
|
|
106918
|
+
});
|
|
106919
|
+
}, sx: {
|
|
106920
|
+
'& .MuiInputBase-root': {
|
|
106921
|
+
backgroundColor: (theme) => theme.palette.mode === 'dark'
|
|
106922
|
+
? 'rgba(76,175,80,0.08)'
|
|
106923
|
+
: 'rgba(76,175,80,0.04)'
|
|
106924
|
+
}
|
|
106925
|
+
} })),
|
|
106926
|
+
!textData.generating && pairTranslations[i]?.textRu?.trim() ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { component: "div", variant: "caption", sx: {
|
|
106927
|
+
mt: -0.25,
|
|
106928
|
+
pl: 1.5,
|
|
106929
|
+
pr: 1,
|
|
106930
|
+
fontSize: '0.7rem',
|
|
106931
|
+
lineHeight: 1.45,
|
|
106932
|
+
color: 'text.secondary',
|
|
106933
|
+
opacity: 0.92,
|
|
106934
|
+
whiteSpace: 'pre-wrap',
|
|
106935
|
+
wordBreak: 'break-word',
|
|
106936
|
+
} }, pairTranslations[i].textRu)) : null)))));
|
|
106601
106937
|
}))))),
|
|
106602
106938
|
(landingGenerationLogs.length > 0 || generatingLanding) && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { mb: 2 } },
|
|
106603
106939
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "h6", gutterBottom: true, sx: { fontWeight: 'bold' } }, "\u041F\u0440\u043E\u0446\u0435\u0441\u0441 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u044F \u043B\u0435\u043D\u0434\u0438\u043D\u0433\u0430"),
|
|
@@ -106625,10 +106961,38 @@ ${imageData.originalPrompt}
|
|
|
106625
106961
|
'text.primary'
|
|
106626
106962
|
} }, log)))))),
|
|
106627
106963
|
generatingLanding && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_5__["default"], { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 2 } },
|
|
106628
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106964
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_14__["default"], { size: 20 }),
|
|
106629
106965
|
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", sx: { color: 'text.secondary' } }, formatElapsedTime(elapsedTime.landing)))),
|
|
106630
|
-
!generatingLanding && generatedLandingHTML && generatedLandingImageBlob && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106631
|
-
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(
|
|
106966
|
+
!generatingLanding && generatedLandingHTML && generatedLandingImageBlob && (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "outlined", color: "primary", onClick: handlePreviewLanding, startIcon: react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_icons_material__WEBPACK_IMPORTED_MODULE_53__["default"], null), fullWidth: true }, "\u041F\u0440\u0435\u0434\u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440 \u043B\u0435\u043D\u0434\u0438\u043D\u0433\u0430"))))))))),
|
|
106967
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_32__["default"], { open: approachLoadChoice !== null, onClose: handleApproachLoadKeepCurrent, maxWidth: "md", fullWidth: true }, approachLoadChoice ? (react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
106968
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_33__["default"], null, "\u041F\u043E\u0434\u0445\u043E\u0434\u044B \u0438\u0437 \u0444\u0430\u0439\u043B\u0430 \u043E\u0444\u0444\u0435\u0440\u0430"),
|
|
106969
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_34__["default"], null,
|
|
106970
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", color: "text.secondary", sx: { mb: 2 } }, "\u0412 project-settings.json \u0435\u0441\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u043F\u043E\u0434\u0445\u043E\u0434\u044B \u0434\u043B\u044F \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432/\u0442\u0435\u043A\u0441\u0442\u043E\u0432 \u0438 \u0434\u043B\u044F \u043A\u0440\u0435\u043E. \u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0438\u0445 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438 \u0438\u043B\u0438 \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0442\u0435, \u0447\u0442\u043E \u0443\u0436\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u044B \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E?"),
|
|
106971
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { spacing: 2 },
|
|
106972
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "subtitle2" }, "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0438 \u0438 \u0442\u0435\u043A\u0441\u0442\u044B (\u043F\u0430\u0440\u044B \u043F\u043E\u0434\u0445\u043E\u0434\u043E\u0432)"),
|
|
106973
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2 },
|
|
106974
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_31__["default"], { variant: "outlined", sx: { p: 1.5, flex: 1 } },
|
|
106975
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary", display: "block", gutterBottom: true }, "\u0421\u0435\u0439\u0447\u0430\u0441 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438"),
|
|
106976
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", component: "div", sx: { whiteSpace: 'pre-wrap', fontFamily: 'inherit' } }, formatPairApproachesForDisplay(approachLoadChoice.currentPairs))),
|
|
106977
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_31__["default"], { variant: "outlined", sx: { p: 1.5, flex: 1 } },
|
|
106978
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary", display: "block", gutterBottom: true }, "\u0412 \u0444\u0430\u0439\u043B\u0435 \u043E\u0444\u0444\u0435\u0440\u0430"),
|
|
106979
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", component: "div", sx: { whiteSpace: 'pre-wrap', fontFamily: 'inherit' } }, approachLoadChoice.savedPairs
|
|
106980
|
+
? formatPairApproachesForDisplay(approachLoadChoice.savedPairs)
|
|
106981
|
+
: '— не указано (список для текстов не изменится)'))),
|
|
106982
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "subtitle2" }, "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F (\u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u043F\u043E \u043F\u043E\u0434\u0445\u043E\u0434\u0443)"),
|
|
106983
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_11__["default"], { direction: { xs: 'column', sm: 'row' }, spacing: 2 },
|
|
106984
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_31__["default"], { variant: "outlined", sx: { p: 1.5, flex: 1 } },
|
|
106985
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary", display: "block", gutterBottom: true }, "\u0421\u0435\u0439\u0447\u0430\u0441 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438"),
|
|
106986
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", component: "div", sx: { whiteSpace: 'pre-wrap', fontFamily: 'inherit' } }, formatImageCountsForDisplay(approachLoadChoice.currentCounts))),
|
|
106987
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_31__["default"], { variant: "outlined", sx: { p: 1.5, flex: 1 } },
|
|
106988
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "caption", color: "text.secondary", display: "block", gutterBottom: true }, "\u0412 \u0444\u0430\u0439\u043B\u0435 \u043E\u0444\u0444\u0435\u0440\u0430"),
|
|
106989
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_6__["default"], { variant: "body2", component: "div", sx: { whiteSpace: 'pre-wrap', fontFamily: 'inherit' } }, approachLoadChoice.savedCounts
|
|
106990
|
+
? formatImageCountsForDisplay(approachLoadChoice.savedCounts)
|
|
106991
|
+
: '— не указано (количества крео не изменятся)'))))),
|
|
106992
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_35__["default"], null,
|
|
106993
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { onClick: handleApproachLoadKeepCurrent }, "\u041E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u043A\u0430\u043A \u0441\u0435\u0439\u0447\u0430\u0441"),
|
|
106994
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_mui_material__WEBPACK_IMPORTED_MODULE_20__["default"], { variant: "contained", onClick: handleApproachLoadApplyFromFile }, "\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0438\u0437 \u0444\u0430\u0439\u043B\u0430")))) : null),
|
|
106995
|
+
react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_PromptManagerDialog__WEBPACK_IMPORTED_MODULE_54__["default"], { open: promptManagerOpen, onClose: () => setPromptManagerOpen(false) }))));
|
|
106632
106996
|
}
|
|
106633
106997
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (App);
|
|
106634
106998
|
|
|
@@ -107724,6 +108088,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
107724
108088
|
/* harmony export */ PRODUCT_TYPE_IMAGE_PRESETS: () => (/* binding */ PRODUCT_TYPE_IMAGE_PRESETS),
|
|
107725
108089
|
/* harmony export */ PRODUCT_TYPE_TEXT_PAIR_PRESETS: () => (/* binding */ PRODUCT_TYPE_TEXT_PAIR_PRESETS),
|
|
107726
108090
|
/* harmony export */ PROMPT_OVERRIDES_SAVED_EVENT: () => (/* binding */ PROMPT_OVERRIDES_SAVED_EVENT),
|
|
108091
|
+
/* harmony export */ applyParsedApproachesFromDrive: () => (/* binding */ applyParsedApproachesFromDrive),
|
|
107727
108092
|
/* harmony export */ getCreoApproachOverride: () => (/* binding */ getCreoApproachOverride),
|
|
107728
108093
|
/* harmony export */ getImageApproachCounts: () => (/* binding */ getImageApproachCounts),
|
|
107729
108094
|
/* harmony export */ getPairsCount: () => (/* binding */ getPairsCount),
|
|
@@ -107734,6 +108099,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
107734
108099
|
/* harmony export */ mergePromptApproachesFromDriveFile: () => (/* binding */ mergePromptApproachesFromDriveFile),
|
|
107735
108100
|
/* harmony export */ normalizeImageApproachCountsFromDrive: () => (/* binding */ normalizeImageApproachCountsFromDrive),
|
|
107736
108101
|
/* harmony export */ normalizeSelectedPairApproachesFromDrive: () => (/* binding */ normalizeSelectedPairApproachesFromDrive),
|
|
108102
|
+
/* harmony export */ parseApproachesFromDriveData: () => (/* binding */ parseApproachesFromDriveData),
|
|
107737
108103
|
/* harmony export */ productPresetNumbersToImageCounts: () => (/* binding */ productPresetNumbersToImageCounts),
|
|
107738
108104
|
/* harmony export */ productPresetNumbersToIndices: () => (/* binding */ productPresetNumbersToIndices),
|
|
107739
108105
|
/* harmony export */ resetAllOverrides: () => (/* binding */ resetAllOverrides),
|
|
@@ -107919,12 +108285,17 @@ function savePromptOverrides(overrides) {
|
|
|
107919
108285
|
}
|
|
107920
108286
|
/** Имя события после сохранения подходов в менеджере промптов — чтобы синхронизировать JSON на Drive. */
|
|
107921
108287
|
const PROMPT_OVERRIDES_SAVED_EVENT = 'docs-combiner-prompt-overrides-saved';
|
|
108288
|
+
/** Прочитать валидные подходы из объекта настроек с диска (без записи в localStorage). */
|
|
108289
|
+
function parseApproachesFromDriveData(loadedData) {
|
|
108290
|
+
return {
|
|
108291
|
+
pairs: normalizeSelectedPairApproachesFromDrive(loadedData.selectedPairApproaches),
|
|
108292
|
+
counts: normalizeImageApproachCountsFromDrive(loadedData.imageApproachCounts),
|
|
108293
|
+
};
|
|
108294
|
+
}
|
|
107922
108295
|
/**
|
|
107923
|
-
*
|
|
108296
|
+
* Применить к localStorage только те части, для которых переданы ненулевые массивы.
|
|
107924
108297
|
*/
|
|
107925
|
-
function
|
|
107926
|
-
const pairs = normalizeSelectedPairApproachesFromDrive(loadedData.selectedPairApproaches);
|
|
107927
|
-
const counts = normalizeImageApproachCountsFromDrive(loadedData.imageApproachCounts);
|
|
108298
|
+
function applyParsedApproachesFromDrive(pairs, counts) {
|
|
107928
108299
|
if (!pairs && !counts)
|
|
107929
108300
|
return false;
|
|
107930
108301
|
const overrides = loadPromptOverrides();
|
|
@@ -107943,6 +108314,13 @@ function mergePromptApproachesFromDriveFile(loadedData) {
|
|
|
107943
108314
|
}
|
|
107944
108315
|
return false;
|
|
107945
108316
|
}
|
|
108317
|
+
/**
|
|
108318
|
+
* Подмешать в localStorage выбранные подходы из project-settings.json на Drive (если поля валидны).
|
|
108319
|
+
*/
|
|
108320
|
+
function mergePromptApproachesFromDriveFile(loadedData) {
|
|
108321
|
+
const { pairs, counts } = parseApproachesFromDriveData(loadedData);
|
|
108322
|
+
return applyParsedApproachesFromDrive(pairs, counts);
|
|
108323
|
+
}
|
|
107946
108324
|
/**
|
|
107947
108325
|
* Получить оверрайд для простого промпта
|
|
107948
108326
|
*/
|
|
@@ -108138,57 +108516,57 @@ function _debugLog(...args) {
|
|
|
108138
108516
|
const PAIR_APPROACH_POOL = [
|
|
108139
108517
|
{
|
|
108140
108518
|
name: 'болевая точка',
|
|
108141
|
-
titleApproach: 'одна ясная боль (не две проблемы в одном заголовке). Усиливай через несправедливость / ощущение «так несправедливо» (устал бороться, снова срыв, тело не слушается) — не только сухое перечисление симптомов. ЗАГОЛОВОК = КОНСТАТАЦИЯ, не вопрос: ЗАПРЕЩЕНО заканчивать на «почему?»,
|
|
108519
|
+
titleApproach: 'одна ясная боль (не две проблемы в одном заголовке). Усиливай через несправедливость / ощущение «так несправедливо» (устал бороться, снова срыв, тело не слушается) — не только сухое перечисление симптомов. ЗАГОЛОВОК = КОНСТАТАЦИЯ, не вопрос: ЗАПРЕЩЕНО заканчивать на «почему?», «зачем?», «why?» и подобное — боль называешь фактом, не спрашиваешь',
|
|
108142
108520
|
textApproach: 'Одна центральная проблема за текст — не распыляйся на несколько болей. ЗАПРЕЩЕНО перечислять ингредиенты, состав, matcha/MCT/«формулу» — это территория «авторитет/экспертиза», не болевой точки. Опиши дискомфорт и как продукт снимает именно эту боль; без каталога компонентов.',
|
|
108143
108521
|
},
|
|
108144
108522
|
{
|
|
108145
108523
|
name: 'трансформация до/после',
|
|
108146
|
-
titleApproach: 'контраст СОСТОЯНИЙ и ощущений до/после (вздутие/усталость → лёгкость, тяжесть → контроль, «не узнаю себя в зеркале» → спокойствие) с якорем во времени во фразе, но БЕЗ цифр на весах. ЗАПРЕЩЕНО в заголовке: −X kg,
|
|
108147
|
-
textApproach: 'СТРОГО от первого лица (
|
|
108524
|
+
titleApproach: 'контраст СОСТОЯНИЙ и ощущений до/после (вздутие/усталость → лёгкость, тяжесть → контроль, «не узнаю себя в зеркале» → спокойствие) с якорем во времени во фразе, но БЕЗ цифр на весах. ЗАПРЕЩЕНО в заголовке: −X kg, «минус N кг», весы, любой явный минус килограммов (для похудения такой акцент — только у testimonial и только если продукт явно про вес)',
|
|
108525
|
+
textApproach: 'СТРОГО от первого лица (на языке GEO — естественное «я» для локали). Это не отзыв с именем — это МОЙ контраст «как было плохо / как стало лучше» по телу и эмоциям. ЗАПРЕЩЕНО копировать формат отзыва: не начинай как реклама «я попробовала продукт и минус X кг» подряд; сначала ощущения и жизнь до/после, продукт — связка, а не пересказ цифр с весов (цифры веса допустимы в тексте лишь второстепенно, если уместно; акцент — на смене состояния). ЗАПРЕЩЕНО соцдоказательство («многие отмечают», «тысячи уже выбрали» вместо личной истории).',
|
|
108148
108526
|
},
|
|
108149
108527
|
{
|
|
108150
108528
|
name: 'testimonial',
|
|
108151
108529
|
isTestimonial: true,
|
|
108152
|
-
titleApproach: 'короткая «живая» фраза с
|
|
108530
|
+
titleApproach: 'короткая «живая» фраза с **конкретным результатом по теме продукта** и сроком (7–14 дней). Цифры −кг, весы, «минус на весах» — **только** если продукт явно про похудение / контроль веса. Для паразитов/ЖКТ/суставов/простаты/сна и т.п. — результат = облегчение симптомов, комфорт, сон, подвижность, меньше дискомфорта (без выдуманных кг). Это отличает testimonial от «трансформации». НЕ используй «Имя, возраст:» в заголовке — только в тексте',
|
|
108153
108531
|
textApproach: `Это единственный подход-ОТЗЫВ: читатель должен поверить в реального человека.
|
|
108154
|
-
* Обязательно начало текста с «Имя, возраст:» (
|
|
108532
|
+
* Обязательно начало текста с «Имя, возраст:» (формат на языке GEO, например «Анна, 49 лет:», «Олег, 41 год:»)
|
|
108155
108533
|
* История только от первого лица после имени
|
|
108156
|
-
* Конкретный результат с таймингом (7–14 дней),
|
|
108534
|
+
* Конкретный результат с таймингом (7–14 дней), релевантный категории продукта; килограммы упоминай только если оффер действительно про вес/похудение
|
|
108157
108535
|
* Заканчивается приглашением попробовать + CTA`,
|
|
108158
108536
|
},
|
|
108159
108537
|
{
|
|
108160
108538
|
name: 'срочность/дефицит',
|
|
108161
108539
|
titleApproach: 'ТОЛЬКО дефицит оффера: время до конкретного дедлайна, остаток штук, «до полуночи», «осталось N упаковок» — ЗАПРЕЩЕНО в заголовке проблема, тело, продукт, «лишние кг», категория товара. Не баннер магазина — конкретная граница (день, час, число мест)',
|
|
108162
|
-
textApproach: 'Начни с конкретного сигнала ограниченности — времени или количества (
|
|
108540
|
+
textApproach: 'Начни с конкретного сигнала ограниченности — времени или количества («только сегодня», «последние упаковки», «Осталось 12 упаковок», «Акция до конца дня» — всё на языке GEO). Весь текст строится ИСКЛЮЧИТЕЛЬНО вокруг дефицита или дедлайна: осталось мало, время заканчивается, потом будет дороже или не будет вообще. ЗАПРЕЩЕНО упоминать состав, ингредиенты, свойства или пользу продукта — только ограниченность оффера. CTA максимально срочный.',
|
|
108163
108541
|
},
|
|
108164
108542
|
{
|
|
108165
108543
|
name: 'социальное доказательство',
|
|
108166
|
-
titleApproach: 'одна ЧИТАЕМАЯ фраза с крупной цифрой (
|
|
108167
|
-
textApproach: 'Начни с цифры или массового факта («Уже 50 000 клиентов», «9
|
|
108544
|
+
titleApproach: 'одна ЧИТАЕМАЯ фраза с крупной цифрой (уровень: «Уже 50 000 женщин выбрали … 🔥» на языке GEO) — грамматика и смысл на языке GEO должны сходиться; читатель понимает фразу с первого раза. ЗАПРЕЩЕНО несвязные склейки («9 из 10 выбирают контроль 🔥 голод» — бессмыслица) и обрывки, где цифра + существительные не составляют нормального высказывания',
|
|
108545
|
+
textApproach: 'Начни с цифры или массового факта («Уже 50 000 клиентов», «9 из 10 отмечают разницу» — на языке GEO). Акцент на том, что проблему уже решили тысячи — и ты тоже можешь.',
|
|
108168
108546
|
},
|
|
108169
108547
|
{
|
|
108170
108548
|
name: 'любопытство/интрига',
|
|
108171
|
-
titleApproach: 'провокационный вопрос или утверждение, которое ломает сразу ДВА привычных решения (диета
|
|
108172
|
-
textApproach: 'Начни с провокационного вопроса или неожиданного инсайта («Знаете, почему обычные средства не помогают?»,
|
|
108549
|
+
titleApproach: 'провокационный вопрос или утверждение, которое ломает сразу ДВА привычных решения (например диета и спорт одновременно) — но ОДНОЙ ЦЕЛЬНОЙ фразой: связный синтаксис, без рубки на обрывки через запятую и эмодзи посередине. Пример уровня на русском для тона: «Диета и зал, а живот всё равно? 🤔» — на GEO перепиши естественно; не три оторванных куска',
|
|
108550
|
+
textApproach: 'Начни с провокационного вопроса или неожиданного инсайта («Знаете, почему обычные средства не помогают?», «А вы знали, что…» — на языке GEO). Раскрой неочевидный факт о проблеме или механизме решения и выведи к продукту.',
|
|
108173
108551
|
},
|
|
108174
108552
|
{
|
|
108175
108553
|
name: 'авторитет/экспертиза',
|
|
108176
|
-
titleApproach: 'information gap: в заголовке ЗАПРЕЩЕНО называть ингредиенты и раскрывать метод/механизм напрямую — никаких matcha, MCT,
|
|
108177
|
-
textApproach: 'Начни с ФАКТА/утверждения об экспертизе (
|
|
108554
|
+
titleApproach: 'information gap: в заголовке ЗАПРЕЩЕНО называть ингредиенты и раскрывать метод/механизм напрямую — никаких matcha, MCT, «зелёный чай», «формула с…», «натуральный метод для…», «ускорить обмен веществ», «поддерживает обмен веществ» и т.п.; иначе ответ уже в заголовке и клик не нужен. Подай состав или подход как тайну / открытие / «что скрывают» / «почему это не то же самое, что обычные средства» — без конкретики, ответ только в основном тексте. ЗАПРЕЩЕНЫ эмодзи-подсказки по составу (например 🍵, если по смыслу выдаёт чай), если они заменяют то, что должен открыть текст. Не закрывай интригу сухими схемами вроде «Почему X и Y поддерживают…»',
|
|
108555
|
+
textApproach: 'Начни с ФАКТА/утверждения об экспертизе («Итальянская рецептура», «Произведено в Италии», «3 натуральных компонента», «Разработано фармацевтами» — перенеси смысл на язык GEO). Акцент на составе, происхождении или механизме действия. Почему это работает — объясни просто и убедительно.',
|
|
108178
108556
|
},
|
|
108179
108557
|
{
|
|
108180
108558
|
name: 'страх бездействия',
|
|
108181
|
-
titleApproach: 'узнаваемый паттерн промедления — ОДНА СВЯЗНАЯ фраза (допустимы многоточие, союз «но», тире), а не перечень обрывков через запятую. Пример уровня:
|
|
108182
|
-
textApproach: 'Начни с описания негативного сценария бездействия («С каждым днём становится хуже…», «Если не взять под контроль сейчас…»). Покажи, что проблема прогрессирует. Финальный CTA — ТОЛЬКО про заботу о себе / начать сейчас / не откладывать (на языке GEO). ЗАПРЕЩЕНЫ прямые призывы к заказу в финале:
|
|
108559
|
+
titleApproach: 'узнаваемый паттерн промедления — ОДНА СВЯЗНАЯ фраза (допустимы многоточие, союз «но», тире), а не перечень обрывков через запятую. Пример уровня: «Отложила на понедельник… а голод не ждёт 😣» — на GEO перепиши естественно; смысл течёт от начала к концу',
|
|
108560
|
+
textApproach: 'Начни с описания негативного сценария бездействия («С каждым днём становится хуже…», «Если не взять под контроль сейчас…»). Покажи, что проблема прогрессирует. Финальный CTA — ТОЛЬКО про заботу о себе / начать сейчас / не откладывать (на языке GEO). ЗАПРЕЩЕНЫ прямые призывы к заказу в финале: «закажи», «закажи сейчас», «купи», «купи сейчас», «оформи заказ» — вместо них: взять под контроль, сделать первый шаг, начать сегодня и т.п.',
|
|
108183
108561
|
},
|
|
108184
108562
|
{
|
|
108185
108563
|
name: 'прямой оффер/выгода',
|
|
108186
|
-
titleApproach: '
|
|
108187
|
-
textApproach: '
|
|
108564
|
+
titleApproach: 'выгода в заголовке = **-50%** как есть (знак процента), плюс по желанию 2–4 слова срочности на языке GEO («только сегодня», «сейчас»). ОБЯЗАТЕЛЬНО минимум один эмодзи (💸 🔥 ✨ 🎁 ⏳ 📦). **Не придумывай** другую механику: никаких «2-й пакет», «вторая упаковка», «полцены» вместо простого **-50%**, если в задании пользователя явно не сказано иначе. **-50% = просто -50%.**',
|
|
108565
|
+
textApproach: 'Коротко про сделку: **-50% не перефразируй** длинно («платишь половину», «акция на сегодня», «скидка на вторую упаковку»), если пользователь этого не писал — повтори **-50%** и добавь одну короткую фразу срочности + CTA. ЗАПРЕЩЕНО расписывать математику скидки и выдумывать условия акции. ЗАПРЕЩЕНО объяснять пользу продукта или боли — только **-50%**, срочность, CTA.',
|
|
108188
108566
|
},
|
|
108189
108567
|
{
|
|
108190
108568
|
name: 'ситуационный/узнаваемый момент',
|
|
108191
|
-
titleApproach: 'одна яркая узнаваемая сцена в 1–2 коротких связных сегментах (лучше одна картинка), без перечня симптомов через запятую. Пример уровня:
|
|
108569
|
+
titleApproach: 'одна яркая узнаваемая сцена в 1–2 коротких связных сегментах (лучше одна картинка), без перечня симптомов через запятую. Пример уровня: «После обеда джинсы жмут 😩» — на GEO перепиши естественно; сразу видно момент и боль; ЗАПРЕЩЕНО нагромождать «после обеда 😩 джинсы, живот, тесно» отдельными ярлыками',
|
|
108192
108570
|
textApproach: 'Начни с конкретной жизненной сцены, где проблема ощущается («[ключевой симптом категории продукта]…», «Вечером перед сном не можешь уснуть из-за дискомфорта…» — адаптируй под категорию). Создай узнаваемую ситуацию — читатель должен сказать «это про меня» — и предложи решение.',
|
|
108193
108571
|
},
|
|
108194
108572
|
];
|
|
@@ -108305,7 +108683,7 @@ ${distributionLines}
|
|
|
108305
108683
|
|
|
108306
108684
|
КРИТИЧНО — СРОК + ОФФЕР ДЛЯ КОНВЕРСИИ:
|
|
108307
108685
|
${deadlineNote}
|
|
108308
|
-
- Опционально (не обязательно): усили CTA упоминанием
|
|
108686
|
+
- Опционально (не обязательно): усили CTA упоминанием **-50%** как есть и ограниченности по времени («только сегодня/ограничено») — коротко, в конце; **не** заменяй -50% на «полцены», «вторая упаковка» и т.п., если это не в задании.${hasTestimonial ? '' : ''}
|
|
108309
108687
|
|
|
108310
108688
|
Требования к стилю и тону:
|
|
108311
108689
|
- Копия должна звучать как прямая реклама, а не как рассказ
|
|
@@ -108326,7 +108704,7 @@ ${deadlineNote}
|
|
|
108326
108704
|
- КРИТИЧНО: Каждый текст должен содержать хотя бы одно ясное ключевое слово проблемы, релевантное категории продукта (например, для суставов: боль/скованность/подвижность; для пищеварения: дискомфорт/тяжесть; для сна: бессонница/усталость — примеры только для формата, адаптируй под категорию). Если ключевое слово проблемы отсутствует — перепиши текст
|
|
108327
108705
|
- КРИТИЧНО: Каждый текст должен заканчиваться сильным и явным призывом к действию (кликни, попробуй сейчас, закажи сегодня, узнай больше и т.д.)
|
|
108328
108706
|
- Избегай слабых окончаний или информационного тона. Слабые или нейтральные окончания не допускаются
|
|
108329
|
-
- CTA должен быть “нажимным”: допускаются формулировки «не откладывай», «последний шанс», «только сегодня», «забери -50%» (всё строго на языке GEO)
|
|
108707
|
+
- CTA должен быть “нажимным”: допускаются формулировки «не откладывай», «последний шанс», «только сегодня», «забери -50%» (всё строго на языке GEO). Если пишешь скидку — **-50%** буквально, без выдуманной механики акции
|
|
108330
108708
|
- В каждом тексте строго следуй заданному формату старта согласно его подходу (см. распределение выше)
|
|
108331
108709
|
- Если ингредиенты предоставлены в дополнительной информации, упоминай их ТОЛЬКО если они естественно подходят выбранному рекламному подходу. Например: подходы авторитета/экспертизы выигрывают от деталей ингредиентов, в то время как подходы срочности/эмоционального триггера могут не нуждаться в них. Упоминай только релевантные ингредиенты, не обязательно все из них. Если ингредиенты не подходят подходу или не предоставлены — полностью пропусти их упоминание и не изобретай и не упоминай никакие ингредиенты
|
|
108332
108710
|
- Добавляй только существенные поддерживающие детали, которые усиливают убеждение или ясность, а не заполнители или общие утверждения. Будь кратким и прямым
|
|
@@ -108339,7 +108717,7 @@ ${deadlineNote}
|
|
|
108339
108717
|
- Разделяй разные тексты пустой строкой (двойной перевод строки)
|
|
108340
108718
|
- КРИТИЧНО: Каждый текст ДОЛЖЕН быть многострочным с естественными переносами строк. Используй переносы строк для разделения предложений, выделения ключевых моментов или создания визуальной структуры. НЕ пиши описания как одиночные непрерывные строки
|
|
108341
108719
|
- КРИТИЧНО: Все тексты ДОЛЖНЫ быть написаны на языке ${geo}. Используй точное название языка "${geo}" — не используй русский, английский или любой другой язык
|
|
108342
|
-
- ВСЕ слова в тексте должны быть на языке GEO. Английские фразы вроде «Made in Italy», «Made in Germany» ЗАПРЕЩЕНЫ — используй
|
|
108720
|
+
- ВСЕ слова в тексте должны быть на языке GEO. Английские фразы вроде «Made in Italy», «Made in Germany» ЗАПРЕЩЕНЫ — используй перевод на язык GEO (например «Произведено в Италии», «Сделано в Германии» и аналоги).
|
|
108343
108721
|
- После создания проверь их правильность И убедись в максимальном разнообразии между текстами
|
|
108344
108722
|
- Верни только финальные результаты. Не добавляй объяснений или комментариев`;
|
|
108345
108723
|
}
|
|
@@ -108417,6 +108795,7 @@ function getPairsSystemPrompt(geo, noOverride, count = 3, selectedIndices) {
|
|
|
108417
108795
|
- Служебные метки в начале строки пиши РОВНО как в примере: слово «ЗАГОЛОВОК» целиком кириллицей (не ZAG, не смесь латиницы и кириллицы), слово «ТЕКСТ» целиком кириллицей.
|
|
108418
108796
|
- Не вставляй строки «ЗАГОЛОВОК N:» внутрь текста объявления; каждый заголовок — отдельная строка перед своим «ТЕКСТ N:».
|
|
108419
108797
|
- Контент объявления (заголовок и текст) — на языке ${geo}; только метки ЗАГОЛОВОК/ТЕКСТ остаются кириллицей как шаблон.
|
|
108798
|
+
- Язык ${geo}: если это название страны — пиши на **официальном языке этой страны**; не путай близкие коды и локали (например Словения ≠ Словакия, хорватский ≠ словенский).
|
|
108420
108799
|
|
|
108421
108800
|
РАСПРЕДЕЛЕНИЕ ПОДХОДОВ ПО ПАРАМ:
|
|
108422
108801
|
${distributionLines}
|
|
@@ -108426,27 +108805,28 @@ ${distributionLines}
|
|
|
108426
108805
|
- Текст — раскрывает тот же угол глубже, добавляет детали, заканчивается CTA
|
|
108427
108806
|
- Текст НЕ повторяет заголовок дословно, но развивает его смысл
|
|
108428
108807
|
- Не подмешивай чужие углы: например в «трансформация до/после» не используй формулировки соцдоказательства («многие отмечают», «клиенты говорят»)
|
|
108429
|
-
${hasTransformAndTestimonial ? '\n- РАЗВЕДЕНИЕ «трансформация до/после» и «testimonial» в одном ответе: у трансформации заголовок = контраст ощущений/состояния (без −кг и без «минус X kg за N дней»); у testimonial
|
|
108808
|
+
${hasTransformAndTestimonial ? '\n- РАЗВЕДЕНИЕ «трансформация до/после» и «testimonial» в одном ответе: у трансформации заголовок = контраст ощущений/состояния (без −кг и без «минус X kg за N дней»); у testimonial −кг и весы в заголовке — **только если продукт в задании явно про похудение**; иначе testimonial = конкретный симптомный/комфортный результат + срок. Не делай два заголовка в одном формате «цифра + срок на весах».' : ''}
|
|
108430
108809
|
|
|
108431
108810
|
ТРЕБОВАНИЯ К ЗАГОЛОВКУ:
|
|
108432
108811
|
- До 55–60 символов, максимум 6–7 слов
|
|
108433
108812
|
- Цельность: заголовок читается как одно высказывание (или один связный вопрос целиком). ЗАПРЕЩЕНО склеивать несвязные ярлыки запятыми ради ключевых слов; эмодзи не должно разрывать грамматику так, что фраза перестаёт быть человеческой
|
|
108434
108813
|
- ЗАПРЕЩЕНО двоеточие (:) — используй тире (—) или переформулируй
|
|
108435
108814
|
- 1–2 эмодзи естественно (часто в конце фразы или после целого смыслового блока); избегай ⚠️ и 🚨${hasDirectOffer ? '\n- Для пары «прямой оффер/выгода» эмодзи в заголовке ОБЯЗАТЕЛЕН (минимум один) — визуально вровень с остальными парами набора' : ''}
|
|
108436
|
-
- Хотя бы одно ключевое слово проблемы, релевантное продукту${hasUrgencyScarcity ? '\n- ИСКЛЮЧЕНИЕ: для пары с подходом «срочность/дефицит» в заголовке ЗАПРЕЩЕНЫ симптомы, проблема, тело, продукт — только лимит оффера (время, количество, дедлайн)' : ''}${hasAuthorityExpertise ? '\n- Пара «авторитет/экспертиза»: заголовок держит information gap — без ингредиентов и без прямого названия механизма; состав и «как это работает» — только в тексте пары' : ''}
|
|
108437
|
-
- НЕ упоминай название продукта — заголовок = боль + триггер${hasUrgencyScarcity ? ' (кроме пары «срочность/дефицит»: там заголовок = только дефицит/дедлайн, без продукта и без боли)' : ''}${hasSocialProof ? '\n- Исключение: в паре «социальное доказательство» название продукта в заголовке допустимо, если оно входит в цельную фразу про массовый выбор (например
|
|
108815
|
+
- Хотя бы одно ключевое слово проблемы, релевантное продукту${hasUrgencyScarcity ? '\n- ИСКЛЮЧЕНИЕ: для пары с подходом «срочность/дефицит» в заголовке ЗАПРЕЩЕНЫ симптомы, проблема, тело, продукт — только лимит оффера (время, количество, дедлайн)' : ''}${hasDirectOffer ? '\n- ИСКЛЮЧЕНИЕ: для пары «прямой оффер/выгода» ключевое слово проблемы в заголовке **не обязательно**; ядро — **-50%** (+эмодзи + короткая срочность). **Не выдумывай** «2-й пакет / вторая упаковка / полцены» без данных в задании — **-50% это просто -50%.**' : ''}${hasAuthorityExpertise ? '\n- Пара «авторитет/экспертиза»: заголовок держит information gap — без ингредиентов и без прямого названия механизма; состав и «как это работает» — только в тексте пары' : ''}
|
|
108816
|
+
- НЕ упоминай название продукта — заголовок = боль + триггер${hasUrgencyScarcity ? ' (кроме пары «срочность/дефицит»: там заголовок = только дефицит/дедлайн, без продукта и без боли)' : ''}${hasSocialProof ? '\n- Исключение: в паре «социальное доказательство» название продукта в заголовке допустимо, если оно входит в цельную фразу про массовый выбор (например «Уже N тысяч человек выбрали [продукт]» на языке GEO)' : ''}
|
|
108438
108817
|
- Звучит как живая рекламная фраза, а не строка ключевых слов
|
|
108439
108818
|
|
|
108440
108819
|
ТРЕБОВАНИЯ К ТЕКСТУ:
|
|
108441
|
-
- 150–280 символов (testimonial — до 300)
|
|
108442
|
-
- Хотя бы одно ключевое слово проблемы (для «срочность/дефицит» в тексте допустимо слабее, если весь фокус — на лимите оффера)
|
|
108443
|
-
- Сильный явный CTA в конце («кликни», «попробуй сейчас», «закажи», «не жди»)${hasFearInaction ? '\n- ИСКЛЮЧЕНИЕ: для пары «страх бездействия» финальная фраза — не заказ, а забота о себе / начать сейчас; без
|
|
108444
|
-
- Короткие рубленые фразы, императивы, FOMO допустим${hasTestimonial ? '\n- Testimonial: строго от первого лица, начинается с «Имя, возраст:», конкретный результат с
|
|
108820
|
+
- 150–280 символов (testimonial — до 300)${hasDirectOffer ? '; для пары «прямой оффер/выгода» достаточно **120–200** символов, если текст = **-50%** + срочность + CTA без воды' : ''}
|
|
108821
|
+
- Хотя бы одно ключевое слово проблемы (для «срочность/дефицит» в тексте допустимо слабее, если весь фокус — на лимите оффера)${hasDirectOffer ? '; для «прямой оффер/выгода» ключевое слово проблемы **не обязательно** — фокус на **-50%** и CTA' : ''}
|
|
108822
|
+
- Сильный явный CTA в конце («кликни», «попробуй сейчас», «закажи», «не жди»)${hasFearInaction ? '\n- ИСКЛЮЧЕНИЕ: для пары «страх бездействия» финальная фраза — не заказ, а забота о себе / начать сейчас; без «закажи», «купи», «оформи заказ» в конце' : ''}
|
|
108823
|
+
- Короткие рубленые фразы, императивы, FOMO допустим${hasTestimonial ? '\n- Testimonial: строго от первого лица, начинается с «Имя, возраст:», конкретный результат с таймингом; тема результата = как в названии/описании продукта (антипаразитарное → ЖКТ/вздутие/дискомфорт и т.д.), не минус кг если продукт не про вес' : ''}
|
|
108445
108824
|
- Ингредиенты и состав из доп. информации — только в углах «авторитет/экспертиза» (и сходных); в «болевой точке» и чисто эмоциональных углах состав не перечислять
|
|
108446
108825
|
${deadlineNote}
|
|
108447
108826
|
|
|
108448
108827
|
ОБЩИЕ ТРЕБОВАНИЯ:
|
|
108449
108828
|
- Язык: ${geo} — все тексты строго на этом языке
|
|
108829
|
+
- Релевантность продукту из пользовательского сообщения: не подменяй категорию. Капли/средства от паразитов, детокс ЖКТ → симптомы и облегчение в этой зоне; **не делай главным мотивом −кг и весы**, если в задании нет явного похудения. Аналогично не смешивай суставы с простатой и т.д.
|
|
108450
108830
|
- Естественный человеческий тон, без академизма и AI-звучания
|
|
108451
108831
|
- Разные психологические триггеры в каждой паре, минимальное пересечение
|
|
108452
108832
|
- Верни ТОЛЬКО пары в указанном формате, без объяснений и комментариев`;
|
|
@@ -108569,10 +108949,10 @@ OTHER_TEXT: ["..."] (любой другой рекламный текст на
|
|
|
108569
108949
|
ШАГ 1 — HOOK/HEADLINE (критично):
|
|
108570
108950
|
- Должен быть ВЫШЕ всех элементов и читабелен (хорошо читается на телефоне)
|
|
108571
108951
|
- Допускается 1–4 строки (это НЕ ошибка). Ошибка только если текст нечитабелен или есть разрыв/перенос внутри слова.
|
|
108572
|
-
- Смысл: релевантно проблеме/выгоде продукта. Допускаются и боль/дискомфорт, и обещание/выгода (например
|
|
108952
|
+
- Смысл: релевантно проблеме/выгоде продукта. Допускаются и боль/дискомфорт, и обещание/выгода (например «станет легче день ото дня» — смысл на языке GEO). НЕ считай ошибкой формулировки обещаний результата или клеймы.
|
|
108573
108953
|
- ОБЯЗАТЕЛЬНО: ключевое слово проблемы явно в формулировке. Примеры по категориям: простата → простатит, простата; похудение → лишний вес, похудение; суставы → боль, колени, скованность; пищеварение → дискомфорт, вздутие; сон → бессонница, усталость. Отсутствие ключевого слова — ОШИБКА. Дополнительно для ориентира: ${keywords.join(', ')} (можно синонимы).
|
|
108574
|
-
- Проверь вторую часть заголовка. Если она состоит только из абстрактных слов (
|
|
108575
|
-
- Если заголовок слишком общий/абстрактный (
|
|
108954
|
+
- Проверь вторую часть заголовка. Если она состоит только из абстрактных слов («легче», «лучше», «решение», «помощь» без конкретики на языке GEO) без конкретного бенефита — отметь: РЕКОМЕНДАЦИЯ: заголовок можно усилить конкретикой
|
|
108955
|
+
- Если заголовок слишком общий/абстрактный («легче», «лучше» без конкретики) — отметь как РЕКОМЕНДАЦИЯ к улучшению (не ошибка, но слабо)
|
|
108576
108956
|
- РЕКОМЕНДАЦИЯ (CTR): верхний текст лучше делать как HOOK — ОЧЕНЬ крупный, жирный, ВСЕ БУКВЫ ПРОПИСНЫЕ, на яркой контрастной плашке. Если это не так — не ошибка, но отметь рекомендацией
|
|
108577
108957
|
|
|
108578
108958
|
${step2Bullets}
|
|
@@ -108643,6 +109023,8 @@ function getImageGenerationBasePrompt(generateGeo, generatePrice, generateCurren
|
|
|
108643
109023
|
Создай рекламный креатив для Facebook Ads ${ratio} (${ratioLabel}).
|
|
108644
109024
|
ВАЖНО: изображение должно быть ${ratioShape} — строго соблюдай пропорции холста.
|
|
108645
109025
|
Язык текста: ${generateGeo}.
|
|
109026
|
+
Если GEO — название страны (например «Чехия», «Румыния»), используй **основной официальный язык этой страны** на макете (Чехия → чешский; Румыния → румынский и т.д.). Валюта/символ цены из брифа и язык текста должны соответствовать одному рынку: при Kč — весь рекламный текст на чешском, не на румынском/польском/венгерском.
|
|
109027
|
+
ЗАПРЕЩЕНО копировать на макет примеры формулировок из этого промпта, если они на другом языке, чем требуется для ${generateGeo} — примеры только про структуру, слова придумывай на целевом языке.
|
|
108646
109028
|
|
|
108647
109029
|
🚫 СЛУЖЕБНЫЕ СЛОВА НЕ РИСОВАТЬ НА КАРТИНКЕ (КРИТИЧНО):
|
|
108648
109030
|
Слова HOOK, CTA, CAPS, BULLET, HEADLINE, PRICE, DISCOUNT, BULLETS, LAYER и любые похожие английские метки из этой инструкции (в т.ч. thumb‑stop) — только для тебя; на макете их НЕТ ни на кнопке, ни на плашках, ни мелким текстом. Кнопка: только реальный призыв на языке ${generateGeo} (1–2 слова), без префикса «CTA». Заголовок: только живой текст оффера, без слова HOOK. Заголовок делай прописными буквами на языке ${generateGeo}, но не пиши на изображении слово CAPS и не подписывай блоки ярлыками.
|
|
@@ -108678,20 +109060,20 @@ HOOK / HEADLINE (строгое правило):
|
|
|
108678
109060
|
- ОБЯЗАТЕЛЬНО содержит ключевое слово проблемы ЯВНО. Примеры по категориям: простата → простатит, простата; похудение → лишний вес, похудение; суставы → боль в суставах, колени, скованность; пищеварение → дискомфорт, вздутие, тяжесть; сон → бессонница, усталость. Без ключевого слова — ОШИБКА
|
|
108679
109061
|
- HOOK ВЫШЕ всех элементов (продукт, буллеты, CTA, цена). Самый крупный текстовый элемент на креативе
|
|
108680
109062
|
- HOOK должен быть ВИЗУАЛЬНО “тяжёлым”: ОЧЕНЬ крупный, ТОЛСТЫЙ/жирный шрифт, весь текст заголовка ПРОПИСНЫМИ буквами на языке ${generateGeo}, на яркой контрастной плашке/подложке. Это верхний главный элемент, цепляющий внимание в ленте
|
|
108681
|
-
- Можно (не обязательно) включить СРОК прямо в HOOK (например «7
|
|
108682
|
-
- Заголовок должен быть РЕЗКИМ и призывным: короткие рубленые фразы, вопросы и предупреждения допустимы. Можно использовать обращение на «ты» (
|
|
109063
|
+
- Можно (не обязательно) включить СРОК прямо в HOOK (например «7 дней», «14 дней» — перенеси число и слово «дней» на язык ${generateGeo}) как триггер
|
|
109064
|
+
- Заголовок должен быть РЕЗКИМ и призывным: короткие рубленые фразы, вопросы и предупреждения допустимы. Можно использовать обращение на «ты» (естественное для языка ${generateGeo}) и вопросительный знак
|
|
108683
109065
|
- заголовок НЕ должен быть абстрактным слоганом/лозунгом или метафорой без конкретной боли. Допускается «thumb‑stop» стиль (вызов/вопрос/предупреждение), если это конкретно и релевантно категории
|
|
108684
109066
|
- если не влезает: сначала измени композицию (расширь блок/переставь элементы), затем перепиши короче. НЕЛЬЗЯ уменьшать шрифт. HOOK всегда остаётся выше всех остальных элементов
|
|
108685
109067
|
- Не повторяй один и тот же заголовок в разных подходах: для текущего подхода придумай новый, уникальный заголовок. Варьируй: угол боли, формулировку, акцент (проблема vs облегчение)
|
|
108686
|
-
- Вторая часть заголовка = конкретное улучшение, не абстрактное слово.
|
|
109068
|
+
- Вторая часть заголовка = конкретное улучшение, не абстрактное слово. ПРАВИЛЬНО (структура; на макете — только язык ${generateGeo}): боль/вопрос + конкретное облегчение. НЕ ТАК: размытые «легче», «лучше», «решение» без конкретики
|
|
108687
109069
|
- Специфические медицинские термины или диагнозы разрешены в заголовке, но не обязательны. Варьируй между прямыми формулировками (если релевантно категории) и мягкими формулировками, фокусирующимися на симптомах и дискомфорте, для разных креативов. Не используй один и тот же термин во всех креативах
|
|
108688
|
-
ПРИМЕР (
|
|
108689
|
-
- НЕ ТАК:
|
|
108690
|
-
- ТАК (пищеварение):
|
|
108691
|
-
- ТАК (суставы):
|
|
108692
|
-
- ТАК (сон):
|
|
108693
|
-
- ТАК (простата):
|
|
108694
|
-
- ТАК (похудение):
|
|
109070
|
+
ПРИМЕР (русский — только формат и ритм; на макете пиши строго на языке ${generateGeo}, не копируй русский текст, если GEO не русскоязычный):
|
|
109071
|
+
- НЕ ТАК: «Борьба с токсинами» (лозунг, абстрактно)
|
|
109072
|
+
- ТАК (пищеварение): «Вздутие мучает? Легче к вечеру»
|
|
109073
|
+
- ТАК (суставы): «Боль в суставах? Двигайся свободнее»
|
|
109074
|
+
- ТАК (сон): «Бессонные ночи? Выспишься наконец»
|
|
109075
|
+
- ТАК (простата): «Простата беспокоит? Быстрое облегчение»
|
|
109076
|
+
- ТАК (похудение): «Лишний вес? Без жёстких диет»
|
|
108695
109077
|
❗ Если заголовок > 12 слов, похож на длинное предложение или звучит как лозунг без ключевого слова проблемы — ОШИБКА → пересоздай вариант.
|
|
108696
109078
|
|
|
108697
109079
|
BULLETS (жёсткое правило, ровно 3):
|
|
@@ -108701,14 +109083,14 @@ BULLETS (жёсткое правило, ровно 3):
|
|
|
108701
109083
|
- ВИЗУАЛ БУЛЛЕТОВ: крупные, с иконками/галочками (✓), на контрастных подложках. Буллеты ВНЕ упаковки/банки — не на продукте.
|
|
108702
109084
|
- Буллиты должны быть расположены ВЕРТИКАЛЬНО (столбиком), не горизонтально в одну строку. Минимальный размер шрифта буллитов — чтобы читались на экране телефона без зума
|
|
108703
109085
|
|
|
108704
|
-
❗ ВЫБОР БУЛЛЕТОВ (КРИТИЧНО):
|
|
109086
|
+
❗ ВЫБОР БУЛЛЕТОВ (КРИТИЧНО): Если выше по промпту задан блок «ОБЯЗАТЕЛЬНЫЕ БУЛЛЕТЫ» — используй ТОЛЬКО его (перевод на язык ${generateGeo}). Если такого блока нет — выбери 3 случайных смысла из пула ниже; пул на английском только для смысла, на макете **ноль английского** — короткие фразы строго на языке ${generateGeo}. Не копируй на макет язык примеров из этого промпта, кроме целевого ${generateGeo}.
|
|
108705
109087
|
|
|
108706
|
-
ПУЛ
|
|
108707
|
-
•
|
|
108708
|
-
•
|
|
108709
|
-
•
|
|
108710
|
-
•
|
|
108711
|
-
•
|
|
109088
|
+
ПУЛ СМЫСЛОВ (английский не печатать; переписать на ${generateGeo}, 2–4 слова каждый):
|
|
109089
|
+
• Action/benefit: less discomfort, less bloating, less pain, fast relief, daily comfort, easier movement, fewer symptoms, pain-free, calm stomach, calm nights, visible result
|
|
109090
|
+
• Time/speed: effect in 7–14 days, effect in 2 weeks, fast result, relief from day one, 3× faster, from first day, in the first days
|
|
109091
|
+
• Social proof: 9 of 10 recommend, 9 of 10 men recommend, 93% confirm, 8 of 10 satisfied, thousands happy customers
|
|
109092
|
+
• Formula: natural formula, natural ingredients, no harsh chemicals, selected composition, dermatologically tested
|
|
109093
|
+
• Quality of life: active comfort, worry-free days, more energy, restful sleep, easier life
|
|
108712
109094
|
|
|
108713
109095
|
❗ Если хоть один буллет > 4 слов или похож на предложение/обещание — ОШИБКА → пересоздай.
|
|
108714
109096
|
|
|
@@ -108716,9 +109098,9 @@ TEXT LIMIT:
|
|
|
108716
109098
|
- кроме: HOOK, 3 буллетов, цены, скидки, кнопки — ЛЮБОЙ другой текст запрещён (ярлыки/подписи/дисклеймеры/пояснения)
|
|
108717
109099
|
- ИСКЛЮЧЕНИЕ: если 🎯 ПОДХОД = ${noBulletsCond} → кроме HOOK, цены, скидки, CTA — НИКАКОГО другого текста. Буллиты запрещены. Other_text/urgency/trust‑печати запрещены
|
|
108718
109100
|
- ДОПУСКАЕТСЯ (не обязательно) ОДИН бейдж срочности: только ясные формулировки («только сегодня», «последние штуки», «акция до конца дня»). ЗАПРЕЩЕНО: «24h» — непонятно что означает.
|
|
108719
|
-
- ДОПУСКАЕТСЯ (не обязательно) 1–3 trust‑печати: печати цветные, яркие, в стиле FDA. Текст СТРОГО на языке ${generateGeo} — запрещены английские слова («NATURAL», «QUALITY» и т.д.).
|
|
109101
|
+
- ДОПУСКАЕТСЯ (не обязательно) 1–3 trust‑печати: печати цветные, яркие, в стиле FDA. Текст СТРОГО на языке ${generateGeo} — запрещены английские слова («NATURAL», «QUALITY» и т.д.). По смыслу: «натуральный», «натуральный состав» — оформи короткой фразой на языке ${generateGeo}, не латиницей. Размер как минимум как у буллитов. Мелкие печати — ОШИБКА.
|
|
108720
109102
|
- HOOK + буллеты <= 24 слова суммарно (HOOK до 12, буллеты до 12); если больше — ОШИБКА → пересоздай
|
|
108721
|
-
- Если хочешь добавить ощущение срочности — делай это через формулировки в HOOK/BULLETS, через реквизит/иконки, ИЛИ (не обязательно) через один короткий бейдж срочности. Только ясные формулировки (
|
|
109103
|
+
- Если хочешь добавить ощущение срочности — делай это через формулировки в HOOK/BULLETS, через реквизит/иконки, ИЛИ (не обязательно) через один короткий бейдж срочности. Только ясные формулировки на языке ${generateGeo} (уровень смысла: «последние штуки», «только сегодня», «акция до конца дня»). ЗАПРЕЩЕНО «24h» — непонятно что означает.
|
|
108722
109104
|
|
|
108723
109105
|
CTA > PRICE:
|
|
108724
109106
|
- кнопка CTA (1–2 слова на языке ${generateGeo}) — главный якорь нижнего блока (самый контрастный элемент внизу)
|
|
@@ -108734,7 +109116,7 @@ CTA > PRICE:
|
|
|
108734
109116
|
- Скидка: «-50%» ОБЯЗАТЕЛЬНО отдельным видимым бейджем (не только в цене!). Процент скидки должен быть явно читаем. Ярко, заметно, строго НЕ на банке/упаковке, визуально слабее CTA
|
|
108735
109117
|
- Кнопка CTA (1-2 слова)
|
|
108736
109118
|
- Опционально: 1 короткий бейдж срочности (ясные формулировки: «только сегодня», «последние штуки»; ЗАПРЕЩЕНО «24h»). Бейдж в углу кадра, контрастный, но меньше CTA. НЕ обязателен
|
|
108737
|
-
- Опционально: 1–3 trust‑печати (цветные, яркие, в стиле FDA; натуральность, премиальность, безопасность). Текст СТРОГО на языке ${generateGeo} — никакого английского.
|
|
109119
|
+
- Опционально: 1–3 trust‑печати (цветные, яркие, в стиле FDA; натуральность, премиальность, безопасность). Текст СТРОГО на языке ${generateGeo} — никакого английского. По смыслу: «натуральный», «натуральный состав», «качество» — коротко на ${generateGeo}; НЕ «NATURAL», «QUALITY». Размер как минимум как у буллитов. НЕ обязательны
|
|
108738
109120
|
- ИСКЛЮЧЕНИЕ: если 🎯 ПОДХОД = ${noBulletsCond} → показывай только: HOOK + PRICE + DISCOUNT + CTA. Буллиты/urgency/trust‑печати запрещены
|
|
108739
109121
|
|
|
108740
109122
|
ВИЗУАЛ:
|